public static bool Prefix(Survival __instance, GameObject useObj) { if (useObj != null) { Eatable component = useObj.GetComponent <Eatable>(); if (component != null) { if (component.GetFoodValue() == -25f) { if (Config.FOOD_VEGAN.Equals(DeathRun.config.foodChallenge)) { DeathRunUtils.CenterMessage("Vegan Challenge: Negative Food Value!", 5); } else if (Config.FOOD_VEGETARIAN.Equals(DeathRun.config.foodChallenge)) { DeathRunUtils.CenterMessage("Vegetarian Challenge: Negative Food Value!", 5); } else if (Config.FOOD_PESCATARIAN.Equals(DeathRun.config.foodChallenge)) { DeathRunUtils.CenterMessage("Pescatarian Challenge: Negative Food Value!", 5); } } } } return(true); }
public static void Prefix(uGUI_HardcoreGameOver __instance) { DeathRun.setCause("Victory"); DeathRun.saveData.runData.updateVitals(true); DeathRun.statsData.SaveStats(); TimeSpan timeSpan = TimeSpan.FromSeconds((double)DeathRun.saveData.playerSave.allLives); string text = "Victory! In " + DeathRunUtils.sayTime(timeSpan) + " (" + (DeathRun.saveData.playerSave.numDeaths + 1) + " "; if (DeathRun.saveData.playerSave.numDeaths == 0) { text += "life"; } else { text += "lives"; } text += ")"; DeathRunUtils.CenterMessage(text, 10); CattleLogger.Message(text); string text2 = "Score: " + DeathRun.saveData.runData.Score; DeathRunUtils.CenterMessage(text, 10, 1); CattleLogger.Message(text); //ErrorMessage.AddMessage(text); }
private static void timedMessage(string message, float delta) { if (DeathRun.playerMonitor.JustWentAbove(DeathRun.saveData.playerSave.startedGame + delta)) { DeathRunUtils.CenterMessage(message, 5); } }
public static bool Prefix(MainMenuLoadButton __instance) { if (!__instance.IsEmpty()) { DeathRunUtils.HideHighScores(true); } return(true); }
public static bool Prefix(bool show) { if (show) { DeathRunUtils.ShowHighScores(true); } else { DeathRunUtils.HideHighScores(true); } return(true); }
/** * 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(EscapePod __instance, ref Vector3 __result) { DeathRun.playerIsDead = false; if (Config.BASIC_GAME.Equals(DeathRun.config.startLocation)) { DeathRun.saveData.podSave.podGravity = false; DeathRun.saveData.podSave.podSinking = false; DeathRun.saveData.podSave.podAnchored = false; DeathRun.saveData.podSave.spotPicked = true; DeathRun.saveData.startSave = new StartSpot(0, 0, "Safe Shallows"); DeathRunUtils.CenterMessage("DEATH RUN", 10, 2); DeathRunUtils.CenterMessage("Start: \"" + DeathRun.saveData.startSave.message + "\"", 10, 3); CattleLogger.Message("Start: " + DeathRun.saveData.startSave.message); return(true); } int picker = UnityEngine.Random.Range(0, spots.Count); StartSpot spot = spots[picker]; // If a specific spot was specified in the config, use that instead. foreach (StartSpot s in spots) { if (s.message.Equals(DeathRun.config.startLocation)) { spot = s; break; } } DeathRun.saveData.podSave.podGravity = true; // Pod should sink DeathRun.saveData.podSave.podSinking = false; // ... but isn't sinking yet DeathRun.saveData.podSave.podAnchored = false; // ... and hasn't come to rest on the bottom DeathRun.saveData.podSave.spotPicked = true; // But we have picked the spot for it DeathRun.saveData.startSave = spot; // Here's where we started //ErrorMessage.AddMessage("\"" + spot.message + "\""); DeathRunUtils.CenterMessage("DEATH RUN", 10, 2); DeathRunUtils.CenterMessage("Start: \"" + spot.message + "\"", 10, 3); CattleLogger.Message("Start: " + spot.message); __result.x = spot.x; __result.y = spot.y; __result.z = spot.z; return(false); }
private static void doAscentWarning(int ticks) { if (!Config.NEVER.Equals(DeathRun.config.showWarnings)) { if ((DeathRun.saveData.nitroSave.ascentWarningTicks == 0) || Config.WHENEVER.Equals(DeathRun.config.showWarnings) || (Config.OCCASIONAL.Equals(DeathRun.config.showWarnings) && (ticks - DeathRun.saveData.nitroSave.ascentWarningTicks > 600))) { ErrorMessage.AddMessage("Ascending too quickly!"); DeathRunUtils.CenterMessage("Ascending too quickly!", 5); } } DeathRun.saveData.nitroSave.ascentWarningTicks = ticks; }
private static void Postfix(string slotName, UserStorageUtils.LoadOperation loadOperation) { byte[] bytes; if (loadOperation.GetSuccessful()) { if (loadOperation.files.TryGetValue(DeathRun.SaveFile, out bytes)) { DeathRunSaveData saveData = new DeathRunSaveData(); if (DeathRunSaveData.LoadFromBytes(bytes, out saveData)) { DeathRunUtils.RegisterSave(slotName, saveData); } } } }
public static bool Prefix(DamageType damageType) { try { setCauseOfDeath(damageType); DeathRun.saveData.playerSave.numDeaths++; DeathRun.saveData.playerSave.timeOfDeath = DayNightCycle.main.timePassedAsFloat; DeathRun.saveData.playerSave.spanAtDeath = DeathRun.saveData.playerSave.allLives; TimeSpan timeSpan = TimeSpan.FromSeconds((double)DeathRun.saveData.playerSave.currentLife); string text = "Time of Death"; if (DeathRun.saveData.playerSave.numDeaths > 1) { text += " #" + DeathRun.saveData.playerSave.numDeaths; } text += ": "; text += DeathRunUtils.sayTime(timeSpan); DeathRunUtils.CenterMessage(text, 10); CattleLogger.Message(text); text = "Cause of Death: " + DeathRun.cause; DeathRunUtils.CenterMessage(text, 10, 1); //ErrorMessage.AddMessage(text); DeathRun.saveData.playerSave.killOpening = true; DeathRun.saveData.runData.updateVitals(false); DeathRun.saveData.nitroSave.setDefaults(); // Reset all nitrogen state DeathRun.playerIsDead = true; } catch (Exception ex) { CattleLogger.GenericError("During Player.OnKill - ", ex); } return(true); }
private static void doRespawnMessages() { if (DeathRun.playerMonitor.JustWentAbove(DeathRun.saveData.playerSave.timeOfDeath + 10)) { DeathRun.playerIsDead = false; } if (DeathRun.playerMonitor.JustWentAbove(DeathRun.saveData.playerSave.timeOfDeath + 15)) { ErrorMessage.AddMessage(DeathRunUtils.centerMessages[0].getText()); if (DeathRun.saveData.playerSave.numDeaths > 1) { TimeSpan timeSpan2 = TimeSpan.FromSeconds((double)DeathRun.saveData.playerSave.spanAtDeath); string text; if (DeathRun.saveData.playerSave.numDeaths == 2) { text = "Both Lives: "; } else { text = "All " + DeathRun.saveData.playerSave.numDeaths + " Lives: "; } text += DeathRunUtils.sayTime(timeSpan2); DeathRunUtils.CenterMessage(text, 10); } } if (DeathRun.playerMonitor.JustWentAbove(DeathRun.saveData.playerSave.timeOfDeath + 25)) { TimeSpan timeSpan2 = TimeSpan.FromSeconds((double)DeathRun.saveData.playerSave.spanAtDeath); string text; if (DeathRun.saveData.playerSave.numDeaths == 2) { text = "Both Lives: "; } else { text = "All " + DeathRun.saveData.playerSave.numDeaths + " Lives: "; } text += DeathRunUtils.sayTime(timeSpan2); ErrorMessage.AddMessage(text); } }
public static void Postfix(MainMenuLoadPanel __instance, MainMenuLoadButton lb) { SaveLoadManager.GameInfo gameInfo = SaveLoadManager.main.GetGameInfo(lb.saveGame); if ((gameInfo == null) || !gameInfo.IsValid() || gameInfo.isFallback) { return; } DeathRunSaveData slotData = DeathRunUtils.FindSave(lb.saveGame); if (slotData == null) { return; } if (!"".Equals(slotData.startSave.message)) { lb.load.FindChild("SaveGameMode").GetComponent <Text>().text = slotData.startSave.message; slotData.runData.updateFromSave(slotData); string duration = Utils.PrettifyTime((int)slotData.playerSave.allLives); if (slotData.playerSave.allLives >= 60 * 60 * 24) { int total = (int)slotData.playerSave.allLives; int days = total / (60 * 60 * 24); total -= (days * 60 * 60 * 24); int hours = total / (60 * 60); total -= hours * 60 * 60; int minutes = total / 60; total -= minutes; duration = "" + days + " " + ((days == 1) ? "day" : "days") + ", " + hours + ":" + ((minutes < 10) ? "0" : "") + minutes; } duration += ". Score: " + slotData.runData.Score; lb.load.FindChild("SaveGameLength").GetComponent <Text>().text = duration; } }
public static bool Prefix(EscapePod __instance) { if (Config.BASIC_GAME.Equals(DeathRun.config.startLocation)) { return(true); } WorldForces wf = __instance.GetComponent <WorldForces>(); float depth = Ocean.main.GetDepthOf(__instance.gameObject); // Copy our current transform if (!DeathRun.saveData.podSave.podAnchored || isRighting()) { DeathRun.saveData.podSave.podTransform.copyFrom(__instance.transform); } // This block makes sure the pod doesn't sink *during* the opening cinematic etc. if (!DeathRun.saveData.podSave.podSinking) { frozen = false; // This checks if we're holding on the "press any key to continue" screen or intro cinematic if (DeathRunUtils.isIntroStillGoing()) { return(true); } // Otherwise, "turn on gravity" for the pod if (DeathRun.saveData.podSave.podGravity) { DeathRun.saveData.podSave.podSinking = true; wf.underwaterGravity = 9.81f; if (depth <= 0) { wf.aboveWaterGravity = 50f; } else { wf.aboveWaterGravity = 9.81f; } } } // Once we're below the surface, return gravity to normal if (wf.aboveWaterGravity == 50f && depth > 0) { wf.aboveWaterGravity = 9.81f; } // Give player some early feedback the lifepod is sinking if (DeathRun.saveData.podSave.podGravity && (depth > 6) && (DeathRun.saveData.podSave.lastDepth < 6)) { ErrorMessage.AddMessage("The Life Pod is sinking!"); DeathRunUtils.CenterMessage("The Life Pod is sinking!", 6); } int secs = (int)DayNightCycle.main.timePassedAsFloat; if (secs != DeathRun.saveData.podSave.prevSecs) { // Note if we've recently been frozen in place by cut scene or player distance if (frozen || __instance.rigidbodyComponent.isKinematic) { frozenSecs = secs; } // Check when pod hits bottom so we can stop processing it. if (!DeathRun.saveData.podSave.podRepaired && (DeathRun.saveData.podSave.prevSecs > 0) && (secs - frozenSecs > 2) && (depth > 20)) { float dist = Vector3.Distance(DeathRun.saveData.podSave.podPrev.position, DeathRun.saveData.podSave.podTransform.position); if (!DeathRun.saveData.podSave.podAnchored && (dist < 0.5)) { ErrorMessage.AddMessage("The Escape Pod has struck bottom!"); DeathRunUtils.CenterMessage("The Escape Pod has struck bottom!", 6); DeathRun.saveData.podSave.podAnchored = true; float random = UnityEngine.Random.value; float angle; float up = 2; if (random < .10f) { angle = 30; } else if (random < .20f) { angle = 45; } else if (random < .30f) { angle = 60; } else if (random < .40f) { angle = 120; } else if (random < .50f) { angle = 135; up = 3; } else if (random < .60f) { angle = 150; up = 4; } else if (random < .70f) { angle = 170; up = 4; } else if (random < .80f) { angle = 300; } else if (random < .90f) { angle = 315; } else { angle = 330; } __instance.transform.Translate(0, up, 0); if (Player.main.IsInside()) { Player.main.transform.Translate(0, 2, 0); } // Make a copy of our "upright state" DeathRun.saveData.podSave.podStraight.copyFrom(__instance.transform); // Now tip the pod over and copy that __instance.transform.Rotate(Vector3.forward, angle); // Jolt at bottom! DeathRun.saveData.podSave.podTipped.copyFrom(__instance.transform); // If we're supposed to (based on preferences) stay straight up, copy THAT back if (DeathRun.config.podStayUpright) { DeathRun.saveData.podSave.podStraight.copyTo(__instance.transform); } // Finally, store the stable transform we're supposed to use. DeathRun.saveData.podSave.podTransform.copyFrom(__instance.transform); } } DeathRun.saveData.podSave.prevSecs = secs; DeathRun.saveData.podSave.podPrev.copyFrom(DeathRun.saveData.podSave.podTransform); } // If player is away from the pod, stop gravity so that it doesn't fall through the world when the geometry unloads frozen = (Vector3.Distance(__instance.transform.position, Player.main.transform.position) > 20) || (DeathRun.saveData.podSave.podAnchored && !isRighting()); if (frozen) { wf.underwaterGravity = 0.0f; } else { wf.underwaterGravity = 9.81f; } // Once pod is repaired, we give it a little time to right itself and then restore kinematic mode "for safety" if (isRighting()) { if ((DeathRun.saveData.podSave.podRightingTime > 0) && (DayNightCycle.main.timePassedAsFloat > DeathRun.saveData.podSave.podRightingTime + 15)) { DeathRun.saveData.podSave.podRighted = true; __instance.rigidbodyComponent.isKinematic = true; } } DeathRun.saveData.podSave.lastDepth = depth; return(true); }
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); }
public static bool Prefix() { DeathRunUtils.HideHighScores(true); DeathRun.StartNewGame(); return(true); }
public static bool PlayReachSurfaceSound(WaterAmbience __instance) { if (!isAirPoisoned(Player.main)) { if (!isSurfaceAirPoisoned() && !Player.main.IsInside() && (Ocean.main.GetDepthOf(Player.main.gameObject) < 5)) { if (warnedNotBreathable) { warnedNotBreathable = true; warningTime = Time.time; ErrorMessage.AddMessage("You find the surface air is now breathable!"); } } return(true); } // If we're at a pipe so we can actually breathe, treat it normally. if (DeathRun.saveData.nitroSave.atPipe) { return(true); } if (Player.main.currentMountedVehicle != null) { return(true); } // Smoke choke sounds in unbreathable atmosphere PlayerDamageSounds s = Player.main.gameObject.GetComponent <PlayerDamageSounds>(); if (s != null) { s.painSmoke.Play(); } if (!Config.NEVER.Equals(DeathRun.config.showWarnings)) { if (!warnedNotBreathable || Config.WHENEVER.Equals(DeathRun.config.showWarnings) || (Config.OCCASIONAL.Equals(DeathRun.config.showWarnings) && (Time.time > warningTime + 300))) { if (!warnedNotBreathable || (Time.time > warningTime + 30f)) { warnedNotBreathable = true; warningTime = Time.time; if (Config.POISONED.Equals(DeathRun.config.surfaceAir)) { DeathRunUtils.CenterMessage("WARNING! Surface air not breathable!", 5); DeathRunUtils.CenterMessage("A Floating Pump could filter it.", 5, 1); ErrorMessage.AddMessage("WARNING! The surface air on this planet is not breathable!"); ErrorMessage.AddMessage("Use of a Floating Pump could filter it however."); } else { DeathRunUtils.CenterMessage("WARNING! Surface air now too irradiated to breathe!", 5); DeathRunUtils.CenterMessage("A Floating Pump could filter it.", 5, 1); ErrorMessage.AddMessage("The surface air is now too irradiated to breathe!"); } } } } var time = __instance.GetType().GetField("timeReachSurfaceSoundPlayed", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (Time.time < (float)time.GetValue(__instance) + 1f) { return(false); } // Skip other sounds as they are dependent on breathing time.SetValue(__instance, Time.time); __instance.reachSurfaceWithTank.Play(); // Different sound so no splash return(false); }
public static void Postfix() { DeathRunUtils.ShowHighScores(true); }
public static void Postfix(ref uGUI_SunbeamCountdown __instance) { if (DayNightCycle.main == null) { return; } if (CrashedShipExploder.main == null) { return; } // These are the internal parameters for the Aurora story events (see AuroraWarnings for time thresholds) float timeToStartWarning = CrashedShipExploder.main.GetTimeToStartWarning(); float timeToStartCountdown = CrashedShipExploder.main.GetTimeToStartCountdown(); float timeNow = DayNightCycle.main.timePassedAsFloat; DeathRun.countdownMonitor.Update(timeNow); int deep; if (Config.EXPLOSION_DEATHRUN.Equals(DeathRun.config.explodeDepth)) { deep = 100; } else if (Config.EXPLOSION_HARD.Equals(DeathRun.config.explodeDepth)) { deep = 50; } else { deep = 0; } if (deep > 0) { // At time of second Aurora warning if (DeathRun.countdownMonitor.JustWentAbove(Mathf.Lerp(timeToStartWarning, timeToStartCountdown, 0.5f))) { DeathRunUtils.CenterMessage("Explosion Shockwave Will Be", MESSAGE_TIME); DeathRunUtils.CenterMessage("Over " + deep + "m Deep!", MESSAGE_TIME, 1); } if (DeathRun.countdownMonitor.JustWentAbove(Mathf.Lerp(timeToStartWarning, timeToStartCountdown, 0.5f) + MESSAGE_TIME)) { ErrorMessage.AddMessage("WARNING: Explosion will produce shockwave over " + deep + "m deep!"); } // At time of third Aurora warning if (DeathRun.countdownMonitor.JustWentAbove(Mathf.Lerp(timeToStartWarning, timeToStartCountdown, 0.8f))) { DeathRunUtils.CenterMessage("Prepare To Evacuate At Least", MESSAGE_TIME); DeathRunUtils.CenterMessage("" + deep + "m Deep. Preferably Inside.", MESSAGE_TIME, 1); } if (DeathRun.countdownMonitor.JustWentAbove(Mathf.Lerp(timeToStartWarning, timeToStartCountdown, 0.8f) + MESSAGE_TIME)) { ErrorMessage.AddMessage("Prepare to evacuate at least " + deep + "m deep, preferably inside!"); } // At time of final countdown if (DeathRun.countdownMonitor.JustWentAbove(timeToStartCountdown)) { DeathRunUtils.CenterMessage("Seek Safe Depth Immediately!", MESSAGE_TIME); DeathRunUtils.CenterMessage("Preferably Inside!", MESSAGE_TIME, 1); } if (DeathRun.countdownMonitor.JustWentAbove(timeToStartCountdown + MESSAGE_TIME)) { ErrorMessage.AddMessage("Seek safe depth immediately! Preferably inside!"); } } deep = (int)RadiationUtils.getRadiationMaxDepth(); if (deep > 0) { if (DeathRun.countdownMonitor.JustWentAbove(timeToStartCountdown + 100f)) { DeathRunUtils.CenterMessage("Radiation Will Gradually Permeate", MESSAGE_TIME); DeathRunUtils.CenterMessage("Ocean As Deep As " + deep + "m.", MESSAGE_TIME, 1); } if (DeathRun.countdownMonitor.JustWentAbove(timeToStartCountdown + 100f + MESSAGE_TIME)) { ErrorMessage.AddMessage("Radiation will gradually permeate the sea, as deep as " + deep + "m."); } if (DeathRun.countdownMonitor.JustWentAbove(timeToStartCountdown + 100f + MESSAGE_TIME * 2)) { DeathRunUtils.CenterMessage("All devices will consume power more rapidly", MESSAGE_TIME); DeathRunUtils.CenterMessage("while exposed to RADIATION, and recharge slowly.", MESSAGE_TIME, 1); } if (DeathRun.countdownMonitor.JustWentAbove(timeToStartCountdown + 100f + MESSAGE_TIME * 3)) { ErrorMessage.AddMessage("All devices will consume power more rapidly while exposed to RADIATION and recharge slowly."); } } // If the Sunbeam rescue timer is showing, give that precedence over our countdown timer. if (isSunbeamShowing(__instance)) { showingShip = false; return; } // This is the time of the very first warning about the Aurora if (timeNow >= Mathf.Lerp(timeToStartWarning, timeToStartCountdown, 0.2f) && // Time of first Aurora warning (timeNow < timeToStartCountdown + 24f)) // Actual explosion time (24 sec after countdown) { float timeLeft = (timeToStartCountdown + 24f) - timeNow; if (timeLeft < 0) { timeLeft *= -1; } showShip(ref __instance); updateShip(ref __instance, timeLeft); } else { hideShip(ref __instance); } }
public static void TrjEjectPostfix(Player __instance) { if ((vehicle == null) || !(vehicle.gameObject.transform.position.y < vehicle.worldForces.waterDepth + 2f) || vehicle.precursorOutOfWater || vehicle.IsInsideAquarium()) { return; } if (Player.main.precursorOutOfWater) { return; } if (PrecursorMoonPoolTrigger.inMoonpool) { return; } // Can always get out for free inside Precursor locations string biome = __instance.CalculateBiome(); if (biome.StartsWith("precursor", StringComparison.OrdinalIgnoreCase) || biome.StartsWith("prison", StringComparison.OrdinalIgnoreCase)) { return; } float divisor; if (Config.DEATHRUN.Equals(DeathRun.config.powerExitVehicles)) { divisor = 1; } else if (Config.HARD.Equals(DeathRun.config.powerExitVehicles)) { divisor = 2; } else if (Config.EXORBITANT.Equals(DeathRun.config.powerExitVehicles)) { divisor = 0.25f; } else { return; } float factor; if (vehicle is SeaMoth) { factor = 10; } else if (vehicle is Exosuit) { factor = 20; } else { return; } int energyCost; float depth = Ocean.main.GetDepthOf(vehicle.gameObject); if (factor > 0) { energyCost = (int)(depth / (factor * divisor)); if (energyCost > 0) { energyCost += (int)(10 / divisor); } } else { return; } int deco = vehicle.modules.GetCount(DeathRun.decoModule.TechType); if (deco > 2) { energyCost = 0; } else { for (int dec = 0; dec < deco; dec++) { energyCost /= 2; if (energyCost < 1) { return; } } } if (energyCost > 0) { vehicle.energyInterface.ConsumeEnergy(energyCost); string name = DeathRunUtils.getFriendlyName(vehicle.gameObject); ErrorMessage.AddMessage(name + " power cell drained of " + energyCost + " energy for exit at depth " + (int)depth + "m."); if ((vehicle is SeaMoth) && !DeathRun.saveData.playerSave.toldSeamothCosts) { DeathRun.saveData.playerSave.toldSeamothCosts = true; DeathRunUtils.CenterMessage("Exiting the Seamoth underwater causes battery drain.", 10); DeathRunUtils.CenterMessage("Exit at surface or Moon Bay for optimum power use.", 10, 1); } if ((vehicle is Exosuit) && !DeathRun.saveData.playerSave.toldExosuitCosts) { DeathRun.saveData.playerSave.toldExosuitCosts = true; DeathRunUtils.CenterMessage("Although more efficient than the Seamoth, the Prawn suit", 10); DeathRunUtils.CenterMessage("does draw power when exited at depth.", 10, 1); } } }
public static void Postfix() { // Don't do anything if we're holding on the "press any key to continue" screen or intro cinematic if (DeathRunUtils.isIntroStillGoing()) { return; } // Adds our "Data Bank" entries if (!DeathRun.encyclopediaAdded && (DeathRun.saveData.playerSave.startedGame > 0)) { DeathRun.encyclopediaAdded = true; PDAEncyclopedia.Add("DeathRun", false); PDAEncyclopedia.Add("Aggression", false); PDAEncyclopedia.Add("Atmosphere", false); PDAEncyclopedia.Add("CrushDepth", false); PDAEncyclopedia.Add("Explosion", false); PDAEncyclopedia.Add("Nitrogen", false); PDAEncyclopedia.Add("Radiation", false); PDAEncyclopedia.Add("PowerCosts", false); PDAEncyclopedia.Add("LifePodSank", false); PDAEncyclopedia.Add("ExitVehicles", false); } // Officially start our mod's timer/monitor, if we haven't if (DeathRun.saveData.playerSave.startedGame == 0) { DeathRun.saveData.playerSave.startedGame = DayNightCycle.main.timePassedAsFloat; DeathRun.playerMonitor.Update(DayNightCycle.main.timePassedAsFloat); DeathRun.playerIsDead = false; return; } if (DeathRun.saveData.podSave.spotPicked) { DeathRun.saveData.runData.startNewRun(); DeathRun.saveData.podSave.spotPicked = false; DeathRun.playerIsDead = false; } // If any difficulty settings have changed, make sure we register any lower ones against the score stats if ((DeathRun.configDirty > 0) && (Time.time > DeathRun.configDirty + 5)) { DeathRun.saveData.runData.countSettings(); DeathRun.configDirty = 0; } DeathRun.playerMonitor.Update(DayNightCycle.main.timePassedAsFloat); float interval = DeathRun.playerMonitor.currValue - DeathRun.playerMonitor.prevValue; // Update our "time alive" DeathRun.saveData.playerSave.currentLife += interval; DeathRun.saveData.playerSave.allLives += interval; // Roll the "Mod Intro" messages if (!DeathRun.saveData.playerSave.killOpening && (DayNightCycle.main.timePassedAsFloat - DeathRun.saveData.playerSave.startedGame < 200)) { doIntroMessages(); } else { DeathRun.saveData.playerSave.killOpening = true; } // Respawn messages if ((DeathRun.saveData.playerSave.timeOfDeath > 0) && ((DayNightCycle.main.timePassedAsFloat - DeathRun.saveData.playerSave.timeOfDeath < 200))) { doRespawnMessages(); } // Delayed encyclopedia entries if ((DeathRun.saveData.playerSave.cueTime > 0) && (DayNightCycle.main.timePassedAsFloat > DeathRun.saveData.playerSave.cueTime)) { if (!"".Equals(DeathRun.saveData.playerSave.cueKey)) { PDAEncyclopedia.Add(DeathRun.saveData.playerSave.cueKey, true); if (KnownTechInitPatcher.UnlockSound != null) { try { PDASounds.queue.PlayQueued(KnownTechInitPatcher.UnlockSound); } catch (Exception exception) { Debug.LogException(exception); } } } DeathRun.saveData.playerSave.cueTime = 0; } }
public static void Postfix() { // Check if we've repaired the pod if (!EscapePod.main.damageEffectsShowing && !DeathRun.saveData.podSave.podRepaired) { if (EscapePod.main.liveMixin.GetHealthFraction() > 0.99f) { DeathRun.saveData.podSave.podRepaired = true; DeathRun.saveData.podSave.podRepairTime = DayNightCycle.main.timePassedAsFloat; } } // This just fixes a situation that 1.7.1 screwed up for some people if (EscapePod.main.damageEffectsShowing && DeathRun.saveData.podSave.podRepaired) { DeathRun.saveData.podSave.podRepaired = false; DeathRun.saveData.podSave.podRepairTime = 0; } // If we've repaired the pod but it hasn't right itself yet, let it off the kinematic leash to turn itself upright if (EscapePod_FixedUpdate_Patch.isRighting()) { if (Vector3.Distance(EscapePod.main.transform.position, Player.main.transform.position) < 15) { if (DeathRun.saveData.podSave.podRightingTime <= 0) { DeathRun.saveData.podSave.podRightingTime = DayNightCycle.main.timePassedAsFloat; } EscapePod.main.rigidbodyComponent.isKinematic = false; WorldForces wf = EscapePod.main.GetComponent <WorldForces>(); wf.underwaterGravity = 0.0f; } } EscapePod_FixedUpdate_Patch.CheckSolarCellRate(); if (damaged != EscapePod.main.damageEffectsShowing) { if (!EscapePod.main.damageEffectsShowing) { // At repair, give a one-time "full recharge" RegeneratePowerSource[] cells = EscapePod.main.gameObject.GetAllComponentsInChildren <RegeneratePowerSource>(); if (cells != null) { foreach (RegeneratePowerSource cell in cells) { float chargeable = cell.powerSource.GetMaxPower() - cell.powerSource.GetPower(); cell.powerSource.ModifyPower(chargeable, out _); } } } } else { if ((lastBlink == 0) || (lastBlink > Time.time)) { lastBlink = Time.time; } else if (Time.time >= lastBlink + 0.5) { lastBlink = Time.time; blinkOn = !blinkOn; } bool radioFound = false; bool radioWorks = false; if (EscapePod.main.radioSpawner != null && EscapePod.main.radioSpawner.spawnedObj != null) { LiveMixin component = EscapePod.main.radioSpawner.spawnedObj.GetComponent <LiveMixin>(); if (component) { radioFound = true; if (component.IsFullHealth()) { radioWorks = true; } } } if (damaged) { string content = Language.main.Get("IntroEscapePod3Content"); string bonus; if (DeathRun.saveData.podSave.podAnchored || Config.BASIC_GAME.Equals(DeathRun.config.startLocation)) { if (!Config.BASIC_GAME.Equals(DeathRun.config.startLocation)) { content = content.Replace("Flotation Devices: DEPLOYED", "Flotation Devices: FAILED"); if (DeathRun.config.podStayUpright || DeathRun.saveData.podSave.podRepaired) { content = content.Replace("Hull Integrity: OK", "Inertial Stabilizers: DEPLOYED"); } else { content = content.Replace("Hull Integrity: OK", "Inertial Stabilizers: " + (blinkOn ? "FAILED" : "")); } } } else { content = content.Replace("Flotation Devices: DEPLOYED", "Flotation Devices: " + (blinkOn ? "FAILED" : "")); } if (radioWorks) { content = content.Replace("Radio: OFFLINE", "Radio: INCOMING ONLY"); } if (!Config.NORMAL.Equals(DeathRun.config.creatureAggression)) { content = content.Replace("Uncharted ocean planet 4546B", "Planet 4546B: HOSTILE FAUNA"); } if (BreathingPatcher.isSurfaceAirPoisoned()) { content = content.Replace("Oxygen/nitrogen atmosphere", "Atmosphere: requires filtration"); } bonus = ""; if (BreathingPatcher.isSurfaceAirPoisoned()) { bonus += "\n\n- Atmosphere: " + (blinkOn ? "NOT BREATHABLE" : "") + "\n- Recommend Air Pumps to Filter Oxygen"; } if (DeathRunUtils.isExplosionClockRunning()) { bonus += "\n\n" + (blinkOn ? "- QUANTUM EXPLOSION WARNING" : ""); } if (RadiationUtils.isRadiationActive()) { bonus += "\n\n" + (blinkOn ? "- EXTREME RADIATION HAZARD" : ""); } uGUI_EscapePod.main.SetHeader(Language.main.Get("IntroEscapePod3Header"), new Color32(243, 201, 63, byte.MaxValue), 2f); uGUI_EscapePod.main.SetContent(content + bonus, new Color32(233, 63, 27, byte.MaxValue)); } else { string content = Language.main.Get("IntroEscapePod4Content"); if (radioFound && !radioWorks) { content = content.Replace("Incoming radio communication: ONLINE", "Incoming radio communication: OFFLINE"); } if (!Config.NORMAL.Equals(DeathRun.config.creatureAggression)) { content = content.Replace("Uncharted ocean planet 4546B", (blinkOn ? "Planet 4546B: HOSTILE FAUNA" : "Planet 4546B: ")); } if (BreathingPatcher.isSurfaceAirPoisoned()) { content = content.Replace("Oxygen/nitrogen atmosphere", "Atmosphere: requires filtration"); } if (!Config.BASIC_GAME.Equals(DeathRun.config.startLocation)) { content = content.Replace("Flotation Devices: DEPLOYED", "Flotation Devices: FAILED"); if (DeathRun.config.podStayUpright || DeathRun.saveData.podSave.podRepaired) { content = content.Replace("Hull Integrity: OK", "Inertial Stabilizers: DEPLOYED"); } else { content = content.Replace("Hull Integrity: OK", "Inertial Stabilizers: FAILED"); } } if (BreathingPatcher.isSurfaceAirPoisoned()) { content = content.Replace("Oxygen/nitrogen atmosphere", "Atmosphere: requires filtration"); } string bonus = ""; if (DeathRunUtils.isExplosionClockRunning()) { bonus += "\n " + (blinkOn ? "- QUANTUM EXPLOSION WARNING" : ""); } if (RadiationUtils.isRadiationActive()) { if (Config.NORMAL.Equals(DeathRun.config.radiationDepth)) { bonus += "\n - Radiation Hazard: Aurora"; } else { bonus += "\n " + (blinkOn ? "- EXTREME RADIATION HAZARD" : ""); } } uGUI_EscapePod.main.SetHeader(Language.main.Get("IntroEscapePod4Header"), new Color32((byte)(blinkOn ? 243 : 223), (byte)(blinkOn ? 243 : 223), 63, byte.MaxValue)); //, 2f); uGUI_EscapePod.main.SetContent(content + bonus, new Color32((byte)(blinkOn ? 243 : 223), (byte)(blinkOn ? 243 : 223), 63, byte.MaxValue)); } } }