/// <summary> /// Creates the starting ship. /// Note, changes are not submitted to database /// </summary> /// <param name="startingSystem">The starting system.</param> public void CreateStartingShip(CosmoSystem startingSystem) { CosmoMongerDbDataContext db = CosmoManager.GetDbContext(); if (this.Ship != null) { throw new InvalidOperationException("Player already has a ship"); } // Create new player ship this.Ship = startingSystem.CreateShip(Player.StartingShip); }
/// <summary> /// This creates a player in the database and returns a reference to the new player. /// If the player already exists an ArgumentException will be thrown, referencing the name argument. /// </summary> /// <param name="name">The player name.</param> /// <param name="race">The race of the new Player.</param> /// <returns>The newly created Player</returns> public virtual Player CreatePlayer(string name, Race race) { CosmoMongerDbDataContext db = CosmoManager.GetDbContext(); bool otherPlayerName = (from p in db.Players where p.Name == name && p.User != this select p).Any(); if (otherPlayerName) { throw new ArgumentException("Player by another user with the same name already exists", "name"); } Dictionary <string, object> props = new Dictionary <string, object> { { "Name", name }, { "Race", race.Name } }; Logger.Write("Creating player in User.CreatePlayer", "Model", 700, 0, TraceEventType.Information, "Creating Player", props); Player player = new Player(); player.User = this; player.Name = name; player.Race = race; player.Alive = true; player.LastPlayed = DateTime.UtcNow; // Assign the default starting location based on the race CosmoSystem startingSystem = race.HomeSystem; if (startingSystem == null) { Logger.Write("Unable to load player starting system from database", "Model", 1000, 0, TraceEventType.Critical); return(null); } // Create a new ship for this player player.CreateStartingShip(startingSystem); // Starting credits is 2000 player.Ship.Credits = 2000; player.UpdateNetWorth(); db.Players.InsertOnSubmit(player); db.SaveChanges(); return(player); }
/// <summary> /// Starts the ship traveling to the target system. /// </summary> /// <param name="targetSystem">The target system to travel to.</param> /// <returns>The number of seconds before the ship arrives at the target system</returns> /// <exception cref="ArgumentException">Thrown if the ship is already in the target system</exception> /// <exception cref="ArgumentOutOfRangeException">Thrown if the target system is out of range of the ship</exception> /// <exception cref="InvalidOperationException">Thrown if the ship is already traveling</exception> public virtual int Travel(CosmoSystem targetSystem) { // Check if ship is in the target system if (this.CosmoSystem == targetSystem) { throw new ArgumentException("Ship is already in the target system", "targetSystem"); } // Check that the system is within range CosmoSystem[] inRangeSystems = this.GetInRangeSystems(); if (!inRangeSystems.Contains(targetSystem)) { throw new ArgumentOutOfRangeException("targetSystem", "Target system is out of JumpDrive range"); } // Check that the ship is not already traveling if (this.TargetSystemId != null || this.TargetSystemArrivalTime != null) { throw new InvalidOperationException("Ship is already traveling"); } // Get the travel time int travelTime = this.JumpDrive.ChargeTime; // Update the player stats Player shipPlayer = this.Players.SingleOrDefault(); if (shipPlayer != null) { shipPlayer.DistanceTraveled += this.GetSystemDistance(targetSystem); } // Update the database CosmoMongerDbDataContext db = CosmoManager.GetDbContext(); this.TargetSystemId = targetSystem.SystemId; this.TargetSystemArrivalTime = DateTime.UtcNow.AddSeconds(travelTime); db.SaveChanges(); return(travelTime); }
/// <summary> /// Gets the distance from the ship to the target system /// </summary> /// <param name="targetSystem">The target system to measure to.</param> /// <returns>A floating-point distance</returns> public double GetSystemDistance(CosmoSystem targetSystem) { return(Math.Sqrt(Math.Pow(targetSystem.PositionX - this.CosmoSystem.PositionX, 2) + Math.Pow(targetSystem.PositionY - this.CosmoSystem.PositionY, 2))); }
/// <summary> /// Called when the other ship has been destroyed. Current turn ship has won /// </summary> private void OtherShipDestroyed() { CosmoMongerDbDataContext db = CosmoManager.GetDbContext(); // No longer traveling, combat has ended with one ship being destroyed this.ShipOther.TargetSystemId = null; this.ShipOther.TargetSystemArrivalTime = null; this.ShipTurn.TargetSystemId = null; this.ShipTurn.TargetSystemArrivalTime = null; // Destroy some of the other ship's credits/cargo double creditsCargoDestroyedPerc = this.rnd.Next(Combat.CreditsCargoDestroyedPercentMin, Combat.CreditsCargoDestroyedPercentMax) / 100.0; Dictionary <string, object> props; foreach (ShipGood good in this.ShipOther.ShipGoods) { // Calculate how many goods to destroy int goodsDestroyed = (int)Math.Round(good.Quantity * creditsCargoDestroyedPerc); props = new Dictionary <string, object> { { "CombatId", this.CombatId }, { "OtherShipId", good.ShipId }, { "GoodId", good.GoodId }, { "Quantity", good.Quantity }, { "QuantityDestroyed", goodsDestroyed } }; Logger.Write("Destroying some of losing ship cargo", "Model", 150, 0, TraceEventType.Verbose, "InProgressCombat.OtherShipDestroyed", props); // Destroy the goods good.Quantity -= goodsDestroyed; } // Calculate how many credits to destroy int cashCreditsDestroyed = (int)Math.Round(this.ShipOther.Credits * creditsCargoDestroyedPerc); props = new Dictionary <string, object> { { "CombatId", this.CombatId }, { "OtherShipCredits", this.ShipOther.Credits }, { "CashCreditsDestroyed", cashCreditsDestroyed } }; Logger.Write("Destroying some of losing shipcredits", "Model", 150, 0, TraceEventType.Verbose, "InProgressCombat.OtherShipDestroyed", props); // Destroy credits this.ShipOther.Credits -= cashCreditsDestroyed; // Sending cargo into space this.SendCargoIntoSpace(this.ShipOther); // Move cargo into our cargo bays this.LoadCargo(); props = new Dictionary <string, object> { { "CombatId", this.CombatId }, { "OtherShipCredits", this.ShipOther.Credits }, { "TurnShipCredits", this.ShipTurn.Credits } }; Logger.Write("Transfering losing player credits to winner", "Model", 150, 0, TraceEventType.Verbose, "InProgressCombat.OtherShipDestroyed", props); // Take the other ship credits this.StealCredits(); Player otherPlayer = this.ShipOther.Players.SingleOrDefault(); if (otherPlayer != null) { // Relocate other player to nearest system with a bank CosmoSystem bankSystem = this.ShipOther.GetNearestBankSystem(); // Save a reference to the players old ship Ship otherPlayerOldShip = otherPlayer.Ship; otherPlayer.Ship = null; props = new Dictionary <string, object> { { "CombatId", this.CombatId }, { "OtherPlayerId", otherPlayer.PlayerId }, { "BankSystemId", bankSystem.SystemId } }; Logger.Write("Relocating losing player to nearest system with bank", "Model", 150, 0, TraceEventType.Verbose, "InProgressCombat.OtherShipDestroyed", props); // Give the player a new ship in the bank system otherPlayer.CreateStartingShip(bankSystem); // Restore ship credits otherPlayer.Ship.Credits = otherPlayerOldShip.Credits; // Update other player stats otherPlayer.ShipsLost++; } // Update turn player stats Player turnPlayer = this.ShipTurn.Players.SingleOrDefault(); if (turnPlayer != null) { turnPlayer.ShipsDestroyed++; } // Combat has ended this.Status = CombatStatus.ShipDestroyed; // Save database changes db.SaveChanges(); // Cleanup combat this.CleanupCombat(); // End combat turn this.EndTurn(); }