public bool ContainmentBreach()
 {
     WSXStuff.RedAlert(vessel);
     WSXStuff.PowerfulExplosion(part);
     return(false);
 }
        private bool CheckBubbleDistances()
        {
            try
            {
                int    partn             = 0;
                Part[] ExplodeParts      = new Part[10];
                bool   SomethingExploded = false;

                var   posBubble     = part.partTransform.position;
                float sqrBubbleSize = BubbleSize + BubbleEnhancement;
                sqrBubbleSize *= sqrBubbleSize;
                bool inside, outside;
                int  ex;

                foreach (var p in vessel.parts)
                {
                    if (p == part)
                    {
                        continue;
                    }

                    if (p.physicalSignificance == Part.PhysicalSignificance.NONE)
                    {
                        continue;
                    }

                    float longest = -1;

                    inside  = false;
                    outside = false;
                    ex      = 1;

                    bool ignoreThis = false;;

                    // The Communotron 99-99 causes problems
                    if (p.FindModuleImplementing <ModuleDataTransmitter>())
                    {
                        ignoreThis = true;
                    }

                    if (ignoreThis)
                    {
                        continue;
                    }

                    MeshFilter[] mf = p.FindModelComponents <MeshFilter>();
                    for (var i = 0; i < mf.Length; i++)
                    {
                        Bounds mrb = mf[i].mesh.bounds;

                        for (var z = -1; z <= 1; z += 2)
                        {
                            for (var y = -1; y <= 1; y += 2)
                            {
                                for (var x = -1; x <= 1; x += 2)
                                {
                                    // xzy because that's the coordinate system KSP likes to use
                                    Vector3 boxpt = new Vector3(mrb.center.x + ex * x * mrb.extents.x,
                                                                mrb.center.z + ex * z * mrb.extents.z, mrb.center.y + ex * y * mrb.extents.y);
                                    Vector3 tpt = p.transform.TransformPoint(boxpt);

                                    float sqrDistance = (tpt - posBubble).sqrMagnitude;
                                    if (sqrDistance <= sqrBubbleSize)
                                    {
                                        inside = true;
                                    }
                                    else
                                    {
                                        outside = true;
                                    }

                                    if (sqrDistance > longest)
                                    {
                                        longest = sqrDistance;
                                    }

                                    // The bubble cuts this one in half
                                    if (inside && outside)
                                    {
                                        SomethingExploded     = true;
                                        ExplodeParts[partn++] = p;
                                        print("[WSXWARP] Bubble hit " + p.name + " at dist " + Math.Sqrt(longest));
                                        if (partn == ExplodeParts.Length)
                                        {
                                            Array.Resize <Part>(ref ExplodeParts, ExplodeParts.Length * 2);
                                        }
                                        goto GotoConsideredHarmful;
                                    }

                                    if (ex == 0)
                                    {
                                        goto GotoConsideredHarmful;
                                    }
                                }
                            }
                        }
                    }

GotoConsideredHarmful:
                    continue;
                }

                if (SomethingExploded)
                {
                    BubbleCollapse();
                    ShutdownDrive(true);

                    for (var x = 0; x < partn; x++)
                    {
                        WSXStuff.PowerfulExplosion(ExplodeParts[x]);
                    }

                    WarningSound();
                    RedAlert();
                    return(false);
                }
            }
            catch (Exception ex)
            {
                print(String.Format("[WSXWARP] Error in CheckBubbleDistances - {0}", ex.Message));
            }

            return(true);
        }
 double ChargeAvailable()
 {
     return(WSXStuff.ThingAvailable(vessel, resourceUsed));
 }
        public void Develocitize()
        {
            // This code is inspired quite heavily by HyperEdit's OrbitEditor.cs
            if (recharge <= 0.0f)
            {
                double   ut              = Planetarium.GetUniversalTime();
                Orbit    curo            = vessel.orbitDriver.orbit;
                Vector3d currentVelocity = curo.getOrbitalVelocityAtUT(ut);
                Vector3d prograde        = currentVelocity.normalized;

                bool     nomoon     = false;
                Vector3d vlocal     = new Vector3d(0.0, 0.0, 0.0);
                Vector3d vplanetary = new Vector3d(0.0, 0.0, 0.0);
                if (vessel.mainBody && vessel.mainBody.orbitDriver)
                {
                    vlocal = vessel.mainBody.orbitDriver.orbit.getOrbitalVelocityAtUT(ut);

                    CelestialBody rb = vessel.mainBody.referenceBody;
                    if (rb != null && rb != vessel.mainBody && rb.orbitDriver)
                    {
                        vplanetary = rb.orbitDriver.orbit.getOrbitalVelocityAtUT(ut);
                    }
                    else
                    {
                        vplanetary = vlocal;
                        vlocal     = new Vector3d(0.0, 0.0, 0.0);
                        nomoon     = true;
                    }
                }

                // Do not call GetObtVelocity and expect it to work with this code
                // It switches around Y and Z
                Vector3d velocityToCancel = new Vector3d(0.0, 0.0, 0.0);
                if (rFrameVal > 0)
                {
                    velocityToCancel += vlocal;
                }
                if (rFrameVal > 1)
                {
                    velocityToCancel += vplanetary;
                }
                Vector3d exVelocityToCancel = velocityToCancel;
                velocityToCancel += currentVelocity;

                double speedToCancel = velocityToCancel.magnitude;
                double powerCost     = (int)speedToCancel * powerMultiplier;
                double powerGot      = WSXStuff.ThingAvailable(vessel, resourceUsed);
                if (powerGot < powerCost)
                {
                    rechargeNotice = "Partial Devlocitize";
                    this.recharge  = 5.0f;
                    powerCost      = powerGot;
                }

                powerDrain    = (float)powerCost;
                maxPowerDrain = powerDrain;
                part.Effect(engageEffectName, 1.0f);

                // Extremely small velocities cause the game to mess up very badly, so try something small and increase...
                float mult = 0.0f;
                if (rFrameVal == 0 || nomoon)
                {
                    mult = 2.0f;
                }
                Orbit newo;
                do
                {
                    Vector3d retro = prograde * -mult;
                    newo = new Orbit(curo.inclination, curo.eccentricity, curo.semiMajorAxis,
                                     curo.LAN, curo.argumentOfPeriapsis, curo.meanAnomalyAtEpoch, curo.epoch, curo.referenceBody);
                    newo.UpdateFromStateVectors(curo.pos, retro - exVelocityToCancel, curo.referenceBody, ut);
                    mult += 1.0f;
                } while (double.IsNaN(newo.getOrbitalVelocityAtUT(ut).magnitude));

                mult -= 1.0f;
                print("[WSXDV] Needed Multiplier " + mult.ToString());

                vessel.Landed   = false;
                vessel.Splashed = false;
                vessel.landedAt = string.Empty;

                // I'm actually not sure what this is for... but HyperEdit does it.
                // I had weird problems when I took it out, anyway.
                try
                {
                    OrbitPhysicsManager.HoldVesselUnpack(60);
                }
                catch (NullReferenceException)
                {
                    print("[WSXDV] NullReferenceException");
                }
                var allVessels = FlightGlobals.fetch == null ? (IEnumerable <Vessel>) new[] { vessel } : FlightGlobals.Vessels;
                foreach (var v in allVessels.Where(v => v.packed == false))
                {
                    v.GoOnRails();
                }
                // End HyperEdit code I don't really understand

                curo.inclination         = newo.inclination;
                curo.eccentricity        = newo.eccentricity;
                curo.semiMajorAxis       = newo.semiMajorAxis;
                curo.LAN                 = newo.LAN;
                curo.argumentOfPeriapsis = newo.argumentOfPeriapsis;
                curo.meanAnomalyAtEpoch  = newo.meanAnomalyAtEpoch;
                curo.epoch               = newo.epoch;
                curo.Init();
                curo.UpdateFromUT(ut);

                vessel.orbitDriver.pos = vessel.orbit.pos.xzy;
                vessel.orbitDriver.vel = vessel.orbit.vel;

                Events ["Develocitize"].active = false;
                this.recharge = 5.0f;
            }
        }