public static void Postfix(Survival __instance, GameObject useObj, bool __result) { if (__result && (useObj != null)) { TechType techType = CraftData.GetTechType(useObj); if ((techType == TechType.Boomerang) || (techType == TechType.LavaBoomerang)) { NitrogenLevel nitrogenLevel = Player.main.gameObject.GetComponent <NitrogenLevel>(); if (DeathRun.saveData.nitroSave.safeDepth > 10f) { DeathRun.saveData.nitroSave.safeDepth /= 2; if (Time.time - ticksNotice > 60) { ticksNotice = Time.time; ErrorMessage.AddMessage("The tasty raw Boomerang helps purge Nitrogen from your bloodstream!"); } if (DeathRun.saveData.nitroSave.safeDepth < 10f) { nitrogenLevel.nitrogenLevel = DeathRun.saveData.nitroSave.safeDepth * 10; } } else { nitrogenLevel.nitrogenLevel = 0; } } } }
public static bool Prefix(ref NitrogenLevel __instance, Player player) { Inventory main = Inventory.main; TechType bodySlot = Inventory.main.equipment.GetTechTypeInSlot("Body"); TechType headSlot = Inventory.main.equipment.GetTechTypeInSlot("Head"); if (GameModeUtils.RequiresOxygen()) { float depthOf = Ocean.main.GetDepthOf(player.gameObject); if (__instance.nitrogenEnabled) { float modifier = 1f; if (depthOf > 0f) { if (bodySlot == ReinforcedSuitsCore.ReinforcedSuit3ID) { modifier = 0.55f; } else if ((bodySlot == ReinforcedSuitsCore.ReinforcedSuit2ID || bodySlot == ReinforcedSuitsCore.ReinforcedStillSuit) && depthOf <= 1300f) { modifier = 0.75f; } else if (bodySlot == TechType.ReinforcedDiveSuit && depthOf <= 800f) { modifier = 0.85f; } else if ((bodySlot == TechType.RadiationSuit || bodySlot == TechType.Stillsuit) && depthOf <= 500f) { modifier = 0.95f; } if (headSlot == TechType.Rebreather) { modifier -= 0.05f; } } float num = __instance.depthCurve.Evaluate(depthOf / 2048f); __instance.safeNitrogenDepth = UWE.Utils.Slerp(__instance.safeNitrogenDepth, depthOf, num * __instance.kBreathScalar * modifier); } if (crushEnabled && Player.main.GetDepthClass() == Ocean.DepthClass.Crush) { if (UnityEngine.Random.value < 0.5f) { float crushDepth = PlayerGetDepthClassPatcher.divingCrushDepth; if (depthOf > crushDepth) { DamagePlayer(depthOf - crushDepth); } } } } return(false); }
/** * DecoDamage - this actually applies the decompression damage from getting the bends. Includes "anti-one-shotting" protection. Also * resets the "safe depth" higher after each shot of damage. */ private static void DecoDamage(ref NitrogenLevel __instance, float depthOf, int ticks) { LiveMixin component = Player.main.gameObject.GetComponent <LiveMixin>(); float damageBase = (Config.DEATHRUN.Equals(DeathRun.config.nitrogenBends)) ? 20f : 10f; if ((DeathRun.saveData.nitroSave.safeDepth - depthOf) < 5) { damageBase /= 2; } if ((DeathRun.saveData.nitroSave.safeDepth - depthOf) < 2) { damageBase /= 2; } float damage = damageBase + UnityEngine.Random.value * damageBase + (DeathRun.saveData.nitroSave.safeDepth - depthOf); if (damage >= component.health) { if (component.health > 0.1f) { damage = component.health - 0.05f; if (damage <= 0) { return; } } } if (component.health - damage > 0f) { if (!Config.NEVER.Equals(DeathRun.config.showWarnings)) { if ((DeathRun.saveData.nitroSave.reallyTookDamageTicks == 0) || Config.WHENEVER.Equals(DeathRun.config.showWarnings) || (Config.OCCASIONAL.Equals(DeathRun.config.showWarnings) && (ticks - DeathRun.saveData.nitroSave.reallyTookDamageTicks > 600))) { ErrorMessage.AddMessage("You have the bends from ascending too quickly!"); DeathRunUtils.CenterMessage("You have the bends!", 6); DeathRunUtils.CenterMessage("Slow your ascent!", 6, 1); } } } //else //{ // ErrorMessage.AddMessage("You died of the bends!"); // DeathRunUtils.CenterMessage("You died of the bends!", 5); //} DeathRun.setCause("The Bends"); component.TakeDamage(damage, default, DamageType.Starve, null);
public static bool Prefix(ref NitrogenLevel __instance) { if (__instance.nitrogenEnabled && GameModeUtils.RequiresOxygen() && Time.timeScale > 0f) { float depthOf = Ocean.main.GetDepthOf(Player.main.gameObject); if (depthOf < __instance.safeNitrogenDepth - 10f && UnityEngine.Random.value < 0.0125f) { LiveMixin component = Player.main.gameObject.GetComponent <LiveMixin>(); float damage = 1f + damageScaler * (__instance.safeNitrogenDepth - depthOf) / 10f; if (component.health - damage > 0f) { component.TakeDamage(damage, default, DamageType.Normal, null);
public static bool Prefix(ref Survival __instance, ref bool __result, GameObject useObj) { bool prefixFlag = true; if (useObj != null) { TechType techType = CraftData.GetTechType(useObj); NitrogenLevel nitrogenLevel = null; bool nFlag = false; if (Player.main.gameObject.GetComponent <NitrogenLevel>() != null) { nitrogenLevel = Player.main.gameObject.GetComponent <NitrogenLevel>(); if (nitrogenLevel.safeNitrogenDepth >= 10f) { nFlag = true; } } if (techType == TechType.FirstAidKit) { if (Player.main.GetComponent <LiveMixin>().AddHealth(50f) > 0.1f) { prefixFlag = false; __result = true; } if (nFlag) { if (nitrogenLevel.safeNitrogenDepth > 10f) { nitrogenLevel.safeNitrogenDepth -= 10f; } else { nitrogenLevel.safeNitrogenDepth = 0f; } prefixFlag = false; __result = true; } if (__result) { string useEatSound = CraftData.GetUseEatSound(techType); FMODUWE.PlayOneShot(useEatSound, Player.main.transform.position, 1f); } } } return(prefixFlag); }
public static bool Prefix(ref NitrogenLevel __instance, Player player) { if (GameModeUtils.RequiresOxygen() && !PrisonManager.IsInsideAquarium(player.gameObject.transform.position)) { float depthOf = Ocean.main.GetDepthOf(player.gameObject); // Player's personal crush depth if (crushEnabled) { if (Player.main.GetDepthClass() == Ocean.DepthClass.Crush) { if (!crushed) { ErrorMessage.AddMessage("Personal crush depth exceeded. Return to safe depth!"); crushed = true; } if (UnityEngine.Random.value < 0.5f) { float crushDepth = DeathRun.saveData.playerSave.crushDepth; if (depthOf > crushDepth) { float crush = depthOf - crushDepth; if (crush < 50) { DamagePlayer(4); } else if (crush < 100) { DamagePlayer(8); } else if (crush < 200) { DamagePlayer(16); } else { DamagePlayer(32); // "Okay, Sparky..." } } } } else { crushed = false; } } } return(false); }
public static bool Prefix(ref Survival __instance, ref bool __result, GameObject useObj) { usedSemaphore = false; if (useObj != null) { TechType techType = CraftData.GetTechType(useObj); if (techType == TechType.FirstAidKit) { NitrogenLevel nitrogenLevel = Player.main.gameObject.GetComponent <NitrogenLevel>(); if (DeathRun.saveData.nitroSave.safeDepth > 10f) { DeathRun.saveData.nitroSave.safeDepth /= 2; usedSemaphore = true; if (Time.time - ticksNotice > 60) { ticksNotice = Time.time; ErrorMessage.AddMessage("First Aid Kit helps purge Nitrogen from your bloodstream."); } if (DeathRun.saveData.nitroSave.safeDepth < 10f) { nitrogenLevel.nitrogenLevel = DeathRun.saveData.nitroSave.safeDepth * 10; } } else { if (nitrogenLevel.nitrogenLevel > 0) { nitrogenLevel.nitrogenLevel = 0; usedSemaphore = true; } } } } return(true); }
public override void Initialize() { _prefabId = GetComponentInParent <PrefabIdentifier>(); if (_prefabId == null) { QuickLogger.Error("Prefab Identifier Component was not found"); } if (_buildable == null) { _buildable = GetComponentInParent <Constructable>() ?? GetComponent <Constructable>(); } if (!FindAllComponents()) { IsInitialized = false; throw new MissingComponentException("Failed to find all components"); } if (PowerManager == null) { PowerManager = gameObject.EnsureComponent <AMMiniMedBayPowerManager>(); } if (PlayerTrigger == null) { PlayerTrigger = gameObject.FindChild("model").FindChild("Trigger").EnsureComponent <AMMiniMedBayTrigger>(); } if (PlayerTrigger != null) { PlayerTrigger.OnPlayerStay += OnPlayerStay; PlayerTrigger.OnPlayerExit += OnPlayerExit; } else { QuickLogger.Error("Player Trigger Component was not found"); } if (AnimationManager == null) { AnimationManager = gameObject.EnsureComponent <AMMiniMedBayAnimationManager>(); } if (PowerManager != null) { PowerManager.Initialize(this); PowerManager.OnPowerOutage += OnPowerOutage; PowerManager.OnPowerResume += OnPowerResume; //Setting to true to prevent power consumption when not in use on load PowerManager.SetHasBreakerTripped(true); } else { QuickLogger.Error("Power Manager Component was not found"); } PageHash = UnityEngine.Animator.StringToHash("state"); if (AudioHandler == null) { AudioHandler = new AMMiniMedBayAudioManager(gameObject.GetComponent <FMOD_CustomLoopingEmitter>()); } if (Container == null) { Container = new AMMiniMedBayContainer(this); } if (_display == null) { _display = gameObject.AddComponent <AMMiniMedBayDisplay>(); } if (Player.main.gameObject.GetComponent <NitrogenLevel>() != null) { _nitrogenLevel = Player.main.gameObject.GetComponent <NitrogenLevel>(); InvokeRepeating(nameof(UpdateNitrogenDisplay), 1, 0.5f); } IsInitialized = true; }
public static void Postfix(NitrogenLevel __instance) { typeof(NitrogenLevel).GetField("nitrogenEnabled", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(__instance, QMultiModSettings.Instance.NitrogenEnabled); }
public static bool Prefix(ref NitrogenLevel __instance) { if (DeathRun.murkinessDirty) { if (WaterBiomeManager.main != null) { WaterBiomeManager.main.Rebuild(); DeathRun.murkinessDirty = false; } } // Nitrogen tracking doesn't start until player leaves the pod (for underwater starts) if ((EscapePod.main == null) || (!EscapePod.main.topHatchUsed && !EscapePod.main.bottomHatchUsed)) { return(false); } if (DeathRun.playerIsDead || (Player.main == null) || (Ocean.main == null) || (Inventory.main == null)) { return(false); } float depth = Ocean.main.GetDepthOf(Player.main.gameObject); // Update our deepest depth for stats DeathRun.saveData.runData.Deepest = Mathf.Max(DeathRun.saveData.runData.Deepest, depth); // // NITROGEN controller // if (!Config.NORMAL.Equals(DeathRun.config.nitrogenBends) && Time.timeScale > 0f) { int ticks = (int)(DayNightCycle.main.timePassedAsFloat * 2); bool tick = (ticks != DeathRun.saveData.nitroSave.oldTicks) && (DeathRun.saveData.nitroSave.oldTicks > 0); DeathRun.saveData.nitroSave.oldTicks = ticks; Inventory main = Inventory.main; TechType bodySlot = Inventory.main.equipment.GetTechTypeInSlot("Body"); TechType headSlot = Inventory.main.equipment.GetTechTypeInSlot("Head"); bool isSwimming = Player.main.IsSwimming(); Vehicle vehicle = Player.main.GetVehicle(); bool isInVehicle = Player.main.GetCurrentSub()?.isCyclops == true || vehicle is SeaMoth || vehicle is Exosuit; bool isInBase = Player.main.IsInside() && !isInVehicle; //!isSwimming && (depth > 10) && !GameModeUtils.RequiresOxygen(); bool isSeaglide = (Player.main.motorMode == Player.MotorMode.Seaglide); if (!isSeaglide) { Pickupable held = Inventory.main.GetHeld(); if (held != null && held.gameObject.GetComponent <Seaglide>() != null) { isSeaglide = true; } } float ascent = __instance.GetComponent <Rigidbody>().velocity.y; // Player's current positive Y velocity is the ascent rate (fastest seems somewhat above 6) DeathRun.saveData.nitroSave.ascentRate = ((DeathRun.saveData.nitroSave.ascentRate * 29) + ascent) / 30; // Average based on 30 frames-per-second // // NITROGEN - Main Nitrogen adjustment calculations - run twice a second. // if (tick) { float modifier; if (isSwimming) { modifier = 1f; if (depth > 0f) { // Increasingly better suits help lower rate of nitrogen accumulation if (bodySlot == ReinforcedSuitsCore.ReinforcedSuit3ID) { modifier = 0.55f; } else if ((bodySlot == ReinforcedSuitsCore.ReinforcedSuit2ID || bodySlot == ReinforcedSuitsCore.ReinforcedStillSuit)) { modifier = 0.75f; } else if (bodySlot == TechType.ReinforcedDiveSuit) { modifier = 0.85f; } else if ((bodySlot == TechType.RadiationSuit || bodySlot == TechType.Stillsuit)) { modifier = 0.95f; } if (headSlot == TechType.Rebreather) { modifier -= 0.05f; } } } else { modifier = 0.5f; } float num = __instance.depthCurve.Evaluate(depth / 2048f) * 2; float baselineSafe; if (Config.DEATHRUN.Equals(DeathRun.config.nitrogenBends)) { baselineSafe = (depth < 0) ? 0 : depth * 3 / 4; // At any given depth our safe equilibrium gradually approaches 3/4 of current depth } else { baselineSafe = ((depth < 0) || !isSwimming) ? 0 : depth * 3 / 4; // At any given depth our safe equilibrium gradually approaches 3/4 of current depth } // "Deco Module" vehicle upgrade if (vehicle != null) { int deco = vehicle.modules.GetCount(DeathRun.decoModule.TechType); if (deco > 0) { baselineSafe = ((deco < 2) && (DeathRun.saveData.nitroSave.safeDepth >= 10)) ? 1 : 0; //CattleLogger.Message("baselineSafe = " + baselineSafe + " deco=" + deco); } } if (isInBase || Player.main.GetCurrentSub()?.isCyclops == true) { if (Inventory.main.equipment.GetCount(DeathRun.filterChip.TechType) > 0) { baselineSafe = 0; } } // Better dissipation when we're breathing through a pipe, or in a vehicle/base, or riding Seaglide, or wearing Rebreather if ((baselineSafe > 0) && (DeathRun.saveData.nitroSave.atPipe || !isSwimming || isSeaglide || (headSlot == TechType.Rebreather))) { float adjustment = depth * (2 + (!isSwimming ? 1 : 0) + (isSeaglide ? 1 : 0)) / 8; if ((baselineSafe - adjustment <= DeathRun.saveData.nitroSave.safeDepth) && (baselineSafe > 1)) { baselineSafe = baselineSafe - adjustment; if (baselineSafe < 1) { baselineSafe = 1; } } if (DeathRun.saveData.nitroSave.atPipe) { float now = DayNightCycle.main.timePassedAsFloat; if ((now > DeathRun.saveData.nitroSave.pipeTime + 1) && (now > DeathRun.saveData.nitroSave.bubbleTime + 3)) { DeathRun.saveData.nitroSave.atPipe = false; } } } if ((baselineSafe < DeathRun.saveData.nitroSave.safeDepth) || (DeathRun.saveData.nitroSave.safeDepth < 10)) { modifier = 1 / modifier; // If we're dissipating N2, don't have our high quality suit slow it down // Intentionally more forgiving when deeper num = 0.05f + (0.01f * (int)(DeathRun.saveData.nitroSave.safeDepth / 100)); } DeathRun.saveData.nitroSave.safeDepth = UWE.Utils.Slerp(DeathRun.saveData.nitroSave.safeDepth, baselineSafe, num * __instance.kBreathScalar * modifier); // This little % buffer helps introduce the concept of N2 (both initially and as a positive feedback reminder) float target; if (Player.main.precursorOutOfWater || (baselineSafe <= 0)) { target = 0; } else if ((DeathRun.saveData.nitroSave.safeDepth > 10f) || (depth >= 20)) { target = 100; } else if (depth <= 10) { target = 0; } else { target = (depth - 10) * 10; // Transition zone between 10m and 20m } float rate; if (target > 0) { rate = 1 + depth / 50f; } else { rate = (depth <= 1) ? 6 : (DeathRun.saveData.nitroSave.atPipe || !isSwimming) ? 4 : 2; } __instance.nitrogenLevel = UWE.Utils.Slerp(__instance.nitrogenLevel, target, rate * modifier); __instance.nitrogenLevel = Mathf.Clamp(__instance.nitrogenLevel, 0, 100); if (__instance.nitrogenLevel >= 100) { if (DeathRun.saveData.nitroSave.safeDepth <= 10) { DeathRun.saveData.nitroSave.safeDepth = 10.01f; } } } // // DAMAGE - Check if we need to take damage // if ((__instance.nitrogenLevel >= 100) && (DeathRun.saveData.nitroSave.safeDepth >= 10f) && ((int)depth < (int)DeathRun.saveData.nitroSave.safeDepth)) { if (!isInVehicle && !isInBase) { if (DeathRun.saveData.nitroSave.n2WarningTicks == 0) { // If we've NEVER had an N2 warning, institute a hard delay before we can take damage DeathRun.saveData.nitroSave.tookDamageTicks = ticks; } if ((DeathRun.saveData.nitroSave.n2WarningTicks == 0) || (ticks - DeathRun.saveData.nitroSave.n2WarningTicks > 60)) { if ((DeathRun.saveData.nitroSave.safeDepth >= 13f) || ((int)depth + 1) < (int)DeathRun.saveData.nitroSave.safeDepth) // Avoid spurious warnings right at surface { if (!Config.NEVER.Equals(DeathRun.config.showWarnings)) { if ((DeathRun.saveData.nitroSave.n2WarningTicks == 0) || Config.WHENEVER.Equals(DeathRun.config.showWarnings) || (Config.OCCASIONAL.Equals(DeathRun.config.showWarnings) && (ticks - DeathRun.saveData.nitroSave.n2WarningTicks > 600))) { DeathRunUtils.CenterMessage("Decompression Warning", 5); DeathRunUtils.CenterMessage("Dive to Safe Depth!", 5, 1); } } DeathRun.saveData.nitroSave.n2WarningTicks = ticks; } } int danger = (int)DeathRun.saveData.nitroSave.safeDepth - (int)depth; float deco = (isSwimming ? 0.0125f : 0.025f); if (danger < 5) { deco /= 2; } if (danger < 2) { deco /= 2; } if (UnityEngine.Random.value < deco) { if ((DeathRun.saveData.nitroSave.tookDamageTicks == 0) || (ticks - DeathRun.saveData.nitroSave.tookDamageTicks > 10)) { DecoDamage(ref __instance, depth, ticks); DeathRun.saveData.nitroSave.tookDamageTicks = ticks; DeathRun.saveData.nitroSave.reallyTookDamageTicks = ticks; } } } } else { if ((__instance.nitrogenLevel <= 90) || ((depth <= 1) && (DeathRun.saveData.nitroSave.ascentRate < 4) && (DeathRun.saveData.nitroSave.safeDepth < 10f)) || ((depth >= DeathRun.saveData.nitroSave.safeDepth + 10) && isSwimming)) { DeathRun.saveData.nitroSave.tookDamageTicks = 0; } } // // ASCENT RATE - Check for ascending too quickly while swimming // if (isSwimming) { if (DeathRun.saveData.nitroSave.ascentRate > (isSeaglide ? 3 : 2)) { if (DeathRun.saveData.nitroSave.ascentRate > 4) { DeathRun.saveData.nitroSave.ascentWarning++; if (DeathRun.saveData.nitroSave.ascentWarning == 1) { doAscentWarning(ticks); } else if (DeathRun.saveData.nitroSave.ascentRate >= (isSeaglide ? 5.5 : 5)) { if (__instance.nitrogenLevel < 100) { if ((DeathRun.saveData.nitroSave.ascentWarning % (isSeaglide ? 4 : 2)) == 0) { if (((DeathRun.saveData.nitroSave.ascentWarning % 8) == 0) || Config.DEATHRUN.Equals(DeathRun.config.nitrogenBends)) { __instance.nitrogenLevel++; } } } else { if (DeathRun.saveData.nitroSave.ascentWarning >= (isSeaglide ? 90 : 60)) // After about 2 seconds of too fast { int tickrate; if (Config.DEATHRUN.Equals(DeathRun.config.nitrogenBends)) { tickrate = 10; } else { tickrate = 20; } if (isSeaglide) { tickrate = tickrate * 3 / 2; } if (DeathRun.saveData.nitroSave.ascentWarning % tickrate == 0) { if (DeathRun.saveData.nitroSave.safeDepth < depth * 1.25f) { DeathRun.saveData.nitroSave.safeDepth += 1; } } } if ((DeathRun.saveData.nitroSave.ascentWarning % 120) == 0) { doAscentWarning(ticks); } } } } } else { // if returned to slow speed then increase our buffer if (DeathRun.saveData.nitroSave.ascentWarning > 0) { DeathRun.saveData.nitroSave.ascentWarning--; } // Once we've basically stopped, can do a text warning again if we get too fast if (DeathRun.saveData.nitroSave.ascentRate <= 0.5f) { DeathRun.saveData.nitroSave.ascentWarning = 0; } } } HUDController(__instance, false); // (DeathRun.saveData.nitroSave.ascentRate >= 5) && (DeathRun.saveData.nitroSave.ascentWarning >= 30)); } else { if (Time.timeScale > 0f) { __instance.nitrogenLevel = 0; DeathRun.saveData.nitroSave.safeDepth = 0; BendsHUDController.SetActive(false, false); } } return(false); }