Exemple #1
0
        public ActionResult SellGoods(int goodId, int quantity, int price)
        {
            ShipGood shipGood = this.ControllerGame.CurrentPlayer.Ship.GetGood(goodId);

            if (shipGood != null)
            {
                try
                {
                    shipGood.Sell(this.ControllerGame.CurrentPlayer.Ship, quantity, price);
                    return(RedirectToAction("ListGoods"));
                }
                catch (ArgumentOutOfRangeException ex)
                {
                    // Log this exception
                    ExceptionPolicy.HandleException(ex, "Controller Policy");

                    if (ex.ParamName == "price")
                    {
                        // Go to the SellGoodsPriceChange view
                        // Price has changed on the good
                        // Confirm the player still wants to sell the good
                        ViewData["goodId"]   = goodId;
                        ViewData["quantity"] = quantity;
                        ViewData["oldPrice"] = price;
                        ViewData["goodName"] = shipGood.Good.Name;

                        // Try to get the current price
                        SystemGood systemGood = this.ControllerGame.CurrentPlayer.Ship.CosmoSystem.GetGood(goodId);
                        if (systemGood != null)
                        {
                            ViewData["newPrice"] = systemGood.Price;
                        }

                        return(View("SellGoodsPriceChange"));
                    }
                    else
                    {
                        ModelState.AddModelError("quantity", ex.Message, quantity);
                    }
                }
                catch (InvalidOperationException ex)
                {
                    // Log this exception
                    ExceptionPolicy.HandleException(ex, "Controller Policy");

                    ModelState.AddModelError("goodId", ex.Message, quantity);
                }
            }
            else
            {
                ModelState.AddModelError("goodId", "Good is not bought in the system", goodId);
            }

            return(View());
        }
Exemple #2
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");
        }
        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");
        }
Exemple #4
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");
        }
Exemple #5
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");
        }
Exemple #6
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");
        }
        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");
        }
        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");
        }
        /// <summary>
        /// Updates the system good count, causing systems to produce goods as needed.
        /// </summary>
        private void UpdateSystemGoodCount()
        {
            CosmoMongerDbDataContext    db = CosmoManager.GetDbContext();
            Dictionary <string, object> props;

            foreach (Good good in db.Goods)
            {
                // Get the total number of this good type available in all systems
                int    totalSystemGoodCount = good.SystemGoods.Sum(x => x.Quantity);
                double targetBreak          = (((double)good.TargetCount) / 10.0);

                // Check if we need to add some of this good to the galaxy
                while (totalSystemGoodCount < good.TargetCount)
                {
                    // Randomly select a system with  equal to or fewer than targetBreak number of goods to produce.
                    var goodProducingSystems = (from g in good.SystemGoods
                                                where g.ProductionFactor > 0 && g.Quantity <= targetBreak
                                                select g);
                    if (goodProducingSystems.Count() == 0)
                    {
                        // No systems produce this good?
                        // Continue on to the next good type
                        break;
                    }

                    SystemGood selectedProducingSystemGood = goodProducingSystems.ElementAt(rnd.Next(goodProducingSystems.Count()));

                    // Produce the good, using the count needed and the production factor
                    double adjustedProductionFactor = (rnd.NextDouble() + selectedProducingSystemGood.ProductionFactor) / 2;
                    int    lackingGoodCount         = (int)(rnd.Next(10) * adjustedProductionFactor);
                    selectedProducingSystemGood.Quantity += lackingGoodCount;

                    props = new Dictionary <string, object>
                    {
                        { "SystemId", selectedProducingSystemGood.SystemId },
                        { "GoodId", selectedProducingSystemGood.GoodId },
                        { "Quantity", selectedProducingSystemGood.Quantity },
                        { "AddedQuantity", lackingGoodCount }
                    };
                    Logger.Write("Producing Goods", "NPC", 400, 0, TraceEventType.Verbose, "Producing Goods", props);

                    // Update the total good count
                    totalSystemGoodCount += lackingGoodCount;

                    try
                    {
                        // Send changes to database
                        db.SubmitChanges(ConflictMode.ContinueOnConflict);
                    }
                    catch (ChangeConflictException ex)
                    {
                        ExceptionPolicy.HandleException(ex, "SQL Policy");

                        // Another thread has made changes to this SystemGood row,
                        // which could be from someone buying or selling the good at a system
                        // Best case to resolve this would be to simply start over in the good production,
                        // because the good quantity has been changed by another method.
                        foreach (ObjectChangeConflict occ in db.ChangeConflicts)
                        {
                            // Refresh values from database
                            occ.Resolve(RefreshMode.OverwriteCurrentValues);
                        }

                        continue;
                    }
                }

                // Now consume some of this good in the galaxy
                // Randomly select a good at a system to consume where the quantity is equal to or higher
                // than targetBreak number of goods
                var goodConsumingSystems = (from g in good.SystemGoods
                                            where g.ConsumptionFactor > 0 && g.Quantity >= targetBreak &&
                                            g.Quantity > 0
                                            select g);
                if (goodConsumingSystems.Count() == 0)
                {
                    // No systems consume this good?
                    // Continue on to the next good type
                    continue;
                }

                SystemGood selectedConsumingSystemGood = goodConsumingSystems.ElementAt(rnd.Next(goodConsumingSystems.Count()));

                // Consuming the good, using the count needed and the consumption factor
                double adjustedConsumptionFactor = (rnd.NextDouble() + selectedConsumingSystemGood.ConsumptionFactor) / 2;
                int    usageGoodCount            = (int)(rnd.Next(10) * adjustedConsumptionFactor);
                usageGoodCount = Math.Min(usageGoodCount, selectedConsumingSystemGood.Quantity);
                selectedConsumingSystemGood.Quantity -= usageGoodCount;

                props = new Dictionary <string, object>
                {
                    { "SystemId", selectedConsumingSystemGood.SystemId },
                    { "GoodId", selectedConsumingSystemGood.GoodId },
                    { "Quantity", selectedConsumingSystemGood.Quantity },
                    { "RemovedQuantity", usageGoodCount }
                };
                Logger.Write("Consuming Goods", "NPC", 400, 0, TraceEventType.Verbose, "Consuming Goods", props);

                try
                {
                    // Send changes to database
                    db.SubmitChanges(ConflictMode.ContinueOnConflict);
                }
                catch (ChangeConflictException ex)
                {
                    ExceptionPolicy.HandleException(ex, "SQL Policy");

                    // Another thread has made changes to this SystemGood row,
                    // which could be from someone buying or selling the good at a system
                    // Best case to resolve this would be to simply ignore the good consumption,
                    // we like to produce more than we consume
                    foreach (ObjectChangeConflict occ in db.ChangeConflicts)
                    {
                        // Refresh values from database
                        occ.Resolve(RefreshMode.OverwriteCurrentValues);
                    }
                }
            }
        }
Exemple #10
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();
        }