Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TradeForRevive v1.0.0
TradeForRevive.dll
Decompiled 7 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("REPOJP")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("zabuMod")] [assembly: AssemblyTitle("zabuMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TradeForReviveMod { [BepInPlugin("REPOJP.TradeForRevive", "TradeForRevive", "1.0.0")] public sealed class TradeForRevivePlugin : BaseUnityPlugin { public const string PluginGuid = "REPOJP.TradeForRevive"; public const string PluginName = "TradeForRevive"; public const string PluginVersion = "1.0.0"; internal static TradeForRevivePlugin Instance; internal static ManualLogSource Log; private void Awake() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown try { Instance = this; Log = ((BaseUnityPlugin)this).Logger; ((Component)this).transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); GameObject val = new GameObject("TradeForReviveManager"); val.transform.parent = null; ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<TradeForReviveManager>(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"TradeForRevive 1.0.0 loaded"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Awake failed\n" + ex)); } } } internal sealed class TradeForReviveManager : MonoBehaviour { private sealed class HoldState { public int ItemKey; public float StartTime; } private sealed class TradeCandidate { public PlayerDeathHead DeathHead; public PlayerAvatar PlayerAvatar; public PhysGrabObject PhysGrabObject; public ItemAttributes ItemAttributes; public string SourceLabel; public int TargetHp; public float DistanceSqr; } private struct ReviveValueResult { public bool Valid; public int TargetHp; public string SourceLabel; } [CompilerGenerated] private sealed class <ExecuteTradeReviveRoutine>d__32 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public TradeCandidate candidate; public int headViewId; public TradeForReviveManager <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ExecuteTradeReviveRoutine>d__32(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!<>4__this.CanExecuteTrade(candidate)) { <>4__this.runningHeadIds.Remove(headViewId); return false; } <>4__this.ForceReleaseAllGrabbers(candidate.PhysGrabObject); <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if (!<>4__this.CanExecuteTrade(candidate)) { <>4__this.runningHeadIds.Remove(headViewId); return false; } <>4__this.ExecuteTradeCore(candidate); <>2__current = null; <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = null; <>1__state = 3; return true; case 3: <>1__state = -1; <>2__current = null; <>1__state = 4; return true; case 4: <>1__state = -1; <>4__this.FinalizeReviveHealth(candidate, headViewId); <>4__this.runningHeadIds.Remove(headViewId); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static ConfigEntry<bool> configEnableMod; private static ConfigEntry<float> configDetectRadius; private static ConfigEntry<float> configTouchHoldSeconds; private static ConfigEntry<float> configScanInterval; private static ConfigEntry<float> configHeadCooldown; private static ConfigEntry<bool> configRequirePurchasedItem; private static ConfigEntry<bool> configAllowBatteryItems; private static ConfigEntry<bool> configAllowHealthPacks; private static ConfigEntry<bool> configAllowZeroBatteryRevive; private static ConfigEntry<bool> configConsumeItem; private static ConfigEntry<bool> configDestroyWithEffects; private static ConfigEntry<bool> configDebugLog; private static readonly FieldInfo FieldPlayerDeathHeadTriggered = typeof(PlayerDeathHead).GetField("triggered", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldPlayerDeathHeadInExtractionPoint = typeof(PlayerDeathHead).GetField("inExtractionPoint", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldPlayerAvatarIsDisabled = typeof(PlayerAvatar).GetField("isDisabled", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldPlayerHealthHealth = typeof(PlayerHealth).GetField("health", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldPlayerHealthMaxHealth = typeof(PlayerHealth).GetField("maxHealth", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldItemAttributesInstanceName = typeof(ItemAttributes).GetField("instanceName", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldPhysGrabObjectImpactDetector = typeof(PhysGrabObject).GetField("impactDetector", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldPlayerDeathHeadPhysGrabObject = typeof(PlayerDeathHead).GetField("physGrabObject", BindingFlags.Instance | BindingFlags.NonPublic); private readonly Dictionary<int, float> headCooldownUntil = new Dictionary<int, float>(); private readonly HashSet<int> runningHeadIds = new HashSet<int>(); private readonly Dictionary<int, HoldState> holdStates = new Dictionary<int, HoldState>(); private float scanTimer; private void Awake() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown try { if (configEnableMod == null) { ConfigFile config = ((BaseUnityPlugin)TradeForRevivePlugin.Instance).Config; configEnableMod = config.Bind<bool>("General", "EnableMod", true, "Enable revive trading system.蘇生トレード機能の有効化"); configDetectRadius = config.Bind<float>("General", "DetectRadius", 0.55f, new ConfigDescription("Detection radius around a death head for trade items.デスヘッド周囲で引き換えアイテムを検知する半径", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>())); configTouchHoldSeconds = config.Bind<float>("General", "TouchHoldSeconds", 2f, new ConfigDescription("Required continuous contact time before revive trade activates.蘇生トレードが発動するまでに必要な連続接触時間 秒", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>())); configScanInterval = config.Bind<float>("General", "ScanInterval", 0.05f, new ConfigDescription("Scan interval in seconds.検知処理の実行間隔 秒", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>())); configHeadCooldown = config.Bind<float>("General", "HeadCooldown", 0.75f, new ConfigDescription("Cooldown per death head after a successful trade.蘇生成功後の同一デスヘッド再判定クールダウン 秒", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>())); configRequirePurchasedItem = config.Bind<bool>("General", "RequirePurchasedItem", true, "Only allow purchased items to be traded.購入済みアイテムのみ引き換え対象にする"); configAllowBatteryItems = config.Bind<bool>("General", "AllowBatteryItems", true, "Allow battery powered items as revive payment.バッテリー付きアイテムを蘇生素材として許可する"); configAllowHealthPacks = config.Bind<bool>("General", "AllowHealthPacks", true, "Allow health packs as revive payment.ヘルスパックを蘇生素材として許可する"); configAllowZeroBatteryRevive = config.Bind<bool>("General", "AllowZeroBatteryRevive", true, "Allow battery items with zero charge to revive with 1 HP.残量0のバッテリーでもHP1で蘇生を許可する"); configConsumeItem = config.Bind<bool>("General", "ConsumeItem", true, "Consume the traded item on success.蘇生成功時にアイテムを消費する"); configDestroyWithEffects = config.Bind<bool>("General", "DestroyWithEffects", false, "Destroy consumed item with normal break effects.消費アイテムを通常破壊演出ありで消す"); configDebugLog = config.Bind<bool>("Debug", "DebugLog", false, "Enable verbose debug logging.詳細デバッグログの有効化"); } ((Component)this).transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("Manager Awake failed\n" + ex)); } } private void Update() { try { if (configEnableMod == null || !configEnableMod.Value || !SemiFunc.IsMasterClientOrSingleplayer() || !SemiFunc.RunIsLevel()) { return; } scanTimer -= Time.deltaTime; if (scanTimer > 0f) { return; } scanTimer = configScanInterval.Value; if (!((Object)(object)GameDirector.instance == (Object)null) && GameDirector.instance.PlayerList != null) { for (int i = 0; i < GameDirector.instance.PlayerList.Count; i++) { PlayerAvatar player = GameDirector.instance.PlayerList[i]; TryProcessPlayerDeathHead(player); } } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("Update failed\n" + ex)); } } private void TryProcessPlayerDeathHead(PlayerAvatar player) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player.playerDeathHead == (Object)null || (Object)(object)player.playerHealth == (Object)null || !GetPlayerIsDisabled(player)) { return; } PlayerDeathHead playerDeathHead = player.playerDeathHead; PhysGrabObject deathHeadPhysGrabObject = GetDeathHeadPhysGrabObject(playerDeathHead); if (!IsDeathHeadTriggered(playerDeathHead) || (Object)(object)deathHeadPhysGrabObject == (Object)null) { return; } PhotonView component = ((Component)playerDeathHead).GetComponent<PhotonView>(); int num = (((Object)(object)component != (Object)null) ? component.ViewID : ((Object)playerDeathHead).GetInstanceID()); if (runningHeadIds.Contains(num) || (headCooldownUntil.TryGetValue(num, out var value) && Time.time < value)) { return; } Collider[] array = Physics.OverlapSphere(deathHeadPhysGrabObject.centerPoint, configDetectRadius.Value, -1, (QueryTriggerInteraction)2); if (array == null || array.Length == 0) { return; } TradeCandidate tradeCandidate = null; for (int i = 0; i < array.Length; i++) { TradeCandidate tradeCandidate2 = BuildCandidateFromCollider(array[i], playerDeathHead); if (tradeCandidate2 != null && (tradeCandidate == null || tradeCandidate2.DistanceSqr < tradeCandidate.DistanceSqr)) { tradeCandidate = tradeCandidate2; } } if (tradeCandidate == null) { ClearHoldState(num); } else if (UpdateHoldStateAndCheckReady(num, tradeCandidate)) { runningHeadIds.Add(num); ClearHoldState(num); ((MonoBehaviour)this).StartCoroutine(ExecuteTradeReviveRoutine(tradeCandidate, num)); } } private TradeCandidate BuildCandidateFromCollider(Collider hitCollider, PlayerDeathHead deathHead) { //IL_018d: 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_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hitCollider == (Object)null) { return null; } PlayerDeathHead componentInParent = ((Component)hitCollider).GetComponentInParent<PlayerDeathHead>(); if ((Object)(object)componentInParent != (Object)null) { return null; } PhysGrabObject componentInParent2 = ((Component)hitCollider).GetComponentInParent<PhysGrabObject>(); if ((Object)(object)componentInParent2 == (Object)null) { return null; } PhysGrabObject deathHeadPhysGrabObject = GetDeathHeadPhysGrabObject(deathHead); if ((Object)(object)componentInParent2 == (Object)(object)deathHeadPhysGrabObject) { return null; } ItemAttributes val = ((Component)componentInParent2).GetComponent<ItemAttributes>(); if ((Object)(object)val == (Object)null) { val = ((Component)componentInParent2).GetComponentInParent<ItemAttributes>(); } if ((Object)(object)val == (Object)null || (Object)(object)val.item == (Object)null) { return null; } if (!IsTradeItemCurrentlyHeld(componentInParent2)) { return null; } if (configRequirePurchasedItem.Value && !IsPurchasedTradeItem(val)) { return null; } int playerMaxHealth = GetPlayerMaxHealth(deathHead.playerAvatar); ReviveValueResult reviveValue = GetReviveValue(val, componentInParent2, playerMaxHealth); if (!reviveValue.Valid) { return null; } if ((Object)(object)deathHeadPhysGrabObject == (Object)null) { return null; } TradeCandidate tradeCandidate = new TradeCandidate(); tradeCandidate.DeathHead = deathHead; tradeCandidate.PlayerAvatar = deathHead.playerAvatar; tradeCandidate.PhysGrabObject = componentInParent2; tradeCandidate.ItemAttributes = val; tradeCandidate.SourceLabel = reviveValue.SourceLabel; tradeCandidate.TargetHp = Mathf.Clamp(reviveValue.TargetHp, 1, playerMaxHealth); Vector3 val2 = componentInParent2.centerPoint - deathHeadPhysGrabObject.centerPoint; tradeCandidate.DistanceSqr = ((Vector3)(ref val2)).sqrMagnitude; return tradeCandidate; } private bool UpdateHoldStateAndCheckReady(int headViewId, TradeCandidate candidate) { if (candidate == null || (Object)(object)candidate.PhysGrabObject == (Object)null) { ClearHoldState(headViewId); return false; } int tradeItemKey = GetTradeItemKey(candidate.PhysGrabObject, candidate.ItemAttributes); float time = Time.time; if (!holdStates.TryGetValue(headViewId, out var value)) { value = new HoldState(); value.ItemKey = tradeItemKey; value.StartTime = time; holdStates[headViewId] = value; return false; } if (value.ItemKey != tradeItemKey) { value.ItemKey = tradeItemKey; value.StartTime = time; holdStates[headViewId] = value; return false; } if (time - value.StartTime < configTouchHoldSeconds.Value) { return false; } return true; } private void ClearHoldState(int headViewId) { if (holdStates.ContainsKey(headViewId)) { holdStates.Remove(headViewId); } } private int GetTradeItemKey(PhysGrabObject physGrabObject, ItemAttributes itemAttributes) { if ((Object)(object)physGrabObject != (Object)null) { PhotonView component = ((Component)physGrabObject).GetComponent<PhotonView>(); if ((Object)(object)component != (Object)null) { return component.ViewID; } } if ((Object)(object)itemAttributes != (Object)null) { string instanceName = GetInstanceName(itemAttributes); if (!string.IsNullOrEmpty(instanceName)) { return instanceName.GetHashCode(); } } if ((Object)(object)physGrabObject != (Object)null) { return ((Object)physGrabObject).GetInstanceID(); } return 0; } private ReviveValueResult GetReviveValue(ItemAttributes itemAttributes, PhysGrabObject physGrabObject, int playerMaxHealth) { ReviveValueResult result = default(ReviveValueResult); result.Valid = false; result.TargetHp = 0; result.SourceLabel = string.Empty; if (configAllowHealthPacks.Value) { ItemHealthPack val = ((Component)physGrabObject).GetComponent<ItemHealthPack>(); if ((Object)(object)val == (Object)null) { val = ((Component)physGrabObject).GetComponentInParent<ItemHealthPack>(); } if ((Object)(object)val != (Object)null) { result.Valid = true; result.TargetHp = Mathf.Clamp(val.healAmount, 1, playerMaxHealth); result.SourceLabel = GetDisplayItemName(itemAttributes); return result; } } if (configAllowBatteryItems.Value) { ItemBattery val2 = ((Component)physGrabObject).GetComponent<ItemBattery>(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)physGrabObject).GetComponentInParent<ItemBattery>(); } if ((Object)(object)val2 != (Object)null) { string instanceName = GetInstanceName(itemAttributes); float batteryPercent = GetBatteryPercent(val2, instanceName); int targetHp; if (batteryPercent <= 0f) { if (!configAllowZeroBatteryRevive.Value) { return result; } targetHp = 1; } else { targetHp = Mathf.Max(1, Mathf.FloorToInt((float)playerMaxHealth * batteryPercent)); } result.Valid = true; result.TargetHp = targetHp; result.SourceLabel = GetDisplayItemName(itemAttributes); return result; } } return result; } [IteratorStateMachine(typeof(<ExecuteTradeReviveRoutine>d__32))] private IEnumerator ExecuteTradeReviveRoutine(TradeCandidate candidate, int headViewId) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ExecuteTradeReviveRoutine>d__32(0) { <>4__this = this, candidate = candidate, headViewId = headViewId }; } private bool CanExecuteTrade(TradeCandidate candidate) { try { if (candidate == null) { return false; } if ((Object)(object)candidate.DeathHead == (Object)null || (Object)(object)candidate.PlayerAvatar == (Object)null || (Object)(object)candidate.PlayerAvatar.playerHealth == (Object)null) { return false; } if ((Object)(object)candidate.PhysGrabObject == (Object)null || (Object)(object)candidate.ItemAttributes == (Object)null || (Object)(object)candidate.ItemAttributes.item == (Object)null) { return false; } if (!GetPlayerIsDisabled(candidate.PlayerAvatar)) { return false; } if (!IsDeathHeadTriggered(candidate.DeathHead)) { return false; } return true; } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("CanExecuteTrade failed\n" + ex)); return false; } } private void ExecuteTradeCore(TradeCandidate candidate) { try { if (configConsumeItem.Value) { ConsumePurchasedItem(candidate.ItemAttributes); RemoveFromShoppingList(candidate.ItemAttributes); DestroyTradeItem(candidate.PhysGrabObject); } SetDeathHeadInExtractionPoint(candidate.DeathHead, value: true); candidate.DeathHead.Revive(); } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("ExecuteTradeCore failed\n" + ex)); } } private void FinalizeReviveHealth(TradeCandidate candidate, int headViewId) { try { if (candidate != null && !((Object)(object)candidate.PlayerAvatar == (Object)null) && !((Object)(object)candidate.PlayerAvatar.playerHealth == (Object)null) && !GetPlayerIsDisabled(candidate.PlayerAvatar)) { int playerCurrentHealth = GetPlayerCurrentHealth(candidate.PlayerAvatar); int playerMaxHealth = GetPlayerMaxHealth(candidate.PlayerAvatar); int num = Mathf.Clamp(candidate.TargetHp, 1, playerMaxHealth); int num2 = num - playerCurrentHealth; if (num2 > 0) { candidate.PlayerAvatar.playerHealth.HealOther(num2, true); } headCooldownUntil[headViewId] = Time.time + configHeadCooldown.Value; if (configDebugLog.Value) { TradeForRevivePlugin.Log.LogInfo((object)("Revived " + GetPlayerName(candidate.PlayerAvatar) + " with " + num + " HP by " + candidate.SourceLabel)); } } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("FinalizeReviveHealth failed\n" + ex)); } } private bool IsTradeItemCurrentlyHeld(PhysGrabObject physGrabObject) { try { if ((Object)(object)physGrabObject == (Object)null) { return false; } if (physGrabObject.playerGrabbing != null && physGrabObject.playerGrabbing.Count > 0) { return true; } if (physGrabObject.grabbed || physGrabObject.grabbedLocal) { return true; } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("IsTradeItemCurrentlyHeld failed" + ex)); } return false; } private void ForceReleaseAllGrabbers(PhysGrabObject physGrabObject) { try { if ((Object)(object)physGrabObject == (Object)null) { return; } List<PhysGrabber> list = new List<PhysGrabber>(physGrabObject.playerGrabbing); PhotonView component = ((Component)physGrabObject).GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null) { return; } for (int i = 0; i < list.Count; i++) { PhysGrabber val = list[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val.photonView == (Object)null)) { val.photonView.RPC("ReleaseObjectRPC", (RpcTarget)0, new object[3] { false, 0.1f, component.ViewID }); } } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("ForceReleaseAllGrabbers failed\n" + ex)); } } private void ConsumePurchasedItem(ItemAttributes itemAttributes) { try { if ((Object)(object)itemAttributes == (Object)null || (Object)(object)itemAttributes.item == (Object)null || (Object)(object)StatsManager.instance == (Object)null) { return; } string instanceName = GetInstanceName(itemAttributes); if (!string.IsNullOrEmpty(instanceName) && StatsManager.instance.item.ContainsKey(instanceName)) { StatsManager.instance.ItemRemove(instanceName); } else { int num = 0; if (StatsManager.instance.itemsPurchased.ContainsKey(((Object)itemAttributes.item).name)) { num = StatsManager.instance.itemsPurchased[((Object)itemAttributes.item).name]; } StatsManager.instance.SetItemPurchase(itemAttributes.item, Mathf.Max(0, num - 1)); } if ((Object)(object)ItemManager.instance != (Object)null) { ItemManager.instance.purchasedItems.Remove(itemAttributes.item); } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("ConsumePurchasedItem failed\n" + ex)); } } private void RemoveFromShoppingList(ItemAttributes itemAttributes) { try { if ((Object)(object)itemAttributes != (Object)null && (Object)(object)ShopManager.instance != (Object)null) { ShopManager.instance.ShoppingListItemRemove(itemAttributes); } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("RemoveFromShoppingList failed\n" + ex)); } } private void DestroyTradeItem(PhysGrabObject physGrabObject) { try { if (!((Object)(object)physGrabObject == (Object)null)) { PhysGrabObjectImpactDetector val = GetImpactDetector(physGrabObject); if ((Object)(object)val == (Object)null) { val = ((Component)physGrabObject).GetComponent<PhysGrabObjectImpactDetector>(); } if (!((Object)(object)val == (Object)null)) { val.DestroyObject(configDestroyWithEffects.Value); } } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("DestroyTradeItem failed\n" + ex)); } } private float GetBatteryPercent(ItemBattery itemBattery, string instanceName) { try { if ((Object)(object)StatsManager.instance != (Object)null && !string.IsNullOrEmpty(instanceName) && StatsManager.instance.itemStatBattery.ContainsKey(instanceName)) { int batteryLevel = StatsManager.instance.GetBatteryLevel(instanceName); return Mathf.Clamp01((float)batteryLevel / 100f); } if ((Object)(object)itemBattery != (Object)null) { return Mathf.Clamp01(itemBattery.batteryLife / 100f); } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetBatteryPercent failed\n" + ex)); } return 0f; } private bool IsPurchasedTradeItem(ItemAttributes itemAttributes) { try { if ((Object)(object)itemAttributes == (Object)null || (Object)(object)itemAttributes.item == (Object)null || (Object)(object)StatsManager.instance == (Object)null) { return false; } string instanceName = GetInstanceName(itemAttributes); if (!string.IsNullOrEmpty(instanceName) && StatsManager.instance.item.ContainsKey(instanceName)) { return true; } if (StatsManager.instance.itemsPurchased.ContainsKey(((Object)itemAttributes.item).name)) { return StatsManager.instance.itemsPurchased[((Object)itemAttributes.item).name] > 0; } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("IsPurchasedTradeItem failed\n" + ex)); } return false; } private bool IsDeathHeadTriggered(PlayerDeathHead deathHead) { try { if ((Object)(object)deathHead == (Object)null || FieldPlayerDeathHeadTriggered == null) { return false; } object value = FieldPlayerDeathHeadTriggered.GetValue(deathHead); return value is bool && (bool)value; } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("IsDeathHeadTriggered failed\n" + ex)); return false; } } private void SetDeathHeadInExtractionPoint(PlayerDeathHead deathHead, bool value) { try { if ((Object)(object)deathHead != (Object)null && FieldPlayerDeathHeadInExtractionPoint != null) { FieldPlayerDeathHeadInExtractionPoint.SetValue(deathHead, value); } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("SetDeathHeadInExtractionPoint failed\n" + ex)); } } private bool GetPlayerIsDisabled(PlayerAvatar playerAvatar) { try { if ((Object)(object)playerAvatar == (Object)null || FieldPlayerAvatarIsDisabled == null) { return false; } object value = FieldPlayerAvatarIsDisabled.GetValue(playerAvatar); return value is bool && (bool)value; } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetPlayerIsDisabled failed\n" + ex)); return false; } } private int GetPlayerCurrentHealth(PlayerAvatar playerAvatar) { try { if ((Object)(object)playerAvatar == (Object)null || (Object)(object)playerAvatar.playerHealth == (Object)null || FieldPlayerHealthHealth == null) { return 1; } object value = FieldPlayerHealthHealth.GetValue(playerAvatar.playerHealth); if (value is int) { return (int)value; } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetPlayerCurrentHealth failed\n" + ex)); } return 1; } private int GetPlayerMaxHealth(PlayerAvatar playerAvatar) { try { if ((Object)(object)playerAvatar == (Object)null || (Object)(object)playerAvatar.playerHealth == (Object)null || FieldPlayerHealthMaxHealth == null) { return 100; } object value = FieldPlayerHealthMaxHealth.GetValue(playerAvatar.playerHealth); if (value is int) { return Mathf.Max(1, (int)value); } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetPlayerMaxHealth failed\n" + ex)); } return 100; } private string GetPlayerName(PlayerAvatar playerAvatar) { try { if ((Object)(object)playerAvatar == (Object)null) { return "Unknown"; } return ((Object)playerAvatar).name; } catch { return "Unknown"; } } private string GetDisplayItemName(ItemAttributes itemAttributes) { try { if ((Object)(object)itemAttributes == (Object)null || (Object)(object)itemAttributes.item == (Object)null) { return "Unknown Item"; } return itemAttributes.item.itemName; } catch { return "Unknown Item"; } } private string GetInstanceName(ItemAttributes itemAttributes) { try { if ((Object)(object)itemAttributes == (Object)null || FieldItemAttributesInstanceName == null) { return string.Empty; } object value = FieldItemAttributesInstanceName.GetValue(itemAttributes); if (value is string) { return (string)value; } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetInstanceName failed\n" + ex)); } return string.Empty; } private PhysGrabObject GetDeathHeadPhysGrabObject(PlayerDeathHead deathHead) { try { if ((Object)(object)deathHead == (Object)null || FieldPlayerDeathHeadPhysGrabObject == null) { return null; } object? value = FieldPlayerDeathHeadPhysGrabObject.GetValue(deathHead); return (PhysGrabObject)((value is PhysGrabObject) ? value : null); } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetDeathHeadPhysGrabObject failed\n" + ex)); return null; } } private PhysGrabObjectImpactDetector GetImpactDetector(PhysGrabObject physGrabObject) { try { if ((Object)(object)physGrabObject == (Object)null || FieldPhysGrabObjectImpactDetector == null) { return null; } object? value = FieldPhysGrabObjectImpactDetector.GetValue(physGrabObject); return (PhysGrabObjectImpactDetector)((value is PhysGrabObjectImpactDetector) ? value : null); } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetImpactDetector failed\n" + ex)); return null; } } } }