Decompiled source of FreeGrillerLibs v0.1.2
NGA.FreeGrillerLibs.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FistVR; using HarmonyLib; using Microsoft.CodeAnalysis; using Sodalite.Api; using Sodalite.ModPanel; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyCompany("NGA")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Persistent player progression! Raid, stash loot, and deploy with seemless scene/loadout saving.")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("NGA.FreeGrillerLibs")] [assembly: AssemblyTitle("BepInEx Plugin Title")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.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 NGA { public class ContractEvaluationContext { public FGContract myContract; public List<FGContractEvent> eventsInSession; public bool isFinalCheck = false; } public interface IContractConstraint { void EvaluateAndUpdateContract(ContractEvaluationContext context); string GetDescription(); } public static class ConstraintFactory { private static Dictionary<string, Func<IContractConstraint>> constraintRegistry = new Dictionary<string, Func<IContractConstraint>> { { "GrillViaProjectile", () => new GrillViaProjectileConstraint() }, { "GrillAllTargets", () => new GrillAllTargetsConstraint() } }; public static IContractConstraint GetConstraint(string id) { return constraintRegistry.ContainsKey(id) ? constraintRegistry[id]() : null; } public static void AddConstraint(string id, Func<IContractConstraint> constructor) { if (!constraintRegistry.ContainsKey(id)) { constraintRegistry[id] = constructor; } else { Debug.LogWarning((object)("Constraint '" + id + "' is already registered.")); } } public static FGContract.ConstraintAndReward CreateConstraintAndReward(FGContract.ConstraintAndReward constraintData, bool isItMet, bool isItFailed) { FGContract.ConstraintAndReward result = default(FGContract.ConstraintAndReward); result.ConstraintID = constraintData.ConstraintID; result.optional = constraintData.optional; result.constraintSuccess = isItMet; result.constraintViolated = isItFailed; result.rewardAddedIfSucceed = constraintData.rewardAddedIfSucceed; result.rewardSubtractedIfFail = constraintData.rewardSubtractedIfFail; return result; } public static void UpdateConstraintInContract(ContractEvaluationContext context, string constraintID, bool isConstraintMet, bool isConstraintFailed) { List<FGContract.ConstraintAndReward> list = context.myContract.ConstraintsAndRewards.FindAll((FGContract.ConstraintAndReward x) => x.ConstraintID == constraintID); if (list.Count == 0) { Debug.LogError((object)(constraintID + " constraint not found in contract.")); return; } foreach (FGContract.ConstraintAndReward item in list) { int index = context.myContract.ConstraintsAndRewards.IndexOf(item); context.myContract.ConstraintsAndRewards[index] = CreateConstraintAndReward(item, isConstraintMet, isConstraintFailed); } } public static bool IsConstraintInConstract(FGContract contract, string constraintID) { return contract.ConstraintsAndRewards.Exists((FGContract.ConstraintAndReward x) => x.ConstraintID == constraintID); } public static bool AreThereTargetsInScene() { return FG_GM.Instance.mapLoader.TargetPosses.Count > 0; } public static bool IsContractInAnyPosse(FGContract contract) { foreach (FGTargetPosse targetPoss in FG_GM.Instance.mapLoader.TargetPosses) { if ((Object)(object)targetPoss == (Object)null || targetPoss.contract == null || targetPoss.contract.uniqueID != contract.uniqueID) { continue; } return true; } return false; } } public class GrillViaProjectileConstraint : IContractConstraint { public string constraintKey = "GrillViaProjectile"; public void EvaluateAndUpdateContract(ContractEvaluationContext context) { //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Invalid comparison between Unknown and I4 if (!ConstraintFactory.IsConstraintInConstract(context.myContract, constraintKey) || !ConstraintFactory.AreThereTargetsInScene() || !ConstraintFactory.IsContractInAnyPosse(context.myContract)) { return; } FGTargetPosse fGTargetPosse = FG_GM.Instance.mapLoader.TargetPosses.Find((FGTargetPosse x) => x.contract.uniqueID == context.myContract.uniqueID); List<FGContractEvent> list = context.eventsInSession.FindAll((FGContractEvent x) => x.EventKey == "OnSosigKill"); int num = 0; HashSet<Sosig> hashSet = new HashSet<Sosig>(); foreach (FGContractEvent item in list) { if (item.OnSosigKill == null) { continue; } Sosig sosig = item.OnSosigKill.Sosig; if ((Object)(object)sosig == (Object)null) { Debug.LogError((object)"Unexpected sosig null OnSosigKill."); continue; } if (hashSet.Contains(sosig)) { Debug.LogError((object)"Sosig already killed by projectile - unexpected event again."); continue; } FGTrackedSosig fGTrackedSosig = fGTargetPosse.FindSosig(sosig); if (fGTrackedSosig != null && fGTrackedSosig.Manifest?.IsTarget == true) { num++; DamageClass diedFromClass = sosig.GetDiedFromClass(); if ((int)diedFromClass == 1) { hashSet.Add(sosig); } } } bool isConstraintMet = num > 0 && num == hashSet.Count; bool isConstraintFailed = false; if (context.isFinalCheck) { isConstraintFailed = num > 0 && num != hashSet.Count; } ConstraintFactory.UpdateConstraintInContract(context, constraintKey, isConstraintMet, isConstraintFailed); } public string GetDescription() { return "Eliminate all targets with a projectile."; } } public class GrillAllTargetsConstraint : IContractConstraint { public string constraintKey = "GrillAllTargets"; public void EvaluateAndUpdateContract(ContractEvaluationContext context) { if (!ConstraintFactory.IsConstraintInConstract(context.myContract, constraintKey) || !ConstraintFactory.AreThereTargetsInScene() || !ConstraintFactory.IsContractInAnyPosse(context.myContract)) { return; } FGTargetPosse fGTargetPosse = FG_GM.Instance.mapLoader.TargetPosses.Find((FGTargetPosse x) => x.contract.uniqueID == context.myContract.uniqueID); int count = fGTargetPosse.trackedTargets.Count; List<FGContractEvent> list = context.eventsInSession.FindAll((FGContractEvent x) => x.EventKey == "OnSosigKill"); HashSet<Sosig> hashSet = new HashSet<Sosig>(); foreach (FGContractEvent item in list) { if (item.OnSosigKill == null) { continue; } Sosig sosig = item.OnSosigKill.Sosig; if ((Object)(object)sosig == (Object)null) { Debug.LogError((object)"Unexpected sosig null OnSosigKill."); continue; } if (hashSet.Contains(sosig)) { Debug.LogWarning((object)"Sosig already killed - unexpected event again."); continue; } FGTrackedSosig fGTrackedSosig = fGTargetPosse.FindSosig(sosig); if (fGTrackedSosig != null && fGTrackedSosig.Manifest?.IsTarget == true) { hashSet.Add(sosig); } } bool isConstraintMet = count == hashSet.Count; bool isConstraintFailed = false; if (context.isFinalCheck) { isConstraintFailed = count != hashSet.Count; } ConstraintFactory.UpdateConstraintInContract(context, constraintKey, isConstraintMet, isConstraintFailed); } public string GetDescription() { return "Eliminate all targets."; } } [Serializable] public class FGContract { [Serializable] public class SerializableKeyValuePair { public string Key; public string Value; public SerializableKeyValuePair() { } public SerializableKeyValuePair(string key, string value) { Key = key; Value = value; } } [Serializable] public struct ReputationReward { public string FactionID; public float Rep; } [Serializable] public struct ReputationRequirement { public string FactionID; public float MinimumRep; public float MaximumRep; } [Serializable] public struct ConstraintAndReward { public string ConstraintID; public bool optional; public bool constraintSuccess; public bool constraintViolated; public int rewardSubtractedIfFail; public int rewardAddedIfSucceed; } public int uniqueID; public string DisplayName; public string HiringFactionID; public string TargetFirstName; public string TargetLastName; public string Infraction; [SerializeField] private List<SerializableKeyValuePair> TargetIDs = new List<SerializableKeyValuePair>(); [SerializeField] private List<SerializableKeyValuePair> GuardIDs = new List<SerializableKeyValuePair>(); [SerializeField] private List<SerializableKeyValuePair> ExtrasIDs = new List<SerializableKeyValuePair>(); [NonSerialized] public Dictionary<string, List<SosigEnemyID>> _TargetIDs = new Dictionary<string, List<SosigEnemyID>>(); [NonSerialized] public Dictionary<string, List<SosigEnemyID>> _GuardIDs = new Dictionary<string, List<SosigEnemyID>>(); [NonSerialized] public Dictionary<string, List<SosigEnemyID>> _ExtrasIDs = new Dictionary<string, List<SosigEnemyID>>(); [SerializeField] private List<SerializableKeyValuePair> Faction_Target = new List<SerializableKeyValuePair>(); [SerializeField] private List<SerializableKeyValuePair> Faction_Guards = new List<SerializableKeyValuePair>(); [SerializeField] private List<SerializableKeyValuePair> Faction_Extras = new List<SerializableKeyValuePair>(); [NonSerialized] public Dictionary<string, string> _Faction_Target = new Dictionary<string, string>(); [NonSerialized] public Dictionary<string, string> _Faction_Guards = new Dictionary<string, string>(); [NonSerialized] public Dictionary<string, string> _Faction_Extras = new Dictionary<string, string>(); public string SceneName; public string SceneCivConfigName; public string SceneEnemyConfigName; public List<ReputationRequirement> ReputationRequirements; public List<ConstraintAndReward> ConstraintsAndRewards = new List<ConstraintAndReward>(); public string expirationTime; public int Compensation; public List<ReputationReward> ReputationRewards; public bool hasEnded; public bool isAccepted; public bool hasSucceeded; public bool hasFailed; public DateTime ExpirationDateTime => DateTime.Parse(expirationTime); public string PrintContract() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Contract: " + DisplayName); stringBuilder.AppendLine("Hiring Faction: " + HiringFactionID); stringBuilder.AppendLine("Target: " + TargetFirstName + " " + TargetLastName); stringBuilder.AppendLine("Infraction: " + Infraction); stringBuilder.AppendLine("Scene: " + SceneName); DateTime currentTime = FGTimeSystem.Instance.CurrentTime; if (ExpirationDateTime > currentTime) { TimeSpan timeSpan = FGTimeSystem.Instance.CalculateRealTimeUntil(currentTime, ExpirationDateTime); stringBuilder.AppendLine($"Time until expiration: {timeSpan.Hours}h {timeSpan.Minutes}m {timeSpan.Seconds}s"); } stringBuilder.AppendLine($"Compensation: ${Compensation:N0}"); if (ReputationRequirements != null && ReputationRequirements.Count > 0) { stringBuilder.AppendLine("Reputation Requirements:"); foreach (ReputationRequirement reputationRequirement in ReputationRequirements) { stringBuilder.AppendLine($" - {reputationRequirement.FactionID}: {reputationRequirement.MinimumRep} to {reputationRequirement.MaximumRep}"); } } if (ReputationRewards != null && ReputationRewards.Count > 0) { stringBuilder.AppendLine("Reputation Rewards:"); foreach (ReputationReward reputationReward in ReputationRewards) { stringBuilder.AppendLine($" - {reputationReward.FactionID}: {reputationReward.Rep:+0.0;-0.0}"); } } if (ConstraintsAndRewards != null && ConstraintsAndRewards.Count > 0) { List<ConstraintAndReward> list = ConstraintsAndRewards.Where((ConstraintAndReward c) => !c.optional).ToList(); List<ConstraintAndReward> list2 = ConstraintsAndRewards.Where((ConstraintAndReward c) => c.optional).ToList(); if (list.Count > 0) { stringBuilder.AppendLine("Required Conditions:"); foreach (ConstraintAndReward item in list) { string text = (item.constraintSuccess ? "✔ Completed" : (item.constraintViolated ? "✖ Failed" : "Pending")); string text2 = ((item.rewardSubtractedIfFail > 0) ? $" -${item.rewardSubtractedIfFail}" : ""); stringBuilder.AppendLine(" - " + item.ConstraintID + " (" + text + ")" + text2); } } if (list2.Count > 0) { stringBuilder.AppendLine("Optional Bonuses:"); foreach (ConstraintAndReward item2 in list2) { string text3 = (item2.constraintSuccess ? "✔ Completed" : (item2.constraintViolated ? "✖ Failed" : "Pending")); string text4 = ((item2.rewardAddedIfSucceed > 0) ? $" +${item2.rewardAddedIfSucceed}" : ""); stringBuilder.AppendLine(" - " + item2.ConstraintID + " (" + text3 + ")" + text4); } } } return stringBuilder.ToString(); } public List<IContractConstraint> GetConstraints() { List<IContractConstraint> list = new List<IContractConstraint>(); foreach (ConstraintAndReward constraintsAndReward in ConstraintsAndRewards) { IContractConstraint constraint = ConstraintFactory.GetConstraint(constraintsAndReward.ConstraintID); if (constraint != null) { list.Add(constraint); } } return list; } public void PrepareForSave() { ConvertToSerializable(); } public void PrepareFromLoad() { ConvertToDictionary(); } public void ConvertToSerializable() { GuardIDs.Clear(); foreach (KeyValuePair<string, List<SosigEnemyID>> guardID in _GuardIDs) { GuardIDs.Add(new SerializableKeyValuePair(guardID.Key, string.Join(",", guardID.Value.Select((SosigEnemyID id) => ((int)id).ToString()).ToArray()))); } TargetIDs.Clear(); foreach (KeyValuePair<string, List<SosigEnemyID>> targetID in _TargetIDs) { TargetIDs.Add(new SerializableKeyValuePair(targetID.Key, string.Join(",", targetID.Value.Select((SosigEnemyID id) => ((int)id).ToString()).ToArray()))); } ExtrasIDs.Clear(); foreach (KeyValuePair<string, List<SosigEnemyID>> extrasID in _ExtrasIDs) { ExtrasIDs.Add(new SerializableKeyValuePair(extrasID.Key, string.Join(",", extrasID.Value.Select((SosigEnemyID id) => ((int)id).ToString()).ToArray()))); } Faction_Target.Clear(); foreach (KeyValuePair<string, string> item in _Faction_Target) { Faction_Target.Add(new SerializableKeyValuePair(item.Key, item.Value)); } Faction_Guards.Clear(); foreach (KeyValuePair<string, string> faction_Guard in _Faction_Guards) { Faction_Guards.Add(new SerializableKeyValuePair(faction_Guard.Key, faction_Guard.Value)); } Faction_Extras.Clear(); foreach (KeyValuePair<string, string> faction_Extra in _Faction_Extras) { Faction_Extras.Add(new SerializableKeyValuePair(faction_Extra.Key, faction_Extra.Value)); } } public void ConvertToDictionary() { _GuardIDs.Clear(); foreach (SerializableKeyValuePair guardID in GuardIDs) { _GuardIDs.Add(guardID.Key, (from id in guardID.Value.Split(new char[1] { ',' }) select (SosigEnemyID)int.Parse(id)).ToList()); } _TargetIDs.Clear(); foreach (SerializableKeyValuePair targetID in TargetIDs) { _TargetIDs.Add(targetID.Key, (from id in targetID.Value.Split(new char[1] { ',' }) select (SosigEnemyID)int.Parse(id)).ToList()); } _ExtrasIDs.Clear(); foreach (SerializableKeyValuePair extrasID in ExtrasIDs) { _ExtrasIDs.Add(extrasID.Key, (from id in extrasID.Value.Split(new char[1] { ',' }) select (SosigEnemyID)int.Parse(id)).ToList()); } _Faction_Target.Clear(); foreach (SerializableKeyValuePair item in Faction_Target) { _Faction_Target.Add(item.Key, item.Value); } _Faction_Guards.Clear(); foreach (SerializableKeyValuePair faction_Guard in Faction_Guards) { _Faction_Guards.Add(faction_Guard.Key, faction_Guard.Value); } _Faction_Extras.Clear(); foreach (SerializableKeyValuePair faction_Extra in Faction_Extras) { _Faction_Extras.Add(faction_Extra.Key, faction_Extra.Value); } } } public class FGContractEvent { public class OnSosigKillEvent { public Sosig Sosig { get; set; } } public class OnSosigMadeEnemyWithEvent { public Sosig Sosig { get; set; } public int IFF { get; set; } } public class OnSosigAlertEvent { public Sosig Sosig { get; set; } public Vector3 Position { get; set; } } public class OnShotFiredEvent { public FVRFireArm Firearm { get; set; } } public class OnSosiggunFiredEvent { public SosigWeapon Weapon { get; set; } } public string EventKey { get; set; } public OnSosigKillEvent OnSosigKill { get; set; } public OnSosigMadeEnemyWithEvent OnSosigMadeEnemyWith { get; set; } public OnSosigAlertEvent OnSosigAlert { get; set; } public OnShotFiredEvent OnShotFired { get; set; } public OnSosiggunFiredEvent OnSosiggunFired { get; set; } public string GenericEventContents { get; set; } } public class FGContractEventsRecorder { private bool sessionActive = false; public Action<FGContractEvent> OnEventHappened { get; set; } public Action<FGContractEvent> OnEventRegistered { get; set; } public List<FGContractEvent> CurrentSessionEvents { get; private set; } = new List<FGContractEvent>(); public FGContractEventsRecorder() { OnEventHappened = (Action<FGContractEvent>)Delegate.Combine(OnEventHappened, new Action<FGContractEvent>(AppendEventToSession)); } public void AppendEventToSession(FGContractEvent contractEvent) { if (!sessionActive) { Debug.LogWarning((object)("FGContractEventsRecorder: Attempted to append event " + contractEvent.EventKey + " to session, but session is not active.")); return; } Debug.LogWarning((object)("FGContractEventsRecorder: Appending event " + contractEvent.EventKey + " to session.")); CurrentSessionEvents.Add(contractEvent); OnEventRegistered?.Invoke(contractEvent); } public void StartSession() { Debug.Log((object)"FGContractEventsRecorder: Starting session."); sessionActive = true; CurrentSessionEvents.Clear(); ListenToClassicH3Events(); } public void WipeSession() { Debug.Log((object)"FGContractEventsRecorder: Wiping session."); sessionActive = false; CurrentSessionEvents.Clear(); StopListeningToClassicH3Events(); } private void ListenToClassicH3Events() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown GM.CurrentSceneSettings.SosigKillEvent += new SosigKill(OnSosigKill); GM.CurrentSceneSettings.SosigMadeEnemyWithEvent += new SosigMadeEnemyWith(OnSosigMadeEnemyWith); GM.CurrentSceneSettings.SosigAlertEvent += new SosigAlert(OnSosigAlert); GM.CurrentSceneSettings.ShotFiredEvent += new ShotFired(OnShotFired); GM.CurrentSceneSettings.SosiggunFiredEvent += new SosiggunFired(OnSosiggunFired); GM.CurrentSceneSettings.SosigFleeFromEvent += new SosigFleeFrom(OnSosigFleeFrom); } private void OnSosigKill(Sosig s) { FGContractEvent fGContractEvent = new FGContractEvent(); fGContractEvent.EventKey = "OnSosigKill"; fGContractEvent.OnSosigKill = new FGContractEvent.OnSosigKillEvent { Sosig = s }; OnEventHappened?.Invoke(fGContractEvent); } private void OnSosigMadeEnemyWith(Sosig S, int iff) { FGContractEvent fGContractEvent = new FGContractEvent(); fGContractEvent.EventKey = "OnSosigMadeEnemyWith"; fGContractEvent.OnSosigMadeEnemyWith = new FGContractEvent.OnSosigMadeEnemyWithEvent { Sosig = S, IFF = iff }; OnEventHappened?.Invoke(fGContractEvent); } private void OnSosigAlert(Sosig s, Vector3 p) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) FGContractEvent fGContractEvent = new FGContractEvent(); fGContractEvent.EventKey = "OnSosigAlert"; fGContractEvent.OnSosigAlert = new FGContractEvent.OnSosigAlertEvent { Sosig = s, Position = p }; OnEventHappened?.Invoke(fGContractEvent); } private void OnShotFired(FVRFireArm firearm) { FGContractEvent fGContractEvent = new FGContractEvent(); fGContractEvent.EventKey = "OnShotFired"; fGContractEvent.OnShotFired = new FGContractEvent.OnShotFiredEvent { Firearm = firearm }; OnEventHappened?.Invoke(fGContractEvent); } private void OnSosiggunFired(SosigWeapon weapon) { FGContractEvent fGContractEvent = new FGContractEvent(); fGContractEvent.EventKey = "OnSosiggunFired"; fGContractEvent.OnSosiggunFired = new FGContractEvent.OnSosiggunFiredEvent { Weapon = weapon }; OnEventHappened?.Invoke(fGContractEvent); } private void OnSosigFleeFrom(Sosig S, int iff) { FGContractEvent fGContractEvent = new FGContractEvent(); fGContractEvent.EventKey = "OnSosigFleeFrom"; fGContractEvent.OnSosigMadeEnemyWith = new FGContractEvent.OnSosigMadeEnemyWithEvent { Sosig = S, IFF = iff }; OnEventHappened?.Invoke(fGContractEvent); } private void StopListeningToClassicH3Events() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown GM.CurrentSceneSettings.SosigKillEvent -= new SosigKill(OnSosigKill); GM.CurrentSceneSettings.SosigMadeEnemyWithEvent -= new SosigMadeEnemyWith(OnSosigMadeEnemyWith); GM.CurrentSceneSettings.SosigAlertEvent -= new SosigAlert(OnSosigAlert); GM.CurrentSceneSettings.ShotFiredEvent -= new ShotFired(OnShotFired); GM.CurrentSceneSettings.SosiggunFiredEvent -= new SosiggunFired(OnSosiggunFired); GM.CurrentSceneSettings.SosigFleeFromEvent -= new SosigFleeFrom(OnSosigFleeFrom); } } public class FGContractTemplateFactory { private static List<FGContractTemplate> contractTemplates = new List<FGContractTemplate>(); public static void RegisterTemplate(FGContractTemplate template) { FGContractTemplate fGContractTemplate = contractTemplates.FirstOrDefault((FGContractTemplate t) => t.TemplateID == template.TemplateID); if (fGContractTemplate != null) { contractTemplates.Remove(fGContractTemplate); } contractTemplates.Add(template); } public static FGContractTemplate GetTemplateForFactionAndReputation(string factionID, float reputation) { List<FGContractTemplate> list = new List<FGContractTemplate>(); for (int i = 0; i < contractTemplates.Count; i++) { FGContractTemplate fGContractTemplate = contractTemplates[i]; if (fGContractTemplate.HiringFactionID != factionID) { continue; } bool flag = fGContractTemplate.ReputationRequirements.Count == 0; for (int j = 0; j < fGContractTemplate.ReputationRequirements.Count; j++) { FGContract.ReputationRequirement reputationRequirement = fGContractTemplate.ReputationRequirements[j]; if (reputationRequirement.FactionID == factionID && reputation >= reputationRequirement.MinimumRep && reputation <= reputationRequirement.MaximumRep) { flag = true; break; } } if (flag) { list.Add(fGContractTemplate); } } return (list.Count > 0) ? list[Random.Range(0, list.Count)] : null; } } [Serializable] public class FGContractTemplate { public string TemplateID; public string HiringFactionID; public string Infraction; public int MinGuards; public int MaxGuards; public List<SosigEnemyID> PossibleGuardTypes; public List<string> PossibleGuardFactionIDs; public int MinTargets = 1; public int MaxTargets; public List<SosigEnemyID> PossibleTargetTypes; public List<string> PossibleTargetFactionIDs; public int MinExtras; public int MaxExtras; public List<SosigEnemyID> PossibleExtraTypes; public List<string> PossibleExtrasFactionIDs; public List<string> PossibleScenes; public List<string> PossibleSceneCivConfigs; public List<string> PossibleSceneEnemConfigs; public int MaxConstraints = 3; public List<FGContract.ConstraintAndReward> PossibleConstraints = new List<FGContract.ConstraintAndReward>(); public int MinCompensation; public int MaxCompensation; public int MinHoursLimit = 3; public int MaxHoursLimit = 8; public List<FGContract.ReputationReward> RepRewards = new List<FGContract.ReputationReward>(); public List<FGContract.ReputationRequirement> ReputationRequirements = new List<FGContract.ReputationRequirement>(); public FGContract GenerateContract() { if (!ValidateContract()) { Debug.LogError((object)"You made a mistake Bucko! Contract invalid."); return null; } int num = Random.Range(MinCompensation, MaxCompensation); FGContract fGContract = new FGContract { uniqueID = Random.Range(0, 10000000), DisplayName = $"{HiringFactionID}: ${num}", TargetFirstName = "First", TargetLastName = "Last", Infraction = Infraction, HiringFactionID = HiringFactionID, Compensation = num, SceneName = PossibleScenes[Random.Range(0, PossibleScenes.Count)], SceneCivConfigName = GetRandomFromListOrEmpty(PossibleSceneCivConfigs), SceneEnemyConfigName = GetRandomFromListOrEmpty(PossibleSceneEnemConfigs), ConstraintsAndRewards = GenerateConstraints(MaxConstraints), expirationTime = FGTimeSystem.Instance.GetInGameTimeAfterRealDuration(TimeSpan.FromHours(Random.Range(MinHoursLimit, MaxHoursLimit))).ToString("o"), ReputationRequirements = ReputationRequirements, hasEnded = false, isAccepted = false, hasSucceeded = false, hasFailed = false, ReputationRewards = RepRewards }; AssignTargetsGuardsExtras(fGContract); AssignFactionsTargetsGuardsExtras(fGContract); fGContract.ConvertToSerializable(); return fGContract; } private bool ValidateContract() { bool result = PossibleScenes.Count > 0; if (MinTargets < 1) { Debug.LogError((object)"I expected MinTargets must be at least 1."); } return result; } private void AssignTargetsGuardsExtras(FGContract contract) { int num = Random.Range(MinTargets, MaxTargets + 1); int num2 = Random.Range(MinGuards, MaxGuards + 1); int num3 = Random.Range(MinExtras, MaxExtras + 1); Debug.Log((object)$"Assigning {num} targets, {num2} guards, {num3} extras."); Debug.Log((object)("PossibleTargetTypes: " + string.Join(", ", PossibleTargetTypes.Select((SosigEnemyID type) => ((object)(SosigEnemyID)(ref type)).ToString()).ToArray()))); Debug.Log((object)("PossibleGuardTypes: " + string.Join(", ", PossibleGuardTypes.Select((SosigEnemyID type) => ((object)(SosigEnemyID)(ref type)).ToString()).ToArray()))); contract._TargetIDs["targets"] = SelectRandomSubset(PossibleTargetTypes, num); contract._GuardIDs["guards"] = SelectRandomSubset(PossibleGuardTypes, num2); contract._ExtrasIDs["extras"] = SelectRandomSubset(PossibleExtraTypes, num3); } private void AssignFactionsTargetsGuardsExtras(FGContract contract) { Debug.Log((object)("PossibleTargetFactionIDs: " + string.Join(", ", PossibleTargetFactionIDs.ToArray()))); Debug.Log((object)("PossibleGuardFactionIDs: " + string.Join(", ", PossibleGuardFactionIDs.ToArray()))); contract._Faction_Target["targets"] = GetRandomFromListOrEmpty(PossibleTargetFactionIDs); contract._Faction_Guards["guards"] = GetRandomFromListOrEmpty(PossibleGuardFactionIDs); contract._Faction_Extras["extras"] = GetRandomFromListOrEmpty(PossibleExtrasFactionIDs); } private string GetRandomFromListOrEmpty(List<string> list) { return (list != null && list.Count > 0) ? list[Random.Range(0, list.Count)] : ""; } private List<SosigEnemyID> SelectRandomSubset(List<SosigEnemyID> source, int count) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) List<SosigEnemyID> list = new List<SosigEnemyID>(); if (source.Count == 0) { return list; } for (int i = 0; i < count; i++) { list.Add(source[Random.Range(0, source.Count)]); } return list; } private List<FGContract.ConstraintAndReward> GenerateConstraints(int maxConstraints) { List<FGContract.ConstraintAndReward> list = new List<FGContract.ConstraintAndReward>(); if (PossibleConstraints.Count > 0) { list.AddRange(PossibleConstraints.OrderBy((FGContract.ConstraintAndReward _) => Random.value).Take(Mathf.Min(maxConstraints, PossibleConstraints.Count))); } return list; } } public class FGContractManager : MonoBehaviour { public struct Config { public List<FGContract> activeContracts; public List<FGContract> availableContracts; public List<FGContract> completedContracts; } public static FGContractManager Instance; private List<FGContract> activeContracts = new List<FGContract>(); private List<FGContract> availableContracts = new List<FGContract>(); private List<FGContract> completedContracts = new List<FGContract>(); private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } else { Object.Destroy((Object)(object)((Component)this).gameObject); } } public void InitFromConfig(Config config) { if (config.activeContracts == null) { Debug.LogWarning((object)"activeContracts is null, initializing as empty list."); config.activeContracts = new List<FGContract>(); } if (config.availableContracts == null) { Debug.LogWarning((object)"availableContracts is null, initializing as empty list."); config.availableContracts = new List<FGContract>(); } if (config.completedContracts == null) { Debug.LogWarning((object)"completedContracts is null, initializing as empty list."); config.completedContracts = new List<FGContract>(); } activeContracts = config.activeContracts; availableContracts = config.availableContracts; completedContracts = config.completedContracts; foreach (FGContract activeContract in activeContracts) { if (activeContract != null) { activeContract.PrepareFromLoad(); } else { Debug.LogWarning((object)"Found null contract in activeContracts list."); } } foreach (FGContract availableContract in availableContracts) { if (availableContract != null) { availableContract.PrepareFromLoad(); } else { Debug.LogWarning((object)"Found null contract in availableContracts list."); } } foreach (FGContract completedContract in completedContracts) { if (completedContract != null) { completedContract.PrepareFromLoad(); } else { Debug.LogWarning((object)"Found null contract in completedContracts list."); } } } public Config GetConfig() { foreach (FGContract activeContract in activeContracts) { activeContract.PrepareForSave(); } foreach (FGContract availableContract in availableContracts) { availableContract.PrepareForSave(); } foreach (FGContract completedContract in completedContracts) { completedContract.PrepareForSave(); } Config result = default(Config); result.activeContracts = activeContracts; result.availableContracts = availableContracts; result.completedContracts = completedContracts; return result; } public List<FGContract> GetActiveContracts() { return activeContracts; } public List<FGContract> GetAvailableContracts() { return availableContracts; } public List<FGContract> GetCompletedContracts() { return completedContracts; } private void Start() { } private void OnEnable() { FGTimeSystem.Instance.OnTimeAdvanced += CheckContractExpirations; FGTimeSystem.Instance.OnTimeAdvanced += MaybeAddNewContract; } private void OnDisable() { FGTimeSystem.Instance.OnTimeAdvanced -= CheckContractExpirations; FGTimeSystem.Instance.OnTimeAdvanced -= MaybeAddNewContract; } private void GenerateContract(string factionID, float forPlayerReputation) { FGContractTemplate templateForFactionAndReputation = FGContractTemplateFactory.GetTemplateForFactionAndReputation(factionID, forPlayerReputation); if (templateForFactionAndReputation == null) { Debug.LogWarning((object)$"No contract template found for faction {factionID} with reputation {forPlayerReputation}"); return; } FGContract fGContract = templateForFactionAndReputation.GenerateContract(); if (fGContract == null) { Debug.LogError((object)("Failed to generate contract from template " + templateForFactionAndReputation.TemplateID + " for faction " + factionID)); return; } availableContracts.Add(fGContract); Debug.Log((object)("Generated contract from template: " + fGContract.DisplayName + " for faction " + fGContract.HiringFactionID)); } public void AcceptContract(int uniqueID) { FGContract fGContract = availableContracts.FirstOrDefault((FGContract c) => c.uniqueID == uniqueID); if (fGContract != null) { activeContracts.Add(fGContract); availableContracts.Remove(fGContract); Debug.Log((object)$"Contract with ID {uniqueID} has been accepted."); } else { Debug.LogWarning((object)$"No contract found with uniqueID {uniqueID}."); } } public void RejectContract(int uniqueID) { FGContract fGContract = activeContracts.FirstOrDefault((FGContract c) => c.uniqueID == uniqueID); if (fGContract != null) { activeContracts.Remove(fGContract); Debug.Log((object)$"Contract with ID {uniqueID} has been rejected."); } else { Debug.LogWarning((object)$"No contract found with uniqueID {uniqueID}."); } } private void CheckContractExpirations(DateTime currentTime) { for (int num = activeContracts.Count - 1; num >= 0; num--) { if (IsContractExpired(activeContracts[num])) { Debug.Log((object)("Contract expired: " + activeContracts[num].DisplayName)); AddToCompletedContracts(activeContracts[num]); activeContracts.RemoveAt(num); } } for (int num2 = availableContracts.Count - 1; num2 >= 0; num2--) { if (IsContractExpired(availableContracts[num2])) { Debug.Log((object)("Contract expired: " + availableContracts[num2].DisplayName)); availableContracts.RemoveAt(num2); } } } private void MaybeAddNewContract(DateTime currentTime) { if (availableContracts.Count < 3) { GenerateNewContract(); } } private void AddToCompletedContracts(FGContract contract) { completedContracts.Insert(0, contract); int num = 10; while (completedContracts.Count > num) { completedContracts.RemoveAt(num); } } private bool IsContractExpired(FGContract contract) { DateTime currentTime = FGTimeSystem.Instance.CurrentTime; DateTime expirationDateTime = contract.ExpirationDateTime; return currentTime >= expirationDateTime; } private void GenerateNewContract() { GenerateContract("Hollys", 0f); } public void EvaluateAndUpdateActiveContractsOnEvent(FGContractEvent contractEvent) { Debug.LogWarning((object)("Evaluating contracts on event " + contractEvent.EventKey)); ContractEvaluationContext contractEvaluationContext = new ContractEvaluationContext(); contractEvaluationContext.eventsInSession = FG_GM.Instance.eventsRecorder.CurrentSessionEvents; for (int num = activeContracts.Count - 1; num >= 0; num--) { FGContract fGContract = (contractEvaluationContext.myContract = activeContracts[num]); for (int i = 0; i < fGContract.ConstraintsAndRewards.Count; i++) { FGContract.ConstraintAndReward constraintAndReward = fGContract.ConstraintsAndRewards[i]; IContractConstraint constraint = ConstraintFactory.GetConstraint(constraintAndReward.ConstraintID); if (constraint == null) { Debug.LogWarning((object)("Constraint " + constraintAndReward.ConstraintID + " not found.")); } else { constraint.EvaluateAndUpdateContract(contractEvaluationContext); } } } } public void CheckContractCompletionOnAreaExit() { ContractEvaluationContext contractEvaluationContext = new ContractEvaluationContext(); contractEvaluationContext.eventsInSession = FG_GM.Instance.eventsRecorder.CurrentSessionEvents; for (int num = activeContracts.Count - 1; num >= 0; num--) { FGContract fGContract = (contractEvaluationContext.myContract = activeContracts[num]); contractEvaluationContext.isFinalCheck = true; bool flag = false; bool flag2 = false; int num2 = fGContract.ConstraintsAndRewards.Count((FGContract.ConstraintAndReward c) => !c.optional); int num3 = 0; int num4 = 0; for (int i = 0; i < fGContract.ConstraintsAndRewards.Count; i++) { FGContract.ConstraintAndReward constraintAndReward = fGContract.ConstraintsAndRewards[i]; IContractConstraint constraint = ConstraintFactory.GetConstraint(constraintAndReward.ConstraintID); if (constraint == null) { Debug.LogWarning((object)("Constraint " + constraintAndReward.ConstraintID + " not found.")); continue; } constraint.EvaluateAndUpdateContract(contractEvaluationContext); FGContract.ConstraintAndReward constraintAndReward2 = fGContract.ConstraintsAndRewards[i]; if (constraintAndReward2.constraintSuccess) { num4 += constraintAndReward.rewardAddedIfSucceed; if (!constraintAndReward.optional) { num3++; } } else if (constraintAndReward2.constraintViolated) { num4 -= constraintAndReward.rewardSubtractedIfFail; if (!constraintAndReward2.optional) { Debug.LogWarning((object)("Contract '" + fGContract.DisplayName + "' failed due to constraint " + constraintAndReward.ConstraintID)); flag2 = true; break; } } else if (ConstraintFactory.IsContractInAnyPosse(fGContract) && !constraintAndReward2.optional) { flag2 = true; break; } } if (ConstraintFactory.IsContractInAnyPosse(fGContract) && num3 < num2) { flag2 = true; } else if (num3 >= num2) { flag = true; num4 += fGContract.Compensation; } if (num4 < 0) { num4 = 0; } if (flag) { FGBank.TransactionRecord transaction = new FGBank.TransactionRecord(num4, fGContract.DisplayName); FG_GM.Instance.bank.ProcessTransaction(transaction, forceDecrement: false); foreach (FGContract.ReputationReward reputationReward in fGContract.ReputationRewards) { FG_GM.Instance.factionStance.TryAdjustReputation(reputationReward.FactionID, reputationReward.Rep); } Debug.LogWarning((object)$"Contract '{fGContract.uniqueID}' completed! Total reward: {num4}"); AddToCompletedContracts(fGContract); activeContracts.RemoveAt(num); } else if (flag2) { Debug.LogWarning((object)$"Contract '{fGContract.uniqueID}' failed!"); AddToCompletedContracts(fGContract); activeContracts.RemoveAt(num); } } } } [Serializable] public class FGLoadManifest { public List<FGMap> maps; public List<FGFaction> factions; public List<FGContractTemplate> contractTemplates; } public class FGExternalLoader { public static void LoadManifestsFromBepinex() { try { string pluginPath = Paths.PluginPath; if (!Directory.Exists(pluginPath)) { return; } string[] directories = Directory.GetDirectories(pluginPath); foreach (string text in directories) { string text2 = Path.Combine(text, "fgLoadManifest.json"); if (!File.Exists(text2)) { continue; } FGLoadManifest fGLoadManifest = ExtractManifestFromFile(text2); if (fGLoadManifest == null) { continue; } if (fGLoadManifest.maps != null) { foreach (FGMap map in fGLoadManifest.maps) { FG_GM.Instance.MapContainer?.RegisterMap(map, text); } } else { Debug.LogError((object)("No maps found in manifest: " + text2)); } if (fGLoadManifest.factions != null) { foreach (FGFaction faction in fGLoadManifest.factions) { FG_GM.Instance.factionStance?.RegisterFaction(faction); } } else { Debug.LogError((object)("No factions found in manifest: " + text2)); } if (fGLoadManifest.contractTemplates != null) { foreach (FGContractTemplate contractTemplate in fGLoadManifest.contractTemplates) { FGContractTemplateFactory.RegisterTemplate(contractTemplate); } } else { Debug.LogError((object)("No contract templates found in manifest: " + text2)); } } } catch (Exception ex) { Debug.LogError((object)("Failed to load manifests from Bepinex: " + ex.Message)); } } public static FGLoadManifest ExtractManifestFromFile(string fullFileName) { try { string text = File.ReadAllText(fullFileName); return JsonUtility.FromJson<FGLoadManifest>(text); } catch (Exception ex) { Debug.LogError((object)("Failed to load manifest from " + fullFileName + ": " + ex.Message)); return null; } } } [Serializable] public class FGState { [SerializeField] private List<string> valid_homes = new List<string>(); [SerializeField] private List<string> valid_areas = new List<string>(); public string timeSysConfig; public string contractManConfig; public string bankConfig; public string factionStanceConfig; public static FGState GetDefaultSave() { FGState fGState = new FGState(); fGState.AddValidHome("IndoorRange_Updated"); fGState.AddValidArea("Grillhouse_2Story"); return fGState; } public void AddValidArea(string sceneName) { if (!valid_areas.Contains(sceneName)) { valid_areas.Add(sceneName); } } public bool IsValidArea(string sceneName) { return valid_areas.Contains(sceneName); } public bool IsValidHome(string sceneName) { return valid_homes.Contains(sceneName); } public void AddValidHome(string sceneName) { if (!valid_homes.Contains(sceneName)) { valid_homes.Add(sceneName); } } } public class FG_GM : MonoBehaviour { public FGSceneManip mapLoader; public FGContractManager contractMan; public FGTimeSystem timeSys; public FGBank bank; public FGFactionStance factionStance; public FGContractEventsRecorder eventsRecorder; public bool causedInTransitioningLevels = false; public string lastTransitionedToSceneName = ""; private string saveSlotName = "SaveSlot0"; public string wristUiSpawnId = "NGA_FgWristUi"; private FGContract contractForTransition; public static FG_GM Instance { get; private set; } public FGState saveState { get; private set; } public FGMapsContainer MapContainer { get; private set; } private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } else { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void Start() { timeSys = ((Component)this).gameObject.AddComponent<FGTimeSystem>(); mapLoader = ((Component)this).gameObject.AddComponent<FGSceneManip>(); contractMan = ((Component)this).gameObject.AddComponent<FGContractManager>(); MapContainer = new FGMapsContainer(); bank = new FGBank(); factionStance = new FGFactionStance(); eventsRecorder = new FGContractEventsRecorder(); SceneManager.sceneLoaded += OnSceneLoaded; if (!GM.CurrentSceneSettings.QuitReceivers.Contains(((Component)this).gameObject)) { GM.CurrentSceneSettings.QuitReceivers.Add(((Component)this).gameObject); } Init(); FGExternalLoader.LoadManifestsFromBepinex(); } private void Init() { ((MonoBehaviour)this).StartCoroutine(SpawnWristMenuWithRetries(40, 3f)); InitSaveState(); } private void InitSaveState() { try { if (saveState == null) { FGFileIoHandler.LoadFGState(saveSlotName, out var state); if (state != null) { saveState = state; InitTimeSysFromSave(); InitContractManFromSave(); InitBankFromSave(); InitFactionStanceFromSave(); } else { saveState = FGState.GetDefaultSave(); SaveGameState(); } } } catch (Exception ex) { Debug.LogError((object)("Exception in InitSaveState: " + ex.Message + "\n" + ex.StackTrace)); } } private void InitTimeSysFromSave() { if (saveState == null || string.IsNullOrEmpty(saveState.timeSysConfig)) { Debug.LogError((object)"Save state or time system config is null. Cannot initialize time system."); return; } FGTimeSystem.Config config = JsonUtility.FromJson<FGTimeSystem.Config>(saveState.timeSysConfig); timeSys.InitFromConfig(config); } private void InitContractManFromSave() { if (saveState == null || string.IsNullOrEmpty(saveState.contractManConfig)) { Debug.LogError((object)"Save state or contract manager config is null. Cannot initialize contract manager."); return; } FGContractManager.Config config = JsonUtility.FromJson<FGContractManager.Config>(saveState.contractManConfig); contractMan.InitFromConfig(config); } private void InitBankFromSave() { if (saveState == null || string.IsNullOrEmpty(saveState.bankConfig)) { Debug.LogError((object)"Save state or bank config is null. Cannot initialize bank."); return; } FGBank.Config config = JsonUtility.FromJson<FGBank.Config>(saveState.bankConfig); bank.InitFromConfig(config); } private void InitFactionStanceFromSave() { if (saveState == null || string.IsNullOrEmpty(saveState.factionStanceConfig)) { Debug.LogError((object)"Save state or faction stance config is null. Cannot initialize faction stance."); return; } FGFactionStance.Config config = JsonUtility.FromJson<FGFactionStance.Config>(saveState.factionStanceConfig); factionStance.InitFromConfig(config); } private void SaveGameState() { saveState.timeSysConfig = JsonUtility.ToJson((object)timeSys.GetConfig()); saveState.contractManConfig = JsonUtility.ToJson((object)contractMan.GetConfig()); saveState.bankConfig = JsonUtility.ToJson((object)bank.GetConfig()); saveState.factionStanceConfig = JsonUtility.ToJson((object)factionStance.GetConfig()); FGFileIoHandler.SaveFGState(saveSlotName, saveState); } private bool VerifyTransitionOk(string goto_scene) { if (causedInTransitioningLevels) { return false; } if (!Application.CanStreamedLevelBeLoaded(goto_scene)) { Debug.LogError((object)"Scene name requested does not exist."); return false; } if (!saveState.IsValidHome(goto_scene) && !saveState.IsValidArea(goto_scene)) { Debug.LogError((object)"Character not allowed to travel to that area."); return false; } return true; } private void HandleContractCompletion() { contractMan.CheckContractCompletionOnAreaExit(); eventsRecorder.WipeSession(); FGContractEventsRecorder fGContractEventsRecorder = eventsRecorder; fGContractEventsRecorder.OnEventRegistered = (Action<FGContractEvent>)Delegate.Remove(fGContractEventsRecorder.OnEventRegistered, new Action<FGContractEvent>(contractMan.EvaluateAndUpdateActiveContractsOnEvent)); } public void TransitionToLevel(string goto_scene) { if (VerifyTransitionOk(goto_scene)) { VaultSaveBeforeTransition(goto_scene); HandleContractCompletion(); causedInTransitioningLevels = true; SteamVR_LoadLevel.Begin(goto_scene, false, 0.5f, 0f, 0f, 0f, 1f); } } public void TransitionToLevelFromContract(FGContract contract) { if (!causedInTransitioningLevels) { string sceneName = contract.SceneName; TransitionToLevel(sceneName); if (causedInTransitioningLevels) { contractForTransition = contract; } } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Debug.LogWarning((object)"-------> OnSceneLoaded"); if (!GM.CurrentSceneSettings.QuitReceivers.Contains(((Component)this).gameObject)) { GM.CurrentSceneSettings.QuitReceivers.Add(((Component)this).gameObject); } ((MonoBehaviour)this).StartCoroutine(SpawnWristMenuWithRetries(60, 1f)); SaveGameState(); if (causedInTransitioningLevels) { eventsRecorder.StartSession(); FGContractEventsRecorder fGContractEventsRecorder = eventsRecorder; fGContractEventsRecorder.OnEventRegistered = (Action<FGContractEvent>)Delegate.Combine(fGContractEventsRecorder.OnEventRegistered, new Action<FGContractEvent>(contractMan.EvaluateAndUpdateActiveContractsOnEvent)); if (saveState.IsValidArea(((Scene)(ref scene)).name)) { if (contractForTransition == null) { ((MonoBehaviour)this).StartCoroutine(TryWithRetries(() => mapLoader.InitArea(saveSlotName, ((Scene)(ref scene)).name), 10, 1f)); } else { ((MonoBehaviour)this).StartCoroutine(TryWithRetries(() => mapLoader.InitAreaFromContract(saveSlotName, contractForTransition), 10, 1f)); contractForTransition = null; } } else if (saveState.IsValidHome(((Scene)(ref scene)).name)) { ((MonoBehaviour)this).StartCoroutine(TryWithRetries(() => mapLoader.InitHome(saveSlotName, ((Scene)(ref scene)).name), 10, 1f)); } causedInTransitioningLevels = false; lastTransitionedToSceneName = ((Scene)(ref scene)).name; } else { lastTransitionedToSceneName = ""; } } private void VaultSaveBeforeTransition(string goto_scene) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (lastTransitionedToSceneName != name) { Debug.LogWarning((object)("Scene we're traveling from was not arrived at through FG_GM - FG_GM last took us to " + lastTransitionedToSceneName)); } if (lastTransitionedToSceneName == name) { if (saveState.IsValidHome(lastTransitionedToSceneName)) { SaveHomeSceneConfigToFile(name); SavePlayerQuickbetToFile(); } else if (saveState.IsValidArea(lastTransitionedToSceneName)) { SavePlayerQuickbetToFile(); } else { Debug.LogError((object)("We're transitioning from an FG traveled-to scene that's neither area nor home: " + name)); } } else { Debug.LogWarning((object)("We're not transitioning from an FG traveled-to scene: " + name)); } } private void QUIT() { if (saveState.IsValidHome(lastTransitionedToSceneName)) { SaveHomeSceneConfigToFile(lastTransitionedToSceneName); SavePlayerQuickbetToFile(); } SaveGameState(); } public void SaveHomeSceneConfigToFile(string currSceneName) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown VaultFile val = new VaultFile(); if (!VaultSystem.FindAndScanObjectsInScene(val) || !FGFileIoHandler.SaveHomeVaultFile(saveSlotName, currSceneName, val)) { Debug.LogError((object)"Failed to scan or write player QB durin level transition."); } else { Debug.LogWarning((object)("Succeeded saving home name: " + currSceneName)); } } public void SavePlayerQuickbetToFile() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown VaultFile val = new VaultFile(); if (!VaultSystem.FindAndScanObjectsInQuickbelt(val)) { Debug.LogWarning((object)"Empty quickbelt!"); } if (!FGFileIoHandler.SavePlayerQuickbelt(saveSlotName, val)) { Debug.LogError((object)"Failed to write player QB."); } else { Debug.LogWarning((object)"Succeeded saving player QB."); } } public static IEnumerator TryWithRetries(Func<bool> retryMethod, int maxRetries, float delay) { int attempts = 0; while (attempts < maxRetries) { if (retryMethod()) { Debug.Log((object)$"Operation succeeded on attempt {attempts + 1}."); yield break; } attempts++; Debug.LogWarning((object)$"Operation failed. Retrying {attempts}/{maxRetries} in {delay} seconds..."); yield return (object)new WaitForSeconds(delay); } Debug.LogError((object)$"Operation failed after {maxRetries} attempts."); } private bool SpawnWristMenu() { //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) if (!IM.OD.TryGetValue(wristUiSpawnId, out var value)) { Debug.LogError((object)(wristUiSpawnId + " not found in IM.OD!")); return false; } try { GameObject val = Object.Instantiate<GameObject>(((AnvilAsset)value).GetGameObject(), Vector3.zero, Quaternion.identity); } catch (Exception ex) { Debug.LogError((object)("Failed to spawn wrist menu: " + ex.Message)); return false; } Debug.LogWarning((object)(wristUiSpawnId + " supposedly spawned")); return true; } private IEnumerator SpawnWristMenuWithRetries(int maxRetries, float delay) { int attempts = 0; bool finalCheck = false; while (attempts < maxRetries) { if (finalCheck) { FGWristUi2[] wristUIs = Object.FindObjectsOfType<FGWristUi2>(); if (wristUIs.Length != 0) { for (int i = 1; i < wristUIs.Length; i++) { Object.Destroy((Object)(object)((Component)wristUIs[i]).gameObject); } Debug.Log((object)$"Wrist menu spawned successfully for sure on attempt {attempts + 1}."); yield break; } finalCheck = false; } if (SpawnWristMenu()) { Debug.Log((object)$"Wrist menu spawned successfully on attempt {attempts + 1}. Checking..."); finalCheck = true; yield return (object)new WaitForSeconds(delay); } attempts++; Debug.LogWarning((object)$"Wrist menu spawn failed. Retrying {attempts}/{maxRetries} in {delay} seconds..."); yield return (object)new WaitForSeconds(delay); } Debug.LogError((object)$"Wrist menu failed to spawn after {maxRetries} attempts."); } } public class FGMapFactionAssigner { private Dictionary<string, int> factionToIFF; private int nextIFF; public FGMapFactionAssigner() { factionToIFF = new Dictionary<string, int>(); nextIFF = 1; factionToIFF["player"] = 0; } public int AssignIFF(string factionId) { if (factionToIFF.ContainsKey(factionId)) { return factionToIFF[factionId]; } if (nextIFF > 32) { Debug.LogError((object)"Exceeded maximum number of IFFs - seting to -3"); return -3; } factionToIFF[factionId] = nextIFF; return nextIFF++; } public void SetSosigFriendlyToFaction(Sosig s, string factionId, bool isFriendly) { int num = AssignIFF(factionId); s.Priority.IFFChart[num] = isFriendly; } public void SetSosigThreatableToFaction(Sosig s, string factionId, bool isThreatable) { int num = AssignIFF(factionId); s.Priority.ThreatableChart[num] = isThreatable; } public static void MakeSosigThreatenableToAll(Sosig s) { for (int i = 0; i < s.Priority.ThreatableChart.Length; i++) { s.Priority.ThreatableChart[i] = true; } } } [Serializable] public class FGPaths { public List<Transform> Path; } [Serializable] public class FGSosigMandate { public Transform SpawnPoint; public FGPaths Path; public FGSosigManifest Manifest; } public class FGTrackedSosig { public Sosig SosigInstance; public FGPaths Path; public FGSosigManifest Manifest; } [Serializable] public class FGMap { public string sceneName; public string DisplayName; public int price = 0; public int mapType; public string defaultCivSceneConfigFileName; public string defaultEnemySceneConfigFileName; public List<string> otherSceneConfigFileNames = new List<string>(); public FGMap(FGMap other) { sceneName = other.sceneName; DisplayName = other.DisplayName; price = other.price; mapType = other.mapType; defaultCivSceneConfigFileName = other.defaultCivSceneConfigFileName; defaultEnemySceneConfigFileName = other.defaultEnemySceneConfigFileName; IEnumerable<string> enumerable = other.otherSceneConfigFileNames; otherSceneConfigFileNames = new List<string>(enumerable ?? Enumerable.Empty<string>()); } } public class FGMapsContainer { public List<FGMap> maps = new List<FGMap>(); public bool IsHomeRegistered(string sceneName) { return maps.Exists((FGMap map) => map.sceneName == sceneName && map.mapType == 0); } public bool IsSceneRegistered(string sceneName) { return maps.Exists((FGMap map) => map.sceneName == sceneName); } public bool IsAreaRegistered(string sceneName) { return maps.Exists((FGMap map) => map.sceneName == sceneName && map.mapType == 1); } public int GetHomePrice(string sceneName) { return maps.Find((FGMap map) => map.sceneName == sceneName).price; } public void RegisterMap(FGMap map, string sourceFolderName) { if (map == null) { Debug.LogError((object)("Cannot register null map: " + sourceFolderName)); return; } FGMap fGMap = maps.Find((FGMap m) => m.sceneName == map.sceneName); if (fGMap == null) { FGMap fGMap2 = new FGMap(map); maps.Add(fGMap2); fGMap2.defaultCivSceneConfigFileName = (string.IsNullOrEmpty(map.defaultCivSceneConfigFileName) ? string.Empty : Path.Combine(sourceFolderName, map.defaultCivSceneConfigFileName)); fGMap2.defaultEnemySceneConfigFileName = (string.IsNullOrEmpty(map.defaultEnemySceneConfigFileName) ? string.Empty : Path.Combine(sourceFolderName, map.defaultEnemySceneConfigFileName)); } else { fGMap.DisplayName = map.DisplayName; fGMap.price = map.price; fGMap.mapType = map.mapType; fGMap.defaultCivSceneConfigFileName = (string.IsNullOrEmpty(map.defaultCivSceneConfigFileName) ? string.Empty : Path.Combine(sourceFolderName, map.defaultCivSceneConfigFileName)); fGMap.defaultEnemySceneConfigFileName = (string.IsNullOrEmpty(map.defaultEnemySceneConfigFileName) ? string.Empty : Path.Combine(sourceFolderName, map.defaultEnemySceneConfigFileName)); fGMap.otherSceneConfigFileNames.AddRange(map.otherSceneConfigFileNames?.Select((string fileName) => string.IsNullOrEmpty(fileName) ? string.Empty : Path.Combine(sourceFolderName, fileName)) ?? Enumerable.Empty<string>()); } FGMap fGMap3 = maps.Find((FGMap m) => m.sceneName == map.sceneName); if (!string.IsNullOrEmpty(fGMap3.defaultCivSceneConfigFileName)) { FGFileIoHandler.CopyDefaultAreaConfigFile(fGMap3.sceneName, fGMap3.defaultCivSceneConfigFileName, isEnemy: false); } if (!string.IsNullOrEmpty(map.defaultEnemySceneConfigFileName)) { FGFileIoHandler.CopyDefaultAreaConfigFile(fGMap3.sceneName, fGMap3.defaultEnemySceneConfigFileName, isEnemy: true); } IEnumerable<string> otherSceneConfigFileNames = fGMap3.otherSceneConfigFileNames; foreach (string item in otherSceneConfigFileNames ?? Enumerable.Empty<string>()) { FGFileIoHandler.CopyAreaConfigFile(fGMap3.sceneName, item); } if (map.mapType == 1) { FG_GM.Instance.saveState.AddValidArea(fGMap3.sceneName); } } } public class FGSceneManip : MonoBehaviour { public List<FGTargetPosse> TargetPosses { get; private set; } = new List<FGTargetPosse>(); private void Start() { } private void Update() { } public void ResetFGSceneManip() { TargetPosses.Clear(); } public bool InitHome(string saveSlotName, string sceneName) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) ResetFGSceneManip(); if (GM.IsAsyncLoading) { Debug.LogWarning((object)"Waiting InitHome, IsAsyncLoading aka vault loading."); return false; } string text = ""; VaultSystem.ClearExistingSaveableObjects(true); if (!FGFileIoHandler.LoadHomeVaultFile(saveSlotName, sceneName, out var vf)) { Debug.LogError((object)"Loading CGriller Home Scene file failed"); } else if (VaultSystem.SpawnVaultFile(vf, ((Component)this).transform, false, false, true, ref text, Vector3.zero, (ReturnObjectListDelegate)null, true)) { Debug.LogWarning((object)"Scene config loaded for home."); } else { Debug.LogError((object)("Failed to load scene with error: " + text + "\n on " + (object)vf)); } GM.CurrentMovementManager.TeleportToPoint(GM.CurrentSceneSettings.DeathResetPoint.position, false); SpawnPlayerQbWithRetry(saveSlotName); return true; } public bool InitArea(string saveSlotName, string sceneName) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) ResetFGSceneManip(); if (GM.IsAsyncLoading) { Debug.LogWarning((object)"Waiting InitArea, IsAsyncLoading aka vault loading."); return false; } VaultSystem.ClearExistingSaveableObjects(true); if (FGFileIoHandler.DoesAreaVaultFileExists(sceneName, FGFileIoHandler.default_civ_vault_name)) { SpawnAreaVaultFile(sceneName, FGFileIoHandler.default_civ_vault_name); } ((MonoBehaviour)this).StartCoroutine(FG_GM.TryWithRetries(delegate { if (PLtoFG.TransformPLtoFG()) { ScanAndProcessModeObjects(null); return true; } return false; }, 15, 1f)); GM.CurrentMovementManager.TeleportToPoint(GM.CurrentSceneSettings.DeathResetPoint.position, false); SpawnPlayerQbWithRetry(saveSlotName); return true; } public bool InitAreaFromContract(string saveSlotName, FGContract contract) { //IL_00e2: Unknown result type (might be due to invalid IL or missing references) ResetFGSceneManip(); if (GM.IsAsyncLoading) { Debug.LogWarning((object)"Waiting InitArea, IsAsyncLoading aka vault loading."); return false; } string sceneName = contract.SceneName; string sceneCivConfigName = contract.SceneCivConfigName; VaultSystem.ClearExistingSaveableObjects(true); if (FGFileIoHandler.DoesAreaVaultFileExists(sceneName, sceneCivConfigName)) { SpawnAreaVaultFile(sceneName, sceneCivConfigName); } string text = ((contract.SceneEnemyConfigName == "") ? FGFileIoHandler.default_enemy_vault_name : contract.SceneEnemyConfigName); if (FGFileIoHandler.DoesAreaVaultFileExists(sceneName, text)) { SpawnAreaVaultFile(sceneName, text); } ((MonoBehaviour)this).StartCoroutine(FG_GM.TryWithRetries(delegate { if (PLtoFG.TransformPLtoFG()) { ScanAndProcessModeObjects(contract); return true; } return false; }, 15, 1f)); GM.CurrentMovementManager.TeleportToPoint(GM.CurrentSceneSettings.DeathResetPoint.position, false); SpawnPlayerQbWithRetry(saveSlotName); return true; } private void SpawnAreaVaultFile(string sceneName, string vault_file) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) string text = ""; if (!FGFileIoHandler.LoadAreaVaultFile(sceneName, vault_file, out var vf)) { Debug.LogError((object)("Loading CGriller Area Scene file failed " + sceneName + vault_file)); return; } if (VaultSystem.SpawnVaultFile(vf, ((Component)this).transform, false, false, false, ref text, Vector3.zero, (ReturnObjectListDelegate)null, true)) { Debug.LogWarning((object)("Scene config loaded for area " + sceneName + vault_file)); return; } Debug.LogError((object)("Failed to load scene with error: " + text + "\n on " + ((object)vf)?.ToString() + " " + vault_file)); } public void SpawnPlayerQbWithRetry(string saveSlotName) { ((MonoBehaviour)this).StartCoroutine(FG_GM.TryWithRetries(() => SpawnPlayerQb(saveSlotName), 15, 1f)); } public bool SpawnPlayerQb(string saveSlotName) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (GM.IsAsyncLoading) { Debug.LogWarning((object)"Waiting SpawnPlayerQb, IsAsyncLoading aka vault loading."); return false; } if (!FGFileIoHandler.LoadPlayerQuickbelt(saveSlotName, out var vaultFile)) { Debug.LogError((object)"Loading CGriller Quickbelt file failed"); return true; } string text = ""; if (!GM.IsAsyncLoading && VaultSystem.SpawnVaultFile(vaultFile, ((Component)this).transform, false, true, false, ref text, Vector3.zero, (ReturnObjectListDelegate)null, true)) { Debug.LogWarning((object)"Succeeded loading player loady"); return true; } Debug.LogError((object)("Failed to spawn player loadout for reason:" + text)); return true; } private void ScanAndProcessModeObjects(FGContract contract) { FGTargetPosse[] array = Object.FindObjectsOfType<FGTargetPosse>(); if (array.Length == 0) { Debug.LogWarning((object)"No FGTargetPosse objects found in the scene."); return; } int num = Random.Range(0, array.Length); FGTargetPosse fGTargetPosse = array[num]; if (contract != null) { fGTargetPosse.SetContract(contract); } fGTargetPosse.SelectAndSpawnPosseConfig(); TargetPosses.Add(fGTargetPosse); } } [Serializable] public class FGSosigManifest { [HideInInspector] public string Faction; [HideInInspector] public string FirstName; [HideInInspector] public string LastName; public string UniqueId; public int IFF = -3; public int SosigOrder; public int EnemyId; public bool IsTarget; public bool IsGuard; public bool IsExtra; } public static class FGSosigSpawner { public static Sosig SpawnMySosig(FGSosigMandate mandate) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) //IL_0053: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_00c2: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) if (mandate == null || mandate.Manifest == null || (Object)(object)mandate.SpawnPoint == (Object)null) { Debug.LogError((object)"Invalid SosigMandate! Ensure Mandate, Manifest, and SpawnPoint are assigned."); return null; } FGSosigManifest manifest = mandate.Manifest; Vector3 position = mandate.SpawnPoint.position; Quaternion rotation = mandate.SpawnPoint.rotation; Sosig val = SosigAPI.Spawn(ManagerSingleton<IM>.Instance.odicSosigObjsByID[(SosigEnemyID)manifest.EnemyId], new SpawnOptions(), position, rotation); if ((Object)(object)val == (Object)null) { Debug.LogError((object)"Sosig spawn failed!"); return null; } int iFF = ((manifest.IFF == -1) ? Random.Range(8, 32) : manifest.IFF); val.SetIFF(iFF); val.CurrentOrder = (SosigOrder)manifest.SosigOrder; val.FallbackOrder = (SosigOrder)manifest.SosigOrder; val.SetDominantGuardDirection(rotation * Vector3.forward); val.UpdateGuardPoint(position); val.UpdateAssaultPoint(position); val.SetGuardInvestigateDistanceThreshold(3f); val.UpdateIdlePoint(position); val.SetDominantGuardDirection(((Component)val).transform.forward); val.CanBeThreatened = true; FGMapFactionAssigner.MakeSosigThreatenableToAll(val); val.FallbackOrder = (SosigOrder)manifest.SosigOrder; if (mandate.Path != null && mandate.Path.Path.Count > 0) { val.CommandPathTo(mandate.Path.Path, 0.2f, new Vector2(1f, 10f), 1.2f, (SosigMoveSpeed)3, (PathLoopType)3, (List<Sosig>)null, 0.3f, 10f, false, 20f); } return val; } } public class FGTargetPosse : MonoBehaviour { [Serializable] public class PosseConfig { public List<FGSosigMandate> Targets = new List<FGSosigMandate>(); public List<FGSosigMandate> Guards = new List<FGSosigMandate>(); public List<FGSosigMandate> Extras = new List<FGSosigMandate>(); } public List<PosseConfig> TargetConfigs = new List<PosseConfig>(); public FGContract contract { get; private set; } public PosseConfig selectedPosseConfig { get; private set; } public List<FGTrackedSosig> trackedTargets { get; private set; } = new List<FGTrackedSosig>(); public List<FGTrackedSosig> trackedGuards { get; private set; } = new List<FGTrackedSosig>(); public List<FGTrackedSosig> trackedExtras { get; private set; } = new List<FGTrackedSosig>(); public FGMapFactionAssigner factionAssigner { get; private set; } private void Awake() { factionAssigner = new FGMapFactionAssigner(); } public void SetContract(FGContract newContract) { DestroyAll(); contract = newContract; } public void DestroyAll() { foreach (FGTrackedSosig trackedTarget in trackedTargets) { Object.Destroy((Object)(object)((Component)trackedTarget.SosigInstance).gameObject); } foreach (FGTrackedSosig trackedGuard in trackedGuards) { Object.Destroy((Object)(object)((Component)trackedGuard.SosigInstance).gameObject); } foreach (FGTrackedSosig trackedExtra in trackedExtras) { Object.Destroy((Object)(object)((Component)trackedExtra.SosigInstance).gameObject); } trackedTargets.Clear(); trackedGuards.Clear(); trackedExtras.Clear(); selectedPosseConfig = null; } public void SelectAndSpawnPosseConfig() { if (TargetConfigs.Count != 0) { selectedPosseConfig = TargetConfigs[Random.Range(0, TargetConfigs.Count)]; SpawnSelectedConfig(); } } public void AddPosseConfig(PosseConfig config) { TargetConfigs.Add(config); } public FGTrackedSosig FindSosig(Sosig sosig) { foreach (FGTrackedSosig trackedTarget in trackedTargets) { if ((Object)(object)trackedTarget.SosigInstance == (Object)(object)sosig) { return trackedTarget; } } foreach (FGTrackedSosig trackedGuard in trackedGuards) { if ((Object)(object)trackedGuard.SosigInstance == (Object)(object)sosig) { return trackedGuard; } } foreach (FGTrackedSosig trackedExtra in trackedExtras) { if ((Object)(object)trackedExtra.SosigInstance == (Object)(object)sosig) { return trackedExtra; } } return null; } private void SpawnSelectedConfig() { if (selectedPosseConfig == null || contract == null) { Debug.LogError((object)"No selected posse config or contract."); return; } trackedTargets.Clear(); trackedGuards.Clear(); trackedExtras.Clear(); SpawnEntities(contract._TargetIDs, isTarget: true, isGuard: false, isExtra: false, selectedPosseConfig.Targets, trackedTargets); SpawnEntities(contract._GuardIDs, isTarget: false, isGuard: true, isExtra: false, selectedPosseConfig.Guards, trackedGuards); SpawnEntities(contract._ExtrasIDs, isTarget: false, isGuard: false, isExtra: true, selectedPosseConfig.Extras, trackedExtras); } private void SpawnEntities(Dictionary<string, List<SosigEnemyID>> entityList, bool isTarget, bool isGuard, bool isExtra, List<FGSosigMandate> mandateList, List<FGTrackedSosig> trackedList) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected I4, but got Unknown HashSet<int> pickedIndexes = new HashSet<int>(); foreach (KeyValuePair<string, List<SosigEnemyID>> entity in entityList) { string key = entity.Key; List<SosigEnemyID> value = entity.Value; if (value != null && value.Count != 0) { SosigEnemyID val = (SosigEnemyID)((value != null && value.Count > 0) ? ((int)value[Random.Range(0, value.Count)]) : 0); FGSosigMandate fGSosigMandate = PickUnpickedMandate(key, pickedIndexes, mandateList); if (fGSosigMandate == null) { break; } fGSosigMandate.Manifest.EnemyId = (int)val; if (isTarget) { fGSosigMandate.Manifest.Faction = (contract._Faction_Target.TryGetValue(key, out var value2) ? value2 : ""); fGSosigMandate.Manifest.FirstName = contract.TargetFirstName; fGSosigMandate.Manifest.LastName = contract.TargetLastName; fGSosigMandate.Manifest.IsTarget = true; } else if (isGuard) { fGSosigMandate.Manifest.Faction = (contract._Faction_Guards.TryGetValue(key, out var value3) ? value3 : ""); fGSosigMandate.Manifest.IsGuard = true; } else { fGSosigMandate.Manifest.Faction = (contract._Faction_Extras.TryGetValue(key, out var value4) ? value4 : ""); fGSosigMandate.Manifest.IsExtra = true; } if (string.IsNullOrEmpty(fGSosigMandate.Manifest.UniqueId)) { fGSosigMandate.Manifest.UniqueId = Random.Range(0, 99999).ToString(); } FGTrackedSosig fGTrackedSosig = SpawnNpcFromMandate(fGSosigMandate); if (fGTrackedSosig != null) { trackedList.Add(fGTrackedSosig); ConfigureSosigFaction(fGTrackedSosig, fGSosigMandate.Manifest.Faction); } } } } private FGSosigMandate PickUnpickedMandate(string uniqueId, HashSet<int> pickedIndexes, List<FGSosigMandate> mandates) { for (int i = 0; i < mandates.Count; i++) { FGSosigMandate fGSosigMandate = mandates[i]; if (!pickedIndexes.Contains(i) && fGSosigMandate.Manifest.UniqueId == uniqueId) { pickedIndexes.Add(i); return fGSosigMandate; } } for (int j = 0; j < mandates.Count; j++) { if (!pickedIndexes.Contains(j)) { pickedIndexes.Add(j); return mandates[j]; } } return null; } private FGTrackedSosig SpawnNpcFromMandate(FGSosigMandate mandate) { if (mandate == null || (Object)(object)mandate.SpawnPoint == (Object)null || mandate.Manifest == null) { Debug.LogError((object)"Either spawn point or manifest null"); return null; } Sosig val = FGSosigSpawner.SpawnMySosig(mandate); if ((Object)(object)val == (Object)null) { return null; } return new FGTrackedSosig { SosigInstance = val, Path = mandate.Path, Manifest = mandate.Manifest }; } private void ConfigureSosigFaction(FGTrackedSosig trackedSosig, string faction) { Sosig sosigInstance = trackedSosig.SosigInstance; FGFactionStance factionStance = FG_GM.Instance.factionStance; factionStance.GetFactionEnemies(faction, out var enemies); sosigInstance.SetIFF(factionAssigner.AssignIFF(faction)); sosigInstance.CanBeThreatened = true; sosigInstance.Priority.SetAllFriendly(); FGMapFactionAssigner.MakeSosigThreatenableToAll(sosigInstance); foreach (string item in enemies) { factionAssigner.SetSosigFriendlyToFaction(sosigInstance, item, isFriendly: false); } if (!trackedSosig.Manifest.IsTarget && !trackedSosig.Manifest.IsGuard) { return; } IEnumerable<string> enumerable = contract._Faction_Target.Values.Concat(contract._Faction_Guards.Values).Distinct(); foreach (string item2 in enumerable) { factionAssigner.SetSosigFriendlyToFaction(sosigInstance, item2, isFriendly: true); factionAssigner.SetSosigThreatableToFaction(sosigInstance, item2, isThreatable: false); } } } [BepInPlugin("NGA.FreeGrillerPatchy", "FreeGrillerPatchy", "0.0.1")] [BepInDependency("nrgill28.Sodalite", "1.4.1")] [BepInProcess("h3vr.exe")] public class FreeGrillerPatchy : BaseUnityPlugin { [HarmonyPatch(typeof(GM))] [HarmonyPatch("Awake")] public class FG_GM_Initializer { private static void Postfix(GM __instance) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)FG_GM.Instance == (Object)null) { GameObject val = new GameObject("FG_GM"); val.AddComponent<FG_GM>(); Object.DontDestroyOnLoad((Object)(object)val); } } } [HarmonyPatch(typeof(FVRSceneSettings))] [HarmonyPatch("LoadDefaultSceneRoutine")] private class FVRSceneSettingsLoadDefaultSceneRoutineHook { private static bool Prefix(FVRSceneSettings __instance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (!FG_GM.Instance.causedInTransitioningLevels) { string lastTransitionedToSceneName = FG_GM.Instance.lastTransitionedToSceneName; Scene activeScene = SceneManager.GetActiveScene(); if (!(lastTransitionedToSceneName == ((Scene)(ref activeScene)).name)) { return true; } } return false; } } private static ConfigEntry<bool> GameEnabled; private static ConfigEntry<float> SprintSpeedCap; internal static ManualLogSource Logger { get; private set; } private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; Harmony val = new Harmony("NGA.FreeGrillerPatchy"); Logger.LogMessage((object)"New harmony"); SetUpConfigFields(); Logger.LogMessage((object)"Setted the fields"); val.PatchAll(); Logger.LogMessage((object)"Hello, world! Sent from NGA.FreeGrillerPatchy"); } private void SetUpConfigFields() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown GameEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Overall", "ON/OFF", true, "Completely enable/disable mod"); SprintSpeedCap = ((BaseUnityPlugin)this).Config.Bind<float>("TwinStickArmSwing", "Sprint Added speed v2", 2f, new ConfigDescription("Sprint speed soft-cap on armswing. Bigger than jog.", (AcceptableValueBase)new AcceptableValueFloatRangeStep(0f, 20f, 0.05f), new object[0])); } private static bool CheckSkip() { return !GameEnabled.Value; } } public class FGBank { public struct Config { public int playerBalance; public List<TransactionRecord> transactions; } [Serializable] public class TransactionRecord { public int amount; public string description; public TransactionRecord(int amount, string description) { this.amount = amount; this.description = description; } } public int playerBalance { get; private set; } public List<TransactionRecord> transactions { get; private set; } public FGBank() { playerBalance = 0; transactions = new List<TransactionRecord>(); } public void InitFromConfig(Config config) { playerBalance = config.playerBalance; transactions = config.transactions ?? new List<TransactionRecord>(); } public Config GetConfig() { Config result = default(Config); result.playerBalance = playerBalance; result.transactions = new List<TransactionRecord>(transactions); return result; } public bool TryDecrementPlyBalance(int amount) { if (playerBalance >= amount) { playerBalance -= amount; return true; } return false; } public void ForceDecrementPlyBalance(int amount) { playerBalance -= amount; } public void IncrementPlyBalance(int amount) { playerBalance += amount; } public void ProcessTransaction(TransactionRecord transaction, bool forceDecrement) { if (transaction.amount < 0) { if (forceDecrement) { ForceDecrementPlyBalance(-transaction.amount); } else if (!TryDecrementPlyBalance(-transaction.amount)) { return; } } else { IncrementPlyBalance(transaction.amount); } transactions.Insert(0, transaction); } public string PrintPlyBankInfo(int maxTransactions = 10) { string text = $"<b>Current balance:</b> ${playerBalance:N0}\n\n"; text += "<b>Recent transactions:</b>\n"; int num = 0; foreach (TransactionRecord transaction in transactions) { if (num++ >= maxTransactions) { break; } text += $"${transaction.amount:N0} {transaction.description}\n"; } return text; } } [Serializable] public class FGFaction { public string FactionId; public float currentReputation; public float startingReputation; public float maxPossibleReputation; public float minPossibleReputation; public List<string> AlwaysHostileTowardsFactionIds; } public class FGFactionStance { [Serializable] public struct Config { public List<FGFaction> Factions; } public List<FGFaction> factions = new List<FGFaction>(); public FGFactionStance() { factions = new List<FGFaction>(); } public void InitFromConfig(Config config) { factions = config.Factions; } public Config GetConfig() { Config result = default(Config); result.Factions = factions; return result; } public void RegisterFaction(FGFaction faction) { FGFaction fGFaction = factions.FirstOrDefault((FGFaction f) => f.FactionId == faction.FactionId); if (fGFaction != null) { fGFaction.startingReputation = faction.startingReputation; fGFaction.maxPossibleReputation = faction.maxPossibleReputation; fGFaction.minPossibleReputation = faction.minPossibleReputation; { foreach (string alwaysHostileTowardsFactionId in faction.AlwaysHostileTowardsFactionIds) { if (!fGFaction.AlwaysHostileTowardsFactionIds.Contains(alwaysHostileTowardsFactionId)) { fGFaction.AlwaysHostileTowardsFactionIds.Add(alwaysHostileTowardsFactionId); } } return; } } factions.Add(faction); } public bool TryAdjustReputation(string factionId, float adjustment) { FGFaction fGFaction = factions.FirstOrDefault((FGFaction f) => f.FactionId == factionId); if (fGFaction == null) { return false; } fGFaction.currentReputation = Mathf.Clamp(fGFaction.currentReputation + adjustment, fGFaction.minPossibleReputation, fGFaction.maxPossibleReputation); return true; } public float GetReputationWithFaction(string factionId) { return factions.FirstOrDefault((FGFaction f) => f.FactionId == factionId)?.currentReputation ?? 0f; } public bool IsFactionHostileTowards(string sourceFaction, string toFaction) { return factions.FirstOrDefault((FGFaction f) => f.FactionId == sourceFaction)?.AlwaysHostileTowardsFactionIds.Contains(toFaction) ?? false; } public bool GetFactionEnemies(string factionId, out List<string> enemies) { FGFaction fGFaction = factions.FirstOrDefault((FGFaction f) => f.FactionId == factionId); if (fGFaction == null) { enemies = new List<string>(); return false; } enemies = fGFaction.AlwaysHostileTowardsFactionIds; return true; } public string PrintFactionStance() { StringBuilder stringBuilder = new StringBuilder(); foreach (FGFaction faction in factions) { stringBuilder.AppendLine("<b>Faction ID:</b> " + faction.FactionId); stringBuilder.AppendLine($"<b>Current Reputation:</b> {faction.currentReputation}"); stringBuilder.AppendLine($"<b>Max Reputation:</b> {faction.maxPossibleReputation}"); stringBuilder.AppendLine($"<b>Min Reputation:</b> {faction.minPossibleReputation}"); stringBuilder.AppendLine("<b>Always Hostile Towards:</b> " + string.Join(", ", faction.AlwaysHostileTowardsFactionIds.ToArray())); stringBuilder.AppendLine("---------------------------"); } return stringBuilder.ToString(); } } public class FGTimeSystem : MonoBehaviour { public struct Config { public string CurrTime; public float timeMult; } public static FGTimeSystem Instance; private float realTimeElapsed = 0f; private int lastReportedHour; public float timeMultiplier { get; set; } = 24f; public DateTime CurrentTime { get; private set; } = DateTime.Now; public event Action<DateTime> OnTimeAdvanced; public event Action<DateTime> OnHourPassed; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } else { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void Start() { lastReportedHour = CurrentTime.Hour; } private void Update() { realTimeElapsed += Time.deltaTime * timeMultiplier; if (realTimeElapsed >= 1f) { int num = Mathf.FloorToInt(realTimeElapsed); realTimeElapsed -= num; CurrentTime = CurrentTime.AddSeconds(num); if (CurrentTime.Hour != lastReportedHour) { lastReportedHour = CurrentTime.Hour; this.OnHourPassed?.Invoke(CurrentTime); } } } public void AdvanceTime(int seconds) { CurrentTime = CurrentTime.AddSeconds(seconds); this.OnTimeAdvanced?.Invoke(CurrentTime); } public DateTime GetInGameTimeAfterRealDuration(TimeSpan realDuration) { DateTime currentTime = CurrentTime; double totalSeconds = realDuration.TotalSeconds; double value = totalSeconds * (double)timeMultiplier; return currentTime.AddSeconds(value); } public TimeSpan CalculateRealTimeUntil(DateTime startTime, DateTime targetTime) { if (targetTime <= startTime) { return TimeSpan.Zero; } double totalSeconds = (targetTime - startTime).TotalSeconds; double value = totalSeconds / (double)timeMultiplier; return TimeSpan.FromSeconds(value); } public void InitFromConfig(Config config) { CurrentTime = LoadGameTime(config.CurrTime); timeMultiplier = config.timeMult; lastReportedHour = CurrentTime.Hour; } public Config GetConfig() { Config result = default(Config); result.CurrTime = SaveGameTime(); result.timeMult = timeMultiplier; return result; } public string SaveGameTime() { return CurrentTime.ToString("o"); } private DateTime LoadGameTime(string dateTimeString) { if (string.IsNullOrEmpty(dateTimeString)) { return DateTime.Now; } DateTime result = DateTime.Parse(dateTimeString, null, DateTimeStyles.RoundtripKind); bool flag = false; return result; } } public class FGTimeUi2 : MonoBehaviour { [SerializeField] public Text timeText; private void Start() { ((MonoBehaviour)this).InvokeRepeating("UpdateTimeDisplay", 1f, 1f); } private void UpdateTimeDisplay() { if ((Object)(object)FGTimeSystem.Instance != (Object)null && (Object)(object)timeText != (Object)null) { DateTime dateTime = FGTimeSystem.Instance.CurrentTime.ToLocalTime(); timeText.text = dateTime.ToString("MM/dd/yy HH:mm:ss"); } } private void OnDisable() { ((MonoBehaviour)this).CancelInvoke("UpdateTimeDisplay"); } } public class FGWristUi2 : MonoBehaviour { private int selectedTabIx = 0; private int currQuestTabType = 0; private int selectedQuestIndex = -1; [Header("UI References")] private Transform Canvas; private Transform TimeText; private Transform TravelTab; private Transform ContractsTab; private Transform ContractsVertList; private Transform ContractStickerTempl; private Transform TimeTab; private Transform BankTab; private Transform RepTab; public Transform Face; public FVRViveHand[] Hands = (FVRViveHand[])(object)new FVRViveHand[2]; private FVRViveHand m_currentHand; private bool m_hasHands = false; private bool m_isActive = false; private float m_wristPointRange = 60f; private float m_faceAngleRange = 45f; public void Start() { SetHandsAndFace(((Component)GM.CurrentPlayerBody.RightHand).GetComponent<FVRViveHand>(), ((Component)GM.CurrentPlayerBody.LeftHand).GetComponent<FVRViveHand>(), ((Component)GM.CurrentPlayerBody.EyeCam).transform); FindUiVariables(); AddTimeUiRunner(); CloseTabs(); } public void Update() { UpdateWristMenu(); } private void FindUiVariables() { Canvas = ((Component)this).transform.Find("Canvas"); TravelTab = Canvas.Find("TravelTab"); ContractsTab = Canvas.Find("ContractsTab"); TimeTab = Canvas.Find("TimeTab"); BankTab = Canvas.Find("BankTab"); RepTab = Canvas.Find("RepTab"); TimeText = Canvas.Find("QuickMenu").Find("Time"); ContractsVertList = ContractsTab.Find("ContractsList").Find("ViewPort").Find("Content"); ContractStickerTempl = ContractsTab.Find("ContractsList").Find("ContractStickerTmpl"); } public void CloseTabs() { ((Component)TravelTab).gameObject.SetActive(false); ((Component)ContractsTab).gameObject.SetActive(false); ((Component)TimeTab).gameObject.SetActive(false); ((Component)BankTab).gameObject.SetActive(false); ((Component)RepTab).gameObject.SetActive(false); } public void BTN_DisplayQuests(int i) { //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown currQuestTabType = i; selectedQuestIndex = -1; for (int j = 0; j < ContractsVertList.childCount; j++) { Object.Destroy((Object)(object)((Component)ContractsVertList.GetChild(j)).gameObject); } List<FGContract> currentContractList = GetCurrentContractList(); string text = i switch { 0 => "[Available]", 1 => "[Active]", 2 => "[Finished]", _ => "", }; for (int k = 0; k < currentContractList.Count; k++) { FGContract fGContract = currentContractList[k]; Transform transform = Object.Instantiate<GameObject>(((Component)ContractStickerTempl).gameObject, ContractsVertList).transform; Text componentInChildren = ((Component)transform.Find("Description")).GetComponentInChildren<Text>(); componentInChildren.text = fGContract.DisplayName + "\n" + fGContract.TargetFirstName + " " + fGContract.TargetLastName + "\n" + fGContract.Infraction + "\n" + text; int index = k; Button component = ((Component)transform.Find("Btn_MoreDetails").Find("BTN_MoreDetails")).GetComponent<Button>(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { BTN_DisplayQuestDetail(index); }); ((Component)transform).gameObject.SetActive(true); } selectedQuestIndex = ((currentContractList.Count == 0) ? (-1) : 0); BTN_DisplayQuestDetail(selectedQuestIndex); } public void BTN_DisplayQuestDetail(int i = -1) { selectedQuestIndex = i; Text componentInChildren = ((Component)ContractsTab.Find("ContractDescription").Find("DescriptionScroll").Find("ViewPort") .Find("Description")).GetComponentInChildren<Text>(); if (selectedQuestIndex < 0) { componentInChildren.text = ""; return; } List<FGContract> currentContractList = GetCurrentContractList(); if (selectedQuestIndex >= currentContractList.Count) { componentInChildren.text = "Selected index is invalid " + selectedQuestIndex + " compared to available contracts list " + currentContractList.Count; return; } FGContract fGContract = currentContractList[selectedQuestIndex]; componentInChildren.text = fGContract.PrintContract(); } private List<FGContract> GetCurrentContractList() { return currQuestTabType switch { 0 => FG_GM.Instance.contractMan.GetAvailableContracts(), 1 => FG_GM.Instance.contractMan.GetActiveContracts(), 2 => FG_GM.Instance.contractMan.GetCompletedContracts(), _ => new List<FGContract>(), }; } public void BTN_AcceptContract() { if (selectedQuestIndex < 0 || currQuestTabType != 0) { Debug.LogWarning((object)("Selected index is invalid " + selectedQuestIndex + " or you didn't select Available tab " + currQuestTabType)); return; } List<FGContract> currentContractList = GetCurrentContractList(); if (selectedQuestIndex >= currentContractList.Count) { Debug.LogWarning((object)("Selected index is invalid too big " + selectedQuestIndex + " compared to available contracts list " + currentContractList.Count)); return; } FG_GM.Instance.contractMan.AcceptContract(currentContractList[selectedQuestIndex].uniqueID); BTN_DisplayQuests(currQuestTabType); Debug.LogWarning((object)"Allegedly accepted quest."); } public void BTN_RejectContract() { if (selectedQuestIndex < 0 || currQuestTabType != 1) { Debug.LogWarning((object)("Selected index is invalid " + selectedQuestIndex + " or you didn't select Active tab " + currQuestTabType)); return; } List<FGContract> currentContractList = GetCurrentContractList(); if (selectedQuestIndex >= currentContractList.Count) { Debug.LogWarning((object)("Selected index is invalid too big " + selectedQuestIndex + " compared to active contracts list " + currentContractList.Count)); return; } FG_GM.Instance.contractMan.RejectContract(currentContractList[selectedQuestIndex].uniqueID); BTN_DisplayQuests(currQuestTabType); Debug.LogWarning((object)"Allegedly rejected quest."); } public void BTN_TravelToContractLevel() { if (selectedQuestIndex < 0 || currQuestTabType != 1) { Debug.LogWarning((object)("Selected index is invalid " + selectedQuestIndex + " or you didn't select Active tab " + currQuestTabType)); return; } List<FGContract> currentContractList = GetCurrentContractList(); if (selectedQuestIndex >= currentContractList.Count) { Debug.LogWarning((object)("Selected index is invalid too big " + selectedQuestIndex + " compared to active contracts list " + currentContractList.Count)); } else { FG_GM.Instance.TransitionToLevelFromContract(currentContractList[selectedQuestIndex]); } } public void BTN_RefreshBankInfo() { ((Component)BankTab.Find("Description")).GetComponentInChildren<Text>().text = FG_GM.Instance.bank.PrintPlyBankInfo(); } public void BTN_RefreshRepInfo() { ((Component)RepTab.Find("Description")).GetComponentInChildren<Text>().text = FG_GM.Instance.factionStance.PrintFactionStance(); } public void BTN_OpenTab(int index) { CloseTabs(); switch (index) { case 0: ((Component)TravelTab).gameObject.SetActive(true); break; case 1: ((Component)ContractsTab).gameObject.SetActive(true); BTN_DisplayQuests(currQuestTabType); break; case 2: ((Component)TimeTab).gameObject.SetActive(true); break; case 3: ((Component)BankTab).gameObject.SetActive(true); BTN_RefreshBankInfo(); break; case 4: ((Component)RepTab).gameObject.SetActive(true); BTN_RefreshRepInfo(); break; default: Debug.LogError((object)("Selected tab not supported: " + index)); return; } selectedTabIx = index; } public void BTN_TravelHome() { FG_GM.Instance.TransitionToLevel("IndoorRange_Updated"); } public void BTN_TravelArea() { FG_GM.Instance.TransitionToLevel("Grillhouse_2Story"); } public void BTN_AdvanceHour() { FGTimeSystem.Instance.AdvanceTime(3600); } public void AddTimeUiRunner() { FGTimeUi2 fGTimeUi = ((Component)this).gameObject.AddComponent<FGTimeUi2>(); Text componentInChildren = ((Component)TimeText).GetComponentInChildren<Text>(); if ((Object)(object)componentInChildren != (Object)null) { fGTimeUi.timeText = componentInChildren; } } private void UpdateWristMenu() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Invalid comparison between Unknown and I4 //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Invalid comparison between Unknown and I4 //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) if (!m_hasHands) { return; } if (m_isActive) { PositionWristMenu(); if ((Object)(object)m_currentHand.CurrentInteractable != (Object)null || Vector3.Angle(m_currentHand.G