/// <summary> /// Constructor for the taskgroup, sets name, faction, planet the TG starts in orbit of. /// </summary> /// <param name="Title">Name</param> /// <param name="FID">Faction</param> /// <param name="StartingBody">body taskgroup will orbit at creation.</param> public TaskGroupTN(string Title, Faction FID, OrbitingEntity StartingBody, StarSystem StartingSystem) { Name = Title; /// <summary> /// create these or else anything that relies on a unique global id will break. /// </summary> Id = Guid.NewGuid(); TaskGroupFaction = FID; IsOrbiting = true; OrbitingBody = StartingBody; (OrbitingBody as SystemBody).TaskGroupsInOrbit.Add(this); SSEntity = StarSystemEntityType.TaskGroup; Position.System = StartingSystem; Position.X = OrbitingBody.Position.X; Position.Y = OrbitingBody.Position.Y; Contact = new SystemContact(TaskGroupFaction, this); Contact.LastPosition.X = Contact.Position.X; Contact.LastPosition.Y = Contact.Position.Y; StartingSystem.SystemContactList.Add(Contact); DrawTravelLine = 3; CurrentSpeed = 1; MaxSpeed = 1; CurrentSpeedX = 0.0; CurrentSpeedY = 0.0; CurrentHeading = 0.0; TimeRequirement = 0; TaskGroupOrders = new BindingList<Order>(); TotalOrderDistance = 0.0; /// <summary> /// Change this for PDCS and starbases. /// </summary> CanOrder = Constants.ShipTN.OrderState.AcceptOrders; /// <summary> /// Ships start in the unordered state, so new orders will have to have GetHeading/speed/other functionality performed. /// </summary> NewOrders = true; Ships = new BindingList<ShipTN>(); ShipOutOfFuel = false; ActiveSensorQue = new BindingList<ActiveSensorTN>(); ActiveSensorCount = new BindingList<int>(); TaskGroupLookUpST = new BindingList<int>(); /// <summary> /// Resolution Max needs to go into global constants, or ship constants I think. /// </summary> for (int loop = 0; loop < Constants.ShipTN.ResolutionMax; loop++) { /// <summary> /// TaskGroupLookUpST will be initialized to zero. /// </summary> TaskGroupLookUpST.Add(0); } TaskGroupLookUpMT = new BindingList<int>(); for (int loop = 0; loop < 15; loop++) { /// <summary> /// TaskGroupLookUpMT will be initialized to zero. /// </summary> TaskGroupLookUpMT.Add(0); } BestThermalCount = 0; BestEMCount = 0; ThermalSortList = new LinkedList<int>(); EMSortList = new LinkedList<int>(); ActiveSortList = new LinkedList<int>(); TotalCargoTonnage = 0; CurrentCargoTonnage = 0; TotalCryoCapacity = 0; CurrentCryoStorage = 0; TaskGroupsOrdered = new BindingList<TaskGroupTN>(); TaskGroupPDL = new PointDefenseList(); IsInShipyard = false; SensorUpdateAck = 0; //add default legal order for targeting TGs. _legalOrders.Add(Constants.ShipTN.OrderType.Follow); _legalOrders.Add(Constants.ShipTN.OrderType.Join); _legalOrders.Add(Constants.ShipTN.OrderType.Absorb); _legalOrders.Add(Constants.ShipTN.OrderType.RefuelTargetFleet); _legalOrders.Add(Constants.ShipTN.OrderType.ResupplyTargetFleet); _legalOrders.Add(Constants.ShipTN.OrderType.ReloadTargetFleet); _legalOrders.Add(Constants.ShipTN.OrderType.LandOnAssignedMothership); _legalOrders.Add(Constants.ShipTN.OrderType.LandOnMotherShipNoAssign); _legalOrders.Add(Constants.ShipTN.OrderType.LandOnMothershipAssign); _legalOrders.Add(Constants.ShipTN.OrderType.TractorSpecifiedShip); _legalOrders.Add(Constants.ShipTN.OrderType.TractorSpecifiedShipyard); }
/// <summary> /// PD mode and range will be handled in this function. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void SetPDModeButton_Click(object sender, EventArgs e) { int index = m_oDetailsPanel.PDComboBox.SelectedIndex; float PointDefenseRange = 0.0f; bool res = float.TryParse(m_oDetailsPanel.PDRangeTextBox.Text, out PointDefenseRange); if (isBFC) { if (index <= (int)PointDefenseState.FinalDefensiveFireSelf) { if (res) _CurrnetShip.ShipBFC[_CurrnetFC.componentIndex].SetPointDefenseRange(PointDefenseRange); _CurrnetShip.ShipBFC[_CurrnetFC.componentIndex].SetPointDefenseMode((PointDefenseState)index); StarSystem CurrentSystem = _CurrnetShip.ShipsTaskGroup.Contact.Position.System; if (index != 0) { /// <summary> /// Add the star system list if one does not exist. /// </summary> if (_CurrnetFaction.PointDefense.ContainsKey(CurrentSystem) == false) { PointDefenseList PDL = new PointDefenseList(); _CurrnetFaction.PointDefense.Add(CurrentSystem, PDL); } /// <summary> /// Add the FC to the point defense FC list. BFC is ALWAYS false. /// </summary> if (_CurrnetFaction.PointDefense[CurrentSystem].PointDefenseFC.ContainsKey(_CurrnetShip.ShipBFC[_CurrnetFC.componentIndex]) == false) { _CurrnetFaction.PointDefense[CurrentSystem].AddComponent(_CurrnetShip.ShipBFC[_CurrnetFC.componentIndex], _CurrnetShip, false); _CurrnetShip.ShipsTaskGroup.TaskGroupPDL.AddComponent(_CurrnetShip.ShipBFC[_CurrnetFC.componentIndex], _CurrnetShip, false); } } else { /// <summary> /// This bug will pop up if a ship gets transported to another star system and it isn't handled properly. /// </summary> if (_CurrnetFaction.PointDefense.ContainsKey(CurrentSystem) == false) { String Error = String.Format("Star System {0} not found in point defense listing for {1} on {2}.", CurrentSystem, _CurrnetShip.ShipBFC[_CurrnetFC.componentIndex], _CurrnetShip); MessageEntry MessageEnter = new MessageEntry(MessageEntry.MessageType.Error, _CurrnetShip.ShipsTaskGroup.Contact.Position.System, _CurrnetShip.ShipsTaskGroup.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Error); _CurrnetFaction.MessageLog.Add(MessageEnter); } else { /// <summary> /// Remove the FC from the point defense FC list. /// </summary> if (_CurrnetFaction.PointDefense[CurrentSystem].PointDefenseFC.ContainsKey(_CurrnetShip.ShipBFC[_CurrnetFC.componentIndex]) == true) { _CurrnetFaction.PointDefense[CurrentSystem].RemoveComponent(_CurrnetShip.ShipBFC[_CurrnetFC.componentIndex]); _CurrnetShip.ShipsTaskGroup.TaskGroupPDL.RemoveComponent(_CurrnetShip.ShipBFC[_CurrnetFC.componentIndex]); } /// <summary> /// cleanup the starsystem so that the point defense list isn't cluttered. /// </summary> if (_CurrnetFaction.PointDefense[CurrentSystem].PointDefenseFC.Count == 0) { _CurrnetFaction.PointDefense.Remove(CurrentSystem); } } } } else { String Error = String.Format("Improper point defense state {0} assigned to BFC {1} on {2}", (PointDefenseState)index, _CurrnetFC, _CurrnetShip); MessageEntry MessageEnter = new MessageEntry(MessageEntry.MessageType.Error, _CurrnetShip.ShipsTaskGroup.Contact.Position.System, _CurrnetShip.ShipsTaskGroup.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Error); _CurrnetFaction.MessageLog.Add(MessageEnter); } } else { if (index != 0) index = index + 3; if (index == 0 || (index >= (int)PointDefenseState.AMM1v2 && index <= (int)PointDefenseState.AMM5v1)) { if (res) _CurrnetShip.ShipMFC[_CurrnetFC.componentIndex].SetPointDefenseRange(PointDefenseRange); _CurrnetShip.ShipMFC[_CurrnetFC.componentIndex].SetPointDefenseMode((PointDefenseState)index); StarSystem CurrentSystem = _CurrnetShip.ShipsTaskGroup.Contact.Position.System; /// <summary> /// Clear Point defense. ClearTarget() further down also clears point defense so make any relevant changes there as well. /// </summary> if (index != 0) { /// <summary> /// Add the star system list if one does not exist. /// </summary> if (_CurrnetFaction.PointDefense.ContainsKey(CurrentSystem) == false) { PointDefenseList PDL = new PointDefenseList(); _CurrnetFaction.PointDefense.Add(CurrentSystem, PDL); } /// <summary> /// Add the FC to the point defense FC list. MFC is ALWAYS true. /// </summary> if (_CurrnetFaction.PointDefense[CurrentSystem].PointDefenseFC.ContainsKey(_CurrnetShip.ShipMFC[_CurrnetFC.componentIndex]) == false) { _CurrnetFaction.PointDefense[CurrentSystem].AddComponent(_CurrnetShip.ShipMFC[_CurrnetFC.componentIndex], _CurrnetShip, true); _CurrnetShip.ShipsTaskGroup.TaskGroupPDL.AddComponent(_CurrnetShip.ShipMFC[_CurrnetFC.componentIndex], _CurrnetShip, true); } } else { /// <summary> /// This bug will pop up if a ship gets transported to another star system and it isn't handled properly. /// </summary> if (_CurrnetFaction.PointDefense.ContainsKey(CurrentSystem) == false) { #warning leave this error message in for now String Error = String.Format("Star System {0} not found in point defense listing for {1} on {2}. Not necessarily a bug.", CurrentSystem, _CurrnetShip.ShipMFC[_CurrnetFC.componentIndex], _CurrnetShip); MessageEntry MessageEnter = new MessageEntry(MessageEntry.MessageType.Error, _CurrnetShip.ShipsTaskGroup.Contact.Position.System, _CurrnetShip.ShipsTaskGroup.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Error); _CurrnetFaction.MessageLog.Add(MessageEnter); } /// <summary> /// Remove the FC from the point defense FC list. /// </summary> if (_CurrnetFaction.PointDefense.Count != 0) { if (_CurrnetFaction.PointDefense.ContainsKey(CurrentSystem) == true) { if (_CurrnetFaction.PointDefense[CurrentSystem].PointDefenseFC.ContainsKey(_CurrnetShip.ShipMFC[_CurrnetFC.componentIndex]) == true) { _CurrnetFaction.PointDefense[CurrentSystem].RemoveComponent(_CurrnetShip.ShipMFC[_CurrnetFC.componentIndex]); _CurrnetShip.ShipsTaskGroup.TaskGroupPDL.RemoveComponent(_CurrnetShip.ShipMFC[_CurrnetFC.componentIndex]); } /// <summary> /// Cleanup the starsystem so that the point defense list isn't cluttered. /// </summary> if (_CurrnetFaction.PointDefense[CurrentSystem].PointDefenseFC.Count == 0) { _CurrnetFaction.PointDefense.Remove(CurrentSystem); } } } } } else { String Error = String.Format("Improper point defense state {0} assigned to MFC {1} on {2}", (PointDefenseState)index, _CurrnetFC, _CurrnetShip); MessageEntry MessageEnter = new MessageEntry(MessageEntry.MessageType.Error, _CurrnetShip.ShipsTaskGroup.Contact.Position.System, _CurrnetShip.ShipsTaskGroup.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Error); _CurrnetFaction.MessageLog.Add(MessageEnter); } } BuildCombatSummary(); }
/// <summary> /// End FollowOrders() /// </summary> /// <summary> /// What order should be performed at the target location? /// Update the state of the taskgroup if it is doing a blocking order. also fill out the timer for how long the ship will be blocked. /// overhaul follow orders to make sure that this is handled. /// </summary> public uint PerformOrders(uint TimeSlice) { Order currentOrder = TaskGroupOrders[0]; /// <summary> /// Handle orbiting planets here. breaking orbits is done elsewhere. /// </summary> if (TaskGroupOrders[0].target.SSEntity == StarSystemEntityType.Body || TaskGroupOrders[0].target.SSEntity == StarSystemEntityType.Population) { IsOrbiting = true; if (TaskGroupOrders[0].target.SSEntity == StarSystemEntityType.Body) { OrbitingBody = TaskGroupOrders[0].body; } else { OrbitingBody = TaskGroupOrders[0].pop.Planet; } SystemBody OrbitingPlanet = OrbitingBody as SystemBody; if (!OrbitingPlanet.TaskGroupsInOrbit.Contains(this)) { OrbitingPlanet.TaskGroupsInOrbit.Add(this); } } if (TaskGroupOrders[0].orderDelay >= TimeSlice) { TaskGroupOrders[0].orderDelay = TaskGroupOrders[0].orderDelay - (int)TimeSlice; TimeSlice = 0; } else if (TaskGroupOrders[0].orderDelay < TimeSlice) { TimeSlice = TimeSlice - (uint)TaskGroupOrders[0].orderDelay; TaskGroupOrders[0].orderDelay = 0; switch ((int)TaskGroupOrders[0].typeOf) { #region MoveTo /// <summary> /// Perform no orders for moveto: /// </summary> case (int)Constants.ShipTN.OrderType.MoveTo: TaskGroupOrders[0].orderTimeRequirement = 0; break; #endregion #region Refuel From Colony case (int)Constants.ShipTN.OrderType.RefuelFromColony: TaskGroupOrders[0].orderTimeRequirement = 0; for (int loop = 0; loop < Ships.Count; loop++) { if (TaskGroupOrders[0].pop.FuelStockpile == 0.0f) { /// <summary> /// Orders could not be carried out. A sample message log is below, something like this will need to be done for every type of message. /// </summary> /*DateTime TimeOfMessage = new DateTime(); MessageEntry NewMessage = new MessageEntry(Contact.Position.System, Contact, TimeOfMessage, (int)TimeSlice, "Refueling order could not be completed."); this.Faction.MessageLog.Add(NewMessage);*/ break; } TaskGroupOrders[0].pop.FuelStockpile = Ships[loop].Refuel(TaskGroupOrders[0].pop.FuelStockpile); } break; #endregion #region Resupply From Colony case (int)Constants.ShipTN.OrderType.ResupplyFromColony: TaskGroupOrders[0].orderTimeRequirement = 0; for (int loop = 0; loop < Ships.Count; loop++) { if (TaskGroupOrders[0].pop.MaintenanceSupplies == 0) { /// <summary> /// Order could not be carried out. /// </summary> break; } TaskGroupOrders[0].pop.MaintenanceSupplies = (float)Ships[loop].Resupply((int)Math.Floor(TaskGroupOrders[0].pop.MaintenanceSupplies)); } break; #endregion #region Load Installation /// <summary> /// Load Installation: /// </summary> case (int)Constants.ShipTN.OrderType.LoadInstallation: if (TaskGroupOrders[0].orderTimeRequirement == -1) { CanOrder = Constants.ShipTN.OrderState.CurrentlyLoading; int TaskGroupLoadTime = CalcTaskGroupLoadTime(Constants.ShipTN.LoadType.Cargo); int PlanetaryLoadTime = TaskGroupOrders[0].pop.CalculateLoadTime(TaskGroupLoadTime); TaskGroupOrders[0].orderTimeRequirement = PlanetaryLoadTime; } if (TimeSlice > TaskGroupOrders[0].orderTimeRequirement) { TimeSlice = TimeSlice - (uint)TaskGroupOrders[0].orderTimeRequirement; TaskGroupOrders[0].orderTimeRequirement = 0; LoadCargo(TaskGroupOrders[0].pop, (Installation.InstallationType)TaskGroupOrders[0].secondary, TaskGroupOrders[0].tertiary); CanOrder = Constants.ShipTN.OrderState.AcceptOrders; } else { TaskGroupOrders[0].orderTimeRequirement = TaskGroupOrders[0].orderTimeRequirement - (int)TimeSlice; TimeSlice = 0; } break; #endregion #region Load Ship Component /// <summary> /// Load Ship Component: /// </summary> case (int)Constants.ShipTN.OrderType.LoadShipComponent: if (TaskGroupOrders[0].orderTimeRequirement == -1) { CanOrder = Constants.ShipTN.OrderState.CurrentlyLoading; int TaskGroupLoadTime = CalcTaskGroupLoadTime(Constants.ShipTN.LoadType.Cargo); int PlanetaryLoadTime = TaskGroupOrders[0].pop.CalculateLoadTime(TaskGroupLoadTime); TaskGroupOrders[0].orderTimeRequirement = PlanetaryLoadTime; } if (TimeSlice > TaskGroupOrders[0].orderTimeRequirement) { TimeSlice = TimeSlice - (uint)TaskGroupOrders[0].orderTimeRequirement; TaskGroupOrders[0].orderTimeRequirement = 0; LoadComponents(TaskGroupOrders[0].pop, TaskGroupOrders[0].secondary, TaskGroupOrders[0].tertiary); CanOrder = Constants.ShipTN.OrderState.AcceptOrders; } else { TaskGroupOrders[0].orderTimeRequirement = TaskGroupOrders[0].orderTimeRequirement - (int)TimeSlice; TimeSlice = 0; } break; #endregion #region Unload Installation /// <summary> /// Unload installation: /// </summary> case (int)Constants.ShipTN.OrderType.UnloadInstallation: if (TaskGroupOrders[0].orderTimeRequirement == -1) { CanOrder = Constants.ShipTN.OrderState.CurrentlyUnloading; int TaskGroupLoadTime = CalcTaskGroupLoadTime(Constants.ShipTN.LoadType.Cargo); int PlanetaryLoadTime = TaskGroupOrders[0].pop.CalculateLoadTime(TaskGroupLoadTime); TaskGroupOrders[0].orderTimeRequirement = PlanetaryLoadTime; } if (TimeSlice > TaskGroupOrders[0].orderTimeRequirement) { TimeSlice = TimeSlice - (uint)TaskGroupOrders[0].orderTimeRequirement; TaskGroupOrders[0].orderTimeRequirement = 0; UnloadCargo(TaskGroupOrders[0].pop, (Installation.InstallationType)TaskGroupOrders[0].secondary, TaskGroupOrders[0].tertiary); CanOrder = Constants.ShipTN.OrderState.AcceptOrders; } else { TaskGroupOrders[0].orderTimeRequirement = TaskGroupOrders[0].orderTimeRequirement - (int)TimeSlice; TimeSlice = 0; } break; #endregion #region Unload Ship Component /// <summary> /// Unload Ship Component: /// </summary> case (int)Constants.ShipTN.OrderType.UnloadShipComponent: if (TaskGroupOrders[0].orderTimeRequirement == -1) { CanOrder = Constants.ShipTN.OrderState.CurrentlyUnloading; int TaskGroupLoadTime = CalcTaskGroupLoadTime(Constants.ShipTN.LoadType.Cargo); int PlanetaryLoadTime = TaskGroupOrders[0].pop.CalculateLoadTime(TaskGroupLoadTime); TaskGroupOrders[0].orderTimeRequirement = PlanetaryLoadTime; } if (TimeSlice > TaskGroupOrders[0].orderTimeRequirement) { TimeSlice = TimeSlice - (uint)TaskGroupOrders[0].orderTimeRequirement; TaskGroupOrders[0].orderTimeRequirement = 0; ComponentDefTN UnloadOrder = null; int TGComponentCount = 0; for (int loop = 0; loop < Ships.Count; loop++) { if (Ships[loop].CargoComponentList.Count != 0) { foreach (KeyValuePair<ComponentDefTN, CargoListEntryTN> pair in Ships[loop].CargoComponentList) { if (TaskGroupOrders[0].secondary == TGComponentCount) { UnloadOrder = pair.Key; TGComponentCount = -1; break; } TGComponentCount++; } if (TGComponentCount == -1) break; } } UnloadComponents(TaskGroupOrders[0].pop, UnloadOrder, TaskGroupOrders[0].tertiary); CanOrder = Constants.ShipTN.OrderState.AcceptOrders; } else { TaskGroupOrders[0].orderTimeRequirement = TaskGroupOrders[0].orderTimeRequirement - (int)TimeSlice; TimeSlice = 0; } break; #endregion #region Load Colonists /// <summary> /// Load Colonists: /// </summary> case (int)Constants.ShipTN.OrderType.LoadColonists: if (TaskGroupOrders[0].orderTimeRequirement == -1) { CanOrder = Constants.ShipTN.OrderState.CurrentlyLoading; int TaskGroupLoadTime = CalcTaskGroupLoadTime(Constants.ShipTN.LoadType.Cryo); int PlanetaryLoadTime = TaskGroupOrders[0].pop.CalculateLoadTime(TaskGroupLoadTime); TaskGroupOrders[0].orderTimeRequirement = PlanetaryLoadTime; } if (TimeSlice > TaskGroupOrders[0].orderTimeRequirement) { TimeSlice = TimeSlice - (uint)TaskGroupOrders[0].orderTimeRequirement; TaskGroupOrders[0].orderTimeRequirement = 0; LoadColonists(TaskGroupOrders[0].pop, TaskGroupOrders[0].tertiary); CanOrder = Constants.ShipTN.OrderState.AcceptOrders; } else { TaskGroupOrders[0].orderTimeRequirement = TaskGroupOrders[0].orderTimeRequirement - (int)TimeSlice; TimeSlice = 0; } break; #endregion #region Unload Colonists /// <summary> /// Unload Colonists: /// </summary> case (int)Constants.ShipTN.OrderType.UnloadColonists: if (TaskGroupOrders[0].orderTimeRequirement == -1) { CanOrder = Constants.ShipTN.OrderState.CurrentlyUnloading; int TaskGroupLoadTime = CalcTaskGroupLoadTime(Constants.ShipTN.LoadType.Cryo); int PlanetaryLoadTime = TaskGroupOrders[0].pop.CalculateLoadTime(TaskGroupLoadTime); TaskGroupOrders[0].orderTimeRequirement = PlanetaryLoadTime; } if (TimeSlice > TaskGroupOrders[0].orderTimeRequirement) { TimeSlice = TimeSlice - (uint)TaskGroupOrders[0].orderTimeRequirement; TaskGroupOrders[0].orderTimeRequirement = 0; UnloadColonists(TaskGroupOrders[0].pop, TaskGroupOrders[0].tertiary); CanOrder = Constants.ShipTN.OrderState.AcceptOrders; } else { TaskGroupOrders[0].orderTimeRequirement = TaskGroupOrders[0].orderTimeRequirement - (int)TimeSlice; TimeSlice = 0; } break; #endregion #region Refuel Target Fleet case (int)Constants.ShipTN.OrderType.RefuelTargetFleet: TaskGroupOrders[0].orderTimeRequirement = 0; /// <summary> /// A specific tanker list could come in handy here. But this shouldn't be run every tick so it won't be that big an issue. /// </summary> int FuelPlace = 0; for (int loop = 0; loop < Ships.Count; loop++) { if (Ships[loop].ShipClass.IsTanker == true) { float FuelCutoff = Ships[loop].ShipClass.TotalFuelCapacity / 10.0f; float AvailableFuel = Ships[loop].CurrentFuel - FuelCutoff; for (int loop2 = FuelPlace; loop2 < TaskGroupOrders[0].taskGroup.Ships.Count; loop2++) { if (AvailableFuel <= 0.0f) { /// <summary> /// This tanker is done. /// </summary> break; } /// <summary> /// I want refuel target fleet to refuel all ships, even tankers. /// </summary> AvailableFuel = TaskGroupOrders[0].taskGroup.Ships[loop2].Refuel(AvailableFuel); FuelPlace++; } /// <summary> /// If the ship was below the fuel cutoff originally, that will be reflected in available fuel so this should cause no issues. /// </summary> Ships[loop].CurrentFuel = FuelCutoff + AvailableFuel; } } if (FuelPlace != TaskGroupOrders[0].taskGroup.Ships.Count || TaskGroupOrders[0].taskGroup.Ships.Last().CurrentFuel != TaskGroupOrders[0].taskGroup.Ships.Last().ShipClass.TotalFuelCapacity) { /// <summary> /// Order could not be carried out. /// </summary> } break; #endregion #region Refuel From Own Tankers case (int)Constants.ShipTN.OrderType.RefuelFromOwnTankers: TaskGroupOrders[0].orderTimeRequirement = 0; FuelPlace = 0; for (int loop = 0; loop < Ships.Count; loop++) { if (Ships[loop].ShipClass.IsTanker == true) { float FuelCutoff = Ships[loop].ShipClass.TotalFuelCapacity / 10.0f; float AvailableFuel = Ships[loop].CurrentFuel - FuelCutoff; for (int loop2 = FuelPlace; loop2 < Ships.Count; loop2++) { /// <summary> /// Don't refuel tankers from each other. /// </summary> if (Ships[loop2].ShipClass.IsTanker == false) { if (AvailableFuel <= 0.0f) { /// <summary> /// This Tanker is finished. /// </sumamry> break; } AvailableFuel = Ships[loop2].Refuel(AvailableFuel); FuelPlace++; } } Ships[loop].CurrentFuel = FuelCutoff + AvailableFuel; } } if (FuelPlace != Ships.Count || (Ships.Last().CurrentFuel != Ships.Last().ShipClass.TotalFuelCapacity && Ships.Last().ShipClass.IsTanker == false)) { /// <summary> /// Order could not be carried out. /// </summary> } break; #endregion #region Refuel From Target Fleet case (int)Constants.ShipTN.OrderType.RefuelFromTargetFleet: currentOrder.orderTimeRequirement = 0; FuelPlace = 0; TaskGroupTN targetTG = currentOrder.taskGroup as TaskGroupTN; foreach(ShipTN tankerShip in targetTG.Ships) { if (tankerShip.ShipClass.IsTanker) { float FuelCutoff = tankerShip.ShipClass.TotalFuelCapacity / 10.0f; float AvailableFuel = tankerShip.CurrentFuel - FuelCutoff; foreach (ShipTN myShip in this.Ships) { if (AvailableFuel <= 0.0f) { /// <summary> /// This Tanker is finished. /// </summary> break; } AvailableFuel = myShip.Refuel(AvailableFuel); FuelPlace++; } tankerShip.CurrentFuel = FuelCutoff + AvailableFuel; } } if (FuelPlace != Ships.Count || Ships.Last().CurrentFuel != Ships.Last().ShipClass.TotalFuelCapacity) { /// <summary> /// Order could not be carried out. /// </summary> } break; #endregion #region Unload 90% Of Fuel To SystemBody case (int)Constants.ShipTN.OrderType.UnloadFuelToPlanet: TaskGroupOrders[0].orderTimeRequirement = 0; for (int loop = 0; loop < Ships.Count; loop++) { if (Ships[loop].ShipClass.IsTanker == true) { float FuelCutoff = Ships[loop].ShipClass.TotalFuelCapacity / 10.0f; float AvailableFuel = Ships[loop].CurrentFuel - FuelCutoff; if (AvailableFuel > 0.0f) { TaskGroupOrders[0].pop.FuelStockpile = TaskGroupOrders[0].pop.FuelStockpile + AvailableFuel; Ships[loop].CurrentFuel = Ships[loop].CurrentFuel - AvailableFuel; } } } break; #endregion #region Resupply Target Fleet case (int)Constants.ShipTN.OrderType.ResupplyTargetFleet: TaskGroupOrders[0].orderTimeRequirement = 0; int SupplyPlace = 0; /// <summary> /// Likewise a Supply ship specific list could come in handy. /// </summary> for (int loop = 0; loop < Ships.Count; loop++) { if (Ships[loop].ShipClass.IsSupply == true) { int MSPCutoff = (Ships[loop].ShipClass.TotalMSPCapacity / 10); int AvailableMSP = Ships[loop].CurrentMSP - MSPCutoff; for (int loop2 = SupplyPlace; loop2 < TaskGroupOrders[0].taskGroup.Ships.Count; loop2++) { if (AvailableMSP <= 0) { ///<summary> ///This supply ship is finished. ///</summary> break; } AvailableMSP = TaskGroupOrders[0].taskGroup.Ships[loop2].Resupply(AvailableMSP); SupplyPlace++; } Ships[loop].CurrentMSP = MSPCutoff + AvailableMSP; } } if (SupplyPlace != TaskGroupOrders[0].taskGroup.Ships.Count || TaskGroupOrders[0].taskGroup.Ships.Last().CurrentMSP != TaskGroupOrders[0].taskGroup.Ships.Last().ShipClass.TotalMSPCapacity) { /// <summary> /// Order could not be carried out. /// </summary> } break; #endregion #region Resupply From Own Supply Ships case (int)Constants.ShipTN.OrderType.ResupplyFromOwnSupplyShips: TaskGroupOrders[0].orderTimeRequirement = 0; SupplyPlace = 0; for (int loop = 0; loop < Ships.Count; loop++) { if (Ships[loop].ShipClass.IsSupply == true) { int MSPCutoff = (Ships[loop].ShipClass.TotalMSPCapacity / 10); int AvailableMSP = Ships[loop].CurrentMSP - MSPCutoff; for (int loop2 = SupplyPlace; loop2 < Ships.Count; loop2++) { /// <summary> /// Don't resupply supply ships from each other, or juggle as it will henceforth be refered to. /// </summary> if (Ships[loop2].ShipClass.IsSupply == false) { if (AvailableMSP <= 0) { /// <summary> /// This supply ship is finished. /// </summary> break; } AvailableMSP = Ships[loop2].Resupply(AvailableMSP); SupplyPlace++; } } Ships[loop].CurrentMSP = MSPCutoff + AvailableMSP; } } if (SupplyPlace != Ships.Count || (Ships.Last().CurrentMSP != Ships.Last().ShipClass.TotalMSPCapacity && Ships.Last().ShipClass.IsSupply == false)) { /// <summary> /// Order could not be carried out. /// </summary> } break; #endregion #region Resupply From Target Fleet case (int)Constants.ShipTN.OrderType.ResupplyFromTargetFleet: TaskGroupOrders[0].orderTimeRequirement = 0; SupplyPlace = 0; for (int loop = 0; loop < TaskGroupOrders[0].taskGroup.Ships.Count; loop++) { if (TaskGroupOrders[0].taskGroup.Ships[loop].ShipClass.IsSupply == true) { int MSPCutoff = (TaskGroupOrders[0].taskGroup.Ships[loop].ShipClass.TotalMSPCapacity / 10); int AvailableMSP = TaskGroupOrders[0].taskGroup.Ships[loop].CurrentMSP - MSPCutoff; for (int loop2 = SupplyPlace; loop2 < Ships.Count; loop2++) { if (AvailableMSP <= 0) { /// <summary> /// This supply ship is done. /// </summary> break; } AvailableMSP = Ships[loop2].Resupply(AvailableMSP); SupplyPlace++; } TaskGroupOrders[0].taskGroup.Ships[loop].CurrentMSP = MSPCutoff + AvailableMSP; } } if (SupplyPlace != Ships.Count || Ships.Last().CurrentMSP != Ships.Last().ShipClass.TotalMSPCapacity) { /// <summary> /// Order could not be carried out. /// </summary> } break; #endregion #region Unload 90% Of Supplies To SystemBody case (int)Constants.ShipTN.OrderType.UnloadSuppliesToPlanet: TaskGroupOrders[0].orderTimeRequirement = 0; for (int loop = 0; loop < Ships.Count; loop++) { if (Ships[loop].ShipClass.IsSupply == true) { int MSPCutoff = (Ships[loop].ShipClass.TotalMSPCapacity / 10); int AvailableMSP = Ships[loop].CurrentMSP - MSPCutoff; if (AvailableMSP > 0) { TaskGroupOrders[0].pop.MaintenanceSupplies = TaskGroupOrders[0].pop.MaintenanceSupplies + AvailableMSP; Ships[loop].CurrentMSP = Ships[loop].CurrentMSP - AvailableMSP; } } } break; #endregion #region Load Ordnance From Colony case (int)Constants.ShipTN.OrderType.LoadOrdnanceFromColony: TaskGroupOrders[0].orderTimeRequirement = 0; for (int loop = 0; loop < Ships.Count; loop++) { if (Ships[loop].ShipMagazines.Count != 0) { Ships[loop].LoadOrdnance(TaskGroupOrders[0].pop); } } break; #endregion #region Unload Ordnance To Colony case (int)Constants.ShipTN.OrderType.UnloadOrdnanceToColony: TaskGroupOrders[0].orderTimeRequirement = 0; for (int loop = 0; loop < Ships.Count; loop++) { if (Ships[loop].ShipMagazines.Count != 0) { Ships[loop].UnloadOrdnance(TaskGroupOrders[0].pop); } } break; #endregion #region Standard Transit case (int)Constants.ShipTN.OrderType.StandardTransit: { TaskGroupOrders[0].orderTimeRequirement = 0; JumpPoint CurrentJP = TaskGroupOrders[0].target as JumpPoint; // Check if we can jump. Dictionary<JumpEngineTN, ShipTN> usedJumpEngines; if (CurrentJP.CanJump(this, true, out usedJumpEngines)) { // Handle the jump here. ///< @todo Put jump transition in it's own function within TaskGroup. SystemPosition newPos = CurrentJP.Connect.Position; Position.System.SystemContactList.Remove(Contact); newPos.System.SystemContactList.Add(Contact); Position = newPos; Contact.UpdateLocationAfterTransit(); /// <summary> /// Handle PDList stuff. /// </summary> foreach (KeyValuePair<ComponentTN, ShipTN> pair in TaskGroupPDL.PointDefenseFC) { /// <summary> /// If these aren't true... whoops. /// </summary> if (TaskGroupFaction.PointDefense.ContainsKey(CurrentJP.Position.System) == true) { if (TaskGroupFaction.PointDefense[CurrentJP.Position.System].PointDefenseFC.ContainsKey(pair.Key) == true) { ShipTN Ship = pair.Value; ComponentTN Comp = pair.Key; bool type = TaskGroupFaction.PointDefense[CurrentJP.Position.System].PointDefenseType[pair.Key]; TaskGroupFaction.PointDefense[CurrentJP.Position.System].RemoveComponent(pair.Key); if (TaskGroupFaction.PointDefense.ContainsKey(CurrentJP.Connect.Position.System) == false) { PointDefenseList NewPDL = new PointDefenseList(); TaskGroupFaction.PointDefense.Add(CurrentJP.Connect.Position.System, NewPDL); } TaskGroupFaction.PointDefense[CurrentJP.Connect.Position.System].AddComponent(Comp, Ship, type); } } } /// <summary> /// No jump gate was used. /// Set the jump engines used to transit. /// Set the ship to undergo jump recharge. /// Set every ship to have jump sickness /// There should be at most one civ and one military in this situation. assuming a mixed group. /// </summary> if (usedJumpEngines != null) { foreach (KeyValuePair<JumpEngineTN,ShipTN> JumpShipPair in usedJumpEngines) { JumpShipPair.Key.Transit(); if (TaskGroupFaction.RechargeList.ContainsKey(JumpShipPair.Value) == true) { if((TaskGroupFaction.RechargeList[JumpShipPair.Value] & (int)Faction.RechargeStatus.JumpRecharge) != (int)Faction.RechargeStatus.JumpRecharge) { TaskGroupFaction.RechargeList[JumpShipPair.Value] = TaskGroupFaction.RechargeList[JumpShipPair.Value] + (int)Faction.RechargeStatus.JumpRecharge; } } else { TaskGroupFaction.RechargeList.Add(JumpShipPair.Value, (int)Faction.RechargeStatus.JumpRecharge); } } } /// <summary> /// Set every ship as jump sick, this is done even if a gate is used. /// </summary> foreach (ShipTN CurrentShip in Ships) { CurrentShip.StandardTransit(); if (TaskGroupFaction.RechargeList.ContainsKey(CurrentShip) == true) { if ((TaskGroupFaction.RechargeList[CurrentShip] & (int)Faction.RechargeStatus.JumpStandardSickness) != (int)Faction.RechargeStatus.JumpStandardSickness) { TaskGroupFaction.RechargeList[CurrentShip] = TaskGroupFaction.RechargeList[CurrentShip] + (int)Faction.RechargeStatus.JumpStandardSickness; } } else { TaskGroupFaction.RechargeList.Add(CurrentShip, (int)Faction.RechargeStatus.JumpStandardSickness); } } } } break; #endregion #region Squadron Transit case (int)Constants.ShipTN.OrderType.SquadronTransit: { TaskGroupOrders[0].orderTimeRequirement = 0; // Check if we can jump. Dictionary<JumpEngineTN, ShipTN> usedJumpEngines; if ((TaskGroupOrders[0].target as JumpPoint).CanJump(this, false, out usedJumpEngines)) { // Handle the jump here. ///< @todo Put jump transition in it's own function within TaskGroup. SystemPosition newPos = (TaskGroupOrders[0].target as JumpPoint).Connect.Position; Position.System.SystemContactList.Remove(Contact); newPos.System.SystemContactList.Add(Contact); Position = newPos; Contact.UpdateLocationAfterTransit(); /// <summary> /// Handle PDList stuff. /// </summary> JumpPoint CurrentJP = TaskGroupOrders[0].target as JumpPoint; foreach (KeyValuePair<ComponentTN, ShipTN> pair in TaskGroupPDL.PointDefenseFC) { /// <summary> /// If these aren't true... whoops. /// </summary> if (TaskGroupFaction.PointDefense.ContainsKey(CurrentJP.Position.System) == true) { if (TaskGroupFaction.PointDefense[CurrentJP.Position.System].PointDefenseFC.ContainsKey(pair.Key) == true) { ShipTN Ship = pair.Value; ComponentTN Comp = pair.Key; bool type = TaskGroupFaction.PointDefense[CurrentJP.Position.System].PointDefenseType[pair.Key]; TaskGroupFaction.PointDefense[CurrentJP.Position.System].RemoveComponent(pair.Key); if (TaskGroupFaction.PointDefense.ContainsKey(CurrentJP.Connect.Position.System) == false) { PointDefenseList NewPDL = new PointDefenseList(); TaskGroupFaction.PointDefense.Add(CurrentJP.Connect.Position.System, NewPDL); } TaskGroupFaction.PointDefense[CurrentJP.Connect.Position.System].AddComponent(Comp, Ship, type); } } } /// <summary> /// if Jump Engine is null here, it means there was a problem. /// Set the jump engines used to transit. /// Set the ship to undergo jump recharge. /// Set every ship to have jump sickness /// There should be at least one civ or one military in this situation. potentially more. /// </summary> int MinJumpRadius = -1; if (usedJumpEngines != null) { foreach (KeyValuePair<JumpEngineTN, ShipTN> JumpShipPair in usedJumpEngines) { if (MinJumpRadius == -1 || JumpShipPair.Key.jumpEngineDef.jumpRadius < MinJumpRadius) { MinJumpRadius = JumpShipPair.Key.jumpEngineDef.jumpRadius; } JumpShipPair.Key.Transit(); if (TaskGroupFaction.RechargeList.ContainsKey(JumpShipPair.Value) == true) { if ((TaskGroupFaction.RechargeList[JumpShipPair.Value] & (int)Faction.RechargeStatus.JumpRecharge) != (int)Faction.RechargeStatus.JumpRecharge) { TaskGroupFaction.RechargeList[JumpShipPair.Value] = TaskGroupFaction.RechargeList[JumpShipPair.Value] + (int)Faction.RechargeStatus.JumpRecharge; } } else { TaskGroupFaction.RechargeList.Add(JumpShipPair.Value, (int)Faction.RechargeStatus.JumpRecharge); } } } else { String STE = "Squadron transit happened with no jump engines."; MessageEntry nMsg = new MessageEntry(MessageEntry.MessageType.Error, Position.System, this, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, STE); TaskGroupFaction.MessageLog.Add(nMsg); } /// <summary> /// Set every ship as jump sick, this is done even if a gate is used. /// </summary> foreach (ShipTN CurrentShip in Ships) { CurrentShip.SquadronTransit(); if (TaskGroupFaction.RechargeList.ContainsKey(CurrentShip) == true) { if ((TaskGroupFaction.RechargeList[CurrentShip] & (int)Faction.RechargeStatus.JumpSquadronSickness) != (int)Faction.RechargeStatus.JumpSquadronSickness) { TaskGroupFaction.RechargeList[CurrentShip] = TaskGroupFaction.RechargeList[CurrentShip] + (int)Faction.RechargeStatus.JumpSquadronSickness; } } else { TaskGroupFaction.RechargeList.Add(CurrentShip, (int)Faction.RechargeStatus.JumpSquadronSickness); } } /// <summary> /// MinJumpRadius is the number of raw km this taskgroup should jump by. /// </summary> int degree = GameState.RNG.Next(0, 359); int Jump = GameState.RNG.Next((int)Math.Floor((float)MinJumpRadius * 0.95f), MinJumpRadius); double X = Jump * Math.Cos(degree * Constants.Units.Radian); double Y = Jump * Math.Sin(degree * Constants.Units.Radian); X = Distance.ToAU(X); Y = Distance.ToAU(Y); Position.X = Position.X + X; Position.Y = Position.Y + Y; Contact.UpdateLocationAfterTransit(); } } break; #endregion } } return TimeSlice; }