using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using ItemsReworked.Handlers;
using ItemsReworked.Scrap;
using ItemsReworked.Scrap.ItemsReworked.Scrap;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ItemsReworked")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ItemsReworked")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ef20c8e1-b33c-42f7-8c20-02953334a9b9")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ItemsReworked
{
[BepInPlugin("ItemsReworkedPlugin", "ItemsReworkedPlugin", "1.6.1")]
public class ItemsReworkedPlugin : BaseUnityPlugin
{
private readonly Harmony harmony = new Harmony("ItemsReworkedPlugin");
internal static ManualLogSource mls;
internal ScrapHandler scrapHandler = new ScrapHandler();
internal static ConfigEntry<int> NoEffectProbability;
internal static ConfigEntry<int> IntoxicationEffectProbability;
internal static ConfigEntry<int> PoisoningEffectProbability;
internal static ConfigEntry<int> MaxPoison;
internal static ConfigEntry<int> HealingEffectProbability;
internal static ConfigEntry<int> MaxHealing;
internal static ConfigEntry<float> LaserPointerBatteryDrain;
internal static ConfigEntry<float> GiantsRangeOfView;
internal static ConfigEntry<float> MinDurationStaminaBoost;
internal static ConfigEntry<float> MaxDurationStaminaBoost;
internal static ConfigEntry<int> MinPills;
internal static ConfigEntry<int> MaxPills;
internal static ConfigEntry<float> MinDurationJumpBoost;
internal static ConfigEntry<float> MaxDurationJumpBoost;
internal static ConfigEntry<int> MinRemoteUses;
internal static ConfigEntry<int> MaxRemoteUses;
internal static ConfigEntry<int> RemoteExplosionProbability;
internal static ConfigEntry<int> RemoteZapProbability;
internal static ConfigEntry<bool> DetonateMines;
internal static ConfigEntry<bool> ToggleTurrets;
internal static ItemsReworkedPlugin Instance { get; private set; }
private void Awake()
{
NoEffectProbability = ((BaseUnityPlugin)this).Config.Bind<int>("Flask", "NoEffectProbability", 20, "Probability of flasks to have of having no effect.");
IntoxicationEffectProbability = ((BaseUnityPlugin)this).Config.Bind<int>("Flask", "IntoxicationEffectProbability", 50, "Probability of flasks to intoxicate the player.");
PoisoningEffectProbability = ((BaseUnityPlugin)this).Config.Bind<int>("Flask", "PoisoningEffectProbability", 50, "Probability of flasks to poison the player.");
MaxPoison = ((BaseUnityPlugin)this).Config.Bind<int>("Flask", "MaxPoison", 1, "Health left after being poisoned. 0 Kills the player.");
HealingEffectProbability = ((BaseUnityPlugin)this).Config.Bind<int>("Flask", "HealingEffectProbability", 1, "Probability of flasks to heal the player.");
MaxHealing = ((BaseUnityPlugin)this).Config.Bind<int>("Flask", "MaxHealing", 33, "Max amount of healing a flask can do. (Based on Scrap Value)");
LaserPointerBatteryDrain = ((BaseUnityPlugin)this).Config.Bind<float>("Laser Pointer", "LaserPointerBatteryDrain", 0.1f, "Additional battery drain for the laser pointer. (Recommendation: 0.02 - 0.2)");
GiantsRangeOfView = ((BaseUnityPlugin)this).Config.Bind<float>("Laser Pointer", "GiantsRangeOfView", 200f, "Determines how far a giant can follow the laser without losing track of it. (Recommendation: 75 - 300)");
MinDurationStaminaBoost = ((BaseUnityPlugin)this).Config.Bind<float>("Mug", "MinDuration", 10f, "Min duration of stamina boost. (Based on Scrap Value)");
MaxDurationStaminaBoost = ((BaseUnityPlugin)this).Config.Bind<float>("Mug", "MaxDuration", 30f, "Max duration of stamina boost. (Based on Scrap Value)");
MinPills = ((BaseUnityPlugin)this).Config.Bind<int>("Pill Bottle", "MinPills", 2, "Min amount of pills in a Bottle. (Based on Scrap Value)");
MaxPills = ((BaseUnityPlugin)this).Config.Bind<int>("Pill Bottle", "MaxPills", 33, "Max amount of pills in a Bottle. (Based on Scrap Value)");
MinDurationJumpBoost = ((BaseUnityPlugin)this).Config.Bind<float>("Soda", "MinDuration", 5f, "Min duration of jump boost. (Based on Scrap Value)");
MaxDurationJumpBoost = ((BaseUnityPlugin)this).Config.Bind<float>("Soda", "MaxDuration", 30f, "Max duration of jump boost. (Based on Scrap Value)");
MinRemoteUses = ((BaseUnityPlugin)this).Config.Bind<int>("Remote", "MinDuration", 2, "Min amount of uses for a remote. (Based on Scrap Value)");
MaxRemoteUses = ((BaseUnityPlugin)this).Config.Bind<int>("Remote", "MaxDuration", 10, "Max amount of uses for a remote. (Based on Scrap Value)");
RemoteExplosionProbability = ((BaseUnityPlugin)this).Config.Bind<int>("Remote", "RemoteExplosionProbability", 5, "Probability for the Remote to explode and kill the player when used.");
RemoteZapProbability = ((BaseUnityPlugin)this).Config.Bind<int>("Remote", "RemoteZapProbability", 15, "Probability for the Remote to zap and damage the player when used.");
DetonateMines = ((BaseUnityPlugin)this).Config.Bind<bool>("Remote", "DetonateMines", true, "Enables the detonation of Mines by using the remote.");
ToggleTurrets = ((BaseUnityPlugin)this).Config.Bind<bool>("Remote", "ToggleTurrets", true, "Enables the Disabling/Reenabling of Turrets by using the remote.");
Instance = this;
mls = Logger.CreateLogSource("Loading Items Reworked Plugin");
harmony.PatchAll();
mls.LogInfo((object)"Items Reworked Plugin loaded sucessfully.");
}
}
}
namespace ItemsReworked.Patches
{
[HarmonyPatch(typeof(PlayerControllerB))]
internal class PlayerControllerBPatches
{
private static ItemsReworkedPlugin pluginInstance => ItemsReworkedPlugin.Instance;
[HarmonyPatch("GrabObjectServerRpc")]
[HarmonyPostfix]
private static void PickUpScrapItem(NetworkObjectReference grabbedObject)
{
NetworkObject val = default(NetworkObject);
((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null);
GrabbableObject componentInChildren = ((Component)val).gameObject.GetComponentInChildren<GrabbableObject>();
pluginInstance.scrapHandler.RegisterScrapItem(componentInChildren);
ItemsReworkedPlugin.mls.LogInfo((object)(((Object)componentInChildren).name + " picked up."));
}
[HarmonyPatch("ActivateItem_performed")]
[HarmonyPrefix]
private static void UseScrapItem(PlayerControllerB __instance, CallbackContext context, ref GrabbableObject ___currentlyHeldObjectServer)
{
if ((Object)(object)___currentlyHeldObjectServer != (Object)null)
{
pluginInstance.scrapHandler.UseScrapItem(___currentlyHeldObjectServer, __instance);
}
}
[HarmonyPatch("InspectItem_performed")]
[HarmonyPrefix]
private static void InspectItem_performed(PlayerControllerB __instance, CallbackContext context, ref GrabbableObject ___currentlyHeldObjectServer)
{
if ((Object)(object)___currentlyHeldObjectServer != (Object)null)
{
pluginInstance.scrapHandler.InspectScrapItem(___currentlyHeldObjectServer, __instance);
}
}
[HarmonyPatch("ItemSecondaryUse_performed")]
[HarmonyPrefix]
private static void ItemSecondaryUse_performed(PlayerControllerB __instance, CallbackContext context, ref GrabbableObject ___currentlyHeldObjectServer)
{
if ((Object)(object)___currentlyHeldObjectServer != (Object)null)
{
pluginInstance.scrapHandler.SpecialUse(___currentlyHeldObjectServer, __instance);
}
}
}
}
namespace ItemsReworked.Scrap
{
public abstract class BaseItem
{
public bool inSpecialScenario = false;
public bool hasSpecialUse = false;
public abstract void UseItem(PlayerControllerB player, GrabbableObject item);
public abstract void SpecialUseItem(PlayerControllerB player, GrabbableObject item);
public abstract void InspectItem(PlayerControllerB player, GrabbableObject item);
protected IEnumerator DelayedActivation(PlayerControllerB player, GrabbableObject item, float delayInSeconds, Action activationAction)
{
yield return (object)new WaitForSeconds(delayInSeconds);
activationAction();
}
}
internal class LaserPointer : BaseItem
{
private bool isTurnedOn = false;
private Dictionary<ForestGiantAI, Vector3> distractedGiants;
private ForestGiantAI distractedGiant;
internal LaserPointer(GrabbableObject laserPointer)
{
distractedGiants = new Dictionary<ForestGiantAI, Vector3>();
distractedGiant = null;
hasSpecialUse = false;
isTurnedOn = false;
}
public override void InspectItem(PlayerControllerB player, GrabbableObject item)
{
HUDManager.Instance.DisplayTip("Laser Pointer", "Giants are easily distracted by its light", false, false, "LC_Tip1");
}
public override void UseItem(PlayerControllerB player, GrabbableObject item)
{
if ((Object)(object)item != (Object)null && (Object)(object)player != (Object)null)
{
if (item.insertedBattery.charge > 0f)
{
ToggleLaserPointerPower(!isTurnedOn);
}
if (isTurnedOn)
{
((MonoBehaviour)player).StartCoroutine(EmitLaserRay(player, item));
}
}
else
{
ItemsReworkedPlugin.mls.LogError((object)("Error during using of " + ((Object)item).name));
}
}
public override void SpecialUseItem(PlayerControllerB player, GrabbableObject item)
{
throw new NotImplementedException();
}
private void ToggleLaserPointerPower(bool enable)
{
ItemsReworkedPlugin.mls.LogInfo((object)$"Setting Laser to {enable}");
if (isTurnedOn != enable)
{
isTurnedOn = enable;
}
if (!isTurnedOn)
{
distractedGiants.Clear();
distractedGiant = null;
}
}
private IEnumerator EmitLaserRay(PlayerControllerB player, GrabbableObject item)
{
RaycastHit hit = default(RaycastHit);
while (isTurnedOn && item.insertedBattery.charge > 0f && (Object)(object)item != (Object)null)
{
Battery insertedBattery = item.insertedBattery;
insertedBattery.charge -= ItemsReworkedPlugin.LaserPointerBatteryDrain.Value * Time.deltaTime;
Ray ray = new Ray(((Component)item).transform.position, ((Component)item).transform.forward);
float maxDistance = 800f;
if (Physics.Raycast(ray, ref hit, maxDistance, StartOfRound.Instance.walkableSurfacesMask))
{
if ((Object)(object)distractedGiant == (Object)null)
{
Collider[] hitColliders = Physics.OverlapSphere(((RaycastHit)(ref hit)).point, 50f);
Collider[] array = hitColliders;
foreach (Collider hitCollider in array)
{
distractedGiant = ((Component)hitCollider).GetComponent<ForestGiantAI>();
if ((Object)(object)distractedGiant != (Object)null && !distractedGiants.ContainsKey(distractedGiant))
{
distractedGiants.Add(distractedGiant, default(Vector3));
}
}
}
if (distractedGiants.Count > 0)
{
DistractGiants(distractedGiants, hit);
}
}
yield return null;
hit = default(RaycastHit);
}
if (item.insertedBattery.charge <= 0f)
{
ToggleLaserPointerPower(enable: false);
}
}
private void DistractGiants(Dictionary<ForestGiantAI, Vector3> forestGiants, RaycastHit laser)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
foreach (KeyValuePair<ForestGiantAI, Vector3> forestGiant in forestGiants)
{
if (!((EnemyAI)forestGiant.Key).inSpecialAnimation && Vector3.Distance(((Component)forestGiant.Key).transform.position, ((RaycastHit)(ref laser)).transform.position) < ItemsReworkedPlugin.GiantsRangeOfView.Value)
{
distractedGiants[forestGiant.Key] = ((RaycastHit)(ref laser)).point;
forestGiant.Key.lookTarget.position = ((RaycastHit)(ref laser)).point;
forestGiant.Key.turnCompass.LookAt(((RaycastHit)(ref laser)).point);
((EnemyAI)forestGiant.Key).SetDestinationToPosition(((RaycastHit)(ref laser)).point, false);
((EnemyAI)forestGiant.Key).SwitchToBehaviourState(0);
}
else
{
forestGiant.Key.investigatePosition = distractedGiants[forestGiant.Key];
((EnemyAI)forestGiant.Key).SetDestinationToPosition(distractedGiants[forestGiant.Key], true);
}
}
}
}
internal class RedSodaCan : BaseItem
{
private float effectDuration;
internal RedSodaCan(GrabbableObject redSodaCan)
{
effectDuration = CalculateEffectDuration(redSodaCan.scrapValue);
}
public override void InspectItem(PlayerControllerB player, GrabbableObject item)
{
effectDuration = CalculateEffectDuration(item.scrapValue);
ItemsReworkedPlugin.mls.LogInfo((object)$"Effect duration: {effectDuration}");
if (!item.itemUsedUp)
{
HUDManager.Instance.DisplayTip("Some kind of energy drink", "What did they say in those advertisements when I was younger... something about a red bull... and wings? I dunno...", false, false, "LC_Tip1");
}
else
{
HUDManager.Instance.DisplayTip("An empty energy drink", "Wow... the ads were not lying", false, false, "LC_Tip1");
}
}
public override void SpecialUseItem(PlayerControllerB player, GrabbableObject item)
{
throw new NotImplementedException();
}
public override void UseItem(PlayerControllerB player, GrabbableObject item)
{
if (!item.itemUsedUp)
{
item.itemUsedUp = true;
Random random = new Random();
string text = "Soda" + random.Next(1, 3) + ".mp3";
AudioHandler.PlaySound(player, "Scrap\\RedSodaCan\\" + text, 3f, 10f, 1f, 1f, 0f, (AudioRolloffMode)1);
ItemsReworkedPlugin.mls.LogInfo((object)("playing: " + text));
((MonoBehaviour)player).StartCoroutine(DelayedActivation(player, item, 3f, delegate
{
((MonoBehaviour)player).StartCoroutine(Energize(player));
item.SetScrapValue(item.scrapValue / 2);
}));
}
}
private float CalculateEffectDuration(int scrapValue)
{
float value = ItemsReworkedPlugin.MinDurationJumpBoost.Value;
float value2 = ItemsReworkedPlugin.MaxDurationJumpBoost.Value;
float num = (float)(scrapValue - 19) / 71f;
return Mathf.Lerp(value, value2, num);
}
private IEnumerator Energize(PlayerControllerB player)
{
float elapsedTime = 0f;
float originalForce = player.jumpForce;
while (elapsedTime < effectDuration)
{
player.jumpForce = originalForce * 1.5f;
elapsedTime += Time.deltaTime;
yield return null;
}
ItemsReworkedPlugin.mls.LogInfo((object)"Effect worn off");
ItemsReworkedPlugin.mls.LogInfo((object)$"Original force: {originalForce}");
player.jumpForce = originalForce;
}
}
internal class Candy : BaseItem
{
public override void InspectItem(PlayerControllerB player, GrabbableObject item)
{
throw new NotImplementedException();
}
public override void SpecialUseItem(PlayerControllerB player, GrabbableObject item)
{
throw new NotImplementedException();
}
public override void UseItem(PlayerControllerB player, GrabbableObject item)
{
if (!item.itemUsedUp && player.insanityLevel > 1f)
{
player.insanityLevel = 0f;
item.itemUsedUp = true;
player.currentlyHeldObject.DiscardItemOnClient();
}
}
}
internal class Flask : BaseItem
{
private Random random = new Random();
private string flaskEffect = "None";
internal Flask()
{
int num = 0;
int[] array = new int[4]
{
ItemsReworkedPlugin.NoEffectProbability.Value,
0,
0,
0
};
num += array[0];
array[1] = ItemsReworkedPlugin.IntoxicationEffectProbability.Value;
num += array[1];
array[2] = ItemsReworkedPlugin.PoisoningEffectProbability.Value;
num += array[2];
array[3] = ItemsReworkedPlugin.HealingEffectProbability.Value;
num += array[3];
if (num == 0)
{
flaskEffect = "None";
return;
}
int num2 = random.Next(num);
int num3 = 0;
for (int i = 0; i < array.Length; i++)
{
num3 += array[i];
if (num2 < num3)
{
switch (i)
{
case 0:
flaskEffect = "NoEffect";
break;
case 1:
flaskEffect = "Intoxication";
break;
case 2:
flaskEffect = "Poisoning";
break;
case 3:
flaskEffect = "Healing";
break;
}
break;
}
}
}
public override void InspectItem(PlayerControllerB player, GrabbableObject item)
{
if (!item.itemUsedUp)
{
HUDManager.Instance.DisplayTip("A random flask", "Should I really risk drinking the content?", false, false, "LC_Tip1");
}
else
{
HUDManager.Instance.DisplayTip("A random flask", "... the taste, was not great.", false, false, "LC_Tip1");
}
}
public override void UseItem(PlayerControllerB player, GrabbableObject item)
{
if (item.itemUsedUp)
{
return;
}
item.itemUsedUp = true;
((MonoBehaviour)player).StartCoroutine(DelayedActivation(player, item, 3f, delegate
{
switch (flaskEffect)
{
default:
NoEffect(player);
break;
case "Intoxication":
ApplyDrunkEffect(player);
break;
case "Poisoning":
((MonoBehaviour)player).StartCoroutine(ApplyPoisonEffect(player));
break;
case "Healing":
((MonoBehaviour)player).StartCoroutine(ApplyHealEffect(player, item.scrapValue));
break;
}
}));
item.SetScrapValue(3);
}
public override void SpecialUseItem(PlayerControllerB player, GrabbableObject item)
{
throw new NotImplementedException();
}
private void NoEffect(PlayerControllerB player)
{
HUDManager.Instance.DisplayTip("Nothing", "Nothing happened...", false, false, "LC_Tip1");
}
private void ApplyDrunkEffect(PlayerControllerB player)
{
AudioHandler.PlaySound(player, "Scrap\\Flask\\Intoxication.mp3", 3f, 10f, 1f, 1f, 0f, (AudioRolloffMode)1);
player.drunkness = 1f;
HUDManager.Instance.DisplayTip("Intoxication", "You feel a bit dizzy.", false, false, "LC_Tip1");
}
private IEnumerator ApplyPoisonEffect(PlayerControllerB player)
{
HUDManager.Instance.DisplayTip("Poisoning Effect", "You feel a burning sensation.", false, false, "LC_Tip1");
float elapsedTime = 0f;
while (player.health > ItemsReworkedPlugin.MaxPoison.Value)
{
elapsedTime += Time.deltaTime;
if (elapsedTime >= 3f)
{
player.DamagePlayer(1, false, true, (CauseOfDeath)0, 0, false, default(Vector3));
elapsedTime = 0f;
HUDManager.Instance.UpdateHealthUI(player.health, true);
}
yield return null;
}
}
private IEnumerator ApplyHealEffect(PlayerControllerB player, int flaskValue)
{
HUDManager.Instance.DisplayTip("Healing Effect", "You feel rejuvenated.", false, false, "LC_Tip1");
int minHealing = 1;
int maxHealing = ItemsReworkedPlugin.MaxHealing.Value;
int healing;
if (flaskValue <= 16)
{
healing = minHealing;
}
else if (flaskValue >= 44)
{
healing = maxHealing;
}
else
{
float percentage = (float)(flaskValue - 16) / 28f;
healing = Mathf.RoundToInt(Mathf.Lerp((float)minHealing, (float)maxHealing, percentage));
}
int targetHealth = player.health + healing;
float elapsedTime = 0f;
while (player.health < targetHealth && player.health < 100)
{
elapsedTime += Time.deltaTime;
if (elapsedTime >= 3f)
{
player.health++;
elapsedTime = 0f;
player.health = Mathf.Min(player.health, targetHealth);
HUDManager.Instance.UpdateHealthUI(player.health, false);
}
yield return null;
}
}
}
internal class PillBottle : BaseItem
{
private int remainingPills;
private int pillQuality;
internal PillBottle(GrabbableObject pillBottle)
{
pillQuality = GetPillQuality();
remainingPills = CalculatePills(pillBottle.scrapValue);
}
public override void InspectItem(PlayerControllerB player, GrabbableObject item)
{
if (item.itemUsedUp)
{
HUDManager.Instance.DisplayTip("An empty pill bottle", "Seems like there are no pills left in this one...", false, false, "LC_Tip1");
}
else
{
HUDManager.Instance.DisplayTip("A pill bottle", "There are some pills in here...", false, false, "LC_Tip1");
}
}
public override void UseItem(PlayerControllerB player, GrabbableObject item)
{
if (item.itemUsedUp || inSpecialScenario || player.health == 100 || player.inTerminalMenu)
{
return;
}
inSpecialScenario = true;
string text = "PillPop" + pillQuality + ".mp3";
AudioHandler.PlaySound(player, "Scrap\\PillBottle\\" + text, 3f, 10f, 1f, 1f, 0f, (AudioRolloffMode)1);
ItemsReworkedPlugin.mls.LogInfo((object)("playing: " + text));
((MonoBehaviour)player).StartCoroutine(DelayedActivation(player, item, 2f, delegate
{
remainingPills = IngestPills(player, remainingPills);
item.SetScrapValue(remainingPills);
if (remainingPills == 0)
{
item.SetScrapValue(1);
item.itemUsedUp = true;
}
}));
}
private int GetPillQuality()
{
Random random = new Random();
int num = random.Next(-1, 4);
if (num != 0)
{
return num;
}
return 1;
}
private int CalculatePills(int scrapValue)
{
int value = ItemsReworkedPlugin.MinPills.Value;
int value2 = ItemsReworkedPlugin.MaxPills.Value;
if (scrapValue <= 16)
{
return value;
}
if (scrapValue >= 40)
{
return value2;
}
float num = (float)(scrapValue - 16) / 24f;
return Mathf.RoundToInt(Mathf.Lerp((float)value, (float)value2, num));
}
private int IngestPills(PlayerControllerB player, int pills)
{
int num = 100;
int num2 = 0;
int num3 = pills * pillQuality;
if (player.health + num3 > num)
{
num2 = player.health + num3 - num / pillQuality;
((MonoBehaviour)player).StartCoroutine(GradualHealing(player, pills - num2));
}
else
{
((MonoBehaviour)player).StartCoroutine(GradualHealing(player, pills));
}
return num2;
}
private IEnumerator GradualHealing(PlayerControllerB player, int pills)
{
ItemsReworkedPlugin.mls.LogInfo((object)"CoroutineStarted");
int targetHealth = player.health + pills * pillQuality;
float healingDuration = pillQuality switch
{
2 => (float)pills * 5f,
3 => (float)pills * 3f,
_ => (float)pills * 10f,
};
float healingInterval = healingDuration / (float)pills;
float elapsedTime = 0f;
float elapsedIntervalTime = 0f;
while (elapsedTime < healingDuration)
{
if (elapsedIntervalTime > healingInterval)
{
player.health += pillQuality;
HUDManager.Instance.UpdateHealthUI(player.health, false);
elapsedIntervalTime = 0f;
}
elapsedTime += Time.deltaTime;
elapsedIntervalTime += Time.deltaTime;
yield return null;
}
player.health = targetHealth;
HUDManager.Instance.UpdateHealthUI(player.health, false);
inSpecialScenario = false;
}
public override void SpecialUseItem(PlayerControllerB player, GrabbableObject item)
{
throw new NotImplementedException();
}
}
internal class Remote : BaseItem
{
private static int uses;
internal Remote(GrabbableObject remote)
{
uses = CalculateUses(remote.scrapValue);
}
public override void InspectItem(PlayerControllerB player, GrabbableObject item)
{
ItemsReworkedPlugin.mls.LogInfo((object)$"Remaining uses: {uses}.");
}
public override void UseItem(PlayerControllerB player, GrabbableObject item)
{
if (uses > 0)
{
uses--;
ActivateRemote();
((MonoBehaviour)player).StartCoroutine(DelayedActivation(player, item, 1.5f, delegate
{
RemoteMalfunction(player, item);
}));
}
}
private int CalculateUses(int scrapValue)
{
int value = ItemsReworkedPlugin.MinRemoteUses.Value;
int value2 = ItemsReworkedPlugin.MaxRemoteUses.Value;
if (scrapValue <= 20)
{
return value;
}
if (scrapValue >= 48)
{
return value2;
}
float num = (float)(scrapValue - 20) / 28f;
int num2 = Mathf.RoundToInt(Mathf.Lerp((float)value, (float)value2, num));
if (num2 == 0)
{
ItemsReworkedPlugin.mls.LogError((object)"Calculation error in remote uses");
}
return num2;
}
private static bool ActivateRemote()
{
//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)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
Vector3 position = ((Component)localPlayerController.gameplayCamera).transform.position;
Vector3 forward = ((Component)localPlayerController.gameplayCamera).transform.forward;
float num = 20f;
RaycastHit[] array = Physics.RaycastAll(position, forward, num);
RaycastHit[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
RaycastHit val = array2[i];
Landmine component = ((Component)((RaycastHit)(ref val)).collider).GetComponent<Landmine>();
Turret component2 = ((Component)((RaycastHit)(ref val)).collider).GetComponent<Turret>();
if (((Object)(object)component2 != (Object)null) & ItemsReworkedPlugin.ToggleTurrets.Value)
{
ItemsReworkedPlugin.mls.LogInfo((object)"Toggling Turret");
component2.ToggleTurretEnabled(!((Behaviour)component2).enabled);
return true;
}
if ((Object)(object)component != (Object)null && ItemsReworkedPlugin.DetonateMines.Value)
{
ItemsReworkedPlugin.mls.LogInfo((object)"HIT MINE");
component.ExplodeMineServerRpc();
return true;
}
}
return false;
}
private static void RemoteMalfunction(PlayerControllerB player, GrabbableObject remote)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Unknown result type (might be due to invalid IL or missing references)
Random random = new Random();
int num = random.Next(0, 101);
if (num <= ItemsReworkedPlugin.RemoteExplosionProbability.Value)
{
uses = 0;
Landmine.SpawnExplosion(((Component)remote).transform.position, true, 1f, 1f);
if (remote.heldByPlayerOnServer)
{
Vector3 val = (((Component)player.gameplayCamera).transform.position + ((Component)remote).transform.position) / 2f;
remote.playerHeldBy.KillPlayer(val, true, (CauseOfDeath)3, 0);
remote.DestroyObjectInHand(remote.playerHeldBy);
ItemsReworkedPlugin.Instance.scrapHandler.RemoveScrapItem(remote);
ItemsReworkedPlugin.mls.LogInfo((object)("Remote exploded in the hand of the player '" + ((Object)player).name + "'"));
}
remote.SetScrapValue(1);
}
else if (num <= ItemsReworkedPlugin.RemoteZapProbability.Value)
{
if (remote.heldByPlayerOnServer)
{
AudioHandler.PlaySound(player, "Scrap\\Remote\\Zap.mp3", 3f, 10f, 1f, 1f, 0f, (AudioRolloffMode)1);
remote.playerHeldBy.DamagePlayer(10, true, true, (CauseOfDeath)11, 0, false, default(Vector3));
ItemsReworkedPlugin.mls.LogInfo((object)("Remote zapped player '" + ((Object)player).name + "'"));
}
uses = 0;
remote.SetScrapValue(1);
}
}
public override void SpecialUseItem(PlayerControllerB player, GrabbableObject item)
{
throw new NotImplementedException();
}
}
}
namespace ItemsReworked.Scrap.ItemsReworked.Scrap
{
internal class Mug : BaseItem
{
private float effectDuration;
internal Mug(GrabbableObject item)
{
effectDuration = CalculateEffectDuration(item.scrapValue);
}
public override void InspectItem(PlayerControllerB player, GrabbableObject item)
{
ItemsReworkedPlugin.mls.LogInfo((object)$"Caffeine effect duration: {effectDuration}");
if (!item.itemUsedUp)
{
HUDManager.Instance.DisplayTip("A cup of coffee", "I wonder who left it here... it's still warm.", false, false, "LC_Tip1");
}
else
{
HUDManager.Instance.DisplayTip("A cup of coffee", "WHO DRANK IT?", false, false, "LC_Tip1");
}
}
public override void UseItem(PlayerControllerB player, GrabbableObject item)
{
if (!item.itemUsedUp && !inSpecialScenario)
{
inSpecialScenario = true;
string text = "Mug.mp3";
AudioHandler.PlaySound(player, "Scrap\\Mug\\" + text, 3f, 10f, 1f, 1f, 0f, (AudioRolloffMode)1);
ItemsReworkedPlugin.mls.LogInfo((object)("playing: " + text));
((MonoBehaviour)player).StartCoroutine(DelayedActivation(player, item, 1.5f, delegate
{
((MonoBehaviour)player).StartCoroutine(Caffeinated(player));
item.itemUsedUp = true;
item.SetScrapValue(item.scrapValue / 2);
}));
}
}
private float CalculateEffectDuration(int scrapValue)
{
float value = ItemsReworkedPlugin.MinDurationStaminaBoost.Value;
float value2 = ItemsReworkedPlugin.MaxDurationStaminaBoost.Value;
float num = (float)(scrapValue - 24) / 44f;
return Mathf.Lerp(value, value2, num);
}
private IEnumerator Caffeinated(PlayerControllerB player)
{
float elapsedTime = 0f;
while (elapsedTime < effectDuration)
{
player.sprintMeter = 1f;
player.isSprinting = true;
elapsedTime += Time.deltaTime;
yield return null;
}
inSpecialScenario = false;
ItemsReworkedPlugin.mls.LogInfo((object)"Effect has worn off");
}
public override void SpecialUseItem(PlayerControllerB player, GrabbableObject item)
{
throw new NotImplementedException();
}
}
}
namespace ItemsReworked.Handlers
{
public class AudioInfo
{
public bool IsPlaying { get; set; }
public AudioSource AudioSource { get; set; }
}
public class AudioHandler
{
public static Dictionary<PlayerControllerB, AudioInfo> AudioInfoMap = new Dictionary<PlayerControllerB, AudioInfo>();
public static void PlaySound(PlayerControllerB player, string soundFileName, float minDistance = 3f, float maxDistance = 10f, float volume = 1f, float spacialBlend = 1f, float dopplerLevel = 0f, AudioRolloffMode rolloffMode = 1)
{
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
StopAllSounds();
if (!AudioInfoMap.TryGetValue(player, out var audioInfo))
{
audioInfo = new AudioInfo
{
IsPlaying = false,
AudioSource = ((Component)player).gameObject.AddComponent<AudioSource>()
};
audioInfo.AudioSource.spatialBlend = spacialBlend;
audioInfo.AudioSource.dopplerLevel = dopplerLevel;
audioInfo.AudioSource.rolloffMode = rolloffMode;
audioInfo.AudioSource.minDistance = minDistance;
audioInfo.AudioSource.maxDistance = maxDistance;
audioInfo.AudioSource.volume = volume;
AudioInfoMap[player] = audioInfo;
}
if (!audioInfo.IsPlaying)
{
string text = "file://" + Paths.PluginPath + "\\8-ItemsReworked\\SFX\\" + soundFileName;
UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)13);
audioClip.SendWebRequest();
while (!audioClip.isDone)
{
}
AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
audioInfo.AudioSource.clip = content;
audioInfo.AudioSource.PlayOneShot(content);
audioInfo.IsPlaying = true;
float time = 5f;
Task.Run(async delegate
{
await Task.Delay(TimeSpan.FromSeconds(time));
audioInfo.AudioSource.Stop();
audioInfo.IsPlaying = false;
});
}
}
public static void StopAllSounds()
{
foreach (AudioInfo value in AudioInfoMap.Values)
{
if (value.IsPlaying)
{
value.AudioSource.Stop();
value.IsPlaying = false;
}
}
}
}
public class ScrapHandler
{
private Dictionary<int, BaseItem> scrapItemDictionary = new Dictionary<int, BaseItem>();
public void RegisterScrapItem(GrabbableObject scrapItem)
{
if (!scrapItemDictionary.ContainsKey(((Object)scrapItem).GetInstanceID()))
{
BaseItem baseItem = CreateScrapItem(scrapItem);
if (baseItem != null)
{
scrapItemDictionary.Add(((Object)scrapItem).GetInstanceID(), baseItem);
ItemsReworkedPlugin.mls.LogInfo((object)(((Object)scrapItem).name + " registered in ScrapHandler."));
}
}
}
public void RemoveScrapItem(GrabbableObject scrapItem)
{
int instanceID = ((Object)scrapItem).GetInstanceID();
if (scrapItemDictionary.ContainsKey(instanceID) && scrapItemDictionary.Remove(instanceID))
{
ItemsReworkedPlugin.mls.LogInfo((object)(((Object)scrapItem).name + " removed from ScrapHandler."));
}
else
{
ItemsReworkedPlugin.mls.LogError((object)(((Object)scrapItem).name + " not found in ScrapHandler."));
}
}
public void UseScrapItem(GrabbableObject scrapItem, PlayerControllerB player)
{
int instanceID = ((Object)scrapItem).GetInstanceID();
if (scrapItemDictionary.ContainsKey(instanceID))
{
BaseItem baseItem = scrapItemDictionary[instanceID];
baseItem.UseItem(player, scrapItem);
}
}
public void SpecialUse(GrabbableObject scrapItem, PlayerControllerB player)
{
int instanceID = ((Object)scrapItem).GetInstanceID();
if (scrapItemDictionary.ContainsKey(instanceID) && scrapItemDictionary[instanceID].hasSpecialUse)
{
BaseItem baseItem = scrapItemDictionary[instanceID];
baseItem.SpecialUseItem(player, scrapItem);
}
}
public void InspectScrapItem(GrabbableObject scrapItem, PlayerControllerB player)
{
int instanceID = ((Object)scrapItem).GetInstanceID();
if (scrapItemDictionary.ContainsKey(instanceID))
{
BaseItem baseItem = scrapItemDictionary[instanceID];
baseItem.InspectItem(player, scrapItem);
}
}
private BaseItem CreateScrapItem(GrabbableObject scrapItem)
{
switch (((Object)scrapItem).name.Replace("(Clone)", null))
{
case "Candy":
return new Candy();
case "Flask":
return new Flask();
case "Mug":
return new Mug(scrapItem);
case "PillBottle":
return new PillBottle(scrapItem);
case "RedSodaCan":
return new RedSodaCan(scrapItem);
case "Remote":
return new Remote(scrapItem);
case "LaserPointer":
return new LaserPointer(scrapItem);
default:
ItemsReworkedPlugin.mls.LogInfo((object)("Unsupported scrap item type " + ((Object)scrapItem).name + " picked up"));
return null;
}
}
}
}