示例#1
0
        public static Fleet ModifyFleet(string playerName, string password, int fleetID, IEnumerable <ShipTypeCount> fleetShips)
        {
            using (var t = new TransactionScope())
            {
                var db     = new DbDataContext();
                var player = db.GetPlayer(playerName, password);

                var fleet = player.Fleets.SingleOrDefault(x => x.FleetID == fleetID);
                if (fleet.Transit.OrbitsObjectID == null)
                {
                    throw new ApplicationException("Fleet not in orbit");
                }
                var body = fleet.Transit.CelestialObject;
                if (body.OwnerID != player.PlayerID)
                {
                    throw new ApplicationException("Not my planet");
                }

                foreach (var order in fleetShips)
                {
                    if (order.Count > 0)
                    {
                        var garrisonCount = body.GetShipCount(order.ShipTypeID);
                        if (order.Count > garrisonCount)
                        {
                            throw new ApplicationException(string.Format("Not enough ships of type {0}", order.ShipTypeID));
                        }

                        body.SetShipCount(order.ShipTypeID, garrisonCount - order.Count);
                        fleet.SetShipCount(order.ShipTypeID, order.Count);
                    }
                    else
                    {
                        var change     = order.Count;
                        var fleetCount = fleet.GetShipCount(order.ShipTypeID);
                        if (change > fleetCount)
                        {
                            throw new ApplicationException(string.Format("Not enough ships of type {0} in fleet", order.ShipTypeID));
                        }

                        fleet.SetShipCount(order.ShipTypeID, fleetCount - change);
                        body.SetShipCount(order.ShipTypeID, change);
                    }
                }
                if (!fleet.FleetShips.Any())
                {
                    db.Fleets.DeleteOnSubmit(fleet);
                    fleet = null;
                }

                db.MarkDirty();
                db.SubmitChanges();
                if (fleet != null)
                {
                    fleet.FleetShips.Load();
                }
                t.Complete();
                return(fleet);
            }
        }
示例#2
0
        public static void ProcessTurn(int count)
        {
            for (var i = 0; i < count; i++)
            {
                using (var t = new TransactionScope()) {
                    var db = new DbDataContext();

                    var config = db.GetConfig();
                    config.CombatTurn++;

                    FleetLogic.ProcessTransitTurn(db);

                    foreach (var o in db.CelestialObjects)
                    {
                        o.UpdateIncomeInfo();
                    }

                    foreach (var player in db.Players.Where(x => x.IsActive))
                    {
                        if (config.CombatTurn % config.PopulationTick == 0)
                        {
                            player.ApplyPopulationTick(config.CombatTurn);
                        }
                        player.ApplyResourceTurn(config.CombatTurn);
                    }

                    db.MarkDirty();

                    config.TurnStarted = DateTime.UtcNow;                     // todo synchronize properly when not faking
                    db.SubmitChanges();
                    t.Complete();
                }
            }
        }
		public static void ProcessTurn(int count)
		{
			for (var i = 0; i < count; i++) {
				using (var t = new TransactionScope()) {
					var db = new DbDataContext();

					var config = db.GetConfig();
					config.CombatTurn++;

					FleetLogic.ProcessTransitTurn(db);

					foreach (var o in db.CelestialObjects) {
						o.UpdateIncomeInfo();
					}

					foreach (var player in db.Players.Where(x => x.IsActive)) {
						if (config.CombatTurn%config.PopulationTick == 0) player.ApplyPopulationTick(config.CombatTurn);
						player.ApplyResourceTurn(config.CombatTurn);
					}

					db.MarkDirty();

					config.TurnStarted = DateTime.UtcNow; // todo synchronize properly when not faking
					db.SubmitChanges();
					t.Complete();
				}
			}
		}
		public static Fleet CreateFleet(string playerName, string password, int bodyID, IEnumerable<ShipTypeCount> fleetShips)
		{
			using (var t = new TransactionScope())
			{
				var db = new DbDataContext();
				var player = db.GetPlayer(playerName, password);

				var body = player.CelestialObjects.Single(x => x.CelestialObjectID == bodyID);

				var fleet = new Fleet();
				fleet.Transit = new Transit();
				fleet.Transit.OrbitsObjectID = bodyID;

				foreach (var order in fleetShips)
				{
					var garrisonCount = body.GetShipCount(order.ShipTypeID);
					if (order.Count > garrisonCount) throw new ApplicationException(string.Format("Not enough ships of type {0}", order.ShipTypeID));

					body.SetShipCount(order.ShipTypeID, garrisonCount - order.Count);
					fleet.SetShipCount(order.ShipTypeID, order.Count);
				}
				player.Fleets.Add(fleet);

				db.MarkDirty();
				db.SubmitChanges();
				fleet.FleetShips.Load();
				t.Complete();
				return fleet;
			}
		}
示例#5
0
        public static BodyResponse SellStructure(string playerName, string password, int celestialObjectID, int structureTypeID)
        {
            using (var t = new TransactionScope()) {
                var db = new DbDataContext();
                var p  = db.GetPlayer(playerName, password);

                var planet = db.CelestialObjects.Single(x => x.CelestialObjectID == celestialObjectID && x.OwnerID == p.PlayerID);

                var ret = new BodyResponse();

                var cnt = planet.GetStructureCount(structureTypeID);
                if (cnt <= 0)
                {
                    ret.Response = BuildResponse.DoesNotExist;
                    return(ret);
                }
                else
                {
                    planet.SetStructureCount(structureTypeID, cnt - 1);
                }

                p.Metal += db.StructureTypes.Single(x => x.StructureTypeID == structureTypeID).CostMetal / 2.0;
                db.MarkDirty();
                db.SubmitChanges();
                planet.UpdateIncomeInfo();
                db.SubmitChanges();
                t.Complete();
                return(GetBodyOptions(playerName, password, celestialObjectID));
            }
        }
示例#6
0
        public static Fleet CreateFleet(string playerName, string password, int bodyID, IEnumerable <ShipTypeCount> fleetShips)
        {
            using (var t = new TransactionScope())
            {
                var db     = new DbDataContext();
                var player = db.GetPlayer(playerName, password);

                var body = player.CelestialObjects.Single(x => x.CelestialObjectID == bodyID);

                var fleet = new Fleet();
                fleet.Transit = new Transit();
                fleet.Transit.OrbitsObjectID = bodyID;

                foreach (var order in fleetShips)
                {
                    var garrisonCount = body.GetShipCount(order.ShipTypeID);
                    if (order.Count > garrisonCount)
                    {
                        throw new ApplicationException(string.Format("Not enough ships of type {0}", order.ShipTypeID));
                    }

                    body.SetShipCount(order.ShipTypeID, garrisonCount - order.Count);
                    fleet.SetShipCount(order.ShipTypeID, order.Count);
                }
                player.Fleets.Add(fleet);

                db.MarkDirty();
                db.SubmitChanges();
                fleet.FleetShips.Load();
                t.Complete();
                return(fleet);
            }
        }
示例#7
0
        public static Tuple <PopulationTransport, CelestialObject> CreatePopulationTransport(string playerName, string password, int fromBodyID, int toBodyID, int count)
        {
            using (var t = new TransactionScope())
            {
                var db     = new DbDataContext();
                var player = db.GetPlayer(playerName, password);
                var from   = player.CelestialObjects.Single(x => x.CelestialObjectID == fromBodyID);
                var target = db.CelestialObjects.Single(x => x.CelestialObjectID == toBodyID);

                if (from.Population < count)
                {
                    throw new ApplicationException("There are not enough people on this planet");
                }
                from.Population -= count;
                from.UpdateIncomeInfo();
                var transport = new PopulationTransport()
                {
                    Count = count, Player = player, Transit = new Transit()
                };
                player.PopulationTransports.Add(transport);

                var transit = transport.Transit;

                transit.SetTransit(target, FleetBaseWarp, db.GetConfig().CombatTurn + 1, db.GetConfig());                  // will start next turn


                db.MarkDirty();
                db.SubmitChanges();
                t.Complete();
                return(new Tuple <PopulationTransport, CelestialObject>(transport, from));
            }
        }
示例#8
0
        public static BodyResponse SellMothershipModule(string playerName, string password, int structureType)
        {
            using (var t = new TransactionScope()) {
                var db = new DbDataContext();
                var p  = db.GetPlayer(playerName, password);

                var ret = new BodyResponse();


                var cnt = p.GetStructureCount(structureType);
                if (cnt <= 0)
                {
                    ret.Response = BuildResponse.DoesNotExist;
                    return(ret);
                }
                p.SetStructureCount(structureType, cnt - 1);

                p.Metal += db.StructureTypes.Single(x => x.StructureTypeID == structureType).CostMetal / 2.0;

                db.SubmitChanges();
                if (p.CelestialObject != null)
                {
                    p.CelestialObject.UpdateIncomeInfo();
                }
                db.MarkDirty();
                db.SubmitChanges();
                p.MothershipStructures.Load();
                ret.Player = p;
                ret.NewStructureOptions = GetMotherhipModuleBuildOption(playerName, password);
                ret.Body     = p.CelestialObject;
                ret.Response = BuildResponse.Ok;
                t.Complete();
                return(ret);
            }
        }
示例#9
0
        public static RegisterResponse Register(string login, string password)
        {
            using (var t = new TransactionScope()) {
                var db   = new DbDataContext();
                var user = db.SpringAccounts.SingleOrDefault(x => x.Name == login);
                if (user == null)
                {
                    return(RegisterResponse.NotValidSpringLogin);
                }

                if (user.Players != null)
                {
                    return(RegisterResponse.AlreadyRegistered);
                }

                if (db.SpringAccounts.Any(x => x.UserCookie == user.UserCookie && x.Players != null))
                {
                    return(RegisterResponse.IsSmurf);
                }

                if (user.Password != SpringAccount.HashPassword(password))
                {
                    return(RegisterResponse.NotValidSpringPassword);
                }

                // create player and assign to smallest alliance
                var player = new Player()
                {
                    IsActive = true, StarSystem = db.StarSystems.OrderBy(x => x.Players.Where(y => y.IsActive).Count()).First()
                };
                user.Players          = player;
                player.MothershipName = player.SpringAccount.Name + "'s mothership";

                // create his planet
                var mg        = new MapGen();
                var hisPlanet = mg.CreateHomeworld(player.StarSystem.CelestialObject);
                hisPlanet.Name   = player.SpringAccount.Name + "'s home";
                hisPlanet.Player = player;
                player.StarSystem.CelestialObject.ChildCelestialObjects.Add(hisPlanet);

                hisPlanet.UpdateIncomeInfo();

                db.SubmitChanges();

                var e = db.AddEvent(EventType.Player, "{0} joined the {1}", player.Name, player.StarSystem.Name);
                e.Connect(player);
                e.Connect(hisPlanet);
                db.MarkDirty();
                db.SubmitChanges();
                t.Complete();
                return(RegisterResponse.Ok);
            }
        }
示例#10
0
        public static BodyResponse BuildMothershipModule(string playerName, string password, int structureType)
        {
            using (var t = new TransactionScope()) {
                var db = new DbDataContext();
                var p  = db.GetPlayer(playerName, password);

                var ret = new BodyResponse();

                if (p.Level <= p.MothershipStructures.Sum(x => x.Count))
                {
                    ret.Response = BuildResponse.NotEnoughRoomOrBuildpower;
                    return(ret);
                }

                var structure =
                    db.StructureTypes.Single(
                        x => x.StructureTypeID == structureType && (x.NeedsTechID == null || x.Tech.StarSystemTeches.Any(y => y.StarSystemID == p.SystemID)));

                if (structure.CostMetal >= p.Metal)
                {
                    ret.Response = BuildResponse.NotEnoughResources;
                    return(ret);
                }

                p.SetStructureCount(structureType, p.GetStructureCount(structureType) + 1);

                p.Metal -= structure.CostMetal;

                db.SubmitChanges();
                if (p.CelestialObject != null)
                {
                    p.CelestialObject.UpdateIncomeInfo();
                }
                db.MarkDirty();
                db.SubmitChanges();
                p.MothershipStructures.Load();
                ret.Player = p;
                ret.NewStructureOptions = GetMotherhipModuleBuildOption(playerName, password);
                ret.Body     = p.CelestialObject;
                ret.Response = BuildResponse.Ok;
                t.Complete();
                return(ret);
            }
        }
示例#11
0
        public static Tuple <Player, CelestialObject> OrderMothership(string playerName, string password, int toBodyID)
        {
            using (var t = new TransactionScope())
            {
                var db     = new DbDataContext();
                var player = db.GetPlayer(playerName, password);
                if (player.Transit == null)
                {
                    player.Transit = new Transit()
                    {
                        CelestialObject = player.CelestialObject
                    }
                }
                ;
                var originalBody = player.CelestialObject;
                var target       = db.CelestialObjects.Single(x => x.CelestialObjectID == toBodyID);
                var transit      = player.Transit;

                var oldOrbit  = transit.OrbitsObjectID;
                var oldTarget = transit.CelestialObjectByToObjectID;

                transit.SetTransit(target, FleetBaseWarp, db.GetConfig().CombatTurn + 1, db.GetConfig()); // will start next turn

                if (oldOrbit == null && oldTarget != null)                                                // was heading to another planet
                {
                    var ev = db.AddEvent(EventType.Fleet, "{0} changed destination from {1} to {2}, ETA {3}", transit.GetNameWithOwner(), oldTarget.GetNameWithOwner(), transit.CelestialObjectByToObjectID.GetNameWithOwner(), transit.GetEtaString(db.GetConfig().SecondsPerTurn));
                    ev.Connect(transit.Fleets);
                    ev.Connect(transit.GetOwner());
                    ev.Connect(transit.CelestialObjectByToObjectID, oldTarget);
                    ev.Connect(transit.CelestialObjectByToObjectID.Player, oldTarget.Player);
                }

                if (originalBody != null)
                {
                    originalBody.UpdateIncomeInfo();
                }
                db.MarkDirty();
                db.SubmitChanges();
                t.Complete();
                return(new Tuple <Player, CelestialObject>(player, originalBody));
            }
        }
示例#12
0
        public static BodyResponse BuildShip(int count, string playerName, string password, int celestialObjectID, int shipType)
        {
            using (var t = new TransactionScope()) {
                if (count < 1)
                {
                    throw new ApplicationException("Invalid count");
                }
                var db = new DbDataContext();
                var p  = db.GetPlayer(playerName, password);

                var planet = p.CelestialObjects.Single(x => x.CelestialObjectID == celestialObjectID);

                var ship =
                    db.ShipTypes.Single(x => x.ShipTypeID == shipType && (x.NeedsTechID == null || x.Tech.StarSystemTeches.Any(y => y.StarSystemID == p.SystemID)));

                var ret = new BodyResponse();

                if (planet.Buildpower - planet.BuildpowerUsed < ship.MetalCost * count)
                {
                    ret.Response = BuildResponse.NotEnoughRoomOrBuildpower;
                    return(ret);
                }

                if (ship.MetalCost * count > p.Metal || ship.QuantiumCost * count > p.Quantium || ship.DarkMetalCost * count > p.DarkMatter)
                {
                    ret.Response = BuildResponse.NotEnoughResources;
                    return(ret);
                }

                planet.SetShipCount(shipType, planet.GetShipCount(shipType) + count);

                planet.BuildpowerUsed += ship.MetalCost * count;
                p.Metal      -= ship.MetalCost * count;
                p.Quantium   -= ship.QuantiumCost * count;
                p.DarkMatter -= ship.DarkMetalCost * count;
                db.MarkDirty();
                db.SubmitChanges();
                t.Complete();
                return(GetBodyOptions(playerName, password, celestialObjectID));
            }
        }
示例#13
0
        public static BodyResponse BuildStructure(string playerName, string password, int celestialObjectID, int structureTypeID)
        {
            using (var t = new TransactionScope()) {
                var db = new DbDataContext();
                var p  = db.GetPlayer(playerName, password);

                var ret = new BodyResponse();

                var planet = db.CelestialObjects.Single(x => x.CelestialObjectID == celestialObjectID && x.OwnerID == p.PlayerID);

                if (planet.Size <= planet.CelestialObjectStructures.Sum(x => x.Count))
                {
                    ret.Response = BuildResponse.NotEnoughRoomOrBuildpower;
                    return(ret);
                }

                var structure =
                    db.StructureTypes.Single(
                        x => x.StructureTypeID == structureTypeID && (x.NeedsTechID == null || x.Tech.StarSystemTeches.Any(y => y.StarSystemID == p.SystemID)));

                if (structure.CostMetal >= p.Metal)
                {
                    ret.Response = BuildResponse.NotEnoughResources;
                    return(ret);
                }

                planet.SetStructureCount(structureTypeID, planet.GetStructureCount(structureTypeID) + 1);
                p.Metal -= structure.CostMetal;

                db.MarkDirty();
                db.SubmitChanges();
                planet.UpdateIncomeInfo();
                db.SubmitChanges();
                t.Complete();
                return(GetBodyOptions(playerName, password, celestialObjectID));
            }
        }
示例#14
0
        public static Fleet OrderFleet(string playerName, string password, int fleetID, int toBodyID, int futureOffset)
        {
            if (futureOffset < 0)
            {
                throw new ApplicationException("Future offset cannot be smaller than 0");
            }
            using (var t = new TransactionScope())
            {
                var db     = new DbDataContext();
                var player = db.GetPlayer(playerName, password);
                var fleet  = player.Fleets.Single(x => x.FleetID == fleetID);
                var target = db.CelestialObjects.Single(x => x.CelestialObjectID == toBodyID);

                var oldOrbit  = fleet.Transit.OrbitsObjectID;
                var oldTarget = fleet.Transit.CelestialObjectByToObjectID;

                fleet.Transit.SetTransit(target, FleetBaseWarp, db.GetConfig().CombatTurn + 1 + futureOffset, db.GetConfig()); // will start next turn

                if (oldOrbit == null && oldTarget != null)                                                                     // was heading to another planet
                {
                    var transit = fleet.Transit;
                    var ev      = db.AddEvent(EventType.Fleet, "{0} changed destination from {1} to {2}, ETA {3}", transit.GetNameWithOwner(), oldTarget.GetNameWithOwner(), transit.CelestialObjectByToObjectID.GetNameWithOwner(), transit.GetEtaString(db.GetConfig().SecondsPerTurn));
                    ev.Connect(transit.Fleets);
                    ev.Connect(transit.GetOwner());
                    ev.Connect(transit.CelestialObjectByToObjectID, oldTarget);
                    ev.Connect(transit.CelestialObjectByToObjectID.Player, oldTarget.Player);
                }


                db.MarkDirty();
                db.SubmitChanges();
                fleet.FleetShips.Load();
                t.Complete();
                return(fleet);
            }
        }
		public static RegisterResponse Register(string login, string password)
		{
			using (var t = new TransactionScope()) {
				var db = new DbDataContext();
				var user = db.SpringAccounts.SingleOrDefault(x => x.Name == login);
				if (user == null) return RegisterResponse.NotValidSpringLogin;

				if (user.Players != null) return RegisterResponse.AlreadyRegistered;

				if (db.SpringAccounts.Any(x => x.UserCookie == user.UserCookie && x.Players != null)) return RegisterResponse.IsSmurf;

				if (user.Password != SpringAccount.HashPassword(password)) return RegisterResponse.NotValidSpringPassword;

				// create player and assign to smallest alliance
				var player = new Player() { IsActive = true, StarSystem = db.StarSystems.OrderBy(x => x.Players.Where(y => y.IsActive).Count()).First() };
				user.Players = player;
				player.MothershipName = player.SpringAccount.Name + "'s mothership";

				// create his planet 
				var mg = new MapGen();
				var hisPlanet = mg.CreateHomeworld(player.StarSystem.CelestialObject);
				hisPlanet.Name = player.SpringAccount.Name + "'s home";
				hisPlanet.Player = player;
				player.StarSystem.CelestialObject.ChildCelestialObjects.Add(hisPlanet);

				hisPlanet.UpdateIncomeInfo();

				db.SubmitChanges();

				var e = db.AddEvent(EventType.Player, "{0} joined the {1}", player.Name, player.StarSystem.Name);
				e.Connect(player);
				e.Connect(hisPlanet);
				db.MarkDirty();
				db.SubmitChanges();
				t.Complete();
				return RegisterResponse.Ok;
			}
		}
		public static Tuple<PopulationTransport, CelestialObject> CreatePopulationTransport(string playerName, string password, int fromBodyID, int toBodyID, int count)
		{
			using (var t = new TransactionScope())
			{
				var db = new DbDataContext();
				var player = db.GetPlayer(playerName, password);
				var from = player.CelestialObjects.Single(x => x.CelestialObjectID == fromBodyID);
				var target = db.CelestialObjects.Single(x => x.CelestialObjectID == toBodyID);
				
				if (from.Population < count) throw new ApplicationException("There are not enough people on this planet");
				from.Population -= count;
				from.UpdateIncomeInfo();
				var transport = new PopulationTransport() { Count = count, Player = player, Transit = new Transit() };
				player.PopulationTransports.Add(transport);

				var transit = transport.Transit;

				transit.SetTransit(target, FleetBaseWarp, db.GetConfig().CombatTurn + 1 , db.GetConfig()); // will start next turn
        

				db.MarkDirty();
				db.SubmitChanges();
				t.Complete();
				return new Tuple<PopulationTransport, CelestialObject>(transport, from);
			}

		}
		public static Fleet ModifyFleet(string playerName, string password, int fleetID, IEnumerable<ShipTypeCount> fleetShips)
		{
			using (var t = new TransactionScope())
			{
				var db = new DbDataContext();
				var player = db.GetPlayer(playerName, password);

				var fleet = player.Fleets.SingleOrDefault(x => x.FleetID == fleetID);
				if (fleet.Transit.OrbitsObjectID == null) throw new ApplicationException("Fleet not in orbit");
				var body = fleet.Transit.CelestialObject;
				if (body.OwnerID != player.PlayerID) throw new ApplicationException("Not my planet");

				foreach (var order in fleetShips)
				{
					if (order.Count > 0)
					{
						var garrisonCount = body.GetShipCount(order.ShipTypeID);
						if (order.Count > garrisonCount) throw new ApplicationException(string.Format("Not enough ships of type {0}", order.ShipTypeID));

						body.SetShipCount(order.ShipTypeID, garrisonCount - order.Count);
						fleet.SetShipCount(order.ShipTypeID, order.Count);
					}
					else
					{
						var change = order.Count;
						var fleetCount = fleet.GetShipCount(order.ShipTypeID);
						if (change > fleetCount) throw new ApplicationException(string.Format("Not enough ships of type {0} in fleet", order.ShipTypeID));

						fleet.SetShipCount(order.ShipTypeID, fleetCount - change);
						body.SetShipCount(order.ShipTypeID, change);
					}
				}
				if (!fleet.FleetShips.Any())
				{
					db.Fleets.DeleteOnSubmit(fleet);
					fleet = null;
				}

				db.MarkDirty();
				db.SubmitChanges();
				if (fleet != null) fleet.FleetShips.Load();
				t.Complete();
				return fleet;
			}
		}
		public static Fleet OrderFleet(string playerName, string password, int fleetID, int toBodyID, int futureOffset)
		{
			if (futureOffset < 0) throw new ApplicationException("Future offset cannot be smaller than 0");
			using (var t = new TransactionScope())
			{
				var db = new DbDataContext();
				var player = db.GetPlayer(playerName, password);
				var fleet = player.Fleets.Single(x => x.FleetID == fleetID);
				var target = db.CelestialObjects.Single(x => x.CelestialObjectID == toBodyID);

				var oldOrbit = fleet.Transit.OrbitsObjectID;
				var oldTarget = fleet.Transit.CelestialObjectByToObjectID;

				fleet.Transit.SetTransit(target, FleetBaseWarp, db.GetConfig().CombatTurn + 1 + futureOffset, db.GetConfig()); // will start next turn

				if (oldOrbit == null && oldTarget != null) // was heading to another planet
				{
					var transit = fleet.Transit;
					var ev = db.AddEvent(EventType.Fleet, "{0} changed destination from {1} to {2}, ETA {3}", transit.GetNameWithOwner(), oldTarget.GetNameWithOwner(), transit.CelestialObjectByToObjectID.GetNameWithOwner(), transit.GetEtaString(db.GetConfig().SecondsPerTurn));
					ev.Connect(transit.Fleets);
					ev.Connect(transit.GetOwner());
					ev.Connect(transit.CelestialObjectByToObjectID, oldTarget);
					ev.Connect(transit.CelestialObjectByToObjectID.Player, oldTarget.Player);
				}


				db.MarkDirty();
				db.SubmitChanges();
				fleet.FleetShips.Load();
				t.Complete();
				return fleet;
			}
		}
		public static Tuple<Player, CelestialObject> OrderMothership(string playerName, string password, int toBodyID)
		{
			using (var t = new TransactionScope())
			{
				var db = new DbDataContext();
				var player = db.GetPlayer(playerName, password);
				if (player.Transit == null) player.Transit = new Transit()
				                                             	{
				                                             		CelestialObject = player.CelestialObject
				                                             	};
				var originalBody = player.CelestialObject;
				var target = db.CelestialObjects.Single(x => x.CelestialObjectID == toBodyID);
				var transit = player.Transit;

				var oldOrbit = transit.OrbitsObjectID;
				var oldTarget = transit.CelestialObjectByToObjectID;

				transit.SetTransit(target, FleetBaseWarp, db.GetConfig().CombatTurn + 1, db.GetConfig()); // will start next turn

				if (oldOrbit == null && oldTarget != null) // was heading to another planet
				{
					var ev = db.AddEvent(EventType.Fleet, "{0} changed destination from {1} to {2}, ETA {3}", transit.GetNameWithOwner(), oldTarget.GetNameWithOwner(), transit.CelestialObjectByToObjectID.GetNameWithOwner(), transit.GetEtaString(db.GetConfig().SecondsPerTurn));
					ev.Connect(transit.Fleets);
					ev.Connect(transit.GetOwner());
					ev.Connect(transit.CelestialObjectByToObjectID, oldTarget);
					ev.Connect(transit.CelestialObjectByToObjectID.Player, oldTarget.Player);
				}

				if (originalBody != null) originalBody.UpdateIncomeInfo();
				db.MarkDirty();
				db.SubmitChanges();
				t.Complete();
				return new Tuple<Player, CelestialObject>(player, originalBody);
			}
		}