Beispiel #1
0
        private void TravelRandom(object playerIndex)
        {
            Player      testPlayer     = this.CreateTestPlayer();
            Ship        testShip       = testPlayer.Ship;
            CosmoSystem startingSystem = testShip.CosmoSystem;

            for (int i = 0; i < this.shipTravelLoopCount; i++)
            {
                CosmoSystem[] possibleTargetSystems = testShip.GetInRangeSystems();
                Assert.AreNotEqual(0, possibleTargetSystems.Length, "Ship should always be within range of at least one system");

                CosmoSystem targetSystem = possibleTargetSystems[this.rnd.Next(possibleTargetSystems.Length)];

                DateTime startTime    = DateTime.Now;
                int      timeToTravel = testShip.Travel(targetSystem);
                DateTime endTime      = DateTime.Now;
                DateTime travelTime   = startTime.AddSeconds(timeToTravel);

                while (testShip.CheckIfTraveling())
                {
                    endTime = DateTime.Now;
                    Thread.Sleep(0);
                }

                // Calcuate the difference between predicted travel time and actual travel time
                TimeSpan travelTimeDiff = endTime - travelTime;
                Assert.AreEqual(0.0, travelTimeDiff.TotalSeconds, 2.0, "Ship have should taken " + timeToTravel + " seconds to travel, +/-2.0 seconds.");

                Assert.AreEqual(targetSystem, testShip.CosmoSystem, "Ship should now be in the target system");
            }
        }
Beispiel #2
0
        /// <summary>
        /// Create the ship for the NPC
        /// </summary>
        public override void Setup()
        {
            base.Setup();

            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();

            // Select a random race
            Race npcRace = this.rnd.SelectOne(db.Races);

            // Assign the race
            this.npcRow.Race = npcRace;

            // We only start in systems with the same race
            IQueryable <CosmoSystem> possibleStartingSystems = (from s in db.CosmoSystems
                                                                where s.Race == npcRace
                                                                select s);
            CosmoSystem startingSystem = this.rnd.SelectOne(possibleStartingSystems);

            // Randomly select a base ship model
            BaseShip startingShipModel = this.rnd.SelectOne(db.BaseShips);

            // Create the NPC ship
            Ship npcShip = startingSystem.CreateShip(startingShipModel.Name);

            this.npcRow.Ship = npcShip;

            // Randomly assign upgrades
            npcShip.JumpDrive = this.rnd.SelectOne(db.JumpDrives);
            npcShip.Shield    = this.rnd.SelectOne(db.Shields);
            npcShip.Weapon    = this.rnd.SelectOne(db.Weapons);

            // Set the next travel time to now
            this.npcRow.NextTravelTime = DateTime.UtcNow;
        }
Beispiel #3
0
        /// <summary>
        /// Handles the police traveling to a new system
        /// </summary>
        public void DoTravel()
        {
            Ship npcShip = this.npcRow.Ship;

            // We travel to any system of the same race in range
            CosmoSystem[] inRangeSystems = npcShip.GetInRangeSystems();

            // Filter to only include systems of the same race
            IEnumerable <CosmoSystem> targetSystems = (from s in inRangeSystems
                                                       where s.Race == this.npcRow.Race
                                                       select s).AsEnumerable();
            CosmoSystem targetSystem = this.rnd.SelectOne(targetSystems);

            // Start traveling
            int travelTime = npcShip.Travel(targetSystem);

            Dictionary <string, object> props = new Dictionary <string, object>
            {
                { "NpcId", this.npcRow.NpcId },
                { "TargetSystemId", targetSystem.SystemId },
                { "TravelTime", travelTime },
            };

            Logger.Write("Traveling to new System", "NPC", 150, 0, TraceEventType.Verbose, "Police Travel", props);
        }
Beispiel #4
0
        public void GetNearestBankSystem()
        {
            Player testPlayer = this.CreateTestPlayer();

            CosmoSystem bankSystem   = testPlayer.Ship.GetNearestBankSystem();
            double      bankDistance = testPlayer.Ship.GetSystemDistance(bankSystem);

            Debug.WriteLine(string.Format("Bank is {0} sectors away", bankDistance));

            Assert.That(bankSystem.HasBank, Is.True, "System should have a bank");
        }
Beispiel #5
0
        public void Travel()
        {
            // Arrange
            Mock <CosmoSystem> currentSystemMock = new Mock <CosmoSystem>();

            Mock <CosmoSystem> inRangeSystemMock = new Mock <CosmoSystem>();

            CosmoSystem[] inRangeSystems = new CosmoSystem[] { inRangeSystemMock.Object };

            Mock <CosmoSystem> outOfRangeSystemMock = new Mock <CosmoSystem>();

            CosmoSystem[] allSystems = new CosmoSystem[] { currentSystemMock.Object, inRangeSystemMock.Object, outOfRangeSystemMock.Object };

            Mock <User>        userMock    = new Mock <User>();
            Mock <GameManager> managerMock = new Mock <GameManager>(userMock.Object);

            managerMock.Expect(m => m.CurrentPlayer.Ship.CheckIfTraveling())
            .Returns(false)
            .Verifiable();
            managerMock.Expect(m => m.GetGalaxySize())
            .Returns(30)
            .Verifiable();
            managerMock.Expect(m => m.CurrentPlayer.Ship.JumpDrive.Range)
            .Returns(12)
            .Verifiable();
            managerMock.Expect(m => m.CurrentPlayer.Ship.CosmoSystem)
            .Returns(currentSystemMock.Object)
            .Verifiable();
            managerMock.Expect(m => m.CurrentPlayer.Ship.GetInRangeSystems())
            .Returns(inRangeSystems)
            .Verifiable();
            managerMock.Expect(m => m.GetSystems())
            .Returns(allSystems)
            .Verifiable();
            TravelController controller = new TravelController(managerMock.Object);

            // Act
            ActionResult result = controller.Travel();

            // Assert
            Assert.That(result, Is.TypeOf(typeof(ViewResult)), "Should return a view");
            Assert.That(((ViewResult)result).ViewName, Is.SubsetOf(new string[] { "", "Travel" }), "Should return the Travel View");
            Assert.That(controller.ModelState.IsValid, "No error should be returned");
            Assert.That(controller.ViewData["IsTraveling"], Is.False, "The IsTraveling field should be false");
            Assert.That(controller.ViewData["GalaxySize"], Is.EqualTo(30), "The GalaxySize field should be 30");
            Assert.That(controller.ViewData["Range"], Is.EqualTo(12), "The Range field should be 12");
            Assert.That(controller.ViewData["CurrentSystem"], Is.SameAs(currentSystemMock.Object), "The CurrentSystem field should have a reference to the current system object");
            Assert.That(controller.ViewData["InRangeSystems"], Is.EquivalentTo(inRangeSystems), "The InRangeSystems field should have an array containing all the in range systems");
            Assert.That(controller.ViewData["Systems"], Is.EquivalentTo(allSystems), "The Systems field should have an array containing all the systems in the galaxy");

            managerMock.Verify();
        }
Beispiel #6
0
        public void GetLeavingShips()
        {
            Player testPlayer = this.CreateTestPlayer();

            CosmoSystem firstInRangeSystem = testPlayer.Ship.GetInRangeSystems()[0];

            testPlayer.Ship.Travel(firstInRangeSystem);

            // See if the traveling ship shows in the leaving list
            IEnumerable <Ship> leavingShips = testPlayer.Ship.CosmoSystem.GetLeavingShips();

            Assert.That(leavingShips, Has.Member(testPlayer.Ship), "Test Ship should be in the leaving list");
        }
Beispiel #7
0
        public void GetSystems()
        {
            Player      testPlayer = this.CreateTestPlayer();
            GameManager manager    = new GameManager(testPlayer.User.UserName);

            CosmoSystem [] systems = manager.GetSystems();
            Assert.That(systems.Length, Is.GreaterThanOrEqualTo(1), "At least one system should be in the galaxy");

            CosmoSystem solSystem = (from s in systems
                                     where s.Name == "Sol"
                                     select s).SingleOrDefault();

            Assert.That(solSystem, Is.Not.Null, "Sol system should exist in the galaxy");
        }
Beispiel #8
0
        /// <summary>
        /// Used when a Trader travels to another system
        /// </summary>
        /// <param name="targetSystem">The target system.</param>
        private void DoTravel(CosmoSystem targetSystem)
        {
            Ship npcShip = this.npcRow.Ship;

            // Start traveling
            int travelTime = npcShip.Travel(targetSystem);

            Dictionary <string, object> props = new Dictionary <string, object>
            {
                { "NpcId", this.npcRow.NpcId },
                { "TargetSystemId", targetSystem.SystemId },
                { "TravelTime", travelTime },
            };

            Logger.Write("Traveling to new System", "NPC", 150, 0, TraceEventType.Verbose, "Trader Travel", props);
        }
Beispiel #9
0
        public void SellNotSold()
        {
            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();

            // Setup player
            Player      testPlayer     = this.CreateTestPlayer();
            Ship        testShip       = testPlayer.Ship;
            CosmoSystem startingSystem = testShip.CosmoSystem;
            GameManager manager        = new GameManager(testPlayer.User.UserName);

            // Store the player starting cash
            int playerStartingCash = testPlayer.Ship.Credits;

            // Add some water to this ship for us to sell
            Good water = (from g in db.Goods
                          where g.Name == "Water"
                          select g).SingleOrDefault();

            Assert.That(water, Is.Not.Null, "We should have a Water good");
            ShipGood shipGood = new ShipGood();

            shipGood.Good     = water;
            shipGood.Quantity = 10;
            shipGood.Ship     = testShip;
            testShip.ShipGoods.Add(shipGood);

            // Verify that the good is for sell in the current system
            SystemGood systemWater = startingSystem.GetGood(water.GoodId);

            if (systemWater != null)
            {
                // Remove the good from the system
                db.SystemGoods.DeleteOnSubmit(systemWater);
                db.SubmitChanges();
            }
            try
            {
                shipGood.Sell(testShip, 10, systemWater.Price);
            }
            catch (InvalidOperationException ex)
            {
                // Correct
                Assert.That(ex, Is.Not.Null, "InvalidOperationException should be valid");
                return;
            }
            Assert.Fail("Player should not been able to sell in the system when the good was not sold in the system");
        }
Beispiel #10
0
        public ActionResult Travel(int targetSystem)
        {
            CosmoSystem targetSystemModel = this.ControllerGame.GetSystem(targetSystem);

            if (targetSystemModel != null)
            {
                // Check if the player is still traveling
                ViewData["IsTraveling"] = this.ControllerGame.CurrentPlayer.Ship.CheckIfTraveling();

                try
                {
                    int travelTime = this.ControllerGame.CurrentPlayer.Ship.Travel(targetSystemModel);

                    ViewData["TravelTime"] = travelTime;
                    return(View("TravelInProgress"));
                }
                catch (InvalidOperationException ex)
                {
                    // Log this exception
                    ExceptionPolicy.HandleException(ex, "Controller Policy");

                    ModelState.AddModelError("_FORM", ex.Message);
                }
                catch (ArgumentOutOfRangeException ex)
                {
                    // Log this exception
                    ExceptionPolicy.HandleException(ex, "Controller Policy");

                    ModelState.AddModelError("_FORM", ex.Message);
                }
                catch (ArgumentException ex)
                {
                    // Log this exception
                    ExceptionPolicy.HandleException(ex, "Controller Policy");

                    ModelState.AddModelError("_FORM", ex.Message);
                }
            }
            else
            {
                ModelState.AddModelError("targetSystem", "The target system is invalid", targetSystem);
            }

            // If we got down here, then an error was thrown
            return(this.Travel());
        }
Beispiel #11
0
        public void BankWithdrawNoBank()
        {
            // Arrange
            Player testPlayer = this.CreateTestPlayer();

            // Move the player to a system without a bank
            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();
            CosmoSystem noBankSystem    = (from s in db.CosmoSystems
                                           where !s.HasBank
                                           select s).FirstOrDefault();

            Assert.That(noBankSystem, Is.Not.Null, "There should be at least one system in the galaxy without a bank");
            testPlayer.Ship.CosmoSystem = noBankSystem;

            // Act, should throw an exception
            testPlayer.BankWithdraw(1000);
        }
Beispiel #12
0
        public void BuyNotEnoughCash()
        {
            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();

            // Setup player
            Player      testPlayer     = this.CreateTestPlayer();
            Ship        testShip       = testPlayer.Ship;
            CosmoSystem startingSystem = testShip.CosmoSystem;
            GameManager manager        = new GameManager(testPlayer.User.UserName);

            // Reduce the player starting cash
            testPlayer.Ship.Credits = 10;

            // Check that the ship is empty
            Assert.That(testShip.ShipGoods.Count, Is.EqualTo(0), "Ship should start out with no goods on-board");

            // Add some water to the starting system for this ship to buy
            Good water = (from g in db.Goods
                          where g.Name == "Water"
                          select g).SingleOrDefault();

            Assert.That(water, Is.Not.Null, "We should have a Water good");
            startingSystem.AddGood(water.GoodId, 20);

            // Verify that the good was added to the system
            SystemGood systemWater = startingSystem.GetGood(water.GoodId);

            Assert.That(systemWater, Is.Not.Null, "System should now have a water SystemGood");
            Assert.That(systemWater.Quantity, Is.GreaterThanOrEqualTo(20), "System should now have at least 20 water goods");

            int playerCost          = (int)(systemWater.PriceMultiplier * water.BasePrice) * systemWater.Quantity;
            int systemStartingCount = systemWater.Quantity;

            try
            {
                systemWater.Buy(testShip, 20, systemWater.Price);
            }
            catch (ArgumentException ex)
            {
                Assert.That(ex.ParamName, Is.EqualTo("quantity"), "Quantity to buy should be the invalid argument");
                return;
            }

            Assert.Fail("Player should not been able to buy more goods than they can afford");
        }
Beispiel #13
0
        public void SellNotEnoughGoods()
        {
            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();

            // Setup player
            Player      testPlayer     = this.CreateTestPlayer();
            Ship        testShip       = testPlayer.Ship;
            CosmoSystem startingSystem = testShip.CosmoSystem;
            GameManager manager        = new GameManager(testPlayer.User.UserName);

            // Add some water to this ship for us to sell
            Good water = (from g in db.Goods
                          where g.Name == "Water"
                          select g).SingleOrDefault();

            Assert.That(water, Is.Not.Null, "We should have a Water good");
            ShipGood shipGood = new ShipGood();

            shipGood.Good     = water;
            shipGood.Quantity = 10;
            shipGood.Ship     = testShip;
            testShip.ShipGoods.Add(shipGood);
            db.SubmitChanges();

            // Verify that the good is for sell in the current system
            SystemGood systemWater = startingSystem.GetGood(water.GoodId);

            if (systemWater == null)
            {
                startingSystem.AddGood(water.GoodId, 0);
                systemWater = startingSystem.GetGood(water.GoodId);
            }

            try
            {
                shipGood.Sell(testShip, 20, systemWater.Price);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                Assert.That(ex.ParamName, Is.EqualTo("quantity"), "Quantity to sell should be the invalid argument");
                return;
            }

            Assert.Fail("Player should not been able to sell more goods than aboard");
        }
Beispiel #14
0
        public void Sell()
        {
            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();

            // Setup player
            Player      testPlayer     = this.CreateTestPlayer();
            Ship        testShip       = testPlayer.Ship;
            CosmoSystem startingSystem = testShip.CosmoSystem;
            GameManager manager        = new GameManager(testPlayer.User.UserName);

            // Store the player starting cash
            int playerStartingCash = testPlayer.Ship.Credits;

            // Add some water to this ship for us to sell
            Good water = (from g in db.Goods
                          where g.Name == "Water"
                          select g).SingleOrDefault();

            Assert.That(water, Is.Not.Null, "We should have a Water good");
            ShipGood shipGood = new ShipGood();

            shipGood.Good     = water;
            shipGood.Quantity = 10;
            shipGood.Ship     = testShip;
            testShip.ShipGoods.Add(shipGood);

            // Verify that the good is for sell in the current system
            SystemGood systemWater = startingSystem.GetGood(water.GoodId);

            if (systemWater == null)
            {
                startingSystem.AddGood(water.GoodId, 0);
                systemWater = startingSystem.GetGood(water.GoodId);
            }
            int playerProfit        = systemWater.Price * 10;
            int systemStartingCount = systemWater.Quantity;

            shipGood.Sell(testShip, 10, systemWater.Price);

            Assert.That(systemWater.Quantity, Is.EqualTo(systemStartingCount + 10), "System should now have 10 more water goods");
            Assert.That(testPlayer.Ship.Credits, Is.EqualTo(playerStartingCash + playerProfit), "Player should have more cash credits now after selling");
        }
Beispiel #15
0
        /// <summary>
        /// Handles the pirate traveling to a new system
        /// </summary>
        private void DoTravel()
        {
            Ship npcShip = this.npcRow.Ship;

            // We travel to any system in range
            CosmoSystem[] inRangeSystems = npcShip.GetInRangeSystems();
            CosmoSystem   targetSystem   = this.rnd.SelectOne(inRangeSystems);

            // Start traveling
            int travelTime = npcShip.Travel(targetSystem);

            Dictionary <string, object> props = new Dictionary <string, object>
            {
                { "NpcId", this.npcRow.NpcId },
                { "TargetSystemId", targetSystem.SystemId },
                { "TravelTime", travelTime },
            };

            Logger.Write("Traveling to new System", "NPC", 150, 0, TraceEventType.Verbose, "Pirate Travel", props);
        }
Beispiel #16
0
        public void AddGood()
        {
            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();
            CosmoSystem firstSystem     = (from s in db.CosmoSystems select s).FirstOrDefault();

            Assert.That(firstSystem, Is.Not.Null, "We need at least one system in the galaxy");

            // Add some water to the the system
            Good water = (from g in db.Goods
                          where g.Name == "Water"
                          select g).SingleOrDefault();

            Assert.That(water, Is.Not.Null, "We should have a Water good");
            firstSystem.AddGood(water.GoodId, 100);

            // Verify that the good was added to the system
            SystemGood systemWater = firstSystem.GetGood(water.GoodId);

            Assert.That(systemWater, Is.Not.Null, "System should now have a water SystemGood");
            Assert.That(systemWater.Quantity, Is.GreaterThanOrEqualTo(100), "System should now have at least 100 water goods");
        }
Beispiel #17
0
        public void BuyNotEnoughGoods()
        {
            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();

            // Setup player
            Player      testPlayer     = this.CreateTestPlayer();
            Ship        testShip       = testPlayer.Ship;
            CosmoSystem startingSystem = testShip.CosmoSystem;
            GameManager manager        = new GameManager(testPlayer.User.UserName);

            // Check that the ship is empty
            Assert.That(testShip.ShipGoods.Count, Is.EqualTo(0), "Ship should start out with no goods on-board");

            // Add some water to the starting system for this ship to buy
            Good water = (from g in db.Goods
                          where g.Name == "Water"
                          select g).SingleOrDefault();

            Assert.That(water, Is.Not.Null, "We should have a Water good");
            startingSystem.AddGood(water.GoodId, 5);

            // Verify that the good was added to the system
            SystemGood systemWater = startingSystem.GetGood(water.GoodId);

            // Make sure only 5 are at the system
            systemWater.Quantity = 5;

            try
            {
                systemWater.Buy(testShip, 20, systemWater.Price);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                Assert.That(ex.ParamName, Is.EqualTo("quantity"), "Quantity to buy should be the invalid argument");
                return;
            }

            Assert.Fail("Player should not been able to buy more goods than at the system");
        }
Beispiel #18
0
        public void Buy()
        {
            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();

            // Setup player
            Player      testPlayer     = this.CreateTestPlayer();
            Ship        testShip       = testPlayer.Ship;
            CosmoSystem startingSystem = testShip.CosmoSystem;
            GameManager manager        = new GameManager(testPlayer.User.UserName);

            // Store the player starting cash
            int playerStartingCash = testPlayer.Ship.Credits;

            // Check that the ship is empty
            Assert.That(testShip.ShipGoods.Count, Is.EqualTo(0), "Ship should start out with no goods on-board");

            // Add some water to the starting system for this ship to buy
            Good water = (from g in db.Goods
                          where g.Name == "Water"
                          select g).SingleOrDefault();

            Assert.That(water, Is.Not.Null, "We should have a Water good");
            startingSystem.AddGood(water.GoodId, 20);

            // Verify that the good was added to the system
            SystemGood systemWater = startingSystem.GetGood(water.GoodId);

            Assert.That(systemWater, Is.Not.Null, "System should now have a water SystemGood");
            Assert.That(systemWater.Quantity, Is.GreaterThanOrEqualTo(20), "System should now have at least 20 water goods");

            int playerCost          = systemWater.Price * 20;
            int systemStartingCount = systemWater.Quantity;

            systemWater.Buy(testShip, 20, systemWater.Price);

            Assert.That(systemWater.Quantity, Is.EqualTo(systemStartingCount - 20), "System should now have 20 few water goods");
            Assert.That(testPlayer.Ship.Credits, Is.EqualTo(playerStartingCash - playerCost), "Player should have less cash credits now after buying");
        }
Beispiel #19
0
        /// <summary>
        /// This action gets a graph of system good prices
        /// </summary>
        /// <param name="systemId">The system id.</param>
        /// <returns>The GraphGoodPrice view on success, a redirect to the Index action on error.</returns>
        public ActionResult GraphGoodPrice(int systemId)
        {
            CosmoSystem system = this.ControllerGame.GetSystem(systemId);

            if (system != null)
            {
                SystemGood[] goods = system.GetGoods();

                ViewData["systemId"] = new SelectList(this.ControllerGame.GetSystems(), "SystemId", "Name", systemId);
                ViewData["Goods"]    = goods;

                // Get the price history for each system good
                ViewData["PriceHistory"] = goods.Select(g => g.GetPriceHistory());

                return(View());
            }
            else
            {
                ModelState.AddModelError("systemId", "Invalid System", systemId);
            }

            // Show the default action
            return(RedirectToAction("Index"));
        }
Beispiel #20
0
        /// <summary>
        /// Does the action.
        /// </summary>
        public override void DoAction()
        {
            if (!this.SetNextActionDelay(NpcTrader.DelayBeforeNextAction))
            {
                return;
            }

            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();
            Ship npcShip = this.npcRow.Ship;

            // Check if we are still traveling
            npcShip.CheckIfTraveling();

            // Check if we are currently in combat
            if (npcShip.InProgressCombat != null)
            {
                // In Combat!
                this.DoCombat();
            }
            else if (this.npcRow.NextTravelTime < DateTime.UtcNow)
            {
                // Create an array of goods that the Trader has onboard
                ShipGood[] goods = npcShip.GetGoods().Where(g => g.Quantity > 0).ToArray();

                // goodCount != 0, sell all the trader's goods
                foreach (ShipGood good in goods)
                {
                    // Get the number of this good type onboard the Trader's ship
                    int shipGoodQuantity = good.Quantity;

                    // Find the price of the good
                    int shipGoodPrice = 0;

                    try
                    {
                        good.Sell(npcShip, shipGoodQuantity, shipGoodPrice);
                    }
                    catch (InvalidOperationException ex)
                    {
                        // Log this exception
                        ExceptionPolicy.HandleException(ex, "NPC Policy");
                    }
                }

                // This is the minimum amount of money a trader should have before buying goods
                int baseCreditsSizeAdjusted = BaseCreditMultiplier * npcShip.CargoSpaceTotal;

                // Check if we need to give this trader some credits
                if (npcShip.Credits < baseCreditsSizeAdjusted)
                {
                    // Poor trader has no credits, give him some to start
                    npcShip.Credits = baseCreditsSizeAdjusted;
                }

                // Trader buys first good
                SystemGood good1 = (from g in npcShip.CosmoSystem.SystemGoods
                                    orderby(g.PriceMultiplier) ascending
                                    select g).FirstOrDefault();

                // This is the maximum number a Trader can purchase
                double numberCanBuy = Math.Floor((double)npcShip.Credits / good1.Price);

                // This is the maximum number we want the Trader to purchase
                double numberToBuy = Math.Ceiling((double)npcShip.CargoSpaceFree / 2);

                // Make sure that the Trader buys as many of good1 as credits allow
                int numberBuying = (int)Math.Min(numberCanBuy, numberToBuy);

                // Insures that Traders attempt to buy the proper number of good1
                int properNumber = (int)Math.Min(numberBuying, good1.Quantity);

                try
                {
                    good1.Buy(npcShip, properNumber, good1.Price);
                }
                catch (InvalidOperationException ex)
                {
                    // Log this exception
                    ExceptionPolicy.HandleException(ex, "NPC Policy");
                }

                // Find all the systems within range
                CosmoSystem[] inRangeSystems = npcShip.GetInRangeSystems();

                // Finds the system with the highest PriceMultiplier
                CosmoSystem targetSystem = (from g in db.SystemGoods
                                            where inRangeSystems.Contains(g.CosmoSystem) &&
                                            g.Good == good1.Good
                                            orderby(g.PriceMultiplier) descending
                                            select g.CosmoSystem).FirstOrDefault();

                // Get references to the Good entities for all the SystemGoods sold in the target system
                IEnumerable <Good> goodsInTargetSystem = targetSystem.SystemGoods.Select(g => g.Good);

                // Get references to the Good entites for the all the SystemGoods sold in the current system
                IEnumerable <Good> goodsInCurrentSystem = npcShip.CosmoSystem.SystemGoods.Select(g => g.Good);

                // Do an intersetion of both, getting a list of goods sold in both systems
                IEnumerable <Good> goodsInBoth = goodsInTargetSystem.Intersect(goodsInCurrentSystem);

                // Look in the current system for goods sold in both, sorting by PriceMultiplier (lowest at top)
                // and taking the top good in the results
                SystemGood good2 = (from g in npcShip.CosmoSystem.SystemGoods
                                    where goodsInBoth.Contains(g.Good) &&
                                    g != good1
                                    orderby g.PriceMultiplier ascending
                                    select g).FirstOrDefault();

                // This is the maximum number a Trader can purchase
                numberCanBuy = Math.Floor((double)npcShip.Credits / good2.Price);

                // This is the maximum number we want the Trader to purchase
                numberToBuy = Math.Ceiling((double)npcShip.CargoSpaceFree);

                // Make sure that the Trader buys as many of good1 as credits allow
                numberBuying = (int)Math.Min(numberCanBuy, numberToBuy);

                // Insures that Traders attempt to buy the proper number of good1
                properNumber = (int)Math.Min(numberBuying, good2.Quantity);

                try
                {
                    good2.Buy(npcShip, properNumber, good2.Price);
                }
                catch (InvalidOperationException ex)
                {
                    // Log this exception
                    ExceptionPolicy.HandleException(ex, "NPC Policy");
                }

                this.DoTravel(targetSystem);

                // Set next travel time
                this.npcRow.NextTravelTime = DateTime.UtcNow.AddSeconds(this.rnd.Next(60, 120));
            }
            else
            {
                Dictionary <string, object> props = new Dictionary <string, object>
                {
                    { "NpcId", this.npcRow.NpcId },
                    { "NextTravelTime", this.npcRow.NextTravelTime },
                    { "UtcNow", DateTime.UtcNow }
                };
                Logger.Write("Waiting for NextTravelTime", "NPC", 200, 0, TraceEventType.Verbose, "Trader Wait", props);
            }

            db.SaveChanges();
        }