/**
         * When loading game, put escape pod back in any weird position, and restore its anchor.
         */
        public static void JustLoadedGame()
        {
            if (!Config.BASIC_GAME.Equals(DeathRun.config.startLocation))
            {
                WorldForces wf    = EscapePod.main.GetComponent <WorldForces>();
                float       depth = Ocean.main.GetDepthOf(EscapePod.main.gameObject);

                if (DeathRun.saveData.podSave.podSinking)
                {
                    wf.aboveWaterGravity = 9.81f;
                }

                if (DeathRun.saveData.podSave.podAnchored)
                {
                    DeathRun.saveData.podSave.podTransform.copyTo(EscapePod.main.transform);
                    EscapePod.main.rigidbodyComponent.isKinematic = true;
                    wf.underwaterGravity = 0.0f;
                }
                else
                {
                    wf.underwaterGravity = 9.81f;
                }
            }

            if (EscapePod.main.liveMixin.GetHealthFraction() < 0.99f)
            {
                EscapePod.main.damageEffectsShowing = false;
                EscapePod.main.ShowDamagedEffects();
                EscapePod.main.lightingController.SnapToState(2);
                uGUI_EscapePod.main.SetHeader(Language.main.Get("IntroEscapePod3Header"), new Color32(243, 201, 63, byte.MaxValue), 2f);
                uGUI_EscapePod.main.SetContent(Language.main.Get("IntroEscapePod3Content"), new Color32(233, 63, 27, byte.MaxValue));
                uGUI_EscapePod.main.SetPower(Language.main.Get("IntroEscapePod3Power"), new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue));
                EscapePod.main.introCinematic.interpolationTimeOut = 0f;
            }
            else
            {
                EscapePod.main.lightingController.SnapToState(0);   //159,243,63
                uGUI_EscapePod.main.SetHeader(Language.main.Get("IntroEscapePod4Header"), new Color32(243, 243, 63, byte.MaxValue), 2f);
                uGUI_EscapePod.main.SetContent(Language.main.Get("IntroEscapePod4Content"), new Color32(243, 243, 63, byte.MaxValue));
                uGUI_EscapePod.main.SetPower(Language.main.Get("IntroEscapePod4Power"), new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue));
            }
            EscapePod.main.UpdateDamagedEffects();
            CheckSolarCellRate();
        }
        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));
                }
            }
        }
        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);
        }