예제 #1
0
        /// <summary>
        /// Creates a new <see cref="Station"/> instance, and adds it the specified <see cref="Star"/>. If an object
        /// already exists in this star with the same name, it will be turned into a station.
        /// </summary>
        /// <param name="name">The name of the new station</param>
        /// <param name="star">The star system the new station belongs to</param>
        /// <returns>The newly created station</returns>
        /// <exception cref="ArgumentNullException">The provided name or container is null.</exception>
        /// <exception cref="ArgumentException">The provided name is already in use.</exception>
        public static AstronomicalObject CreateStation(string name, AstronomicalObject star)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            if (star == null)
            {
                throw new ArgumentException("star");
            }

            AstronomicalObject result = star.Environment.FindObjectByName(name);

            if (result == null)
            {
                result = new AstronomicalObject(name, star.Environment, AstronomicalObjectType.Station, star);
            }
            else
            {
                result.Star = star;
                result.Type = AstronomicalObjectType.Station;
            }

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Creates a new <see cref="Star"/> instance and adds it into this environment
        /// </summary>
        /// <param name="name">The name of the new star system</param>
        /// <param name="env">The environment that will contain the new star</param>
        /// <returns>The created <see cref="Star"/> instance.</returns>
        /// <exception cref="ArgumentNullException">The provided name is null</exception>
        /// <exception cref="ArgumentException">The provided name is already used by an existing star</exception>
        public static AstronomicalObject CreateStar(string name, EliteEnvironment env)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            if (env == null)
            {
                throw new ArgumentNullException("name");
            }

            AstronomicalObject result   = null;
            AstronomicalObject existing = env.FindObjectByName(name);

            if (existing != null)
            {
                existing.Star = existing;
                existing.Type = AstronomicalObjectType.Star;
                result        = existing;
            }
            else
            {
                result      = new AstronomicalObject(name, env, AstronomicalObjectType.Star, null);
                result.Star = result;
            }

            return(result);
        }
예제 #3
0
        /// <summary>
        /// Returns a list of possible commodities that can be bought in this station and sold in another specified station.
        /// </summary>
        /// <param name="otherStation">A station to sell at</param>
        /// <returns>A list of <see cref="TradeJumpData"/> instances, describing the available trading options</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="otherStation"/> parameter is null</exception>
        /// <exception cref="ArgumentException">The <paramref name="otherStation"/> parameter equals the current station</exception>
        public List <TradeJumpData> FindTradesWith(AstronomicalObject otherStation)
        {
            if (otherStation == null)
            {
                throw new ArgumentNullException("otherStation");
            }

            if (otherStation == this)
            {
                throw new ArgumentException("The otherStation argument cannot contain the Station you call the method on.", "otherStation");
            }

            List <TradeJumpData> result = new List <TradeJumpData>();

            foreach (Trade t in Trades)
            {
                if (!t.CanSell)
                {
                    continue;
                }

                Trade t2 = otherStation.FindCommodity(t.Commodity);
                if (t2 == null || !t2.CanBuy)
                {
                    continue;
                }

                result.Add(new TradeJumpData(t, t2));
            }

            return(result);
        }
예제 #4
0
        /// <summary>
        /// Computes the most profitable trading jump given the specified constraints
        /// </summary>
        /// <param name="from">The <see cref="Station"/> to buy the goods from</param>
        /// <param name="to">The <see cref="Station"/> to sell the goods at</param>
        /// <param name="cargo">The maximum amount of units that can be bought</param>
        /// <param name="budget">The maximum price that can be paid for buying the goods</param>
        /// <returns>A <see cref="TradeJumpData"/> instance describing the ideal trade operation</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="from"/> or <paramref name="to"/> arguments are null.</exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <list type="bullet">
        ///     <item>
        ///         <description>The <paramref name="cargo"/> parameter is negative or zero.</description>
        ///     </item>
        ///     <item>
        ///         <description>The <paramref name="budget"/> parameter is negative or zero.</description>
        ///     </item>
        /// </list>
        /// </exception>
        /// <exception cref="ArgumentException">The <paramref name="from"/> and <paramref name="to"/> parameters are equal</exception>
        public TradeJumpData FindBestProfit(AstronomicalObject from, AstronomicalObject to, int cargo, int budget)
        {
            if (from == null)
            {
                throw new ArgumentNullException("from");
            }
            if (to == null)
            {
                throw new ArgumentNullException("to");
            }
            if (from == to)
            {
                throw new ArgumentException("The from and to stations cannot be the same");
            }
            if (cargo <= 0)
            {
                throw new ArgumentOutOfRangeException("cargo");
            }
            if (budget <= 0)
            {
                throw new ArgumentOutOfRangeException("budget");
            }

            TradeJumpData result = new TradeJumpData();

            result.TotalProfit = Single.MinValue;

            foreach (Trade t in from.Trades)
            {
                if (!t.CanSell)
                {
                    continue;
                }

                Trade t2 = to.FindCommodity(t.Commodity);
                if (t2 == null || !t2.CanBuy)
                {
                    continue;
                }

                float profitPerUnit = t2.BuyingPrice - t.SellingPrice;
                int   cargoSize     = Math.Min(cargo, (int)(budget / t.SellingPrice));
                float totalProfit   = profitPerUnit * cargoSize;

                if (totalProfit > result.TotalProfit)
                {
                    result.Fill(t, t2, cargoSize);
                }
            }

            if (result.Commodity == null)
            {
                return(null);
            }
            return(result);
        }
예제 #5
0
        /// <summary>
        /// Returns the <see cref="AstronomicalObject"/> singleton that is used to represent deep space locations,
        /// moving it to the specified star
        /// </summary>
        /// <param name="moveToStar">The star that the deep space location is near to</param>
        /// <returns>A <see cref="DeepSpace"/> instance</returns>
        public AstronomicalObject GetDeepSpaceObject(AstronomicalObject moveToStar)
        {
            AstronomicalObject result = FindObjectByName(DEEP_SPACE_NAME, StringComparison.InvariantCulture);

            if (result == null)
            {
                result = new AstronomicalObject(DEEP_SPACE_NAME, this, AstronomicalObjectType.DeepSpace, moveToStar);
            }
            else
            {
                result.Star = moveToStar;
            }

            return(result);
        }
예제 #6
0
        /// <summary>
        /// Adds a new entry into the list of stars we know the distance from
        /// </summary>
        /// <param name="otherObject">Another <see cref="Star"/> instance.</param>
        /// <param name="distance">The distance between the current star and the
        /// star specified in the <paramref name="otherObject"/> parameter.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="otherObject"/> parameter is null.</exception>
        /// <exception cref="ArgumentException">The <paramref name="otherObject"/> is equal to the current star</exception>
        /// <exception cref="ArgumentOutOfRangeException">The <paramref name="distance"/> parameter is negative
        /// or equals zero.</exception>
        /// <remarks>
        /// This method can be called either to add a new distance, or to modify an existing distance.
        /// The data will be added in the <see cref="KnownObjectProximities"/> property of both the current star
        /// and the star provided in the <paramref name="otherObject"/> parameter.
        /// </remarks>
        /// <seealso cref="KnownObjectProximities"/>
        public void RegisterDistanceFrom(AstronomicalObject otherObject, float distance)
        {
            if (otherObject == null)
            {
                throw new ArgumentNullException();
            }

            if (otherObject == this)
            {
                throw new ArgumentException("I cannot set a distance between me and myself !", "otherStar");
            }

            if (distance <= 0)
            {
                throw new ArgumentOutOfRangeException("Invalid distance", "distance");
            }

            KnownObjectProximities.Set(otherObject, distance);
            otherObject.KnownObjectProximities.Set(this, distance);
        }
예제 #7
0
        /// <summary>
        /// Creates a new <see cref="AstronomicalObject"/> orbiting around this star.
        /// </summary>
        /// <param name="name">A name for the new object</param>
        /// <param name="star">The <see cref="Star"/> system that will contain the new object</param>
        /// <returns>The newly created <see cref="AstronomicalObject"/></returns>
        public static AstronomicalObject CreateAstronomicalObject(string name, AstronomicalObject star)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name", "A star name cannot be null");
            }

            AstronomicalObject result = star.Environment.FindObjectByName(name);

            if (result == null)
            {
                result = new AstronomicalObject(name, star.Environment, AstronomicalObjectType.NaturalObject, star);
            }
            else
            {
                result.Type = AstronomicalObjectType.NaturalObject;
                result.Star = star;
            }

            return(result);
        }
예제 #8
0
        internal static bool Load(XmlReader reader, EliteEnvironment container)
        {
            if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "trade")
            {
                return(false);
            }

            Commodity          commodity = null;
            AstronomicalObject station   = null;
            float sellingPrice           = 0;
            float buyingPrice            = 0;
            int   stock = 0;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "commodity":
                    commodity = container.FindCommodityByName(reader.Value);
                    if (commodity == null)
                    {
                        throw new EnvironmentLoadException(String.Format("Unknown commodity name '{0}'", reader.Value), reader);
                    }
                    break;

                case "station":
                    station = container.Stations.Where(s => s.Name == reader.Value).FirstOrDefault();
                    if (station == null)
                    {
                        throw new EnvironmentLoadException(String.Format("Unknown station name '{0}'", reader.Value), reader);
                    }
                    break;

                case "sellingPrice":
                    sellingPrice = reader.ReadFloat();
                    break;

                case "buyingPrice":
                    buyingPrice = reader.ReadFloat();
                    break;

                case "stock":
                    stock = reader.ReadInt();
                    break;
                }
            }

            if (commodity == null)
            {
                throw new EnvironmentLoadException("Missing commodity for a trade entry", reader);
            }

            if (station == null)
            {
                throw new EnvironmentLoadException("Missing station for a trade entry", reader);
            }

            station.CreateTrade(commodity, sellingPrice, buyingPrice, stock);

            reader.Read();
            return(true);
        }
예제 #9
0
 internal Trade(AstronomicalObject station, Commodity commodity)
 {
     Station   = station;
     Commodity = commodity;
     DataDate  = DateTime.Now;
 }
예제 #10
0
        /// <summary>
        /// Loads an environment from the specified stream.
        /// </summary>
        /// <param name="source">A stream containing data previously written by the <see cref="Save"/> method.</param>
        /// <exception cref="ArgumentNullException">The provided stream is null</exception>
        /// <exception cref="ArgumentException">The provided stream cannot be read</exception>
        /// <exception cref="EnvironmentLoadException">The stream contained invalid data</exception>
        public void Load(Stream source)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

            if (!source.CanRead)
            {
                throw new ArgumentException("Source stream must be readable", "source");
            }

            XmlReaderSettings xmlSettings = new XmlReaderSettings()
            {
                CloseInput = false,
            };

            using (XmlReader reader = XmlReader.Create(source, xmlSettings))
            {
                string currentName = null;

                while (reader.Read())
                {
                    // Move to the root element
                    if (reader.IsStartElement())
                    {
                        break;
                    }
                }
                while (reader.MoveToNextAttribute())
                {
                    switch (reader.LocalName)
                    {
                    //case "autodistance":
                    //    AutoDistanceEnabled = reader.ReadBool();
                    //    break;

                    case "current":
                        currentName = reader.Value;
                        break;
                    }
                }

                while (reader.Read())
                {
                    if (reader.IsStartElement())
                    {
                        switch (reader.LocalName)
                        {
                        case "commodities":
                            // Using a subtree reader ensures that the rest of the loading
                            // code will not get past the end of the container, and
                            // that we are positionned at the end of the container after
                            // the reading is done
                            using (XmlReader commoditiesReader = reader.ReadSubtree())
                            {
                                while (commoditiesReader.Read())
                                {
                                    if (commoditiesReader.IsStartElement())
                                    {
                                        Commodity.Load(commoditiesReader, this);
                                    }
                                }
                            }
                            break;

                        case "objects":
                            using (XmlReader objectsReader = reader.ReadSubtree())
                            {
                                objectsReader.Read();
                                while (objectsReader.Read())
                                {
                                    if (objectsReader.IsStartElement())
                                    {
                                        if (!AstronomicalObject.Load(reader, this))
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                            break;

                        case "trades":
                            using (XmlReader tradesReader = reader.ReadSubtree())
                            {
                                while (tradesReader.Read())
                                {
                                    if (tradesReader.IsStartElement())
                                    {
                                        Trade.Load(tradesReader, this);
                                    }
                                }
                            }
                            break;
                        }
                    }
                }

                if (currentName != null)
                {
                    CurrentSituation.CurrentLocation = FindObjectByName(currentName);
                }
            }
        }
예제 #11
0
        internal static bool Load(XmlReader reader, EliteEnvironment container)
        {
            if (!reader.IsStartElement())
            {
                return(false);
            }

            AstronomicalObjectType type = AstronomicalObjectType.Unspecified;

            if (Enum.TryParse <AstronomicalObjectType>(reader.LocalName, true, out type))
            {
                string             name = null;
                AstronomicalObject star = null;
                while (reader.MoveToNextAttribute())
                {
                    switch (reader.LocalName)
                    {
                    case "name":
                        name = reader.Value;
                        break;

                    case "star":
                        star = container.FindObjectByName(reader.Value, AstronomicalObjectType.Star);
                        if (star == null)
                        {
                            throw new EnvironmentLoadException(String.Format("The star {0} could not be found", reader.Value), reader);
                        }
                        break;
                    }
                }

                if (name == null)
                {
                    throw new EnvironmentLoadException("Missing name for astronomical object entry", reader);
                }


                AstronomicalObject result = new AstronomicalObject(name, container, type, star);

                // Read child elements
                int curDepth = reader.Depth;
                while (reader.Read() && reader.Depth >= curDepth)
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        switch (reader.LocalName)
                        {
                        case "notes":
                            result.UserNotes = reader.ReadElementContentAsString();
                            break;
                        }
                    }
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #12
0
        // UNKNOWN
        // Star
        // Planet / Moon / Belt
        // Unidentified signals
        // Station

        internal AstronomicalObject(string name, EliteEnvironment environment, AstronomicalObjectType type, AstronomicalObject star)
        {
            Name        = name;
            Environment = environment;

            ObjectsInternal        = new ObservableCollection <AstronomicalObject>();
            Objects                = new ReadOnlyObservableCollection <AstronomicalObject>(ObjectsInternal);
            KnownObjectProximities = new StarProximityCollection();
            _trades                = new ObservableCollection <Trade>();
            Trades          = new ReadOnlyObservableCollection <Trade>(_trades);
            _commodityIndex = new Dictionary <Commodity, int>();

            if (environment.AutoDistanceEnabled)
            {
                float distance = 0;
                foreach (AstronomicalObject otherObject in environment.Objects)
                {
                    if (DistancesDB.TryGetDistance(this, otherObject, out distance))
                    {
                        RegisterDistanceFrom(otherObject, distance);
                    }
                }
            }


            Type = type;
            Star = star ?? this;

            Environment.ObjectsInternal.Add(this);
        }