public ActionResult BuyGoods(int goodId, int quantity, int price) { SystemGood systemGood = this.ControllerGame.CurrentPlayer.Ship.CosmoSystem.GetGood(goodId); if (systemGood != null) { try { systemGood.Buy(this.ControllerGame.CurrentPlayer.Ship, quantity, price); return(RedirectToAction("ListGoods")); } catch (ArgumentOutOfRangeException ex) { // Log this exception ExceptionPolicy.HandleException(ex, "Controller Policy"); if (ex.ParamName == "price") { // Price has changed on the good // Confirm the player still wants to buy the good ViewData["goodId"] = goodId; ViewData["quantity"] = quantity; ViewData["oldPrice"] = price; ViewData["newPrice"] = systemGood.Price; ViewData["goodName"] = systemGood.Good.Name; return(View("BuyGoodsPriceChange")); } else { ModelState.AddModelError("quantity", ex.Message, quantity); } } catch (ArgumentException ex) { // Log this exception ExceptionPolicy.HandleException(ex, "Controller Policy"); ModelState.AddModelError("quantity", ex.Message, quantity); } } else { ModelState.AddModelError("goodId", "Good is not sold in the system", goodId); } return(View()); }
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"); }
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> /// 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(); }