/// <summary>
        /// Executes behavior with given context
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        public override BehaviorReturnCode Behave(IBehaviorContext context)
        {
            UnitBehaviorContext unitContext = context as UnitBehaviorContext;

            if (unitContext == null)
            {
                returnCode = BehaviorReturnCode.Failure;
                return(returnCode);
            }

            MoveableUnit unit = unitContext.Unit as MoveableUnit;

            if (unit == null || unit.Environment == null || !unit.CanMove || unit.IsOnOrbit || unit.IsInDock)
            {
                returnCode = BehaviorReturnCode.Failure;
                return(returnCode);
            }

            HexElement element;

            if (!unit.Environment.UnitsMap.TryGetValue(unit.HexMapKey, out element))
            {
                returnCode = BehaviorReturnCode.Failure;
                return(returnCode);
            }

            if (!unit.Environment.EnvironmentMap.TryGetValue(unit.HexMapKey, out element))
            {
                returnCode = BehaviorReturnCode.Failure;
                return(returnCode);
            }

            if (element is IOrbitable)
            {
                IOrbitable bodyWithOrbit = (IOrbitable)element;
                if (bodyWithOrbit.CanEnterMoreUnits(unit.Owner))
                {
                    returnCode = BehaviorReturnCode.Success;
                    return(returnCode);
                }
            }

            returnCode = BehaviorReturnCode.Failure;
            return(returnCode);
        }
Esempio n. 2
0
        /// <summary>
        /// Define the orbit between 2 body. The most massive will be the main body.
        /// </summary>
        /// <param name="bodyA">The first body of the orbit</param>
        /// <param name="bodyB">The second body of the orbit</param>
        /// <param name="epoch">The t0 date of the system</param>
        /// <param name="eccentricity">derivation from perfect circle : 0 is circle, below 1 is elipsoid, above is a escape trajectory (no units)</param>
        /// <param name="meanDistance">aka the semi Major axis of the orbit (in meters)</param>
        public Orbit(IOrbitable bodyA, IOrbitable bodyB, DateTime epoch, double eccentricity, double meanDistance)
        {
            //Setup bodies position according to their mass, maybe a better approach ?

            if (bodyA.IsVirtual)
            {
                _mainBody = bodyA; _body = bodyB;
            }
            else if (bodyB.IsVirtual)
            {
                _mainBody = bodyB; _body = bodyA;
            }
            else if (bodyA is APhysicalObject bodyAphysical && bodyB is APhysicalObject bodyBphysical)
            {
                if (bodyAphysical.Mass >= bodyBphysical.Mass)
                {
                    _mainBody = bodyA; _body = bodyB;
                }
                else
                {
                    _mainBody = bodyB; _body = bodyA;
                }
            }
Esempio n. 3
0
        private Orbit ForgeOrbit(IOrbitable A, IOrbitable B, double systemAge)
        {
            double periapsis;
            double meanDistance        = 0;
            double orbitalEccentricity = 0;

            do
            {
                int OrbitalEccentricityRand = 0;

                //Mean Separation p10
                int meanAnomalyRand = randomSource.Next(1, 10);
                if (systemAge > 5)
                {
                    meanAnomalyRand++;
                }
                else if (systemAge < 1)
                {
                    meanAnomalyRand--;
                }

                meanAnomalyRand = Physic.Clamp(meanAnomalyRand, 1, 10);
                if (1 <= meanAnomalyRand && meanAnomalyRand <= 3)
                {
                    meanDistance = randomSource.Next(1, 10) * 0.05f; OrbitalEccentricityRand -= 2;
                }                                                                                                                                   //AU
                else if (4 <= meanAnomalyRand && meanAnomalyRand <= 6)
                {
                    meanDistance = randomSource.Next(1, 10) * 0.5f; OrbitalEccentricityRand--;
                }                                                                                                                                     //AU
                else if (7 <= meanAnomalyRand && meanAnomalyRand <= 8)
                {
                    meanDistance = randomSource.Next(1, 10) * 3;                                                    //AU
                }
                else if (meanAnomalyRand == 9)
                {
                    meanDistance = randomSource.Next(1, 10) * 20;                            //AU
                }
                else if (meanAnomalyRand == 10)
                {
                    meanDistance = randomSource.Next(1, 100) * 200;                             //AU
                }
                //Orbital Eccentricity
                OrbitalEccentricityRand += randomSource.Next(1, 10);
                OrbitalEccentricityRand  = Physic.Clamp(OrbitalEccentricityRand, 1, 10);
                int adder = randomSource.Next(1, 10);
                if (1 <= OrbitalEccentricityRand && OrbitalEccentricityRand <= 2)
                {
                    orbitalEccentricity = adder * 0.01f;
                }
                else if (3 <= OrbitalEccentricityRand && OrbitalEccentricityRand <= 4)
                {
                    orbitalEccentricity = 0.01f + adder * 0.01f;
                }
                else if (5 <= OrbitalEccentricityRand && OrbitalEccentricityRand <= 6)
                {
                    orbitalEccentricity = 0.02f + adder * 0.01f;
                }
                else if (7 <= OrbitalEccentricityRand && OrbitalEccentricityRand <= 8)
                {
                    orbitalEccentricity = 0.03f + adder * 0.01f;
                }
                else if (OrbitalEccentricityRand == 9)
                {
                    orbitalEccentricity = 0.04f + adder * 0.01f;
                }
                else if (OrbitalEccentricityRand == 10)
                {
                    orbitalEccentricity = 0.05f + adder * 0.04f;
                }

                periapsis = meanDistance * Physic.AstronomicUnit * (1 + orbitalEccentricity);
            }while (periapsis < A.Radius * Physic.SolarRadius + B.Radius * Physic.SolarRadius); //periapsis<radiusA+radiusB
            //TEST FOR EDGE CASES (ex radius<body radius)

            Orbit orbit;

            //Finaly, put together
            if (_testMode)
            {
                orbit = new Orbit(A, B, DateTime.Now, 0.0, 1 * Physic.AstronomicUnit);
            }
            else
            {
                orbit = new Orbit(A, B, DateTime.Now, orbitalEccentricity, meanDistance * Physic.AstronomicUnit);
            }

            return(orbit);
        }