From 42ecf6bcd28b9722b2438668202099aec09f719a Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 18 Jul 2015 21:14:37 -0500 Subject: [PATCH 01/40] Survey Sensor Lib work the backend work for declaring sensors is complete, the frontend work, and the mechanics and functionality of survey sensors are yet to be done however. --- Pulsar4X/Pulsar4X.Lib/Constants.cs | 9 ++ .../Entities/Components/ComponentListTN.cs | 9 +- .../Entities/Components/ComponentTN.cs | 2 + .../Entities/Components/SurveySensorTN.cs | 99 +++++++++++++++++ Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs | 76 ++++++++++++- Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs | 104 +++++++++++++++++- 6 files changed, 294 insertions(+), 5 deletions(-) create mode 100644 Pulsar4X/Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs diff --git a/Pulsar4X/Pulsar4X.Lib/Constants.cs b/Pulsar4X/Pulsar4X.Lib/Constants.cs index a5312f864..ace6a9385 100644 --- a/Pulsar4X/Pulsar4X.Lib/Constants.cs +++ b/Pulsar4X/Pulsar4X.Lib/Constants.cs @@ -723,6 +723,12 @@ public static class SensorTN public static byte[] ActiveStrength = { 10, 12, 16, 21, 28, 36, 48, 60, 80, 100, 135, 180 }; public static byte[] PassiveStrength = { 5, 6, 8, 11, 14, 18, 24, 32, 40, 50, 60, 75 }; + /// + /// Strength of geological and gravitational survey sensors for standard,improved,advanced, and phased sensors. + /// + public static byte[] SurveyStrength = { 1, 2, 3, 5 }; + public const int SurveyStrengthMax = 4; + /// /// What value are sensors calibrated around searching for? /// @@ -1054,6 +1060,9 @@ public static class GameSettings /// public static bool PrimaryOnlyJumpPoints = false; + /// + /// Follow TN terraforming rules regarding what can be terraformed, and what gases generate what hostile effects. + /// public static bool TNTerraformingRules = false; } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Components/ComponentListTN.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Components/ComponentListTN.cs index dd53832b6..7abda027e 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Components/ComponentListTN.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Components/ComponentListTN.cs @@ -127,6 +127,11 @@ public class ComponentDefListTN /// public BindingList JumpEngineDef { get; set; } + /// + /// Survey sensor definitions. + /// + public BindingList SurveySensorDef { get; set; } + /// /// Number of the total components this faction has for ship building purposes. MissileEngineDef and MissileDef are excluded from this. /// @@ -174,6 +179,8 @@ public ComponentDefListTN() JumpEngineDef = new BindingList(); + SurveySensorDef = new BindingList(); + DefaultPassives = new PassiveSensorDefTN("Default, Don't display this one.", 1.0f, 1, PassiveSensorType.Thermal, 1.0f, 1); } @@ -367,7 +374,7 @@ public void SanityCheck() TotalComponents = CrewQuarters.Count + FuelStorage.Count + EngineeringSpaces.Count + OtherComponents.Count + Engines.Count + PassiveSensorDef.Count + ActiveSensorDef.Count + CargoHoldDef.Count + ColonyBayDef.Count + CargoHandleSystemDef.Count + BeamFireControlDef.Count + BeamWeaponDef.Count + ReactorDef.Count + ShieldDef.Count + MLauncherDef.Count + MagazineDef.Count + - MissileFireControlDef.Count + CIWSDef.Count + TurretDef.Count + JumpEngineDef.Count; + MissileFireControlDef.Count + CIWSDef.Count + TurretDef.Count + JumpEngineDef.Count + SurveySensorDef.Count; } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Components/ComponentTN.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Components/ComponentTN.cs index 29c7319c3..ff0ec9d5a 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Components/ComponentTN.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Components/ComponentTN.cs @@ -78,6 +78,8 @@ public enum ComponentTypeTN JumpEngine, + SurveySensor, + TypeCount } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs new file mode 100644 index 000000000..d2b76fe0b --- /dev/null +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Pulsar4X.Entities.Components +{ + /// + /// Survey sensors are required for finding TN mineral deposits or for finding jump points within a starsystem. + /// + public class SurveySensorDefTN : ComponentDefTN + { + public enum SurveySensorType + { + Geological, + Gravitational, + Count, + } + + /// + /// What type of sensor is this? + /// + private SurveySensorType SensorType; + public SurveySensorType sensorType + { + get { return SensorType; } + } + + /// + /// How strong of a sensor is this? how quickly does it perform its task. Points will accumulate for every unit of time this sensor has been at work, until the amount of points gathered + /// is sufficient to meet the point requirement for the item being surveyed. + /// + private float SensorStrength; + public float sensorStrength + { + get { return SensorStrength; } + } + + /// + /// Constructor for Survey sensors. + /// + /// Name of the sensor. + /// its type. + /// how many points it accumulates per unit of time on a survey job. + public SurveySensorDefTN(String Title, SurveySensorType sType, float sStrength) + { + Name = Title; + Id = Guid.NewGuid(); + + componentType = ComponentTypeTN.SurveySensor; + + SensorType = sType; + SensorStrength = sStrength; + + size = 5.0f; + crew = 25; + cost = 50.0m * ((decimal)sStrength * 50.0m); + htk = 1; + + minerialsCost = new decimal[Constants.Minerals.NO_OF_MINERIALS]; + for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) + { + minerialsCost[mineralIterator] = 0; + } + + minerialsCost[(int)Constants.Minerals.MinerialNames.Uridium] = cost; + + isSalvaged = false; + isObsolete = false; + isMilitary = false; + isDivisible = false; + isElectronic = false; + } + } + + public class SurveySensorTN : ComponentTN + { + /// + /// Definition for this sensor. + /// + private SurveySensorDefTN SurveyDef; + public SurveySensorDefTN surveyDef + { + get { return SurveyDef; } + } + + /// + /// Simple constructor for survey sensors. + /// + /// Definition to use. + public SurveySensorTN(SurveySensorDefTN definition) + { + SurveyDef = definition; + Name = SurveyDef.Name; + + isDestroyed = false; + } + } +} diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs index 3e59f0b09..d1fa8c11b 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs @@ -424,18 +424,35 @@ public enum ShipType /// public int JumpSickness { get; set; } + #region Survey Sensor Info + /// + /// All of the survey sensors on this ship. + /// + public BindingList ShipSurvey { get; set; } + + /// + /// What is the current ability of this ship to perform geosurveys? + /// + public float CurrentGeoSurveyStrength { get; set; } + + /// + /// What is the current ability of this ship to perform gravsurveys? + /// + public float CurrentGravSurveyStrength { get; set; } + #endregion + /// /// If this ship has been destroyed. this will need more sophisticated handling. /// public bool IsDestroyed { get; set; } /// - /// List of ships targeted on this vessel. + /// List of ships targeted on this vessel. On ship destruction this is needed for cleanup. /// public BindingList ShipsTargetting { get; set; } /// - /// Taskgroups with orders to this ship. + /// Taskgroups with orders to this ship. On ship destruction this is needed for cleanup. /// public BindingList TaskGroupsOrdered { get; set; } @@ -917,6 +934,26 @@ public ShipTN(ShipClassTN ClassDefinition, int ShipIndex, int CurrentTimeSlice, } JumpSickness = 0; + ShipSurvey = new BindingList(); + for (int loop = 0; loop < ClassDefinition.ShipSurveyDef.Count; loop++) + { + index = ClassDefinition.ListOfComponentDefs.IndexOf(ClassDefinition.ShipSurveyDef[loop]); + ComponentDefIndex[index] = (ushort)ShipComponents.Count; + for (int loop2 = 0; loop2 < ClassDefinition.ShipSurveyCount[loop]; loop2++) + { + SurveySensorTN Survey = new SurveySensorTN(ClassDefinition.ShipSurveyDef[loop]); + Survey.componentIndex = ShipSurvey.Count; + + int SurveyIndex = loop2 + 1; + Survey.Name = Survey.surveyDef.Name + " #" + SurveyIndex.ToString(); + + ShipSurvey.Add(Survey); + ShipComponents.Add(Survey); + } + } + CurrentGeoSurveyStrength = ShipClass.ShipGeoSurveyStrength; + CurrentGravSurveyStrength = ShipClass.ShipGravSurveyStrength; + IsDestroyed = false; ShipsTargetting = new BindingList(); @@ -2152,6 +2189,22 @@ public int DestroyComponent(ComponentTypeTN Type, int ComponentListDefIndex, int /// Nothing special needs to be done to ship in this case. /// break; + + case ComponentTypeTN.SurveySensor: + SurveySensorDefTN sDef = ShipSurvey[ShipComponents[ID].componentIndex].surveyDef; + if (sDef.sensorType == SurveySensorDefTN.SurveySensorType.Geological) + { + CurrentGeoSurveyStrength = CurrentGeoSurveyStrength - sDef.sensorStrength; + if (CurrentGeoSurveyStrength < 0) + CurrentGeoSurveyStrength = 0; + } + else if (sDef.sensorType == SurveySensorDefTN.SurveySensorType.Gravitational) + { + CurrentGravSurveyStrength = CurrentGravSurveyStrength - sDef.sensorStrength; + if (CurrentGravSurveyStrength < 0) + CurrentGravSurveyStrength = 0; + } + break; } return DamageReturn; } @@ -2354,6 +2407,22 @@ public void RepairComponent(ComponentTypeTN Type, int ComponentIndex) case ComponentTypeTN.JumpEngine: break; + + case ComponentTypeTN.SurveySensor: + SurveySensorDefTN sDef = ShipSurvey[ShipComponents[ComponentIndex].componentIndex].surveyDef; + if (sDef.sensorType == SurveySensorDefTN.SurveySensorType.Geological) + { + CurrentGeoSurveyStrength = CurrentGeoSurveyStrength + sDef.sensorStrength; + if (CurrentGeoSurveyStrength < 0) + CurrentGeoSurveyStrength = 0; + } + else if (sDef.sensorType == SurveySensorDefTN.SurveySensorType.Gravitational) + { + CurrentGravSurveyStrength = CurrentGravSurveyStrength + sDef.sensorStrength; + if (CurrentGravSurveyStrength < 0) + CurrentGravSurveyStrength = 0; + } + break; } } @@ -2448,6 +2517,9 @@ public decimal GetDamagedComponentsRepairCost(int ID, ComponentTypeTN CType) case ComponentTypeTN.JumpEngine: return ShipJumpEngine[ShipComponents[ID].componentIndex].jumpEngineDef.cost; + + case ComponentTypeTN.SurveySensor: + return ShipSurvey[ShipComponents[ID].componentIndex].surveyDef.cost; } return 0.0m; diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs b/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs index 28ed15f96..bd7aabf43 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs @@ -923,6 +923,48 @@ public decimal[] minerialsCost public int JumpRadius { get; set; } #endregion + #region Survey sensors + /// + /// Definitions for this ships survey sensors. + /// + [DisplayName("Ship Survey sensor List"), + Category("Component Lists"), + Description("The model/type of this ships survey sensors"), + Browsable(true), + ReadOnly(true)] + public BindingList ShipSurveyDef { get; set; } + + /// + /// Counts for this ships survey sensors. + /// + [DisplayName("Survey Sensor Count"), + Category("Component Counts"), + Description("Number of survey sensors on this ship."), + Browsable(true), + ReadOnly(true)] + public BindingList ShipSurveyCount { get; set; } + + /// + /// Total Geological Survey Strength available to this ship. + /// + [DisplayName("Geo Survey Strength"), + Category("Detials"), + Description("How many Geo survey points this ship will generate per unit of time."), + Browsable(true), + ReadOnly(true)] + public float ShipGeoSurveyStrength { get; set; } + + /// + /// Total Gravitational Survey Strength available to this ship. + /// + [DisplayName("Grav Survey Strength"), + Category("Detials"), + Description("How many Grav survey points this ship will generate per unit of time."), + Browsable(true), + ReadOnly(true)] + public float ShipGravSurveyStrength { get; set; } + #endregion + #endregion #region Constructor @@ -1075,6 +1117,11 @@ public ShipClassTN(string Title, Faction ShipClassFaction) SquadronSize = 0; JumpRadius = 0; + ShipSurveyDef = new BindingList(); + ShipSurveyCount = new BindingList(); + ShipGeoSurveyStrength = 0.0f; + ShipGravSurveyStrength = 0.0f; + ShipArmorDef = new ArmorDefTN("Conventional"); NewArmor("Conventional", 2, 1); @@ -2376,6 +2423,59 @@ public void AddJumpEngine(JumpEngineDefTN JumpEngine, short inc) UpdateClass(JumpEngine, inc); } + /// + /// Function to add and subtract Survey Sensors to this design. + /// + /// Survey sensor to add or subtract. + /// number to add or subtract. + public void AddSurveySensor(SurveySensorDefTN SurveySensor, short inc) + { + int SurveySensorIndex = ShipSurveyDef.IndexOf(SurveySensor); + if (SurveySensorIndex != -1) + { + ShipSurveyCount[SurveySensorIndex] = (ushort)((short)ShipSurveyCount[SurveySensorIndex] + inc); + } + + if (SurveySensorIndex == -1 && inc >= 1) + { + ShipSurveyDef.Add(SurveySensor); + ShipSurveyCount.Add((ushort)inc); + } + else + { + if (SurveySensorIndex != -1) + { + if (ShipSurveyCount[SurveySensorIndex] <= 0) + { + ShipSurveyCount.RemoveAt(SurveySensorIndex); + ShipSurveyDef.RemoveAt(SurveySensorIndex); + } + } + else + { + /// + /// Error here so return. + /// + return; + } + } + + if (SurveySensor.sensorType == SurveySensorDefTN.SurveySensorType.Geological) + { + ShipGeoSurveyStrength = ShipGeoSurveyStrength + (SurveySensor.sensorStrength * inc); + if (ShipGeoSurveyStrength < 0) + ShipGeoSurveyStrength = 0; + } + else if (SurveySensor.sensorType == SurveySensorDefTN.SurveySensorType.Gravitational) + { + ShipGravSurveyStrength = ShipGravSurveyStrength + (SurveySensor.sensorStrength * inc); + if (ShipGravSurveyStrength < 0) + ShipGravSurveyStrength = 0; + } + + UpdateClass(SurveySensor, inc); + } + /// /// Set preferred ordnance adds or subtracts missiles from the preferred ordnance list of this class. @@ -2528,8 +2628,8 @@ public void BuildClassSummary() } } - Entry = String.Format("{0} km/s JR {1}-{2} Armour {3}-{4} Shields {5}-{6} Sensors {7}/{8}/{9}/{10} Damage Control Rating {11} PPV {12}\n", MaxSpeed, - SquadronSize, ((int)Math.Round((float)(JumpRadius / 1000))), ShipArmorDef.depth, ShipArmorDef.cNum, TotalShieldPool, ShieldR, BestThermalRating, BestEMRating, 0, 0, MaxDamageControlRating, + Entry = String.Format("{0} km/s JR {1}-{2} Armour {3}-{4} Shields {5}-{6} Sensors {7}/{8}/{9:N0}/{10:N0} Damage Control Rating {11} PPV {12}\n", MaxSpeed, + SquadronSize, ((int)Math.Round((float)(JumpRadius / 1000))), ShipArmorDef.depth, ShipArmorDef.cNum, TotalShieldPool, ShieldR, BestThermalRating, BestEMRating, ShipGeoSurveyStrength, ShipGravSurveyStrength, MaxDamageControlRating, PlanetaryProtectionValue); Summary = String.Format("{0}{1}", Summary, Entry); From 662ebab304e086f6d144731f66fff0c47f3bc029 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 25 Jul 2015 20:31:19 -0500 Subject: [PATCH 02/40] UI Survey sensor work Survey sensors should now be ready for mechanics work to begin, but some mineral issues will need to be resolved and survey points need to be created and handled. jumppoints should also be assigned to survey points for the primary only jp option. --- .../Entities/Components/ComponentListTN.cs | 12 ++ .../Entities/Components/SurveySensorTN.cs | 2 +- .../Entities/ConstructionCycle.cs | 18 +++ .../Entities/StarSystem/TaskGroup.cs | 41 ++++++- Pulsar4X/Pulsar4X.UI/Handlers/ClassDesign.cs | 105 +++++++++++++++++- Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 36 ++++++ 6 files changed, 201 insertions(+), 13 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Components/ComponentListTN.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Components/ComponentListTN.cs index 7abda027e..7a54f3e71 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Components/ComponentListTN.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Components/ComponentListTN.cs @@ -363,6 +363,18 @@ public void AddInitialComponents() MissileDef.Add(MissileAMMDef); + /// + /// Sensor components should be added upon researching the appropriate technology, as they cannot be designed, Count should be at 46 + /// + SurveySensorDefTN GeoSurvey = new SurveySensorDefTN("Geological Survey Sensor", SurveySensorDefTN.SurveySensorType.Geological, 1.0f); + SurveySensorDefTN GravSurvey = new SurveySensorDefTN("Gravitational Survey Sensor", SurveySensorDefTN.SurveySensorType.Gravitational, 1.0f); + + SurveySensorDef.Add(GeoSurvey); + SurveySensorDef.Add(GravSurvey); + + TotalComponents = TotalComponents + 2; + + } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs index d2b76fe0b..b1238a32f 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs @@ -54,7 +54,7 @@ public SurveySensorDefTN(String Title, SurveySensorType sType, float sStrength) size = 5.0f; crew = 25; - cost = 50.0m * ((decimal)sStrength * 50.0m); + cost = 50.0m + ((decimal)sStrength * 50.0m); htk = 1; minerialsCost = new decimal[Constants.Minerals.NO_OF_MINERIALS]; diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs b/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs index d0d6e3f88..69605a626 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs @@ -205,6 +205,15 @@ public static void ConstructionFactoryBuild(Faction CurrentFaction, Population C CurrentPopulation.AddInstallation(CurrentConstruction.installationBuild, Completion); break; case ConstructionBuildQueueItem.CBType.ShipComponent: + + /// + /// Component issues seem more blatant than construction issues. + /// + if (CurrentConstruction.numToBuild < 0.0f) + { + Completion = Completion + CurrentConstruction.numToBuild; + } + CurrentPopulation.HandleBuildItemCost(CurrentConstruction.costPerItem, CurrentConstruction.componentBuild.minerialsCost, Completion); CurrentPopulation.AddComponentsToStockpile(CurrentConstruction.componentBuild, Completion); break; @@ -217,6 +226,15 @@ public static void ConstructionFactoryBuild(Faction CurrentFaction, Population C case ConstructionBuildQueueItem.CBType.PDCRefit: break; case ConstructionBuildQueueItem.CBType.MaintenanceSupplies: + + /// + /// Component issues seem more blatant than construction issues. + /// + if (CurrentConstruction.numToBuild < 0.0f) + { + Completion = Completion + CurrentConstruction.numToBuild; + } + CurrentPopulation.HandleBuildItemCost(CurrentConstruction.costPerItem, Constants.Colony.MaintenanceMineralCost, Completion); CurrentPopulation.AddMSP(Completion); break; diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index 6d6054387..80d087a06 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -449,13 +449,13 @@ public TaskGroupTN(string Title, Faction FID, OrbitingEntity StartingBody, StarS /// /// GeoSurvey specific orders: /// - //if (hasgeo) - // legalOrders.Add(Constants.ShipTN.OrderType.DetachNonGeoSurvey); + if (CalcGeoSurveyPoints() != 0.0f) + legalOrders.Add(Constants.ShipTN.OrderType.DetachNonGeoSurvey); /// /// Grav survey specific orders: /// - //if (hasGrav) - // legalOrders.Add(Constants.ShipTN.OrderType.DetachNonGravSurvey); + if (CalcGravSurveyPoints() != 0.0f) + legalOrders.Add(Constants.ShipTN.OrderType.DetachNonGravSurvey); /// @@ -3300,7 +3300,6 @@ public int CalcTaskGroupLoadTime(Constants.ShipTN.LoadType Type) #endregion - #region Fire Control targetting /// /// Clear all targeting info for this taskgroup @@ -3362,7 +3361,6 @@ public ShipTN getNewTarget() } #endregion - #region Jump Transit taskgroup functions. /// /// This function counts the number of ships of each type in a taskgroup. Yes this can be hardcoded for efficiency on taskgroup formation, but then @@ -3494,6 +3492,37 @@ public bool IsJumpSick() } #endregion + #region Survey Point Count + /// + /// How many Geo Survey points can this Taskgroup generate? + /// + /// + public float CalcGeoSurveyPoints() + { + float TotalGeoSurveyPoints = 0.0f; + foreach (ShipTN Ship in Ships) + { + TotalGeoSurveyPoints = TotalGeoSurveyPoints + Ship.CurrentGeoSurveyStrength; + } + + return TotalGeoSurveyPoints; + } + /// + /// How many Geo Survey points can this Taskgroup generate? + /// + /// + public float CalcGravSurveyPoints() + { + float TotalGravSurveyPoints = 0.0f; + foreach (ShipTN Ship in Ships) + { + TotalGravSurveyPoints = TotalGravSurveyPoints + Ship.CurrentGravSurveyStrength; + } + + return TotalGravSurveyPoints; + } + #endregion + } /// /// End TaskGroupTN diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/ClassDesign.cs b/Pulsar4X/Pulsar4X.UI/Handlers/ClassDesign.cs index f627e1d20..d64d5dc82 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/ClassDesign.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/ClassDesign.cs @@ -433,6 +433,9 @@ private void ObsoleteCompButton_Click(object sender, EventArgs e) case ComponentTypeTN.JumpEngine: List.JumpEngineDef[CIndex].isObsolete = true; break; + case ComponentTypeTN.SurveySensor: + List.SurveySensorDef[CIndex].isObsolete = true; + break; } #endregion @@ -521,6 +524,9 @@ private void ObsoleteCompButton_Click(object sender, EventArgs e) case ComponentTypeTN.JumpEngine: List.JumpEngineDef[CIndex].isObsolete = false; break; + case ComponentTypeTN.SurveySensor: + List.SurveySensorDef[CIndex].isObsolete = false; + break; } #endregion } @@ -1284,8 +1290,7 @@ private void BuildOptionsPanel() /// /// Builds the design tab. Really wishing I'd done these as a dictionary originally. - /// Not implemented: ECCM, ECM,Cloak, Jump Engines, Maintenance Storage Bays,Hangar,Boat Bay,Troop Bay,Drop Pod,Orbital Hab,Rec Facilities, - /// Geo Sensors,Grav Sensors, + /// Not implemented: ECCM, ECM,Cloak, Jump Engines, Maintenance Storage Bays,Hangar,Boat Bay,Troop Bay,Drop Pod,Orbital Hab,Rec Facilities. /// private void BuildDesignTab() { @@ -1422,7 +1427,7 @@ private void BuildDesignTab() m_oOptionsPanel.ComponentsListBox.Items.Add(Entry); } - if (CurrentShipClass.ShipASensorDef.Count != 0 || CurrentShipClass.ShipPSensorDef.Count != 0) + if (CurrentShipClass.ShipASensorDef.Count != 0 || CurrentShipClass.ShipPSensorDef.Count != 0 || CurrentShipClass.ShipSurveyDef.Count != 0) { Entry = "Sensors:"; m_oOptionsPanel.ComponentsListBox.Items.Add(Entry); @@ -1439,6 +1444,12 @@ private void BuildDesignTab() m_oOptionsPanel.ComponentsListBox.Items.Add(Entry); } + for (int loop = 0; loop < CurrentShipClass.ShipSurveyDef.Count; loop++) + { + Entry = String.Format("{0}x {1}", CurrentShipClass.ShipSurveyCount[loop], CurrentShipClass.ShipSurveyDef[loop].Name); + m_oOptionsPanel.ComponentsListBox.Items.Add(Entry); + } + Entry = ""; m_oOptionsPanel.ComponentsListBox.Items.Add(Entry); } @@ -1712,7 +1723,7 @@ private void GetListBoxComponent(out int CType, out Guid CIndex) CurrentLine++; } - if (CurrentShipClass.ShipASensorDef.Count != 0 || CurrentShipClass.ShipPSensorDef.Count != 0) + if (CurrentShipClass.ShipASensorDef.Count != 0 || CurrentShipClass.ShipPSensorDef.Count != 0 || CurrentShipClass.ShipSurveyDef.Count != 0) { if (CurrentLine == m_oOptionsPanel.ComponentsListBox.SelectedIndex) { @@ -1742,6 +1753,17 @@ private void GetListBoxComponent(out int CType, out Guid CIndex) CurrentLine++; } + for (int loop = 0; loop < CurrentShipClass.ShipSurveyDef.Count; loop++) + { + if (CurrentLine == m_oOptionsPanel.ComponentsListBox.SelectedIndex) + { + CType = (int)CurrentShipClass.ShipSurveyDef[loop].componentType; + CIndex = CurrentShipClass.ShipSurveyDef[loop].Id; + return; + } + CurrentLine++; + } + if (CurrentLine == m_oOptionsPanel.ComponentsListBox.SelectedIndex) { return; @@ -2290,7 +2312,7 @@ private void BuildComponentDataGrid() } #endregion - #region Passive Sensors (Geo/Grav not yet implemented) + #region Passive Sensors using (DataGridViewRow NewRow = new DataGridViewRow()) { /// @@ -2316,6 +2338,12 @@ private void BuildComponentDataGrid() PopulateComponentRow(List.PassiveSensorDef[ComponentIterator], row, "Sensor Strength", List.PassiveSensorDef[ComponentIterator].rating.ToString(), ComponentIterator); row++; } + + for (int ComponentIterator = 0; ComponentIterator < List.SurveySensorDef.Count; ComponentIterator++) + { + PopulateComponentRow(List.SurveySensorDef[ComponentIterator], row, "Survey Points", ((int)Math.Floor(List.SurveySensorDef[ComponentIterator].sensorStrength)).ToString(), ComponentIterator); + row++; + } #endregion #region Shields / Electronic Warfare (Cloak not implemented,ecm/eccm not implemented, absorption shield not implemented) @@ -3064,7 +3092,7 @@ private void BuildComponentDataGrid() #region Passives /// - /// An engine was added to the component list. + /// A passive sensor was added to the component list. /// if (CompLocation[(int)ComponentGroup.Shields] != (List.PassiveSensorDef.Count + CompLocation[(int)ComponentGroup.Passives] + 1)) { @@ -3098,6 +3126,41 @@ private void BuildComponentDataGrid() PopulateComponentRow(List.PassiveSensorDef[ComponentIterator], rowLine, "Sensor Strength", List.PassiveSensorDef[ComponentIterator].rating.ToString(), ComponentIterator, true); rowLine++; } + + /// + /// Survey Sensor Section + /// + int PSEnd = rowLine; + int SSCount = 0; + + /// + /// Count the rows that are already filled with component type "SurveySensor". I am not exactly sure which index it is. + /// + while ((string)m_oOptionsPanel.ComponentDataGrid.Rows[rowLine].Cells[(int)ComponentCell.CType].Value == ((int)ComponentTypeTN.SurveySensor).ToString()) + { + rowLine++; + } + + SSCount = rowLine - PSEnd; + + AddedRows = List.SurveySensorDef.Count - SSCount; + + /// + /// Increment all the component locations past the current one(Engine) by added rows count. + /// + for (int loop = (int)ComponentGroup.Shields; loop <= (int)ComponentGroup.TypeCount; loop++) + { + CompLocation[loop] = CompLocation[loop] + AddedRows; + } + + /// + /// insert and fill in the rows where appropriate. + /// + for (int ComponentIterator = SSCount; ComponentIterator <= (List.SurveySensorDef.Count - 1); ComponentIterator++) + { + PopulateComponentRow(List.SurveySensorDef[ComponentIterator], rowLine, "Survey Points", List.SurveySensorDef[ComponentIterator].sensorStrength.ToString(), ComponentIterator, true); + rowLine++; + } } #endregion @@ -3767,6 +3830,26 @@ private void AddComponent(int CType, int CIndex, int CompAmt) else CurrentShipClass.AddJumpEngine(List.JumpEngineDef[CIndex], (short)CompAmt); break; + case ComponentTypeTN.SurveySensor: + if (CompAmt <= -1) + { + int Index = CurrentShipClass.ShipSurveyDef.IndexOf(List.SurveySensorDef[CIndex]); + + if (Index != -1) + { + int Cabs = CompAmt * -1; + + if (Cabs > CurrentShipClass.ShipSurveyCount[Index]) + { + CompAmt = CurrentShipClass.ShipSurveyCount[Index] * -1; + } + + CurrentShipClass.AddSurveySensor(List.SurveySensorDef[CIndex], (short)CompAmt); + } + } + else + CurrentShipClass.AddSurveySensor(List.SurveySensorDef[CIndex], (short)CompAmt); + break; } #endregion @@ -4001,6 +4084,16 @@ private void FindAddListBoxComponent(int CT, Guid CID, int CAmt) } } break; + case ComponentTypeTN.SurveySensor: + for (int loop = 0; loop < List.SurveySensorDef.Count; loop++) + { + if (List.SurveySensorDef[loop].Id == CID) + { + AddComponent(CT, loop, CAmt); + break; + } + } + break; } #endregion } diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index d15db3f00..ed46fbcfb 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -3226,6 +3226,42 @@ private void RefreshIndustryTab() } } + foreach (SurveySensorDefTN Survey in CurrentFaction.ComponentList.SurveySensorDef) + { + if (Survey.isObsolete == false) + { + if (row < BuildTabMaxRows) + { + BuildListObject Temp = new BuildListObject(BuildListObject.ListEntityType.Component, Survey); + BuildLocationDisplayDict.Add(Survey.Id, Survey.Name); + BuildLocationDict.Add(Survey.Id, Temp); + + m_oSummaryPanel.BuildDataGrid.Rows[row].Visible = true; + m_oSummaryPanel.BuildDataGrid.Rows[row].Cells[0].Value = Survey.Name; + row++; + } + else + { + using (DataGridViewRow Row = new DataGridViewRow()) + { + // setup row height. note that by default they are 22 pixels in height! + Row.Height = 17; + m_oSummaryPanel.BuildDataGrid.Rows.Add(Row); + }// make new rows and add items. + + BuildListObject Temp = new BuildListObject(BuildListObject.ListEntityType.Component, Survey); + BuildLocationDisplayDict.Add(Survey.Id, Survey.Name); + BuildLocationDict.Add(Survey.Id, Temp); + + m_oSummaryPanel.BuildDataGrid.Rows[row].Visible = true; + m_oSummaryPanel.BuildDataGrid.Rows[row].Cells[0].Value = Survey.Name; + row++; + BuildTabMaxRows++; + } + } + + } + foreach (ActiveSensorDefTN Active in CurrentFaction.ComponentList.ActiveSensorDef) { if (Active.isObsolete == false) From 7641000748a1441f5e08db6b997f291b2d02c1ea Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 2 Aug 2015 00:36:25 -0500 Subject: [PATCH 03/40] Planetary mineral generation work Hopefully this should be roughly what I want from mineral generation, tweaking will be required though. --- Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs | 4 - Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs | 8 + .../Entities/StarSystem/SystemBody.cs | 152 +++++++++++++++++- 3 files changed, 159 insertions(+), 5 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs index d1fa8c11b..ad837a11d 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs @@ -2413,14 +2413,10 @@ public void RepairComponent(ComponentTypeTN Type, int ComponentIndex) if (sDef.sensorType == SurveySensorDefTN.SurveySensorType.Geological) { CurrentGeoSurveyStrength = CurrentGeoSurveyStrength + sDef.sensorStrength; - if (CurrentGeoSurveyStrength < 0) - CurrentGeoSurveyStrength = 0; } else if (sDef.sensorType == SurveySensorDefTN.SurveySensorType.Gravitational) { CurrentGravSurveyStrength = CurrentGravSurveyStrength + sDef.sensorStrength; - if (CurrentGravSurveyStrength < 0) - CurrentGravSurveyStrength = 0; } break; } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs b/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs index bd7aabf43..6f1728676 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs @@ -3126,6 +3126,14 @@ public void BuildClassSummary() control = true; } + for (int loop = 0; loop < ShipSurveyDef.Count; loop++) + { + Entry = String.Format("{0} ({1}) {2:N0} Survey Points Per Hour\n", ShipSurveyDef[loop].Name, ShipSurveyCount[loop], ShipSurveyDef[loop].sensorStrength); + Summary = String.Format("{0}{1}", Summary, Entry); + + control = true; + } + if (control == true) { Entry = "\n"; diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs index addeeb0d4..beefc8394 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs @@ -42,6 +42,18 @@ public enum TectonicActivity NA } + public enum MineralType + { + NoMinerals, //Nothing. + Asteroid, //500-10k of each mineral, above 1.0 accessibility? 1-5 minerals + Comet, //10-100k 6-10 minerals high accessibility. + FewGood, //Rich world with few but decent quality mineral reserves. 500k-4M range, 2-4 minerals. + ManyGood, //Rich world with many high quality mineral deposits, but not truly massive deposits 500k-4M range 4-8 minerals + MassiveReserves, //Gargantuan amount of resources, low accessibility. 10-150M 8-11 minerals. + Homeworld, //50k-150k of every resource in good amounts. Everything a starting faction will need. + Count, + } + public PlanetType Type { get; set; } /// @@ -210,7 +222,7 @@ public SystemBody(OrbitingEntity parent, PlanetType type) legalOrders.AddRange(_legalOrders); if (this.GeoSurveyList.ContainsKey(faction) == true) { - if (this.GeoSurveyList[faction] == false) + if (this.GeoSurveyList[faction] == false || this.GeoSurveyList.ContainsKey(faction) == false) legalOrders.Add(Constants.ShipTN.OrderType.GeoSurvey); } return legalOrders; @@ -267,6 +279,7 @@ public void UpdatePosition(int tickValue) /// This generates the rich assortment of all minerals for a homeworld. non-hw planets have less, or even no resources. /// should some resources be scarcer than others? /// +#warning More of a bellcurve distribution of minerals would be better, with the lowest and highest results relatively rare. Accessibility, and even mineral type should be the same. public void HomeworldMineralGeneration() { m_aiMinerialReserves[0] = 150000.0f + (100000.0f * ((float)GameState.RNG.Next(0, 100000) / 100000.0f)); @@ -277,6 +290,143 @@ public void HomeworldMineralGeneration() m_aiMinerialAccessibility[mineralIterator] = 1.0f * ((float)GameState.RNG.Next(2, 10) / 10.0f); } } + + /// + /// Asteroids have a small amount of a few types of minerals. but accessibility will be very high. + /// + public void AsteroidMineralGeneration() + { + int mCount = 1 + GameState.RNG.Next(4); + while (mCount != 0) + { + for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) + { + if (GameState.RNG.Next(10) == 1) + { + m_aiMinerialReserves[mineralIterator] = 500.0f + (9500.0f * ((float)GameState.RNG.Next(0, 100000) / 100000.0f)); + m_aiMinerialAccessibility[mineralIterator] = 1.0f * ((float)GameState.RNG.Next(8, 10) / 10.0f); + + mCount--; + } + } + } + } + + /// + /// Comets are fairly rich and have a good assortment of minerals + /// + public void CometMineralGeneration() + { + int mCount = 6 + GameState.RNG.Next(4); + while (mCount != 0) + { + for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) + { + if (GameState.RNG.Next(10) == 1) + { + m_aiMinerialReserves[mineralIterator] = 10000.0f + (90000.0f * ((float)GameState.RNG.Next(0, 100000) / 100000.0f)); + m_aiMinerialAccessibility[mineralIterator] = 1.0f * ((float)GameState.RNG.Next(4, 10) / 10.0f); + + mCount--; + } + } + } + } + + /// + /// Low Planet means that this world should have only a few deposits, though there should be a good amount of resources on them. + /// + public void LowPlanetMineralGeneration() + { + int mCount = 2 + GameState.RNG.Next(2); + while (mCount != 0) + { + for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) + { + if (GameState.RNG.Next(10) == 1) + { + m_aiMinerialReserves[mineralIterator] = 500000.0f + (3500000.0f * ((float)GameState.RNG.Next(0, 100000) / 100000.0f)); + m_aiMinerialAccessibility[mineralIterator] = 1.0f * ((float)GameState.RNG.Next(2, 10) / 10.0f); + + mCount--; + } + } + } + } + + /// + /// High planet indicates that this will be a fairly desirable mining spot. + /// + public void HighPlanetMineralGeneration() + { + int mCount = 4 + GameState.RNG.Next(4); + while (mCount != 0) + { + for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) + { + if (GameState.RNG.Next(10) == 1) + { + m_aiMinerialReserves[mineralIterator] = 500000.0f + (3500000.0f * ((float)GameState.RNG.Next(0, 100000) / 100000.0f)); + m_aiMinerialAccessibility[mineralIterator] = 1.0f * ((float)GameState.RNG.Next(2, 10) / 10.0f); + + mCount--; + } + } + } + } + + /// + /// Planets with truly stupendous amounts of resources, but at low accessibility. + /// + public void MassiveMineralGeneration() + { + int mCount = 8 + GameState.RNG.Next(3); + while (mCount != 0) + { + for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) + { + if (GameState.RNG.Next(10) == 1) + { + m_aiMinerialReserves[mineralIterator] = 10000000.0f + (140000000.0f * ((float)GameState.RNG.Next(0, 100000) / 100000.0f)); + m_aiMinerialAccessibility[mineralIterator] = 0.1f; + + mCount--; + } + } + } + } + + /// + /// determine what type of world this is with regards to mineral generation and generate those minerals. + /// + /// Type of mineral generation this world should get. + public void GenerateMinerals(SystemBody.MineralType MineralType) + { + switch (MineralType) + { + case SystemBody.MineralType.NoMinerals: + break; + case SystemBody.MineralType.Asteroid: + AsteroidMineralGeneration(); + break; + case SystemBody.MineralType.Comet: + CometMineralGeneration(); + break; + case SystemBody.MineralType.FewGood: + LowPlanetMineralGeneration(); + break; + case SystemBody.MineralType.ManyGood: + HighPlanetMineralGeneration(); + break; + case SystemBody.MineralType.MassiveReserves: + MassiveMineralGeneration(); + break; + case SystemBody.MineralType.Homeworld: + HomeworldMineralGeneration(); + break; + } + + } } #region Data Binding From cf51614979ef9ccf006742a8c747d35813adfdb2 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 8 Aug 2015 21:52:28 -0500 Subject: [PATCH 04/40] Geo Survey mechanics work Geo survey should work now, but has not yet been tested. the order itself now appears, mineral generation is being done now on planetary geo survey, and the survey costs have been worked out. --- Pulsar4X/Pulsar4X.Lib/Constants.cs | 10 +++ .../Entities/StarSystem/StarSystem.cs | 9 +++ .../Entities/StarSystem/SystemBody.cs | 50 ++++++++++++-- .../Entities/StarSystem/TaskGroup.cs | 65 +++++++++++++++++++ 4 files changed, 129 insertions(+), 5 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Constants.cs b/Pulsar4X/Pulsar4X.Lib/Constants.cs index ace6a9385..92330b9d9 100644 --- a/Pulsar4X/Pulsar4X.Lib/Constants.cs +++ b/Pulsar4X/Pulsar4X.Lib/Constants.cs @@ -733,6 +733,16 @@ public static class SensorTN /// What value are sensors calibrated around searching for? /// public const uint DefaultPassiveSignature = 1000; + + /// + /// Survey point requirement will be based on body radius relative to earth. + /// + public const float EarthRadius = (float)(6378.1 / Constants.Units.KmPerAu); + + /// + /// And relative to earth's point value from Aurora. + /// + public const uint EarthSurvey = 637; } /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs index 652f41b3a..a32242be4 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs @@ -177,5 +177,14 @@ public void Update(int deltaSeconds) } } } + + /// + /// The cost for Gravitational survey points as per Aurora is: square root ( System Primary's solar masses ) * 400 + /// + /// Number of survey points that must be generated to survey each gravitational survey point. + public int GetSurveyCost() + { + return (int)Math.Floor((float)Math.Sqrt(Stars[0].Orbit.MassRelativeToSol) * 400.0f); + } } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs index beefc8394..6f73f7739 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs @@ -44,6 +44,7 @@ public enum TectonicActivity public enum MineralType { + NotGenerated, NoMinerals, //Nothing. Asteroid, //500-10k of each mineral, above 1.0 accessibility? 1-5 minerals Comet, //10-100k 6-10 minerals high accessibility. @@ -174,6 +175,24 @@ public float[] MinerialAccessibility } } + /// + /// Has mineral generation been run for this world? + /// + private bool _MineralsGenerated; + public bool _mineralsGenerated + { + get { return _MineralsGenerated; } + } + + /// + /// What type of minerals should be generated for this world? + /// + private MineralType _BodyMineralType; + public MineralType _bodyMineralType + { + get { return _BodyMineralType; } + } + public SystemBody(OrbitingEntity parent, PlanetType type) : base() { @@ -207,6 +226,8 @@ public SystemBody(OrbitingEntity parent, PlanetType type) m_aiMinerialReserves[mineralIterator] = 0.0f; m_aiMinerialAccessibility[mineralIterator] = 0.0f; } + _MineralsGenerated = false; + _BodyMineralType = MineralType.NotGenerated; #warning planet generation needs minerals, anomalies, and ruins generation. PlanetaryRuins = new Ruins(); @@ -220,9 +241,13 @@ public SystemBody(OrbitingEntity parent, PlanetType type) { List legalOrders = new List(); legalOrders.AddRange(_legalOrders); - if (this.GeoSurveyList.ContainsKey(faction) == true) + if (this.GeoSurveyList.ContainsKey(faction) == false) { - if (this.GeoSurveyList[faction] == false || this.GeoSurveyList.ContainsKey(faction) == false) + legalOrders.Add(Constants.ShipTN.OrderType.GeoSurvey); + } + else if (this.GeoSurveyList.ContainsKey(faction) == true) + { + if (this.GeoSurveyList[faction] == false) legalOrders.Add(Constants.ShipTN.OrderType.GeoSurvey); } return legalOrders; @@ -399,10 +424,16 @@ public void MassiveMineralGeneration() /// /// determine what type of world this is with regards to mineral generation and generate those minerals. /// - /// Type of mineral generation this world should get. - public void GenerateMinerals(SystemBody.MineralType MineralType) + /// Should this world have homeworld mineral generation? + public void GenerateMinerals(bool isHomeWorld = false) { - switch (MineralType) + + MineralType MType = MineralType.Homeworld; + + if(isHomeWorld == false) + MType = (MineralType)GameState.RNG.Next((int)SystemBody.MineralType.NoMinerals, (int)SystemBody.MineralType.Homeworld); + + switch (MType) { case SystemBody.MineralType.NoMinerals: break; @@ -425,7 +456,16 @@ public void GenerateMinerals(SystemBody.MineralType MineralType) HomeworldMineralGeneration(); break; } + _MineralsGenerated = true; + } + /// + /// Survey cost for bodies is based on their radius relative to that of Earth. + /// + /// Cost in geopoints to survey this world. + public int GetSurveyCost() + { + return (int)Math.Floor((float)Constants.SensorTN.EarthSurvey * ((float)Radius / Constants.SensorTN.EarthRadius)); } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index 80d087a06..0f7b6c026 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -204,6 +204,21 @@ public class TaskGroupTN : StarSystemEntity /// public uint SensorUpdateAck { get; set; } + /// + /// How many GP has this taskgroup accumulated thus far? + /// + public int _GeoSurveyPoints { get; set; } + + /// + /// How many SP has this taskgroup accumulated from surveying gravitational survey points thus far? + /// + public int _GravSurveyPoints { get; set; } + + /// + /// GP and SP are incremented by the hour, so how long has it been since the last hour? + /// + public float _SurveyHourFraction { get; set; } + /// /// Constructor for the taskgroup, sets name, faction, planet the TG starts in orbit of. /// @@ -309,6 +324,10 @@ public TaskGroupTN(string Title, Faction FID, OrbitingEntity StartingBody, StarS SensorUpdateAck = 0; + _GeoSurveyPoints = 0; + _GravSurveyPoints = 0; + _SurveyHourFraction = 0.0f; + //add default legal order for targeting TGs. _legalOrders.Add(Constants.ShipTN.OrderType.Follow); _legalOrders.Add(Constants.ShipTN.OrderType.Join); @@ -450,12 +469,18 @@ public TaskGroupTN(string Title, Faction FID, OrbitingEntity StartingBody, StarS /// GeoSurvey specific orders: /// if (CalcGeoSurveyPoints() != 0.0f) + { + legalOrders.Add(Constants.ShipTN.OrderType.GeoSurvey); legalOrders.Add(Constants.ShipTN.OrderType.DetachNonGeoSurvey); + } /// /// Grav survey specific orders: /// if (CalcGravSurveyPoints() != 0.0f) + { + legalOrders.Add(Constants.ShipTN.OrderType.GravSurvey); legalOrders.Add(Constants.ShipTN.OrderType.DetachNonGravSurvey); + } /// @@ -2850,6 +2875,46 @@ public uint PerformOrders(uint TimeSlice) break; #endregion + #region GeoSurvey + case (int)Constants.ShipTN.OrderType.GeoSurvey: + SystemBody OB = OrbitingBody as SystemBody; + int BodySurveyCost = OB.GetSurveyCost(); + + float hourFract = (float)TimeSlice / (float)Constants.TimeInSeconds.Hour; + int hours = (int)Math.Floor(hourFract); + int RemainderGP = BodySurveyCost - _GeoSurveyPoints; + int TotalGP = (int)(CalcGeoSurveyPoints() * (float)hours); + if (TotalGP < RemainderGP) + { + _GeoSurveyPoints = _GeoSurveyPoints + TotalGP; + TimeSlice = 0; + } + else + { + /// + /// Some time will be left over, return that fraction of time. + /// + int hoursToComplete = (int)Math.Ceiling((float)RemainderGP / CalcGeoSurveyPoints()); + TimeSlice = TimeSlice - ((uint)hoursToComplete * Constants.TimeInSeconds.Hour); + } + + + if (_GeoSurveyPoints >= BodySurveyCost) + { + if (OB.GeoSurveyList.ContainsKey(TaskGroupFaction) == false) + { + OB.GeoSurveyList.Add(TaskGroupFaction, true); + if(OB._mineralsGenerated == false) + OB.GenerateMinerals(); + } + //handle adding the faction to the survey list when complete + //generate minerals? + _GeoSurveyPoints = 0; + } + + break; + #endregion + } From 1f1619d72d09132ccb888471da0eff23487b78ba Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 15 Aug 2015 23:36:15 -0500 Subject: [PATCH 05/40] Survey point class This also contains the determination for where the survey point rings are going to be located, and comments on what the angles for each survey point should be. --- Pulsar4X/Pulsar4X.Lib/Constants.cs | 5 ++ .../Entities/StarSystem/StarSystemEntity.cs | 1 + .../Entities/StarSystem/SurveyPoint.cs | 72 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SurveyPoint.cs diff --git a/Pulsar4X/Pulsar4X.Lib/Constants.cs b/Pulsar4X/Pulsar4X.Lib/Constants.cs index 92330b9d9..9832faa11 100644 --- a/Pulsar4X/Pulsar4X.Lib/Constants.cs +++ b/Pulsar4X/Pulsar4X.Lib/Constants.cs @@ -743,6 +743,11 @@ public static class SensorTN /// And relative to earth's point value from Aurora. /// public const uint EarthSurvey = 637; + + /// + /// Each survey ring is 2B km out for every 1.0 unit of solar mass present. solar mass is sqrted for this calculation as per survey cost and then multiplied by this value. units in AU. + /// + public const double EarthRingDistance = 13.36917422; } /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystemEntity.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystemEntity.cs index 8ae29ca8f..e149491a6 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystemEntity.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystemEntity.cs @@ -14,6 +14,7 @@ public enum StarSystemEntityType TaskGroup, Population, Missile, + SurveyPoint, TypeCount } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SurveyPoint.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SurveyPoint.cs new file mode 100644 index 000000000..e3b5bbef2 --- /dev/null +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SurveyPoint.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Collections.ObjectModel; +using System.ComponentModel; +using Newtonsoft.Json; + +#if LOG4NET_ENABLED +using log4net; +#endif + +namespace Pulsar4X.Entities +{ + public class SurveyPoint : StarSystemEntity + { + /// + /// List of factions that have surveyed this point. + /// + private BindingList _GravSurveyList; + public BindingList _gravSurveyList + { + get { return _GravSurveyList; } + } + + /// + /// List of jump points in this survey points survey area, and will be revealed when this survey point is surveyed. by a surveyor. + /// + private BindingList _JPList; + public BindingList _jPList + { + get { return _JPList; } + } + + /// + /// Constructor for survey points. Survey points will occur in three rings around a system primary for primary only JPs. As with survey cost, the mass of the solar system will be + /// square rooted, and then multiplied to a constant value to determine the distance of the point from the primary. the angle offset will be determined from the logic for + /// making circles. Ring one is 0,60,120,180,240,300. Ring two is 15,45,75,105,135,165,195,225,255,285,315,345. Ring three is 0,30,60,90,120,150,180,210,240,270,300,330. + /// secondary JP surveying is yet to be worked out. + /// + /// System this point is in + /// X Position in AU of this survey point from the system primary(0.0,0.0) + /// Y Position in AU of this survey point from the system primary + public SurveyPoint(StarSystem SystemOfPoint, double xPosition, double yPosition) + { + Position.System = SystemOfPoint; + Position.X = xPosition; + Position.Y = yPosition; + + _GravSurveyList = new BindingList(); + _JPList = new BindingList(); + } + + /// + /// What legal orders will be associated with this star system entity? in the code that determines available orders the order in question, in this case Grav Survey, must be present here + /// and in the taskgroup's orders list in order for it to be a valid order. Here it is present by default, assuming the point is unsurveyed, the taskgroup will only have the order if it has a + /// grav survey sensor. + /// + /// + /// + public override List LegalOrders(Faction faction) + { + List legalOrders = new List(); + legalOrders.AddRange(_legalOrders); + if (this._GravSurveyList.Contains(faction) == false) + { + legalOrders.Add(Constants.ShipTN.OrderType.GravSurvey); + } + return legalOrders; + } + } +} From 1295e0f29f2d99e4e861c1a9512e964ab582708f Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 23 Aug 2015 03:08:21 -0500 Subject: [PATCH 06/40] Survey point logic added Survey points can be generated for stars, and it should be possible to determine which survey point a jumppoint would be within the area of. This is not quite ready yet however. Also some short circuits were put into the construction cycle. --- .../Entities/ConstructionCycle.cs | 9 + .../Entities/StarSystem/StarSystem.cs | 158 ++++++++++++++++++ 2 files changed, 167 insertions(+) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs b/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs index 69605a626..9563619bd 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs @@ -61,6 +61,9 @@ public static void ConstructionFactoryBuild(Faction CurrentFaction, Population C float CurrentIndustry = CurrentPopulation.CalcTotalIndustry() * Constants.Colony.ConstructionCycleFraction; float BuildPercentage = 0.0f; + if (CurrentIndustry == 0.0f) + return; + foreach (ConstructionBuildQueueItem CurrentConstruction in CurrentPopulation.ConstructionBuildQueue) { /// @@ -268,6 +271,9 @@ public static void OrdnanceFactoryBuild(Faction CurrentFaction, Population Curre float CurrentIndustry = CurrentPopulation.CalcTotalOrdnanceIndustry() * Constants.Colony.ConstructionCycleFraction; float BuildPercentage = 0.0f; + if (CurrentIndustry == 0.0f) + return; + foreach (MissileBuildQueueItem CurrentConstruction in CurrentPopulation.MissileBuildQueue) { /// @@ -458,6 +464,9 @@ public static void ProcessShipyards(Faction CurrentFaction, Population CurrentPo int CY = (int)Math.Floor(CurrentPopulation.Installations[(int)Installation.InstallationType.CommercialShipyard].Number); int NY = (int)Math.Floor(CurrentPopulation.Installations[(int)Installation.InstallationType.NavalShipyardComplex].Number); + if (CY == 0 && NY == 0) + return; + List SortedList = CurrentPopulation.ShipyardTasks.Keys.ToList().OrderBy(o => o.Priority).ToList(); BuildShips(CurrentFaction, CurrentPopulation, SortedList); diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs index a32242be4..cd164c571 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs @@ -63,6 +63,14 @@ public class StarSystem : GameEntity private int m_seed; public int Seed { get { return m_seed; } } + + /// + /// Each starsystem will have 30 suvery points under TN rules. + /// Also, I'll need to track which faction has surveyed which point. I could do this at the survey point level, but I think it better to have a starsystem list of factions + /// that have completely surveyed this starsystem, along with a way of handling incomplete surveys. + /// + public BindingList _SurveyPoints { get; set; } + public StarSystem(string name, int seed) : base() { @@ -78,6 +86,8 @@ public StarSystem(string name, int seed) Populations = new BindingList(); OrdnanceGroups = new BindingList(); + _SurveyPoints = new BindingList(); + m_seed = seed; // Subscribe to change events. @@ -186,5 +196,153 @@ public int GetSurveyCost() { return (int)Math.Floor((float)Math.Sqrt(Stars[0].Orbit.MassRelativeToSol) * 400.0f); } + + + /// + /// This should be done after mass has been assigned to Stars[0]. The pattern here is the one in use in TN Aurora. + /// + public void GenerateSurveyPoints() + { + double RingValue = Math.Sqrt(Stars[0].Orbit.MassRelativeToSol) * Constants.SensorTN.EarthRingDistance; + + /// + /// Ring one is 0,60,120,180,240,300. + /// + for (int surveyPointIterator = 0; surveyPointIterator < 360; surveyPointIterator += 60) + { + double dAngle = surveyPointIterator * ((Math.PI) / 180.0); //this would be 2 * PI / 360 + double fX = Math.Cos(dAngle) * RingValue; + double fY = Math.Sin(dAngle) * RingValue; + + SurveyPoint SP = new SurveyPoint(this, fX, fY); + _SurveyPoints.Add(SP); + } + + /// + /// Ring two is 15,45,75,105,135,165,195,225,255,285,315,345. + /// + for (int surveyPointIterator = 15; surveyPointIterator < 360; surveyPointIterator += 30) + { + double dAngle = surveyPointIterator * ((Math.PI) / 180.0); //this would be 2 * PI / 360 + double fX = Math.Cos(dAngle) * (RingValue * 2); + double fY = Math.Sin(dAngle) * (RingValue * 2); + + SurveyPoint SP = new SurveyPoint(this, fX, fY); + _SurveyPoints.Add(SP); + } + + /// + /// Ring three is 0,30,60,90,120,150,180,210,240,270,300,330. + /// + for (int surveyPointIterator = 0; surveyPointIterator < 360; surveyPointIterator += 30) + { + double dAngle = surveyPointIterator * ((Math.PI) / 180.0); //this would be 2 * PI / 360 + double fX = Math.Cos(dAngle) * (RingValue * 32); + double fY = Math.Sin(dAngle) * (RingValue * 3); + + SurveyPoint SP = new SurveyPoint(this, fX, fY); + _SurveyPoints.Add(SP); + } + } + + + /// + /// Which survey point will X,Y be within the area of? Between 0 to RingValue is ring one, RingValue to 2 * RingValue is ring 2, and 3 * RingValue is ring 3. + /// + /// X position + /// Y Position + /// Survey Point Index. -1 means that no survey point should correspond to this location. 0-29 mean 1 through 30 in display terms. index is 0 through 29 however. + public int GetSurveyPointArea(double X, double Y) + { + double RingValue = Math.Sqrt(Stars[0].Orbit.MassRelativeToSol) * Constants.SensorTN.EarthRingDistance; + double distanceFromPrimary = Math.Sqrt(((X * X) + (Y * Y))); + double Angle = (Math.Atan((X / Y)) / Constants.Units.Radian); + + int SurveyIndex = -1; + + if (distanceFromPrimary < (3 * RingValue)) + { + /// + /// Ring 3 contains survey indices 19 through 30, but these are addressed starting from zero. + /// + SurveyIndex = 29; + for (int surveyPointIterator = 330; surveyPointIterator >= 0; surveyPointIterator -= 30) + { + if (surveyPointIterator != 0) + { + int highAngle = surveyPointIterator + 15; + int lowAngle = surveyPointIterator - 15; + if (Angle <= highAngle && Angle >= lowAngle) + { + break; + } + else + { + SurveyIndex--; + } + } + else + { + /// + /// Point zero is a special case here, though this calculation should be unnecessary. + /// + if (Angle >= 345.0 || Angle <= 15.0) + { + break; + } + else + { + /// + /// This is an error condition. The entire circle has been progressed through and we didn't get a match between our angle and survey index. + /// + SurveyIndex = -1; + } + } + } + } + else if (distanceFromPrimary < (2 * RingValue)) + { + /// + /// Ring 2 contains survey indices 7 through 18. + /// + SurveyIndex = 17; + for (int surveyPointIterator = 345; surveyPointIterator >= 15; surveyPointIterator -= 30) + { + int highAngle = surveyPointIterator + 15; + int lowAngle = surveyPointIterator - 15; + if (Angle <= highAngle && Angle >= lowAngle) + { + break; + } + else + { + SurveyIndex--; + } + } + } + else if(distanceFromPrimary < RingValue) + { + /// + /// Ring 1 contains survey indices 1 through 6, again, subtract 1 to address from the survey point List which starts at index 0. + /// because there are fewer points, each point covers more total area, 60 degrees here instead of 30. + /// + SurveyIndex = 5; + for (int surveyPointIterator = 300; surveyPointIterator >= 0; surveyPointIterator -= 60) + { + int highAngle = surveyPointIterator + 30; + int lowAngle = surveyPointIterator - 30; + if (Angle <= highAngle && Angle >= lowAngle) + { + break; + } + else + { + SurveyIndex--; + } + } + } + + return SurveyIndex; + } } } From 2360ebed7a38937c3d6498ee4196690fdddb85e2 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 23 Aug 2015 03:09:42 -0500 Subject: [PATCH 07/40] typo in survey point work. 3 instead of 32. --- Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs index cd164c571..d007f7ba7 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs @@ -237,7 +237,7 @@ public void GenerateSurveyPoints() for (int surveyPointIterator = 0; surveyPointIterator < 360; surveyPointIterator += 30) { double dAngle = surveyPointIterator * ((Math.PI) / 180.0); //this would be 2 * PI / 360 - double fX = Math.Cos(dAngle) * (RingValue * 32); + double fX = Math.Cos(dAngle) * (RingValue * 3); double fY = Math.Sin(dAngle) * (RingValue * 3); SurveyPoint SP = new SurveyPoint(this, fX, fY); From 5b82bb92323ecf36562dc2f6a6b680bb3d988653 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 30 Aug 2015 00:52:51 -0500 Subject: [PATCH 08/40] Survey Point Generation and Display Survey points are displayed as white circles now. Zoom level will need work, and some provision for updating them to be filled in circles will have to be made later. --- .../Entities/StarSystem/StarSystem.cs | 5 ++- .../Entities/StarSystem/SurveyPoint.cs | 11 +++++- Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs | 2 + Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs | 38 +++++++++++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs index d007f7ba7..7d8bfadea 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs @@ -199,7 +199,8 @@ public int GetSurveyCost() /// - /// This should be done after mass has been assigned to Stars[0]. The pattern here is the one in use in TN Aurora. + /// This should be done after mass has been assigned to Stars[0]. The pattern here is the one in use in TN Aurora. I am using angle from top, for my numbers, but + /// that is 90 degrees internally. /// public void GenerateSurveyPoints() { @@ -208,7 +209,7 @@ public void GenerateSurveyPoints() /// /// Ring one is 0,60,120,180,240,300. /// - for (int surveyPointIterator = 0; surveyPointIterator < 360; surveyPointIterator += 60) + for (int surveyPointIterator = 30; surveyPointIterator < 360; surveyPointIterator += 60) { double dAngle = surveyPointIterator * ((Math.PI) / 180.0); //this would be 2 * PI / 360 double fX = Math.Cos(dAngle) * RingValue; diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SurveyPoint.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SurveyPoint.cs index e3b5bbef2..e812b2e3d 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SurveyPoint.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SurveyPoint.cs @@ -12,7 +12,7 @@ namespace Pulsar4X.Entities { - public class SurveyPoint : StarSystemEntity + public class SurveyPoint : OrbitingEntity { /// /// List of factions that have surveyed this point. @@ -47,6 +47,15 @@ public SurveyPoint(StarSystem SystemOfPoint, double xPosition, double yPosition) Position.X = xPosition; Position.Y = yPosition; + SSEntity = StarSystemEntityType.SurveyPoint; + + /// + /// Unused Orbiting Entity data here. + /// + Parent = SystemOfPoint.Stars[0]; + SupportsPopulations = false; + Radius = 0.0; + _GravSurveyList = new BindingList(); _JPList = new BindingList(); } diff --git a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs index 19b055fef..9e84a00f5 100644 --- a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs +++ b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs @@ -198,6 +198,7 @@ public static StarSystem CreateSol() Sun.Class = "G2"; SetHabitableZone(Sun); Sol.Stars.Add(Sun); + Sol.GenerateSurveyPoints(); //must be done after the construction of orbit,and after stars[0] is created as that is where the mass value in use is created. SystemBody Mercury = new SystemBody(Sun, SystemBody.PlanetType.Terrestrial); Mercury.Name = "Mercury"; @@ -737,6 +738,7 @@ private static Star GenerateStar(StarSystem system) Star star = PopulateStarDataBasedOnSpectralType(st, starName, system); system.Stars.Add(star); + system.GenerateSurveyPoints(); //must happen after mass is created. PopulateStarData sets the mass value among other things up properly. return star; } diff --git a/Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs b/Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs index 776787950..363087678 100644 --- a/Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs +++ b/Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs @@ -359,6 +359,13 @@ public Sceen(StarSystem a_oStarSystem, GLEffect a_oDefaultEffect, Pulsar4X.UI.Ha CreateJumpPoint(oCurrStar, oJumpPoint); } + int SPIndex = 1; + foreach (Pulsar4X.Entities.SurveyPoint oSurveyPoint in a_oStarSystem._SurveyPoints) + { + CreateSurveyPoint(oCurrStar, oSurveyPoint, a_oDefaultEffect, SPIndex); + SPIndex++; + } + iStarCounter++; } @@ -430,6 +437,37 @@ private void CreateJumpPoint(SceenElement parent, JumpPoint oJumpPoint) parent.AddChildElement(oJumpPointElement); } + /// + /// Create a survey element by making a default circle element, then creating the GLCircle, and then adding this to the parent element list. + /// + /// + /// + /// + /// + private void CreateSurveyPoint(SceenElement parent, SurveyPoint oSurveyPoint, GLEffect a_oDefaultEffect, int SPIndex) + { + Vector3 v3SPPos = new Vector3((float)oSurveyPoint.Position.X, (float)oSurveyPoint.Position.Y, 0.0f); + + SceenElement oSurveyPointElement = new CircleElement(); + oSurveyPointElement.EntityID = oSurveyPoint.Id; + + GLCircle oSPCircle = new GLCircle(a_oDefaultEffect, + v3SPPos, + 0.1f, + Color.White, + UIConstants.Textures.DEFAULT_TEXTURE); + + + GLUtilities.GLFont oNameLable = new GLUtilities.GLFont(SceenDefaultEffect, v3SPPos, + UIConstants.DEFAULT_TEXT_SIZE, Color.White, UIConstants.Textures.DEFAULT_GLFONT2, SPIndex.ToString()); + + oSurveyPointElement.Lable = oNameLable; + oSurveyPointElement.RealSize = new Vector2(0.0001f, 0.0001f); + oSurveyPointElement.PrimaryPrimitive = oSPCircle; + oSurveyPointElement.AddPrimitive(oSPCircle); + parent.AddChildElement(oSurveyPointElement); + } + /// /// Render the Sceen. /// From d6d6c214bd2274bb96973700e33b555207134d01 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 5 Sep 2015 23:35:08 -0500 Subject: [PATCH 09/40] Survey displayfix and addition to TG locations survey points are now displayed properly on all zoom levels, and can be added as a location for a taskgroup to target. The actual survey mechanics are not yet implemented, and will require storage within a starsystem of the results. I'll want to have a bool for a totally completed survey of a starsystem, as well as some way to store partial results since it will be unlikely for any player to leave a starsystem in an incompletely surveyed state, and thus having to constantly iterate through 30 points to determine if a system is fully surveyed will be unnecessary most of the time. --- .../Entities/StarSystem/TaskGroup.cs | 10 ++++ Pulsar4X/Pulsar4X.UI/GLUtilities/GLCircle.cs | 10 ++++ Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs | 55 +++++++++---------- .../Panels/TaskGroup_Panel.Designer.cs | 11 ++++ .../Pulsar4X.UI/SceenGraph/CircleElement.cs | 28 +++++++++- Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs | 8 ++- 6 files changed, 89 insertions(+), 33 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index 0f7b6c026..96f1e0ff2 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -2914,6 +2914,16 @@ public uint PerformOrders(uint TimeSlice) break; #endregion +#warning implement GravSurvey + #region GravSurvey to be implemented + case (int)Constants.ShipTN.OrderType.GravSurvey: + /// + /// Figure out how to store survey results with a star. I think that Partial for each point, and then a full system wide 0% or 100% bool will work. + /// get the cost to survey this system, see above geo survey costs. + /// reveal detected jumppoints. how will this work? also jumppoint generation needs to be looked at. + /// + break; + #endregion diff --git a/Pulsar4X/Pulsar4X.UI/GLUtilities/GLCircle.cs b/Pulsar4X/Pulsar4X.UI/GLUtilities/GLCircle.cs index c15f94fa5..3fda2df5a 100644 --- a/Pulsar4X/Pulsar4X.UI/GLUtilities/GLCircle.cs +++ b/Pulsar4X/Pulsar4X.UI/GLUtilities/GLCircle.cs @@ -264,5 +264,15 @@ public override void Render() GL.DrawElements(PrimitiveType.LineStrip, m_auiIndicies.Length, DrawElementsType.UnsignedShort, IntPtr.Zero); } + + /// + /// I want sensor survey points to remain a constant size, so I'll have to adjust the radius of the circle, using this function. + /// + /// + public void ChangeRadius(float a_fRadus) + { + m_v2Size.X = (a_fRadus); + RecalculateModelMatrix(); + } } } diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs index 00200cf77..bcabbcb99 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs @@ -36,6 +36,7 @@ public enum ListEntityType TaskGroups, Waypoints, JumpPoint, + SurveyPoints, Count, } @@ -201,10 +202,11 @@ public TaskGroup() SetupShipDataGrid(); m_oTaskGroupPanel.SystemLocationsListBox.SelectedIndexChanged += new EventHandler(SystemLocationListBox_SelectedIndexChanged); - m_oTaskGroupPanel.DisplayContactsCheckBox.CheckStateChanged += new EventHandler(DisplayContactsCheckBox_CheckChanged); - m_oTaskGroupPanel.DisplayTaskGroupsCheckBox.CheckStateChanged += new EventHandler(DisplayTaskGroupsCheckBox_CheckChanged); - m_oTaskGroupPanel.DisplayWaypointsCheckBox.CheckStateChanged += new EventHandler(DisplayWaypointsCheckBox_CheckChanged); + m_oTaskGroupPanel.DisplayContactsCheckBox.CheckStateChanged += new EventHandler(DisplayCheckBox_CheckChanged); + m_oTaskGroupPanel.DisplayTaskGroupsCheckBox.CheckStateChanged += new EventHandler(DisplayCheckBox_CheckChanged); + m_oTaskGroupPanel.DisplayWaypointsCheckBox.CheckStateChanged += new EventHandler(DisplayCheckBox_CheckChanged); m_oTaskGroupPanel.OrderFilteringCheckBox.CheckStateChanged += new EventHandler(OrderFilteringCheckBox_CheckChanged); + m_oTaskGroupPanel.DisplaySurveyLocationsCheckBox.CheckStateChanged += new EventHandler(DisplayCheckBox_CheckChanged); m_oTaskGroupPanel.NewTaskGroupButton.Click += new EventHandler(NewTaskGroupButton_Click); m_oTaskGroupPanel.RenameTaskGroupButton.Click += new EventHandler(RenameTaskGroupButton_Click); @@ -264,33 +266,11 @@ private void TaskGroupSelectComboBox_SelectedIndexChanged(object sender, EventAr } /// - /// If the contacts checkbox is changed: + /// If any checkbox gets checked or unchecked clear the action list and build the system location list /// /// /// - private void DisplayContactsCheckBox_CheckChanged(object sender, EventArgs e) - { - BuildSystemLocationList(); - ClearActionList(); - } - - /// - /// If Taskgroups checkbox is changed: - /// - /// - /// - private void DisplayTaskGroupsCheckBox_CheckChanged(object sender, EventArgs e) - { - BuildSystemLocationList(); - ClearActionList(); - } - - /// - /// If Waypoints checkbox is changed: - /// - /// - /// - private void DisplayWaypointsCheckBox_CheckChanged(object sender, EventArgs e) + private void DisplayCheckBox_CheckChanged(object sender, EventArgs e) { BuildSystemLocationList(); ClearActionList(); @@ -891,6 +871,9 @@ private void BuildSystemLocationList() if (m_oTaskGroupPanel.DisplayWaypointsCheckBox.Checked == true) AddWaypointsToList(targetsystem); + + if (m_oTaskGroupPanel.DisplaySurveyLocationsCheckBox.Checked == true) + AddSurveyPointsToList(targetsystem); } m_oTaskGroupPanel.SystemLocationsListBox.DataSource = SystemLocationGuidDict.Values.ToList(); } @@ -1192,7 +1175,23 @@ private void AddWaypointsToList(StarSystem starsystem) } } - + /// + /// Adds grav survey points to the location list. + /// + /// + private void AddSurveyPointsToList(StarSystem starsystem) + { + int SPIndex = 1; + foreach (SurveyPoint SP in starsystem._SurveyPoints) + { + string keyName = String.Format("Survey Location #{0}",SPIndex); + StarSystemEntity entObj = SP; + SystemListObject valueObj = new SystemListObject(SystemListObject.ListEntityType.SurveyPoints, entObj); + SystemLocationGuidDict.Add(entObj.Id, keyName); + SystemLocationDict.Add(entObj.Id, valueObj); + SPIndex++; + } + } /// /// Time and distance or orders should be calculated here based on the radio button selection choices. diff --git a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs index 303061dfb..4bfe38e8e 100644 --- a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs +++ b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs @@ -113,11 +113,22 @@ public CheckBox DisplayWaypointsCheckBox get { return m_oWaypointCheckBox; } } + /// + /// Filter orders based on what is possible to accomplish given the selected place and taskgroup? + /// public CheckBox OrderFilteringCheckBox { get { return m_oOrderFilteringCheckBox; } } + /// + /// Display survey points as taskgroup move orders targets. + /// + public CheckBox DisplaySurveyLocationsCheckBox + { + get { return m_oSurveyLocationsCheckBox; } + } + /// /// creates a new task group. /// diff --git a/Pulsar4X/Pulsar4X.UI/SceenGraph/CircleElement.cs b/Pulsar4X/Pulsar4X.UI/SceenGraph/CircleElement.cs index 007c56c56..765bf56e3 100644 --- a/Pulsar4X/Pulsar4X.UI/SceenGraph/CircleElement.cs +++ b/Pulsar4X/Pulsar4X.UI/SceenGraph/CircleElement.cs @@ -25,16 +25,26 @@ public Vector3 CurrentPosition } } + /// + /// Is this circle element a survey point circle? + /// + private bool _IsSurveyPoint; + public bool _isSurveyPoint + { + get { return _IsSurveyPoint; } + set { _IsSurveyPoint = value; } + } + public CircleElement() : base() { - + _IsSurveyPoint = false; } public CircleElement(GLEffect a_oDefaultEffect, Vector3 a_oPosition, OrbitingEntity a_oOrbitEntity, System.Drawing.Color a_oColor) : base() { - + _IsSurveyPoint = false; m_oPrimaryPrimitive = new GLCircle(a_oDefaultEffect, a_oPosition, a_oOrbitEntity, @@ -58,10 +68,24 @@ public override void Render() oElement.Render(); } } + + if (_IsSurveyPoint == true) + Lable.Render(); } public override void Refresh(float a_fZoomScaler) { + if (_IsSurveyPoint == true) + { + Lable.Size = UIConstants.DEFAULT_TEXT_SIZE / a_fZoomScaler; + RealSize = new Vector2(0.0001f, 0.0001f) / a_fZoomScaler; + + GLCircle temp = this.PrimaryPrimitive as GLCircle; + if (temp != null) + { + temp.ChangeRadius(4.0f / a_fZoomScaler); + } + } // loop through any children: foreach (SceenElement oElement in m_lChildren) { diff --git a/Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs b/Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs index 363087678..6a7fcd0a2 100644 --- a/Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs +++ b/Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs @@ -448,12 +448,12 @@ private void CreateSurveyPoint(SceenElement parent, SurveyPoint oSurveyPoint, GL { Vector3 v3SPPos = new Vector3((float)oSurveyPoint.Position.X, (float)oSurveyPoint.Position.Y, 0.0f); - SceenElement oSurveyPointElement = new CircleElement(); + CircleElement oSurveyPointElement = new CircleElement(); oSurveyPointElement.EntityID = oSurveyPoint.Id; GLCircle oSPCircle = new GLCircle(a_oDefaultEffect, v3SPPos, - 0.1f, + 4.0f/m_fZoomScaler, Color.White, UIConstants.Textures.DEFAULT_TEXTURE); @@ -461,8 +461,10 @@ private void CreateSurveyPoint(SceenElement parent, SurveyPoint oSurveyPoint, GL GLUtilities.GLFont oNameLable = new GLUtilities.GLFont(SceenDefaultEffect, v3SPPos, UIConstants.DEFAULT_TEXT_SIZE, Color.White, UIConstants.Textures.DEFAULT_GLFONT2, SPIndex.ToString()); + oSurveyPointElement._isSurveyPoint = true; oSurveyPointElement.Lable = oNameLable; - oSurveyPointElement.RealSize = new Vector2(0.0001f, 0.0001f); + oSurveyPointElement.Lable.Size = UIConstants.DEFAULT_TEXT_SIZE / m_fZoomScaler; //Initial taskgroup names weren't being scaled properly for whatever reason. + oSurveyPointElement.RealSize = new Vector2(0.0001f, 0.0001f) / m_fZoomScaler; oSurveyPointElement.PrimaryPrimitive = oSPCircle; oSurveyPointElement.AddPrimitive(oSPCircle); parent.AddChildElement(oSurveyPointElement); From 15b31ccccd2abbc7413790e5ca96d300a94c7663 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 13 Sep 2015 01:15:27 -0500 Subject: [PATCH 10/40] JumpPoint Generation Work jumpPoints are now linked to survey points for PrimaryOnlyJPs. --- Pulsar4X/Pulsar4X.Lib/Constants.cs | 2 +- Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs | 148 +++++++++++++++---- 2 files changed, 123 insertions(+), 27 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Constants.cs b/Pulsar4X/Pulsar4X.Lib/Constants.cs index 9832faa11..9af0ac93a 100644 --- a/Pulsar4X/Pulsar4X.Lib/Constants.cs +++ b/Pulsar4X/Pulsar4X.Lib/Constants.cs @@ -1073,7 +1073,7 @@ public static class GameSettings /// /// Jumppoints will not appear on secondary stars if true. /// - public static bool PrimaryOnlyJumpPoints = false; + public static bool PrimaryOnlyJumpPoints = true; /// /// Follow TN terraforming rules regarding what can be terraformed, and what gases generate what hostile effects. diff --git a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs index 9e84a00f5..8b1de8f3c 100644 --- a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs +++ b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs @@ -1682,46 +1682,142 @@ private static int GetNaturalJumpPointGeneration(Star star) /// private static JumpPoint GenerateJumpPoint(Star star) { - double minRadius = GalaxyGen.OrbitalDistanceByStarSpectralType[star.SpectralType]._min; - double maxRadius = GalaxyGen.OrbitalDistanceByStarSpectralType[star.SpectralType]._max; - - // Clamp generation to within the planetary system. - foreach (SystemBody currentPlanet in star.Planets) + JumpPoint newJumpPoint; + /// + /// Generate jump points connected to survey locations. + /// + if (Constants.GameSettings.PrimaryOnlyJumpPoints == true) { - if (currentPlanet.Type == SystemBody.PlanetType.Comet || currentPlanet.Type == SystemBody.PlanetType.Asteroid) + /// + /// Get the SP this JP should belong to. + /// + int SP = m_RNG.Next(30); + double RingDist = Constants.SensorTN.EarthRingDistance * Math.Sqrt(star.Orbit.MassRelativeToSol); + int RingFactor = 0; + int angle = -1; + int angleMax = 30; + + /// + /// And get the angle for this SP + /// + if (SP <= 6) { - // Don't gen JP's around comets or asteroids. - continue; + RingFactor = 1; + angleMax = 60; + int SPCount = 0; + for (int surveyPointIterator = 30; surveyPointIterator < 360; surveyPointIterator += 60) + { + if (SPCount == SP) + { + angle = surveyPointIterator; + break; + } + SPCount++; + } + } + else if (SP <= 18) + { + RingFactor = 2; + int SPCount = 7; + for (int surveyPointIterator = 15; surveyPointIterator < 360; surveyPointIterator += 30) + { + if (SPCount == SP) + { + angle = surveyPointIterator; + break; + } + SPCount++; + } + } + else + { + RingFactor = 3; + int SPCount = 19; + for (int surveyPointIterator = 0; surveyPointIterator < 360; surveyPointIterator += 30) + { + if (SPCount == SP) + { + angle = surveyPointIterator; + break; + } + SPCount++; + } } - if (minRadius > currentPlanet.Orbit.Periapsis) + /// + /// Generate a random angle from the above + /// + int TheAngle = 0; + if (angle == 0) { - minRadius = currentPlanet.Orbit.Periapsis; + if (m_RNG.Next(100) > 50) + { + TheAngle = 0 + m_RNG.Next((angleMax / 2)); + } + else + { + TheAngle = 360 - (angleMax / 2) + m_RNG.Next((angleMax / 2)); + } } - if (maxRadius < currentPlanet.Orbit.Apoapsis) + else { - maxRadius = currentPlanet.Orbit.Apoapsis; + TheAngle = angle - (angleMax / 2) + m_RNG.Next(angleMax); } - } - // Determine a location for the new JP. - // Location will be between minDistance and 75% of maxDistance. - double offsetX = (maxRadius - minRadius) * RNG_NextDoubleRange(0.0d, 0.75d) + minRadius; - double offsetY = (maxRadius - minRadius) * RNG_NextDoubleRange(0.0d, 0.75d) + minRadius; + /// + /// Now get a distance for this jump point. RingFactor of 1 means from 0 to RingDist. RingFactor of 2 means from RingDist to RingDist * 2. and RingFactor of 3 means from + /// RingDist * 2 to RingDist * 3 + /// + double Distance = (RingDist * ((double)m_RNG.Next(100000) / 100000.0)) + (RingDist * ((RingFactor - 1))) ; - // Randomly flip the sign of the offsets. - if (m_RNG.NextDouble() >= 0.5) - { - offsetX = -offsetX; + double fX = Math.Cos(Helpers.GameMath.Angle.ToRadians((double)TheAngle)) * Distance; + double fY = Math.Sin(Helpers.GameMath.Angle.ToRadians((double)TheAngle)) * Distance; + + newJumpPoint = new JumpPoint(star, fX, fY); } - if (m_RNG.NextDouble() >= 0.5) + else { - offsetY = -offsetY; - } - // Create the new jumpPoint and link it to it's parent system. - JumpPoint newJumpPoint = new JumpPoint(star, offsetX, offsetY); + double minRadius = GalaxyGen.OrbitalDistanceByStarSpectralType[star.SpectralType]._min; + double maxRadius = GalaxyGen.OrbitalDistanceByStarSpectralType[star.SpectralType]._max; + + // Clamp generation to within the planetary system. + foreach (SystemBody currentPlanet in star.Planets) + { + if (currentPlanet.Type == SystemBody.PlanetType.Comet || currentPlanet.Type == SystemBody.PlanetType.Asteroid) + { + // Don't gen JP's around comets or asteroids. + continue; + } + + if (minRadius > currentPlanet.Orbit.Periapsis) + { + minRadius = currentPlanet.Orbit.Periapsis; + } + if (maxRadius < currentPlanet.Orbit.Apoapsis) + { + maxRadius = currentPlanet.Orbit.Apoapsis; + } + } + + // Determine a location for the new JP. + // Location will be between minDistance and 75% of maxDistance. + double offsetX = (maxRadius - minRadius) * RNG_NextDoubleRange(0.0d, 0.75d) + minRadius; + double offsetY = (maxRadius - minRadius) * RNG_NextDoubleRange(0.0d, 0.75d) + minRadius; + // Randomly flip the sign of the offsets. + if (m_RNG.NextDouble() >= 0.5) + { + offsetX = -offsetX; + } + if (m_RNG.NextDouble() >= 0.5) + { + offsetY = -offsetY; + } + + // Create the new jumpPoint and link it to it's parent system. + newJumpPoint = new JumpPoint(star, offsetX, offsetY); + } return newJumpPoint; } From 18faff0a5ebd10f66b7a87fd11122a63d69350fb Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 19 Sep 2015 23:43:38 -0500 Subject: [PATCH 11/40] 6.5 JP generation option Seems roughly the same, though this should generate fewer JPs. --- Pulsar4X/Pulsar4X.Lib/Constants.cs | 5 ++++ Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs | 25 ++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Pulsar4X/Pulsar4X.Lib/Constants.cs b/Pulsar4X/Pulsar4X.Lib/Constants.cs index 9af0ac93a..83bb16c29 100644 --- a/Pulsar4X/Pulsar4X.Lib/Constants.cs +++ b/Pulsar4X/Pulsar4X.Lib/Constants.cs @@ -1079,6 +1079,11 @@ public static class GameSettings /// Follow TN terraforming rules regarding what can be terraformed, and what gases generate what hostile effects. /// public static bool TNTerraformingRules = false; + + /// + /// Jumppoint generation uses the current 6.50 method of reducing the total number of JPs created. + /// + public static bool Aurora65JPGeneration = true; } } } diff --git a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs index 8b1de8f3c..eb70c7ed0 100644 --- a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs +++ b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs @@ -1616,6 +1616,31 @@ private static void GenerateJumpPoints(StarSystem system, int numJumpPoints = -1 numJumpPoints = (int)Math.Round(numJumpPoints * Constants.GameSettings.JumpPointHubConnectivity); } + /// + /// 6.5 jumppoint generation rules. This will generate JPs on a flat chance based only on star mass, not on system bodies or other criteria. + /// + if (Constants.GameSettings.Aurora65JPGeneration == true) + { + int numJPs = 1; + int BaseJPChance = 90; + int JPChance = (BaseJPChance + (int)Math.Round(system.Stars[0].Orbit.MassRelativeToSol)); + while (m_RNG.Next(100) < JPChance) + { + numJPs++; + + if (BaseJPChance == 40) + BaseJPChance = 30; + else if (BaseJPChance == 60) + BaseJPChance = 40; + else if (BaseJPChance == 90) + BaseJPChance = 60; + + JPChance = (BaseJPChance + (int)Math.Round(system.Stars[0].Orbit.MassRelativeToSol)); + } + + numJumpPoints = numJPs; + } + int jumpPointsGenerated = 0; while (jumpPointsGenerated < numJumpPoints) { From 92e4688368354e078a4ede07f4c0cbff5e58be00 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 26 Sep 2015 17:46:28 -0500 Subject: [PATCH 12/40] GLExtent Work for fonts I want to determine the size of a font, or other primitive displayed on the screen, and if there is any potential overlap with another font or primitive. --- Pulsar4X/Pulsar4X.UI/GLUtilities/GLFont.cs | 58 ++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/Pulsar4X/Pulsar4X.UI/GLUtilities/GLFont.cs b/Pulsar4X/Pulsar4X.UI/GLUtilities/GLFont.cs index f62e1eae0..17ff2a921 100644 --- a/Pulsar4X/Pulsar4X.UI/GLUtilities/GLFont.cs +++ b/Pulsar4X/Pulsar4X.UI/GLUtilities/GLFont.cs @@ -165,6 +165,64 @@ public void Render() } } + /// + /// Returns the rectangular extent of this font. + /// + /// + /// + public void GetExtent(out Vector2 UpperLeft, out Vector2 BottomRight) + { + UpperLeft = new Vector2((m_v3Position.X - m_v2Size.X), (m_v3Position.Y - m_v2Size.Y)); + BottomRight = new Vector2((m_v3Position.X + m_v2Size.X), (m_v3Position.Y + m_v2Size.Y)); + } + + /// + /// Compares our extent to the provided one, if it is within ours, return true, if it is not return false. + /// + /// + /// + public bool CompareExtent(Vector2 UpperLeft, Vector2 BottomRight) + { + //m_v3Position + //m_v2Size + Vector2 MyUpperLeft; + Vector2 MyBottomRight; + GetExtent(out MyUpperLeft, out MyBottomRight); + + /// + /// Conditions: + /// Entirely to the left or right + /// Entirely above or below + /// possibly overlapping in X terms + /// possibly overlapping in Y terms + /// + bool inX = false; + bool inY = false; + if ((BottomRight.X < MyUpperLeft.X) || (UpperLeft.X > MyBottomRight.X)) + { + return false; + } + else + { + inX = true; + } + if ((BottomRight.Y < MyUpperLeft.Y) || (UpperLeft.Y > MyBottomRight.Y)) + { + return false; + } + else + { + inY = true; + } + + if (inX == true && inY == true) + { + return true; + } + + return false; + } + private void UpdatePositionAndSize() { Vector3 v3CharPos = new Vector3(); From a42461b87c092616ace6d04ef020ae592a4a2d67 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 27 Sep 2015 02:14:59 -0500 Subject: [PATCH 13/40] Extent works for planets and stars overlapping labels will no longer be drawn. I may have messed some min-orbit code up somewhere along the way, and I should look at that as these shouldn't be displayed on maximum zoom anyway. --- Pulsar4X/Pulsar4X.UI/GLUtilities/GLFont.cs | 39 ++++++++++--------- .../Pulsar4X.UI/SceenGraph/PlanetElement.cs | 25 ++++++++++-- Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs | 10 ++--- .../Pulsar4X.UI/SceenGraph/StarElement.cs | 30 ++++++++++++-- 4 files changed, 74 insertions(+), 30 deletions(-) diff --git a/Pulsar4X/Pulsar4X.UI/GLUtilities/GLFont.cs b/Pulsar4X/Pulsar4X.UI/GLUtilities/GLFont.cs index 17ff2a921..38b3fa436 100644 --- a/Pulsar4X/Pulsar4X.UI/GLUtilities/GLFont.cs +++ b/Pulsar4X/Pulsar4X.UI/GLUtilities/GLFont.cs @@ -172,8 +172,14 @@ public void Render() /// public void GetExtent(out Vector2 UpperLeft, out Vector2 BottomRight) { - UpperLeft = new Vector2((m_v3Position.X - m_v2Size.X), (m_v3Position.Y - m_v2Size.Y)); - BottomRight = new Vector2((m_v3Position.X + m_v2Size.X), (m_v3Position.Y + m_v2Size.Y)); + int iCharsToDraw = m_szText.Length; + if (iCharsToDraw > c_uiMaxNumberOfChars) + { + iCharsToDraw = (int)c_uiMaxNumberOfChars; + } + + UpperLeft = new Vector2((m_v3Position.X - ((m_v2Size.X * iCharsToDraw) / 2.0f)), (m_v3Position.Y - ((m_v2Size.Y) / 2.0f))); + BottomRight = new Vector2((m_v3Position.X + ((m_v2Size.X * iCharsToDraw) / 2.0f)), (m_v3Position.Y + ((m_v2Size.Y) / 2.0f))); } /// @@ -189,6 +195,7 @@ public bool CompareExtent(Vector2 UpperLeft, Vector2 BottomRight) Vector2 MyBottomRight; GetExtent(out MyUpperLeft, out MyBottomRight); + /// /// Conditions: /// Entirely to the left or right @@ -196,31 +203,27 @@ public bool CompareExtent(Vector2 UpperLeft, Vector2 BottomRight) /// possibly overlapping in X terms /// possibly overlapping in Y terms /// - bool inX = false; - bool inY = false; + + /// + /// If my extent is outside of the argument supplied extent on the X axis, then it does not matter where on the Y axis it is. + /// if ((BottomRight.X < MyUpperLeft.X) || (UpperLeft.X > MyBottomRight.X)) { return false; } - else - { - inX = true; - } + + /// + /// As per above, if my extent is outside of the argument supplied extent on the Y axis then it doesn't matter where we are on the X axis. + /// if ((BottomRight.Y < MyUpperLeft.Y) || (UpperLeft.Y > MyBottomRight.Y)) { return false; } - else - { - inY = true; - } - if (inX == true && inY == true) - { - return true; - } - - return false; + /// + /// Having made it this far we know that both extents overlap on both the X and Y axis. + /// + return true; } private void UpdatePositionAndSize() diff --git a/Pulsar4X/Pulsar4X.UI/SceenGraph/PlanetElement.cs b/Pulsar4X/Pulsar4X.UI/SceenGraph/PlanetElement.cs index 3de7160fb..98c913c35 100644 --- a/Pulsar4X/Pulsar4X.UI/SceenGraph/PlanetElement.cs +++ b/Pulsar4X/Pulsar4X.UI/SceenGraph/PlanetElement.cs @@ -30,22 +30,34 @@ public override GameEntity SceenEntity } } + /// + /// What is this PlanetElement's parent? + /// + private SceenElement _ParentElement; + public SceenElement _parentElement + { + get { return _ParentElement; } + } + /// /// This is the display element for the orbit this planet will make. /// private CircleElement m_oOrbitCircle { get; set; } - public PlanetElement() + public PlanetElement(SceenElement PElement) : base() { + _ParentElement = PElement; } - public PlanetElement(GLEffect a_oDefaultEffect, Vector3 a_oPosition, SystemBody a_oPlanet, System.Drawing.Color a_oColor) + public PlanetElement(GLEffect a_oDefaultEffect, Vector3 a_oPosition, SystemBody a_oPlanet, System.Drawing.Color a_oColor, SceenElement PElement) : base(a_oPlanet) { m_oOrbitCircle = new CircleElement(a_oDefaultEffect, a_oPosition, a_oPlanet, a_oColor); #warning Cannot add m_oOrbitCircle to children for Planet Element + + _ParentElement = PElement; } @@ -71,7 +83,14 @@ public override void Render() ///< @todo Make drawing of Asteriod/comet text and orbit circles a setting the player can toggle). or base it on zoom. if (m_oLable != null && m_oPlanet.Type != SystemBody.PlanetType.Asteroid && m_oPlanet.Type != SystemBody.PlanetType.Comet) { - m_oLable.Render(); + Vector2 PUpperLeft, PBottomRight; + m_oLable.GetExtent(out PUpperLeft, out PBottomRight); + bool WithinParent = _ParentElement.Lable.CompareExtent(PUpperLeft, PBottomRight); + /// + /// Don't draw this label if its parent label will obscure it anyway + /// + if(WithinParent == false) + m_oLable.Render(); } } diff --git a/Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs b/Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs index 6a7fcd0a2..c52f6b23f 100644 --- a/Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs +++ b/Pulsar4X/Pulsar4X.UI/SceenGraph/Sceen.cs @@ -241,7 +241,7 @@ public Sceen(StarSystem a_oStarSystem, GLEffect a_oDefaultEffect, Pulsar4X.UI.Ha Vector3 v3MoonPos = Vector3.Zero; // Used to store the Moons Position. // start creating star branches in the sceen graph: - SceenElement oRootStar; + SceenElement oRootStar = null; SceenElement oCurrStar; foreach (Pulsar4X.Entities.Star oStar in a_oStarSystem.Stars) { @@ -249,7 +249,7 @@ public Sceen(StarSystem a_oStarSystem, GLEffect a_oDefaultEffect, Pulsar4X.UI.Ha if (iStarCounter <= 0) { // then we have a secondary, etc star give random position around its orbit! - oRootStar = new StarElement(oStar, a_oDefaultEffect, Vector3.Zero, Pulsar4X.Constants.StarColor.LookupColor(oStar), true); + oRootStar = new StarElement(oStar, a_oDefaultEffect, Vector3.Zero, Pulsar4X.Constants.StarColor.LookupColor(oStar), null, true); oCurrStar = oRootStar; } else @@ -258,7 +258,7 @@ public Sceen(StarSystem a_oStarSystem, GLEffect a_oDefaultEffect, Pulsar4X.UI.Ha v3StarPos.X = (float)(oStar.Position.X); v3StarPos.Y = (float)(oStar.Position.Y); MaxOrbitDistTest(ref dMaxOrbitDist, oStar.Orbit.SemiMajorAxis); - oCurrStar = new StarElement(oStar, a_oDefaultEffect, v3StarPos, Pulsar4X.Constants.StarColor.LookupColor(oStar), false); + oCurrStar = new StarElement(oStar, a_oDefaultEffect, v3StarPos, Pulsar4X.Constants.StarColor.LookupColor(oStar), oRootStar, false); } @@ -283,7 +283,7 @@ public Sceen(StarSystem a_oStarSystem, GLEffect a_oDefaultEffect, Pulsar4X.UI.Ha // now go though and add each planet to render list. foreach (Pulsar4X.Entities.SystemBody oPlanet in oStar.Planets) { - SceenElement oPlanetElement = new PlanetElement(a_oDefaultEffect, v3StarPos, oPlanet, Color.FromArgb(255, 0, 205, 0)); + SceenElement oPlanetElement = new PlanetElement(a_oDefaultEffect, v3StarPos, oPlanet, Color.FromArgb(255, 0, 205, 0), oCurrStar); oPlanetElement.EntityID = oPlanet.Id; if (iPlanetCounter == 0) @@ -318,7 +318,7 @@ public Sceen(StarSystem a_oStarSystem, GLEffect a_oDefaultEffect, Pulsar4X.UI.Ha // now again for the moons: foreach (Pulsar4X.Entities.SystemBody oMoon in oPlanet.Moons) { - SceenElement oMoonElement = new PlanetElement(a_oDefaultEffect, v3PlanetPos, oMoon, Color.FromArgb(255, 0, 205, 0)); + SceenElement oMoonElement = new PlanetElement(a_oDefaultEffect, v3PlanetPos, oMoon, Color.FromArgb(255, 0, 205, 0), oPlanetElement); oMoonElement.EntityID = oMoon.Id; if (iMoonCounter == 0) diff --git a/Pulsar4X/Pulsar4X.UI/SceenGraph/StarElement.cs b/Pulsar4X/Pulsar4X.UI/SceenGraph/StarElement.cs index ddc6d25db..2943540b5 100644 --- a/Pulsar4X/Pulsar4X.UI/SceenGraph/StarElement.cs +++ b/Pulsar4X/Pulsar4X.UI/SceenGraph/StarElement.cs @@ -30,18 +30,27 @@ public override GameEntity SceenEntity } } + /// + /// Does this star element have a parent? if it is a secondary star yes. + /// + private SceenElement _ParentElement; + public SceenElement _parentElement + { + get { return _ParentElement; } + } + /// /// This is the display element for the orbit this planet will make. /// private CircleElement m_oOrbitCircle { get; set; } - public StarElement() + public StarElement(SceenElement PElement) : base() { - + _ParentElement = PElement; } - public StarElement(Star a_oStar, GLEffect a_oDefaultEffect, Vector3 a_oPosition, System.Drawing.Color a_oColor, bool a_bPrimary = true) + public StarElement(Star a_oStar, GLEffect a_oDefaultEffect, Vector3 a_oPosition, System.Drawing.Color a_oColor, SceenElement PElement, bool a_bPrimary = true) : base(a_oStar) { if (!a_bPrimary) @@ -55,6 +64,7 @@ public StarElement(Star a_oStar, GLEffect a_oDefaultEffect, Vector3 a_oPosition, else m_oOrbitCircle = null; + _ParentElement = PElement; } @@ -84,7 +94,19 @@ public override void Render() // render lable: if (m_oLable != null) { - m_oLable.Render(); + if (_ParentElement != null) + { + Vector2 PUpperLeft, PBottomRight; + m_oLable.GetExtent(out PUpperLeft, out PBottomRight); + bool WithinParent = _ParentElement.Lable.CompareExtent(PUpperLeft, PBottomRight); + /// + /// Don't draw this label if its parent label will obscure it anyway + /// + if (WithinParent == false) + m_oLable.Render(); + } + else + m_oLable.Render(); } } From a79da3a4646885922ac334107e96824f6eadd04e Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 4 Oct 2015 02:51:05 -0500 Subject: [PATCH 14/40] Grav survey implementation Gravitational survey should work, it is not yet tested however. --- Pulsar4X/Pulsar4X.Lib/Constants.cs | 5 ++ Pulsar4X/Pulsar4X.Lib/Entities/Order.cs | 31 ++++++++ .../Entities/StarSystem/StarSystem.cs | 45 ++++++++++++ .../Entities/StarSystem/TaskGroup.cs | 73 ++++++++++++++++++- Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs | 43 +++++++++-- 5 files changed, 189 insertions(+), 8 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Constants.cs b/Pulsar4X/Pulsar4X.Lib/Constants.cs index 83bb16c29..6bc5714ab 100644 --- a/Pulsar4X/Pulsar4X.Lib/Constants.cs +++ b/Pulsar4X/Pulsar4X.Lib/Constants.cs @@ -748,6 +748,11 @@ public static class SensorTN /// Each survey ring is 2B km out for every 1.0 unit of solar mass present. solar mass is sqrted for this calculation as per survey cost and then multiplied by this value. units in AU. /// public const double EarthRingDistance = 13.36917422; + + /// + /// How many survey points are there? this is only referenced in taskgroup grav survey code for now. + /// + public const int SurveyPointCount = 30; } /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Order.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Order.cs index 11d235042..0bddcdbee 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Order.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Order.cs @@ -110,6 +110,15 @@ public Waypoint wayPoint get { return WayPoint; } } + /// + /// Storage for survey point targeted orders. + /// + private SurveyPoint SurveyPointOrder { get; set; } + public SurveyPoint surveyPointOrder + { + get { return SurveyPointOrder; } + } + /// /// Installation/Ship Component/Troops/Ship as part of taskgroup identifier for load/tractor orders. /// @@ -293,6 +302,28 @@ public Order(Constants.ShipTN.OrderType TypeOrder, int SecondaryOrder, int Terti Name = TypeOrder.ToString() + " " + ShipOrder.Name.ToString(); } + + /// + /// Constructor for SurveyPoint + /// + /// Type + /// Secondary + /// Tertiary + /// Order delay + /// Ship target of order + public Order(Constants.ShipTN.OrderType TypeOrder, int SecondaryOrder, int TertiaryOrder, int Delay, SurveyPoint SPOrder) + { + TypeOf = TypeOrder; + Target = SPOrder; + Secondary = SecondaryOrder; + Tertiary = TertiaryOrder; + SurveyPointOrder = SPOrder; + OrderDelay = Delay; + + OrderTimeRequirement = -1; + + Name = TypeOrder.ToString() + " " + SurveyPointOrder.Name.ToString(); + } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs index 7d8bfadea..6625b1dc7 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs @@ -14,6 +14,43 @@ namespace Pulsar4X.Entities { + /// + /// Class for storing Jump point detections for each faction. + /// + public class JPDetection + { + public enum Status + { + None, + Incomplete, + Complete, + Count + } + + /// + /// Status of this faction's survey of this starsystem. + /// + public Status _SurveyStatus { get; set; } + + /// + /// Which Points have been surveyed? + /// + public BindingList _SurveyedPoints { get; set; } + + /// + /// List of detected JPs if status is Incomplete. + /// + public BindingList _DetectedJPs { get; set; } + + public JPDetection() + { + _SurveyStatus = Status.None; + _SurveyedPoints = new BindingList(); + _DetectedJPs = new BindingList(); + } + + } + public class StarSystem : GameEntity { public BindingList Stars { get; set; } @@ -71,6 +108,12 @@ public class StarSystem : GameEntity /// public BindingList _SurveyPoints { get; set; } + /// + /// store the results of each faction's surveying here. if no faction is present then it obviously has not done any surveying. otherwise complete means every point is mapped, + /// and incomplete means only those points in JPDetection._DetectedJP are detected. + /// + public Dictionary _SurveyResults { get; set; } + public StarSystem(string name, int seed) : base() { @@ -88,6 +131,8 @@ public StarSystem(string name, int seed) _SurveyPoints = new BindingList(); + _SurveyResults = new Dictionary(); + m_seed = seed; // Subscribe to change events. diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index 96f1e0ff2..c623640db 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -2904,7 +2904,7 @@ public uint PerformOrders(uint TimeSlice) if (OB.GeoSurveyList.ContainsKey(TaskGroupFaction) == false) { OB.GeoSurveyList.Add(TaskGroupFaction, true); - if(OB._mineralsGenerated == false) + if (OB._mineralsGenerated == false) OB.GenerateMinerals(); } //handle adding the faction to the survey list when complete @@ -2922,6 +2922,77 @@ public uint PerformOrders(uint TimeSlice) /// get the cost to survey this system, see above geo survey costs. /// reveal detected jumppoints. how will this work? also jumppoint generation needs to be looked at. /// + int SystemSurveyCost = Contact.Position.System.GetSurveyCost(); + StarSystem CurrentSystem = Contact.Position.System; + + float hourFraction = (float)TimeSlice / (float)Constants.TimeInSeconds.Hour; + int totalHours = (int)Math.Floor(hourFraction); + int RemainderSP = SystemSurveyCost - _GravSurveyPoints; + int TotalSP = (int)(CalcGravSurveyPoints() * (float)totalHours); + + if (TotalSP < RemainderSP) + { + _GravSurveyPoints = _GravSurveyPoints + TotalSP; + TimeSlice = 0; + } + else + { + /// + /// Some time will be left over, return that fraction of time. + /// + int hoursToComplete = (int)Math.Ceiling((float)RemainderSP / CalcGravSurveyPoints()); + TimeSlice = TimeSlice - ((uint)hoursToComplete * Constants.TimeInSeconds.Hour); + } + + if (_GravSurveyPoints >= SystemSurveyCost) + { + /// + /// 1st mark the survey point as surveyed. + /// + if (CurrentSystem._SurveyResults.ContainsKey(TaskGroupFaction) == false) + { + JPDetection newJPDet = new JPDetection(); + newJPDet._SurveyedPoints.Add(TaskGroupOrders[0].surveyPointOrder); + CurrentSystem._SurveyResults.Add(TaskGroupFaction,newJPDet); + CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyStatus = JPDetection.Status.Incomplete; + } + else + { + CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyedPoints.Add(TaskGroupOrders[0].surveyPointOrder); + + /// + /// if 30 points have been surveyed mark the system as totally surveyed. + /// + if(CurrentSystem._SurveyResults.Count == Constants.SensorTN.SurveyPointCount) + { + /// + /// All survey work is complete, so free up these pointers. + /// + CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyStatus = JPDetection.Status.Complete; + CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyedPoints = null; + CurrentSystem._SurveyResults[TaskGroupFaction]._DetectedJPs = null; + } + } + int SPIndex = CurrentSystem._SurveyPoints.IndexOf(TaskGroupOrders[0].surveyPointOrder); + + /// + /// These pointers will be null if status is complete. check for that. otherwise mark any jps at this index as found. + /// + if(CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyStatus != JPDetection.Status.Complete) + { + foreach (JumpPoint JP in CurrentSystem.JumpPoints) + { + int JPIndex = CurrentSystem.GetSurveyPointArea(JP.Position.X,JP.Position.Y); + if (JPIndex == SPIndex) + { + CurrentSystem._SurveyResults[TaskGroupFaction]._DetectedJPs.Add(JP); + } + } + } + + _GravSurveyPoints = 0; + } + break; #endregion diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs index bcabbcb99..e42862ef9 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs @@ -498,6 +498,10 @@ private void AddMoveButton_Clicked(object sender, EventArgs e) Waypoint waypoint = (Waypoint)entity; NewOrder = new Order(selected_ordertype, -1, -1, 0, waypoint); break; + case SystemListObject.ListEntityType.SurveyPoints: + SurveyPoint SPoint = (SurveyPoint)entity; + NewOrder = new Order(selected_ordertype, -1, -1, 0, SPoint); + break; } if (NewOrder != null) CurrentTaskGroup.IssueOrder(NewOrder, SelectedOrderIndex); @@ -1053,16 +1057,41 @@ private void AddPlanetsToList(StarSystem starsystem) /// Add jump points to the available locations list. /// /// -#warning check to see if jump point is detected eventually when grav survey is implemented private void AddJumpPointsToList(StarSystem starsystem) { - foreach (JumpPoint jp in starsystem.JumpPoints) + /// + /// If this starsystem has no survey results for this faction, or the results aren't complete or incomplete then do nothing. + /// + if (starsystem._SurveyResults.ContainsKey(CurrentFaction) == true) { - StarSystemEntity entObj = jp; - SystemListObject.ListEntityType entType = SystemListObject.ListEntityType.JumpPoint; - SystemListObject valueObj = new SystemListObject(entType, entObj); - SystemLocationGuidDict.Add(entObj.Id, jp.Name); - SystemLocationDict.Add(entObj.Id, valueObj); + /// + /// Every JP is detected. add them all. + /// + if (starsystem._SurveyResults[CurrentFaction]._SurveyStatus == JPDetection.Status.Complete) + { + foreach (JumpPoint jp in starsystem.JumpPoints) + { + StarSystemEntity entObj = jp; + SystemListObject.ListEntityType entType = SystemListObject.ListEntityType.JumpPoint; + SystemListObject valueObj = new SystemListObject(entType, entObj); + SystemLocationGuidDict.Add(entObj.Id, jp.Name); + SystemLocationDict.Add(entObj.Id, valueObj); + } + } + /// + /// Only some of the JPs are detected, so list only those. + /// + else if (starsystem._SurveyResults[CurrentFaction]._SurveyStatus == JPDetection.Status.Incomplete) + { + foreach (JumpPoint jp in starsystem._SurveyResults[CurrentFaction]._DetectedJPs) + { + StarSystemEntity entObj = jp; + SystemListObject.ListEntityType entType = SystemListObject.ListEntityType.JumpPoint; + SystemListObject valueObj = new SystemListObject(entType, entObj); + SystemLocationGuidDict.Add(entObj.Id, jp.Name); + SystemLocationDict.Add(entObj.Id, valueObj); + } + } } } From f7177cdec45bde2f67dc6aacc8ff94f41a860f58 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 10 Oct 2015 23:50:24 -0500 Subject: [PATCH 15/40] Grav survey initial testing done some issues resolved, full testing for grav and geo survey is yet to be done however. --- Pulsar4X/Pulsar4X.Lib/Entities/Order.cs | 2 +- .../Entities/StarSystem/SurveyPoint.cs | 2 + .../Entities/StarSystem/TaskGroup.cs | 22 ++++++- Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs | 61 +++++++++++++++++-- .../Panels/TaskGroup_Panel.Designer.cs | 8 +++ 5 files changed, 87 insertions(+), 8 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Order.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Order.cs index 0bddcdbee..bed7bb3a3 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Order.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Order.cs @@ -310,7 +310,7 @@ public Order(Constants.ShipTN.OrderType TypeOrder, int SecondaryOrder, int Terti /// Secondary /// Tertiary /// Order delay - /// Ship target of order + /// survey point target of order public Order(Constants.ShipTN.OrderType TypeOrder, int SecondaryOrder, int TertiaryOrder, int Delay, SurveyPoint SPOrder) { TypeOf = TypeOrder; diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SurveyPoint.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SurveyPoint.cs index e812b2e3d..707578bff 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SurveyPoint.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SurveyPoint.cs @@ -58,6 +58,8 @@ public SurveyPoint(StarSystem SystemOfPoint, double xPosition, double yPosition) _GravSurveyList = new BindingList(); _JPList = new BindingList(); + + Name = "Survey Location #" + (SystemOfPoint._SurveyPoints.Count() + 1).ToString(); } /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index c623640db..41cc10e88 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -2881,7 +2881,13 @@ public uint PerformOrders(uint TimeSlice) int BodySurveyCost = OB.GetSurveyCost(); float hourFract = (float)TimeSlice / (float)Constants.TimeInSeconds.Hour; - int hours = (int)Math.Floor(hourFract); + _SurveyHourFraction = _SurveyHourFraction + hourFract; + int hours = (int)Math.Floor(_SurveyHourFraction); + if (hours != 0) + { + _SurveyHourFraction = _SurveyHourFraction - hours; + } + int RemainderGP = BodySurveyCost - _GeoSurveyPoints; int TotalGP = (int)(CalcGeoSurveyPoints() * (float)hours); if (TotalGP < RemainderGP) @@ -2910,6 +2916,7 @@ public uint PerformOrders(uint TimeSlice) //handle adding the faction to the survey list when complete //generate minerals? _GeoSurveyPoints = 0; + _SurveyHourFraction = 0.0f; } break; @@ -2926,10 +2933,18 @@ public uint PerformOrders(uint TimeSlice) StarSystem CurrentSystem = Contact.Position.System; float hourFraction = (float)TimeSlice / (float)Constants.TimeInSeconds.Hour; - int totalHours = (int)Math.Floor(hourFraction); + _SurveyHourFraction = _SurveyHourFraction + hourFraction; + + int totalHours = (int)Math.Floor(_SurveyHourFraction); + if (totalHours != 0) + { + _SurveyHourFraction = _SurveyHourFraction - totalHours; + } + int RemainderSP = SystemSurveyCost - _GravSurveyPoints; int TotalSP = (int)(CalcGravSurveyPoints() * (float)totalHours); + if (TotalSP < RemainderSP) { _GravSurveyPoints = _GravSurveyPoints + TotalSP; @@ -2940,12 +2955,14 @@ public uint PerformOrders(uint TimeSlice) /// /// Some time will be left over, return that fraction of time. /// + _GravSurveyPoints = SystemSurveyCost; int hoursToComplete = (int)Math.Ceiling((float)RemainderSP / CalcGravSurveyPoints()); TimeSlice = TimeSlice - ((uint)hoursToComplete * Constants.TimeInSeconds.Hour); } if (_GravSurveyPoints >= SystemSurveyCost) { + /// /// 1st mark the survey point as surveyed. /// @@ -2991,6 +3008,7 @@ public uint PerformOrders(uint TimeSlice) } _GravSurveyPoints = 0; + _SurveyHourFraction = 0.0f; } break; diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs index e42862ef9..f9c2729ce 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs @@ -207,6 +207,7 @@ public TaskGroup() m_oTaskGroupPanel.DisplayWaypointsCheckBox.CheckStateChanged += new EventHandler(DisplayCheckBox_CheckChanged); m_oTaskGroupPanel.OrderFilteringCheckBox.CheckStateChanged += new EventHandler(OrderFilteringCheckBox_CheckChanged); m_oTaskGroupPanel.DisplaySurveyLocationsCheckBox.CheckStateChanged += new EventHandler(DisplayCheckBox_CheckChanged); + m_oTaskGroupPanel.ExcludeSurveyedCheckBox.CheckStateChanged += new EventHandler(DisplayCheckBox_CheckChanged); m_oTaskGroupPanel.NewTaskGroupButton.Click += new EventHandler(NewTaskGroupButton_Click); m_oTaskGroupPanel.RenameTaskGroupButton.Click += new EventHandler(RenameTaskGroupButton_Click); @@ -1211,13 +1212,63 @@ private void AddWaypointsToList(StarSystem starsystem) private void AddSurveyPointsToList(StarSystem starsystem) { int SPIndex = 1; + bool DisplaySP = false; foreach (SurveyPoint SP in starsystem._SurveyPoints) { - string keyName = String.Format("Survey Location #{0}",SPIndex); - StarSystemEntity entObj = SP; - SystemListObject valueObj = new SystemListObject(SystemListObject.ListEntityType.SurveyPoints, entObj); - SystemLocationGuidDict.Add(entObj.Id, keyName); - SystemLocationDict.Add(entObj.Id, valueObj); + if (m_oTaskGroupPanel.ExcludeSurveyedCheckBox.Checked == true) + { + /// + /// it is important to always check to see if the desired key is in the dictionary before using said dictionary to prevent null references, crashes, and so on. + /// + if (starsystem._SurveyResults.ContainsKey(CurrentFaction) == true) + { + if (starsystem._SurveyResults[CurrentFaction]._SurveyStatus == JPDetection.Status.Complete) + { + /// + /// Don't display any survey points, they are all surveyed, and surveyed points should be excluded. + /// + return; + } + else if (starsystem._SurveyResults[CurrentFaction]._SurveyStatus == JPDetection.Status.Incomplete) + { + if (starsystem._SurveyResults[CurrentFaction]._SurveyedPoints.Contains(SP) == false) + { + /// + /// Display only those sps not yet surveyed. + /// + DisplaySP = true; + } + } + else + { + /// + /// Display everything, as the survey status should be none in this case. + /// + DisplaySP = true; + } + } + else + { + /// + /// This faction has performed no survey, so add all points. + /// + DisplaySP = true; + } + } + else + { + DisplaySP = true; + } + + if (DisplaySP == true) + { + string keyName = String.Format("Survey Location #{0}", SPIndex); + StarSystemEntity entObj = SP; + SystemListObject valueObj = new SystemListObject(SystemListObject.ListEntityType.SurveyPoints, entObj); + SystemLocationGuidDict.Add(entObj.Id, keyName); + SystemLocationDict.Add(entObj.Id, valueObj); + DisplaySP = false; + } SPIndex++; } } diff --git a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs index 4bfe38e8e..2e9a56c17 100644 --- a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs +++ b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs @@ -129,6 +129,14 @@ public CheckBox DisplaySurveyLocationsCheckBox get { return m_oSurveyLocationsCheckBox; } } + /// + /// Do not display any surveyed bodies or survey points. + /// + public CheckBox ExcludeSurveyedCheckBox + { + get { return m_oExcludeSurveyedCheckBox; } + } + /// /// creates a new task group. /// From 1312a309b4d6cd44dc99b03da93053f588980a46 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 17 Oct 2015 16:31:07 -0500 Subject: [PATCH 16/40] Special Orders Mockup Survey conditionals will be done next to verify that surveying works as intended, and the first step of that is to set up the UI. --- .../Panels/TaskGroup_Panel.Designer.cs | 509 ++++++++++++++++++ 1 file changed, 509 insertions(+) diff --git a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs index 2e9a56c17..80f0981b6 100644 --- a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs +++ b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs @@ -357,6 +357,35 @@ private void InitializeComponent() this.m_oAsteroidsCheckBox = new System.Windows.Forms.CheckBox(); this.m_oMoonsCheckBox = new System.Windows.Forms.CheckBox(); this.m_oSpecialOrdersTabPage = new System.Windows.Forms.TabPage(); + this.m_oTaskforceTrainingGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oStartTaskforceTrainingButton = new System.Windows.Forms.Button(); + this.m_oSubordinateFormationGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oSubordinateFormationsListBox = new System.Windows.Forms.ListBox(); + this.groupBox7 = new System.Windows.Forms.GroupBox(); + this.m_oCopyConditionalCheckBox = new System.Windows.Forms.CheckBox(); + this.m_oCopyDefaultCheckBox = new System.Windows.Forms.CheckBox(); + this.m_oMatchSpeedsCheckBox = new System.Windows.Forms.CheckBox(); + this.m_oCopyOrdersToSubordinateButton = new System.Windows.Forms.Button(); + this.m_oCondOrderAGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oCondAOrderComboBox = new System.Windows.Forms.ComboBox(); + this.m_oCondAConditionComboBox = new System.Windows.Forms.ComboBox(); + this.m_oSuperiorFormationGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oSaveFormationButton = new System.Windows.Forms.Button(); + this.m_oSuperiorFormationComboBox = new System.Windows.Forms.ComboBox(); + this.m_oCombineTaskgroupGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oSaveCombineButton = new System.Windows.Forms.Button(); + this.m_oCombineTaskgroupsComboBox = new System.Windows.Forms.ComboBox(); + this.m_oCondOrderBGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oCondBOrderComboBox = new System.Windows.Forms.ComboBox(); + this.m_oCondBConditionComboBox = new System.Windows.Forms.ComboBox(); + this.m_oDefaultOrderGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oSecondaryDefaultOrdersComboBox = new System.Windows.Forms.ComboBox(); + this.m_oPrimaryDefaultOrdersComboBox = new System.Windows.Forms.ComboBox(); + this.m_oProtectThreatAxisGroupBox = new System.Windows.Forms.GroupBox(); + this.comboBox12 = new System.Windows.Forms.ComboBox(); + this.comboBox11 = new System.Windows.Forms.ComboBox(); + this.comboBox10 = new System.Windows.Forms.ComboBox(); + this.comboBox9 = new System.Windows.Forms.ComboBox(); this.m_oOrganizationTabPage = new System.Windows.Forms.TabPage(); this.m_oShipMoveToTGGroupBox = new System.Windows.Forms.GroupBox(); this.m_oOrgSelectedTGListBox = new System.Windows.Forms.ListBox(); @@ -406,6 +435,17 @@ private void InitializeComponent() this.m_oAddColonyButton = new System.Windows.Forms.Button(); this.m_oSystemMapButton = new System.Windows.Forms.Button(); this.m_oNewTGButton = new System.Windows.Forms.Button(); + this.m_oDefaultPrimaryLabel = new System.Windows.Forms.Label(); + this.m_oDefaultSecondaryLabel = new System.Windows.Forms.Label(); + this.m_oCondACondLabel = new System.Windows.Forms.Label(); + this.m_oCondAOrderLabel = new System.Windows.Forms.Label(); + this.m_oCondBCondLabel = new System.Windows.Forms.Label(); + this.m_oCondBOrderLabel = new System.Windows.Forms.Label(); + this.m_oThreatLabel = new System.Windows.Forms.Label(); + this.m_oTaskGroupThreatLabel = new System.Windows.Forms.Label(); + this.m_oThreatDistanceLabel = new System.Windows.Forms.Label(); + this.m_oOffsetthreatLabel = new System.Windows.Forms.Label(); + this.m_oBearingThreatLabel = new System.Windows.Forms.Label(); this.m_oGeneralTGDetailsBox.SuspendLayout(); this.m_oTaskGroupTabControl.SuspendLayout(); this.m_oTaskGroupOrdersTabPage.SuspendLayout(); @@ -418,6 +458,16 @@ private void InitializeComponent() this.m_oTaskGroupOrdersBox.SuspendLayout(); this.m_oCopyOrdersGroupBox.SuspendLayout(); this.m_oSystemDisplayOptionsBox.SuspendLayout(); + this.m_oSpecialOrdersTabPage.SuspendLayout(); + this.m_oTaskforceTrainingGroupBox.SuspendLayout(); + this.m_oSubordinateFormationGroupBox.SuspendLayout(); + this.groupBox7.SuspendLayout(); + this.m_oCondOrderAGroupBox.SuspendLayout(); + this.m_oSuperiorFormationGroupBox.SuspendLayout(); + this.m_oCombineTaskgroupGroupBox.SuspendLayout(); + this.m_oCondOrderBGroupBox.SuspendLayout(); + this.m_oDefaultOrderGroupBox.SuspendLayout(); + this.m_oProtectThreatAxisGroupBox.SuspendLayout(); this.m_oOrganizationTabPage.SuspendLayout(); this.m_oShipMoveToTGGroupBox.SuspendLayout(); this.m_oTaskGroupInfoTabPage.SuspendLayout(); @@ -1319,6 +1369,15 @@ private void InitializeComponent() // // m_oSpecialOrdersTabPage // + this.m_oSpecialOrdersTabPage.Controls.Add(this.m_oTaskforceTrainingGroupBox); + this.m_oSpecialOrdersTabPage.Controls.Add(this.m_oSubordinateFormationGroupBox); + this.m_oSpecialOrdersTabPage.Controls.Add(this.groupBox7); + this.m_oSpecialOrdersTabPage.Controls.Add(this.m_oCondOrderAGroupBox); + this.m_oSpecialOrdersTabPage.Controls.Add(this.m_oSuperiorFormationGroupBox); + this.m_oSpecialOrdersTabPage.Controls.Add(this.m_oCombineTaskgroupGroupBox); + this.m_oSpecialOrdersTabPage.Controls.Add(this.m_oCondOrderBGroupBox); + this.m_oSpecialOrdersTabPage.Controls.Add(this.m_oDefaultOrderGroupBox); + this.m_oSpecialOrdersTabPage.Controls.Add(this.m_oProtectThreatAxisGroupBox); this.m_oSpecialOrdersTabPage.Location = new System.Drawing.Point(4, 22); this.m_oSpecialOrdersTabPage.Name = "m_oSpecialOrdersTabPage"; this.m_oSpecialOrdersTabPage.Padding = new System.Windows.Forms.Padding(3); @@ -1327,6 +1386,302 @@ private void InitializeComponent() this.m_oSpecialOrdersTabPage.Text = "Special Orders"; this.m_oSpecialOrdersTabPage.UseVisualStyleBackColor = true; // + // m_oTaskforceTrainingGroupBox + // + this.m_oTaskforceTrainingGroupBox.Controls.Add(this.m_oStartTaskforceTrainingButton); + this.m_oTaskforceTrainingGroupBox.Location = new System.Drawing.Point(6, 345); + this.m_oTaskforceTrainingGroupBox.Name = "m_oTaskforceTrainingGroupBox"; + this.m_oTaskforceTrainingGroupBox.Size = new System.Drawing.Size(320, 78); + this.m_oTaskforceTrainingGroupBox.TabIndex = 7; + this.m_oTaskforceTrainingGroupBox.TabStop = false; + // + // m_oStartTaskforceTrainingButton + // + this.m_oStartTaskforceTrainingButton.Location = new System.Drawing.Point(60, 31); + this.m_oStartTaskforceTrainingButton.Name = "m_oStartTaskforceTrainingButton"; + this.m_oStartTaskforceTrainingButton.Size = new System.Drawing.Size(200, 25); + this.m_oStartTaskforceTrainingButton.TabIndex = 0; + this.m_oStartTaskforceTrainingButton.Text = "Start Task Force Training"; + this.m_oStartTaskforceTrainingButton.UseVisualStyleBackColor = true; + // + // m_oSubordinateFormationGroupBox + // + this.m_oSubordinateFormationGroupBox.Controls.Add(this.m_oSubordinateFormationsListBox); + this.m_oSubordinateFormationGroupBox.Location = new System.Drawing.Point(6, 181); + this.m_oSubordinateFormationGroupBox.Name = "m_oSubordinateFormationGroupBox"; + this.m_oSubordinateFormationGroupBox.Size = new System.Drawing.Size(320, 158); + this.m_oSubordinateFormationGroupBox.TabIndex = 6; + this.m_oSubordinateFormationGroupBox.TabStop = false; + this.m_oSubordinateFormationGroupBox.Text = "Subordinate Formations"; + // + // m_oSubordinateFormationsListBox + // + this.m_oSubordinateFormationsListBox.FormattingEnabled = true; + this.m_oSubordinateFormationsListBox.Location = new System.Drawing.Point(6, 19); + this.m_oSubordinateFormationsListBox.Name = "m_oSubordinateFormationsListBox"; + this.m_oSubordinateFormationsListBox.Size = new System.Drawing.Size(308, 134); + this.m_oSubordinateFormationsListBox.TabIndex = 0; + // + // groupBox7 + // + this.groupBox7.Controls.Add(this.m_oCopyConditionalCheckBox); + this.groupBox7.Controls.Add(this.m_oCopyDefaultCheckBox); + this.groupBox7.Controls.Add(this.m_oMatchSpeedsCheckBox); + this.groupBox7.Controls.Add(this.m_oCopyOrdersToSubordinateButton); + this.groupBox7.Location = new System.Drawing.Point(659, 232); + this.groupBox7.Name = "groupBox7"; + this.groupBox7.Size = new System.Drawing.Size(312, 70); + this.groupBox7.TabIndex = 5; + this.groupBox7.TabStop = false; + this.groupBox7.Text = "Copy Orders to Subordinate Formation"; + // + // m_oCopyConditionalCheckBox + // + this.m_oCopyConditionalCheckBox.AutoSize = true; + this.m_oCopyConditionalCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight; + this.m_oCopyConditionalCheckBox.Location = new System.Drawing.Point(227, 42); + this.m_oCopyConditionalCheckBox.Name = "m_oCopyConditionalCheckBox"; + this.m_oCopyConditionalCheckBox.Size = new System.Drawing.Size(75, 17); + this.m_oCopyConditionalCheckBox.TabIndex = 3; + this.m_oCopyConditionalCheckBox.Text = "Inc. Cond."; + this.m_oCopyConditionalCheckBox.UseVisualStyleBackColor = true; + // + // m_oCopyDefaultCheckBox + // + this.m_oCopyDefaultCheckBox.AutoSize = true; + this.m_oCopyDefaultCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight; + this.m_oCopyDefaultCheckBox.Location = new System.Drawing.Point(221, 19); + this.m_oCopyDefaultCheckBox.Name = "m_oCopyDefaultCheckBox"; + this.m_oCopyDefaultCheckBox.Size = new System.Drawing.Size(81, 17); + this.m_oCopyDefaultCheckBox.TabIndex = 2; + this.m_oCopyDefaultCheckBox.Text = "Inc. Default"; + this.m_oCopyDefaultCheckBox.UseVisualStyleBackColor = true; + // + // m_oMatchSpeedsCheckBox + // + this.m_oMatchSpeedsCheckBox.AutoSize = true; + this.m_oMatchSpeedsCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight; + this.m_oMatchSpeedsCheckBox.Location = new System.Drawing.Point(119, 19); + this.m_oMatchSpeedsCheckBox.Name = "m_oMatchSpeedsCheckBox"; + this.m_oMatchSpeedsCheckBox.Size = new System.Drawing.Size(95, 17); + this.m_oMatchSpeedsCheckBox.TabIndex = 1; + this.m_oMatchSpeedsCheckBox.Text = "Match Speeds"; + this.m_oMatchSpeedsCheckBox.UseVisualStyleBackColor = true; + // + // m_oCopyOrdersToSubordinateButton + // + this.m_oCopyOrdersToSubordinateButton.Location = new System.Drawing.Point(38, 19); + this.m_oCopyOrdersToSubordinateButton.Name = "m_oCopyOrdersToSubordinateButton"; + this.m_oCopyOrdersToSubordinateButton.Size = new System.Drawing.Size(75, 23); + this.m_oCopyOrdersToSubordinateButton.TabIndex = 0; + this.m_oCopyOrdersToSubordinateButton.Text = "Copy"; + this.m_oCopyOrdersToSubordinateButton.UseVisualStyleBackColor = true; + // + // m_oCondOrderAGroupBox + // + this.m_oCondOrderAGroupBox.Controls.Add(this.m_oCondAOrderLabel); + this.m_oCondOrderAGroupBox.Controls.Add(this.m_oCondACondLabel); + this.m_oCondOrderAGroupBox.Controls.Add(this.m_oCondAOrderComboBox); + this.m_oCondOrderAGroupBox.Controls.Add(this.m_oCondAConditionComboBox); + this.m_oCondOrderAGroupBox.Location = new System.Drawing.Point(333, 119); + this.m_oCondOrderAGroupBox.Name = "m_oCondOrderAGroupBox"; + this.m_oCondOrderAGroupBox.Size = new System.Drawing.Size(320, 107); + this.m_oCondOrderAGroupBox.TabIndex = 2; + this.m_oCondOrderAGroupBox.TabStop = false; + this.m_oCondOrderAGroupBox.Text = "Conditional Order A(act on order if condition is met)"; + // + // m_oCondAOrderComboBox + // + this.m_oCondAOrderComboBox.FormattingEnabled = true; + this.m_oCondAOrderComboBox.Location = new System.Drawing.Point(75, 58); + this.m_oCondAOrderComboBox.Margin = new System.Windows.Forms.Padding(7); + this.m_oCondAOrderComboBox.Name = "m_oCondAOrderComboBox"; + this.m_oCondAOrderComboBox.Size = new System.Drawing.Size(235, 21); + this.m_oCondAOrderComboBox.TabIndex = 3; + // + // m_oCondAConditionComboBox + // + this.m_oCondAConditionComboBox.FormattingEnabled = true; + this.m_oCondAConditionComboBox.Location = new System.Drawing.Point(75, 23); + this.m_oCondAConditionComboBox.Margin = new System.Windows.Forms.Padding(7); + this.m_oCondAConditionComboBox.Name = "m_oCondAConditionComboBox"; + this.m_oCondAConditionComboBox.Size = new System.Drawing.Size(235, 21); + this.m_oCondAConditionComboBox.TabIndex = 2; + // + // m_oSuperiorFormationGroupBox + // + this.m_oSuperiorFormationGroupBox.Controls.Add(this.m_oSaveFormationButton); + this.m_oSuperiorFormationGroupBox.Controls.Add(this.m_oSuperiorFormationComboBox); + this.m_oSuperiorFormationGroupBox.Location = new System.Drawing.Point(659, 119); + this.m_oSuperiorFormationGroupBox.Name = "m_oSuperiorFormationGroupBox"; + this.m_oSuperiorFormationGroupBox.Size = new System.Drawing.Size(312, 107); + this.m_oSuperiorFormationGroupBox.TabIndex = 4; + this.m_oSuperiorFormationGroupBox.TabStop = false; + this.m_oSuperiorFormationGroupBox.Text = "Superior Formation"; + // + // m_oSaveFormationButton + // + this.m_oSaveFormationButton.Location = new System.Drawing.Point(119, 54); + this.m_oSaveFormationButton.Name = "m_oSaveFormationButton"; + this.m_oSaveFormationButton.Size = new System.Drawing.Size(75, 23); + this.m_oSaveFormationButton.TabIndex = 4; + this.m_oSaveFormationButton.Text = "Save"; + this.m_oSaveFormationButton.UseVisualStyleBackColor = true; + // + // m_oSuperiorFormationComboBox + // + this.m_oSuperiorFormationComboBox.FormattingEnabled = true; + this.m_oSuperiorFormationComboBox.Location = new System.Drawing.Point(10, 23); + this.m_oSuperiorFormationComboBox.Margin = new System.Windows.Forms.Padding(7); + this.m_oSuperiorFormationComboBox.Name = "m_oSuperiorFormationComboBox"; + this.m_oSuperiorFormationComboBox.Size = new System.Drawing.Size(292, 21); + this.m_oSuperiorFormationComboBox.TabIndex = 3; + // + // m_oCombineTaskgroupGroupBox + // + this.m_oCombineTaskgroupGroupBox.Controls.Add(this.m_oSaveCombineButton); + this.m_oCombineTaskgroupGroupBox.Controls.Add(this.m_oCombineTaskgroupsComboBox); + this.m_oCombineTaskgroupGroupBox.Location = new System.Drawing.Point(659, 6); + this.m_oCombineTaskgroupGroupBox.Name = "m_oCombineTaskgroupGroupBox"; + this.m_oCombineTaskgroupGroupBox.Size = new System.Drawing.Size(312, 107); + this.m_oCombineTaskgroupGroupBox.TabIndex = 3; + this.m_oCombineTaskgroupGroupBox.TabStop = false; + this.m_oCombineTaskgroupGroupBox.Text = "Combine with other Task Group"; + // + // m_oSaveCombineButton + // + this.m_oSaveCombineButton.Location = new System.Drawing.Point(118, 54); + this.m_oSaveCombineButton.Name = "m_oSaveCombineButton"; + this.m_oSaveCombineButton.Size = new System.Drawing.Size(75, 23); + this.m_oSaveCombineButton.TabIndex = 3; + this.m_oSaveCombineButton.Text = "Save"; + this.m_oSaveCombineButton.UseVisualStyleBackColor = true; + // + // m_oCombineTaskgroupsComboBox + // + this.m_oCombineTaskgroupsComboBox.FormattingEnabled = true; + this.m_oCombineTaskgroupsComboBox.Location = new System.Drawing.Point(10, 23); + this.m_oCombineTaskgroupsComboBox.Margin = new System.Windows.Forms.Padding(7); + this.m_oCombineTaskgroupsComboBox.Name = "m_oCombineTaskgroupsComboBox"; + this.m_oCombineTaskgroupsComboBox.Size = new System.Drawing.Size(292, 21); + this.m_oCombineTaskgroupsComboBox.TabIndex = 2; + // + // m_oCondOrderBGroupBox + // + this.m_oCondOrderBGroupBox.Controls.Add(this.m_oCondBOrderLabel); + this.m_oCondOrderBGroupBox.Controls.Add(this.m_oCondBCondLabel); + this.m_oCondOrderBGroupBox.Controls.Add(this.m_oCondBOrderComboBox); + this.m_oCondOrderBGroupBox.Controls.Add(this.m_oCondBConditionComboBox); + this.m_oCondOrderBGroupBox.Location = new System.Drawing.Point(333, 232); + this.m_oCondOrderBGroupBox.Name = "m_oCondOrderBGroupBox"; + this.m_oCondOrderBGroupBox.Size = new System.Drawing.Size(320, 107); + this.m_oCondOrderBGroupBox.TabIndex = 3; + this.m_oCondOrderBGroupBox.TabStop = false; + this.m_oCondOrderBGroupBox.Text = "Conditional Order B(act on order if condition is met)"; + // + // m_oCondBOrderComboBox + // + this.m_oCondBOrderComboBox.FormattingEnabled = true; + this.m_oCondBOrderComboBox.Location = new System.Drawing.Point(75, 58); + this.m_oCondBOrderComboBox.Margin = new System.Windows.Forms.Padding(7); + this.m_oCondBOrderComboBox.Name = "m_oCondBOrderComboBox"; + this.m_oCondBOrderComboBox.Size = new System.Drawing.Size(235, 21); + this.m_oCondBOrderComboBox.TabIndex = 5; + // + // m_oCondBConditionComboBox + // + this.m_oCondBConditionComboBox.FormattingEnabled = true; + this.m_oCondBConditionComboBox.Location = new System.Drawing.Point(75, 23); + this.m_oCondBConditionComboBox.Margin = new System.Windows.Forms.Padding(7); + this.m_oCondBConditionComboBox.Name = "m_oCondBConditionComboBox"; + this.m_oCondBConditionComboBox.Size = new System.Drawing.Size(235, 21); + this.m_oCondBConditionComboBox.TabIndex = 4; + // + // m_oDefaultOrderGroupBox + // + this.m_oDefaultOrderGroupBox.Controls.Add(this.m_oDefaultSecondaryLabel); + this.m_oDefaultOrderGroupBox.Controls.Add(this.m_oDefaultPrimaryLabel); + this.m_oDefaultOrderGroupBox.Controls.Add(this.m_oSecondaryDefaultOrdersComboBox); + this.m_oDefaultOrderGroupBox.Controls.Add(this.m_oPrimaryDefaultOrdersComboBox); + this.m_oDefaultOrderGroupBox.Location = new System.Drawing.Point(333, 6); + this.m_oDefaultOrderGroupBox.Name = "m_oDefaultOrderGroupBox"; + this.m_oDefaultOrderGroupBox.Size = new System.Drawing.Size(320, 105); + this.m_oDefaultOrderGroupBox.TabIndex = 1; + this.m_oDefaultOrderGroupBox.TabStop = false; + this.m_oDefaultOrderGroupBox.Text = "Default Orders(if no other orders are set)"; + // + // m_oSecondaryDefaultOrdersComboBox + // + this.m_oSecondaryDefaultOrdersComboBox.FormattingEnabled = true; + this.m_oSecondaryDefaultOrdersComboBox.Location = new System.Drawing.Point(75, 58); + this.m_oSecondaryDefaultOrdersComboBox.Margin = new System.Windows.Forms.Padding(7); + this.m_oSecondaryDefaultOrdersComboBox.Name = "m_oSecondaryDefaultOrdersComboBox"; + this.m_oSecondaryDefaultOrdersComboBox.Size = new System.Drawing.Size(235, 21); + this.m_oSecondaryDefaultOrdersComboBox.TabIndex = 1; + // + // m_oPrimaryDefaultOrdersComboBox + // + this.m_oPrimaryDefaultOrdersComboBox.FormattingEnabled = true; + this.m_oPrimaryDefaultOrdersComboBox.Location = new System.Drawing.Point(75, 23); + this.m_oPrimaryDefaultOrdersComboBox.Margin = new System.Windows.Forms.Padding(7); + this.m_oPrimaryDefaultOrdersComboBox.Name = "m_oPrimaryDefaultOrdersComboBox"; + this.m_oPrimaryDefaultOrdersComboBox.Size = new System.Drawing.Size(235, 21); + this.m_oPrimaryDefaultOrdersComboBox.TabIndex = 0; + // + // m_oProtectThreatAxisGroupBox + // + this.m_oProtectThreatAxisGroupBox.Controls.Add(this.m_oBearingThreatLabel); + this.m_oProtectThreatAxisGroupBox.Controls.Add(this.m_oOffsetthreatLabel); + this.m_oProtectThreatAxisGroupBox.Controls.Add(this.m_oThreatDistanceLabel); + this.m_oProtectThreatAxisGroupBox.Controls.Add(this.m_oTaskGroupThreatLabel); + this.m_oProtectThreatAxisGroupBox.Controls.Add(this.m_oThreatLabel); + this.m_oProtectThreatAxisGroupBox.Controls.Add(this.comboBox12); + this.m_oProtectThreatAxisGroupBox.Controls.Add(this.comboBox11); + this.m_oProtectThreatAxisGroupBox.Controls.Add(this.comboBox10); + this.m_oProtectThreatAxisGroupBox.Controls.Add(this.comboBox9); + this.m_oProtectThreatAxisGroupBox.Location = new System.Drawing.Point(6, 6); + this.m_oProtectThreatAxisGroupBox.Name = "m_oProtectThreatAxisGroupBox"; + this.m_oProtectThreatAxisGroupBox.Size = new System.Drawing.Size(320, 169); + this.m_oProtectThreatAxisGroupBox.TabIndex = 0; + this.m_oProtectThreatAxisGroupBox.TabStop = false; + this.m_oProtectThreatAxisGroupBox.Text = "Protect Threat Axis(Acts as Highest Priority default order)"; + // + // comboBox12 + // + this.comboBox12.FormattingEnabled = true; + this.comboBox12.Location = new System.Drawing.Point(75, 128); + this.comboBox12.Margin = new System.Windows.Forms.Padding(7); + this.comboBox12.Name = "comboBox12"; + this.comboBox12.Size = new System.Drawing.Size(235, 21); + this.comboBox12.TabIndex = 7; + // + // comboBox11 + // + this.comboBox11.FormattingEnabled = true; + this.comboBox11.Location = new System.Drawing.Point(75, 93); + this.comboBox11.Margin = new System.Windows.Forms.Padding(7); + this.comboBox11.Name = "comboBox11"; + this.comboBox11.Size = new System.Drawing.Size(235, 21); + this.comboBox11.TabIndex = 6; + // + // comboBox10 + // + this.comboBox10.FormattingEnabled = true; + this.comboBox10.Location = new System.Drawing.Point(75, 58); + this.comboBox10.Margin = new System.Windows.Forms.Padding(7); + this.comboBox10.Name = "comboBox10"; + this.comboBox10.Size = new System.Drawing.Size(235, 21); + this.comboBox10.TabIndex = 5; + // + // comboBox9 + // + this.comboBox9.FormattingEnabled = true; + this.comboBox9.Location = new System.Drawing.Point(75, 23); + this.comboBox9.Margin = new System.Windows.Forms.Padding(7); + this.comboBox9.Name = "comboBox9"; + this.comboBox9.Size = new System.Drawing.Size(235, 21); + this.comboBox9.TabIndex = 4; + // // m_oOrganizationTabPage // this.m_oOrganizationTabPage.Controls.Add(this.m_oShipMoveToTGGroupBox); @@ -1843,6 +2198,105 @@ private void InitializeComponent() this.m_oNewTGButton.Text = "&New TG"; this.m_oNewTGButton.UseVisualStyleBackColor = true; // + // m_oDefaultPrimaryLabel + // + this.m_oDefaultPrimaryLabel.AutoSize = true; + this.m_oDefaultPrimaryLabel.Location = new System.Drawing.Point(6, 26); + this.m_oDefaultPrimaryLabel.Name = "m_oDefaultPrimaryLabel"; + this.m_oDefaultPrimaryLabel.Size = new System.Drawing.Size(41, 13); + this.m_oDefaultPrimaryLabel.TabIndex = 2; + this.m_oDefaultPrimaryLabel.Text = "Primary"; + // + // m_oDefaultSecondaryLabel + // + this.m_oDefaultSecondaryLabel.AutoSize = true; + this.m_oDefaultSecondaryLabel.Location = new System.Drawing.Point(6, 61); + this.m_oDefaultSecondaryLabel.Name = "m_oDefaultSecondaryLabel"; + this.m_oDefaultSecondaryLabel.Size = new System.Drawing.Size(58, 13); + this.m_oDefaultSecondaryLabel.TabIndex = 3; + this.m_oDefaultSecondaryLabel.Text = "Secondary"; + // + // m_oCondACondLabel + // + this.m_oCondACondLabel.AutoSize = true; + this.m_oCondACondLabel.Location = new System.Drawing.Point(6, 26); + this.m_oCondACondLabel.Name = "m_oCondACondLabel"; + this.m_oCondACondLabel.Size = new System.Drawing.Size(51, 13); + this.m_oCondACondLabel.TabIndex = 4; + this.m_oCondACondLabel.Text = "Condition"; + // + // m_oCondAOrderLabel + // + this.m_oCondAOrderLabel.AutoSize = true; + this.m_oCondAOrderLabel.Location = new System.Drawing.Point(6, 61); + this.m_oCondAOrderLabel.Name = "m_oCondAOrderLabel"; + this.m_oCondAOrderLabel.Size = new System.Drawing.Size(33, 13); + this.m_oCondAOrderLabel.TabIndex = 5; + this.m_oCondAOrderLabel.Text = "Order"; + // + // m_oCondBCondLabel + // + this.m_oCondBCondLabel.AutoSize = true; + this.m_oCondBCondLabel.Location = new System.Drawing.Point(6, 24); + this.m_oCondBCondLabel.Name = "m_oCondBCondLabel"; + this.m_oCondBCondLabel.Size = new System.Drawing.Size(51, 13); + this.m_oCondBCondLabel.TabIndex = 6; + this.m_oCondBCondLabel.Text = "Condition"; + // + // m_oCondBOrderLabel + // + this.m_oCondBOrderLabel.AutoSize = true; + this.m_oCondBOrderLabel.Location = new System.Drawing.Point(6, 61); + this.m_oCondBOrderLabel.Name = "m_oCondBOrderLabel"; + this.m_oCondBOrderLabel.Size = new System.Drawing.Size(33, 13); + this.m_oCondBOrderLabel.TabIndex = 7; + this.m_oCondBOrderLabel.Text = "Order"; + // + // m_oThreatLabel + // + this.m_oThreatLabel.AutoSize = true; + this.m_oThreatLabel.Location = new System.Drawing.Point(6, 26); + this.m_oThreatLabel.Name = "m_oThreatLabel"; + this.m_oThreatLabel.Size = new System.Drawing.Size(38, 13); + this.m_oThreatLabel.TabIndex = 8; + this.m_oThreatLabel.Text = "Threat"; + // + // m_oTaskGroupThreatLabel + // + this.m_oTaskGroupThreatLabel.AutoSize = true; + this.m_oTaskGroupThreatLabel.Location = new System.Drawing.Point(6, 59); + this.m_oTaskGroupThreatLabel.Name = "m_oTaskGroupThreatLabel"; + this.m_oTaskGroupThreatLabel.Size = new System.Drawing.Size(58, 13); + this.m_oTaskGroupThreatLabel.TabIndex = 9; + this.m_oTaskGroupThreatLabel.Text = "Taskgroup"; + // + // m_oThreatDistanceLabel + // + this.m_oThreatDistanceLabel.AutoSize = true; + this.m_oThreatDistanceLabel.Location = new System.Drawing.Point(6, 96); + this.m_oThreatDistanceLabel.Name = "m_oThreatDistanceLabel"; + this.m_oThreatDistanceLabel.Size = new System.Drawing.Size(49, 13); + this.m_oThreatDistanceLabel.TabIndex = 10; + this.m_oThreatDistanceLabel.Text = "Distance"; + // + // m_oOffsetthreatLabel + // + this.m_oOffsetthreatLabel.AutoSize = true; + this.m_oOffsetthreatLabel.Location = new System.Drawing.Point(6, 131); + this.m_oOffsetthreatLabel.Name = "m_oOffsetthreatLabel"; + this.m_oOffsetthreatLabel.Size = new System.Drawing.Size(35, 13); + this.m_oOffsetthreatLabel.TabIndex = 11; + this.m_oOffsetthreatLabel.Text = "Offset"; + // + // m_oBearingThreatLabel + // + this.m_oBearingThreatLabel.AutoSize = true; + this.m_oBearingThreatLabel.Location = new System.Drawing.Point(6, 144); + this.m_oBearingThreatLabel.Name = "m_oBearingThreatLabel"; + this.m_oBearingThreatLabel.Size = new System.Drawing.Size(43, 13); + this.m_oBearingThreatLabel.TabIndex = 12; + this.m_oBearingThreatLabel.Text = "Bearing"; + // // TaskGroup_Panel // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1874,6 +2328,21 @@ private void InitializeComponent() this.m_oCopyOrdersGroupBox.PerformLayout(); this.m_oSystemDisplayOptionsBox.ResumeLayout(false); this.m_oSystemDisplayOptionsBox.PerformLayout(); + this.m_oSpecialOrdersTabPage.ResumeLayout(false); + this.m_oTaskforceTrainingGroupBox.ResumeLayout(false); + this.m_oSubordinateFormationGroupBox.ResumeLayout(false); + this.groupBox7.ResumeLayout(false); + this.groupBox7.PerformLayout(); + this.m_oCondOrderAGroupBox.ResumeLayout(false); + this.m_oCondOrderAGroupBox.PerformLayout(); + this.m_oSuperiorFormationGroupBox.ResumeLayout(false); + this.m_oCombineTaskgroupGroupBox.ResumeLayout(false); + this.m_oCondOrderBGroupBox.ResumeLayout(false); + this.m_oCondOrderBGroupBox.PerformLayout(); + this.m_oDefaultOrderGroupBox.ResumeLayout(false); + this.m_oDefaultOrderGroupBox.PerformLayout(); + this.m_oProtectThreatAxisGroupBox.ResumeLayout(false); + this.m_oProtectThreatAxisGroupBox.PerformLayout(); this.m_oOrganizationTabPage.ResumeLayout(false); this.m_oShipMoveToTGGroupBox.ResumeLayout(false); this.m_oShipMoveToTGGroupBox.PerformLayout(); @@ -2021,5 +2490,45 @@ private void InitializeComponent() private Button m_oOrgMoveRightButton; private ComboBox m_oOrgSelectedTGComboBox; private TextBox m_oOrgCurrentTGTextBox; + private GroupBox m_oCombineTaskgroupGroupBox; + private GroupBox m_oCondOrderBGroupBox; + private GroupBox m_oCondOrderAGroupBox; + private GroupBox m_oDefaultOrderGroupBox; + private GroupBox m_oProtectThreatAxisGroupBox; + private GroupBox m_oSuperiorFormationGroupBox; + private GroupBox groupBox7; + private GroupBox m_oSubordinateFormationGroupBox; + private ComboBox m_oCondAOrderComboBox; + private ComboBox m_oCondAConditionComboBox; + private ComboBox m_oSuperiorFormationComboBox; + private ComboBox m_oCombineTaskgroupsComboBox; + private ComboBox m_oCondBOrderComboBox; + private ComboBox m_oCondBConditionComboBox; + private ComboBox m_oSecondaryDefaultOrdersComboBox; + private ComboBox m_oPrimaryDefaultOrdersComboBox; + private ComboBox comboBox12; + private ComboBox comboBox11; + private ComboBox comboBox10; + private ComboBox comboBox9; + private GroupBox m_oTaskforceTrainingGroupBox; + private Button m_oStartTaskforceTrainingButton; + private Button m_oCopyOrdersToSubordinateButton; + private Button m_oSaveFormationButton; + private Button m_oSaveCombineButton; + private ListBox m_oSubordinateFormationsListBox; + private CheckBox m_oCopyConditionalCheckBox; + private CheckBox m_oCopyDefaultCheckBox; + private CheckBox m_oMatchSpeedsCheckBox; + private Label m_oCondAOrderLabel; + private Label m_oCondACondLabel; + private Label m_oCondBOrderLabel; + private Label m_oCondBCondLabel; + private Label m_oDefaultSecondaryLabel; + private Label m_oDefaultPrimaryLabel; + private Label m_oBearingThreatLabel; + private Label m_oOffsetthreatLabel; + private Label m_oThreatDistanceLabel; + private Label m_oTaskGroupThreatLabel; + private Label m_oThreatLabel; } } \ No newline at end of file From 81fe80fd94503606e88a4f110b817b56d610539b Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 25 Oct 2015 15:17:05 -0500 Subject: [PATCH 17/40] More groundwork for conditional orders taskgroups will be able to determine based on pre-set conditions if there is some task they should perform without further user input when done. the list of orders should be extensible, and merely a matter of implementing the order when all is said and done. --- Pulsar4X/Pulsar4X.Lib/Constants.cs | 114 ++++++++++++++++++ Pulsar4X/Pulsar4X.Lib/Entities/Order.cs | 25 ++++ .../Entities/StarSystem/TaskGroup.cs | 79 +++++++++++- 3 files changed, 214 insertions(+), 4 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Constants.cs b/Pulsar4X/Pulsar4X.Lib/Constants.cs index 6bc5714ab..47ff90a31 100644 --- a/Pulsar4X/Pulsar4X.Lib/Constants.cs +++ b/Pulsar4X/Pulsar4X.Lib/Constants.cs @@ -474,6 +474,120 @@ public enum LoadType Troop, TypeCount } + + public enum DefaultOrders + { + NoSpecialOrder, + SurveyNearestAsteroid, + SurveyNearestMoon, + SurveyNearestPlanet, + SurveyNearestPlanetOrMoon, + SurveyNearestBody, + SurveyNextFiveBodies, + SurveyNearestSurveyLocation, + SurveyNextThreeSurveyLocations, + + /// + /// Superior formation. + /// + FollowHigherFleetInSystem, + MoveToEntryJumpPoint, + RefuelInCurrentSystem, + + /// + /// Any Colony with > 25M people that is set as a colonist source. + /// + LoadColonistsAtNearestSource, + LoadColonistsAtCapital, + + /// + /// Any colony with less than 25M people, or otherwise set as a colonist destination. + /// + UnloadColonistsAtNearestDestination, + BuildJumpGateAtNearestJumpPoint, + + /// + /// Colony with citizens who likely don't need automines. + /// + LoadAutomineFromPopulation, + + /// + /// No people, only mines present, + /// + UnloadAutomineToMiningColony, + + /// + /// Special tradeship only conditional. + /// + MoveToTradeLocation, + + /// + /// Luxury ships? rescue vessels? + /// + UnloadPassengersAtNearestColony, + + /// + /// World with minerals available above world reserve levels? + /// + MoveToMineralSource, + MoveToSoriumGasGiant, + SalvageNearestWreck, + TerraformColony, + TypeCount + } + + public enum Condition + { + NoCondition, + FuelLessThan50, + FuelLessThan40, + FuelLessThan30, + FuelLessThan20, + FuelLessThan10, + FuelTanksFull, + ParentFleetInSystem, + SubFleetInSameLocation, + SpeedLessThanMax, + SupplyPointsLessThan20, + SupplyPointsLessThan10, + HostileActiveContactInSystem, + TypeCount + } + + public enum ConditionalOrders + { + NoConditionalOrder, + Unload90PercentOfFuelAtNearestColony, + UnloadFuelAtColonyAndMoveToSoriumGasGiant, + JoinParentFleetIfInSystem, + RefuelAtNearestColony, + + /// + /// Tanker must have more than 10% of its fuel available to refuel with. + /// + RefuelAtNearestAvailableTanker, + + /// + /// Can be world or tanker. + /// + RefuelAtNearestAvailableSource, + + /// + /// All restrictions that apply to fuel harvesting apply here. + /// + ResupplyAtNearestColony, + ResupplyAtNearestSupplyShip, + RessuplyAtNearestSource, + + ActivateShields, + DeactivateShields, + ClearOrders, + IncorporateSubFleetsAtLocation, + ChangeToMaximumSpeed, + ActiveSensorsOn, + OverhaulAtNearestColony, + TypeCount + } } /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Order.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Order.cs index bed7bb3a3..4e47fb974 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Order.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Order.cs @@ -326,5 +326,30 @@ public Order(Constants.ShipTN.OrderType TypeOrder, int SecondaryOrder, int Terti } } + public class ConditionalOrders + { + /// + /// Order priority is based on their own order within the list. the 1st default order is primary, second is secondary, and so on. + /// + public BindingList _DefaultOrdersList { get; set; } + + /// + /// Conditions work the same as order priority above, and the same as orders for that matter. earlier ones in the list are done/checked first. + /// + public BindingList _ConditionList { get; set; } + + /// + /// Orders to execute if the above conditions match up. + /// + public BindingList _ConditionalOrdersList { get; set; } + + public ConditionalOrders() + { + _DefaultOrdersList = new BindingList(); + _ConditionList = new BindingList(); + _ConditionalOrdersList = new BindingList(); + } + } + } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index 41cc10e88..7102134f6 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -219,6 +219,11 @@ public class TaskGroupTN : StarSystemEntity /// public float _SurveyHourFraction { get; set; } + /// + /// What default and conditional orders does this taskgroup have, if any. + /// + public ConditionalOrders _SpecialOrders { get; set; } + /// /// Constructor for the taskgroup, sets name, faction, planet the TG starts in orbit of. /// @@ -262,6 +267,7 @@ public TaskGroupTN(string Title, Faction FID, OrbitingEntity StartingBody, StarS TimeRequirement = 0; TaskGroupOrders = new BindingList(); + _SpecialOrders = new ConditionalOrders(); TotalOrderDistance = 0.0; @@ -2014,8 +2020,20 @@ public void FollowOrders(uint TimeSlice) } else { - DrawTravelLine = 1; - CanOrder = Constants.ShipTN.OrderState.AcceptOrders; + /// + /// Check conditional and default orders if any. + /// + ProcessDefaultOrders(); + ProcessConditionalOrders(); + + /// + /// Check again to see if no conditional orders got added to taskgroup orders. + /// + if (TaskGroupOrders.Count == 0) + { + DrawTravelLine = 1; + CanOrder = Constants.ShipTN.OrderState.AcceptOrders; + } } } } @@ -2921,8 +2939,8 @@ public uint PerformOrders(uint TimeSlice) break; #endregion -#warning implement GravSurvey - #region GravSurvey to be implemented + + #region GravSurvey case (int)Constants.ShipTN.OrderType.GravSurvey: /// /// Figure out how to store survey results with a star. I think that Partial for each point, and then a full system wide 0% or 100% bool will work. @@ -3021,6 +3039,42 @@ public uint PerformOrders(uint TimeSlice) return TimeSlice; } + /// + /// Any conditional or default orders must also be accomplished here. these will insert real orders based on the conditions involved into the TaskGroupOrders list. + /// + public void ProcessDefaultOrders() + { + foreach(Constants.ShipTN.DefaultOrders DO in _SpecialOrders._DefaultOrdersList) + { + if (DO == Constants.ShipTN.DefaultOrders.NoSpecialOrder) + continue; + + /// + /// Default orders need to be checked to see if they are possible, and if so then placed into the list of Taskgroup orders. there is no reason to interrupt + /// regular orders for a default order. + /// + } + } + + /// + /// Same for this function. + /// + public void ProcessConditionalOrders() + { + foreach (Constants.ShipTN.Condition Cond in _SpecialOrders._ConditionList) + { + if (Cond == Constants.ShipTN.Condition.NoCondition) + continue; + + /// + /// First Cond needs to be checked to see if it has occurred or not. if that is the case, then the conditional order must also be processed, and a regular order + /// added to the list of TaskGroupOrders. Conditional order checking may be worthwhile to interrupt regular orders for, such as fuel constraints. + /// + int cIndex = _SpecialOrders._ConditionList.IndexOf(Cond); + Constants.ShipTN.ConditionalOrders CO = _SpecialOrders._ConditionalOrdersList[cIndex]; + } + } + /// /// Clears the current orders for this TG. Make sure to check to see if we are at a planet, if so we are orbiting. /// @@ -3028,6 +3082,9 @@ public void clearAllOrders() { if (TaskGroupOrders.Count > 0) { + /// + /// Check whether we are in orbit. + /// if ((TaskGroupOrders[0].target.SSEntity == StarSystemEntityType.Body || TaskGroupOrders[0].target.SSEntity == StarSystemEntityType.Population) && (Contact.Position.X == TaskGroupOrders[0].target.Position.X && Contact.Position.Y == TaskGroupOrders[0].target.Position.Y)) { @@ -3049,6 +3106,20 @@ public void clearAllOrders() OrbitingPlanet.TaskGroupsInOrbit.Add(this); } } + + /// + /// inform taskgroups that this taskgroup is no longer ordered to target them in some manner. + /// + foreach (Order TGO in TaskGroupOrders) + { + if (TGO.target.SSEntity == StarSystemEntityType.TaskGroup) + { + if (TGO.taskGroup.TaskGroupsOrdered.Contains(this) == true) + { + TGO.taskGroup.TaskGroupsOrdered.Remove(this); + } + } + } } TaskGroupOrders.Clear(); TimeRequirement = 0; From 2bda795e13253ef3aad5f9d6fc4cf0598d360404 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 1 Nov 2015 00:44:00 -0500 Subject: [PATCH 18/40] Survey in progress work Each system now keeps a list of what surveying is currently in progress, and taskgroups will now check on order removal to make sure that this list does not have spurious entries in it. this is important for default orders to work properly, and make sure that multiple ships don't re-survey the same point or body. --- Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs | 22 ++- .../Entities/StarSystem/StarSystem.cs | 12 ++ .../Entities/StarSystem/TaskGroup.cs | 143 +++++++++++++++++- Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs | 12 +- 4 files changed, 180 insertions(+), 9 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs b/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs index e88facfeb..cefda9e22 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs @@ -1022,8 +1022,14 @@ public void AdvanceSim(BindingList P, Random RNG, int deltaSeconds) /// if ((value & (int)Faction.RechargeStatus.Destroyed) == (int)Faction.RechargeStatus.Destroyed) { + /// + /// Every ship ordered to travel to this ship needs to update to reflect that it is now destroyed. + /// RemoveTaskGroupsOrdered(pair); + /// + /// Every faction that has detected this ship needs to have that cleared. + /// foreach (Faction CurrentFaction in P) { StarSystem CurSystem = Ship.ShipsTaskGroup.Contact.Position.System; @@ -1077,9 +1083,21 @@ public void AdvanceSim(BindingList P, Random RNG, int deltaSeconds) Ship.ShipsTaskGroup.Ships.Remove(pair.Key); Ship.ShipsFaction.Ships.Remove(pair.Key); + /// + /// This taskgroup is now empty, so remove friendly taskgroups moving to this taskgroup. + /// if (Ship.ShipsTaskGroup.Ships.Count == 0) { RemoveFriendlyTaskGroupsOrdered(pair); + + /// + /// Remove every order issued to this taskgroup. some of them may have special conditions such as they survey orders, and the simulation needs to know + /// that a survey in progress isn't being carried out by a body anymore due to ship destruction. + /// + foreach (Order TGO in Ship.ShipsTaskGroup.TaskGroupOrders) + { + Ship.ShipsTaskGroup.RemoveOrder(TGO); + } } RemoveShipsTargetting(pair); @@ -1161,7 +1179,7 @@ private void RemoveTaskGroupsOrdered(KeyValuePair pair) int lastOrder = TaskGroupOrdered.TaskGroupOrders.Count - 1; for (int orderListIterator = lastOrder; orderListIterator >= orderIterator; orderListIterator--) { - TaskGroupOrdered.TaskGroupOrders.RemoveAt(orderListIterator); + TaskGroupOrdered.RemoveOrder(orderListIterator); } break; } @@ -1203,7 +1221,7 @@ private void RemoveFriendlyTaskGroupsOrdered(KeyValuePair pair) int lastOrder = TaskGroupOrdered.TaskGroupOrders.Count - 1; for (int orderListIterator = lastOrder; orderListIterator >= orderIterator; orderListIterator--) { - TaskGroupOrdered.TaskGroupOrders.RemoveAt(orderListIterator); + TaskGroupOrdered.RemoveOrder(orderListIterator); } break; } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs index 6625b1dc7..2eab9bd35 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs @@ -42,11 +42,23 @@ public enum Status /// public BindingList _DetectedJPs { get; set; } + /// + /// These points are marked as claimed for survey purpose so that more than one survey ship doesn't attempt to survey the same point. + /// + public BindingList _GravSurveyInProgress { get; set; } + + /// + /// These system bodies are "claimed" by the geo survey craft surveying them, this should prevent multiple craft from surveying the same body. + /// + public BindingList _GeoSurveyInProgress { get; set; } + public JPDetection() { _SurveyStatus = Status.None; _SurveyedPoints = new BindingList(); _DetectedJPs = new BindingList(); + _GravSurveyInProgress = new BindingList(); + _GeoSurveyInProgress = new BindingList(); } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index 7102134f6..2e9a952a2 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -1888,6 +1888,105 @@ public void IssueOrder(Order OrderToTaskGroup, int index = -1) } dZ = Math.Sqrt(((dX * dX) + (dY * dY))); TotalOrderDistance = TotalOrderDistance + dZ; + + /// + /// Check to see if a GeoSurvey Order or GravSurvey order was added. The survey body should be added to the survey in progress list for the current system. + /// + if (OrderToTaskGroup.typeOf == Constants.ShipTN.OrderType.GeoSurvey) + { + /// + /// A geoSurvey order without a OrderToTaskGroup.body is a problem further up the chain. + /// + if (Contact.Position.System._SurveyResults.ContainsKey(TaskGroupFaction) == true) + { + if (Contact.Position.System._SurveyResults[TaskGroupFaction]._GeoSurveyInProgress.Contains(OrderToTaskGroup.body) == false) + { + /// + /// if this is true then someone else is also geosurveying the world, but I don't care about that. + /// + Contact.Position.System._SurveyResults[TaskGroupFaction]._GeoSurveyInProgress.Add(OrderToTaskGroup.body); + } + } + else + { + JPDetection NewDetection = new JPDetection(); + Contact.Position.System._SurveyResults.Add(TaskGroupFaction, NewDetection); + Contact.Position.System._SurveyResults[TaskGroupFaction]._GeoSurveyInProgress.Add(OrderToTaskGroup.body); + } + } + else if (OrderToTaskGroup.typeOf == Constants.ShipTN.OrderType.GravSurvey) + { + /// + /// A gravSurvey order without a surveyPointOrder is a problem further up the chain. + /// + if (Contact.Position.System._SurveyResults.ContainsKey(TaskGroupFaction) == true) + { + if (Contact.Position.System._SurveyResults[TaskGroupFaction]._GravSurveyInProgress.Contains(OrderToTaskGroup.surveyPointOrder) == false) + { + /// + /// if this is true then someone else is also geosurveying the world, but I don't care about that. + /// + Contact.Position.System._SurveyResults[TaskGroupFaction]._GravSurveyInProgress.Add(OrderToTaskGroup.surveyPointOrder); + } + } + else + { + JPDetection NewDetection = new JPDetection(); + Contact.Position.System._SurveyResults.Add(TaskGroupFaction, NewDetection); + Contact.Position.System._SurveyResults[TaskGroupFaction]._GravSurveyInProgress.Add(OrderToTaskGroup.surveyPointOrder); + } + } + } + + /// + /// Order removal needs to check the survey results member for the current system to check to see if a survey is in progress because of this order. if so remove it. + /// + /// + /// Orders that successfully complete do not need to check Geo/grav survey and will be removed with this function. + public void RemoveOrder(int orderIndex, bool SkipCheck = false) + { + if (SkipCheck == true) + { + if (TaskGroupOrders.Count > orderIndex) + { + if (TaskGroupOrders[orderIndex].typeOf == Constants.ShipTN.OrderType.GeoSurvey) + { + if (Contact.Position.System._SurveyResults[TaskGroupFaction]._GeoSurveyInProgress.Contains(TaskGroupOrders[orderIndex].body) == true) + { + Contact.Position.System._SurveyResults[TaskGroupFaction]._GeoSurveyInProgress.Remove(TaskGroupOrders[orderIndex].body); + } + } + if (TaskGroupOrders[orderIndex].typeOf == Constants.ShipTN.OrderType.GravSurvey) + { + if (Contact.Position.System._SurveyResults[TaskGroupFaction]._GravSurveyInProgress.Contains(TaskGroupOrders[orderIndex].surveyPointOrder) == true) + { + Contact.Position.System._SurveyResults[TaskGroupFaction]._GravSurveyInProgress.Remove(TaskGroupOrders[orderIndex].surveyPointOrder); + } + } + } + } + + TaskGroupOrders.RemoveAt(orderIndex); + } + + public void RemoveOrder(Order orderToRemove) + { + if (orderToRemove.typeOf == Constants.ShipTN.OrderType.GeoSurvey) + { + if (Contact.Position.System._SurveyResults[TaskGroupFaction]._GeoSurveyInProgress.Contains(orderToRemove.body) == true) + { + Contact.Position.System._SurveyResults[TaskGroupFaction]._GeoSurveyInProgress.Remove(orderToRemove.body); + } + } + if (orderToRemove.typeOf == Constants.ShipTN.OrderType.GravSurvey) + { + if (Contact.Position.System._SurveyResults[TaskGroupFaction]._GravSurveyInProgress.Contains(orderToRemove.surveyPointOrder) == true) + { + Contact.Position.System._SurveyResults[TaskGroupFaction]._GravSurveyInProgress.Remove(orderToRemove.surveyPointOrder); + } + } + + TaskGroupOrders.Remove(orderToRemove); } @@ -2011,7 +2110,12 @@ public void FollowOrders(uint TimeSlice) } } } - TaskGroupOrders.RemoveAt(0); + + /// + /// This order was completed successfully, so do not bother checking it for any conditions. + /// + RemoveOrder(0, true); + //TaskGroupOrders.RemoveAt(0); if (TaskGroupOrders.Count > 0) { @@ -2034,9 +2138,14 @@ public void FollowOrders(uint TimeSlice) DrawTravelLine = 1; CanOrder = Constants.ShipTN.OrderState.AcceptOrders; } - } - } - } + else + { + NewOrders = true; + FollowOrders(TimeSlice); + } + }//end else taskgrouporders.Count > 0. as a result check for conditional and default orders. + }//end if timeslice > 0, which means follow orders for the timeslice. + }//end if timeRequirement for orders < timeSlice, which means orders can be completed within the timeslice. else { @@ -2931,6 +3040,16 @@ public uint PerformOrders(uint TimeSlice) if (OB._mineralsGenerated == false) OB.GenerateMinerals(); } + + /// + /// Clear the survey in progress list. + /// + if (Contact.Position.System._SurveyResults.ContainsKey(TaskGroupFaction) == true) + { + if (Contact.Position.System._SurveyResults[TaskGroupFaction]._GeoSurveyInProgress.Contains(OB) == true) + Contact.Position.System._SurveyResults[TaskGroupFaction]._GeoSurveyInProgress.Remove(OB); + } + //handle adding the faction to the survey list when complete //generate minerals? _GeoSurveyPoints = 0; @@ -3025,6 +3144,15 @@ public uint PerformOrders(uint TimeSlice) } } + /// + /// Clear the survey in progress list. + /// + if (Contact.Position.System._SurveyResults.ContainsKey(TaskGroupFaction) == true) + { + if (Contact.Position.System._SurveyResults[TaskGroupFaction]._GravSurveyInProgress.Contains(TaskGroupOrders[0].surveyPointOrder) == true) + Contact.Position.System._SurveyResults[TaskGroupFaction]._GravSurveyInProgress.Remove(TaskGroupOrders[0].surveyPointOrder); + } + _GravSurveyPoints = 0; _SurveyHourFraction = 0.0f; } @@ -3053,6 +3181,13 @@ public void ProcessDefaultOrders() /// Default orders need to be checked to see if they are possible, and if so then placed into the list of Taskgroup orders. there is no reason to interrupt /// regular orders for a default order. /// + switch (DO) + { + case Constants.ShipTN.DefaultOrders.SurveyNearestBody: + break; + case Constants.ShipTN.DefaultOrders.SurveyNearestSurveyLocation: + break; + } } } diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs index f9c2729ce..c97b4ef0c 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs @@ -540,10 +540,12 @@ private void RemoveButton_Clicked(object sender, EventArgs e) } if (removeindex == -1) - CurrentTaskGroup.TaskGroupOrders.Remove(CurrentTaskGroup.TaskGroupOrders.Last()); + CurrentTaskGroup.RemoveOrder(CurrentTaskGroup.TaskGroupOrders.Last()); + //CurrentTaskGroup.TaskGroupOrders.Remove(CurrentTaskGroup.TaskGroupOrders.Last()); else { - CurrentTaskGroup.TaskGroupOrders.RemoveAt(removeindex); + CurrentTaskGroup.RemoveOrder(removeindex); + //CurrentTaskGroup.TaskGroupOrders.RemoveAt(removeindex); //int prevIndex = SelectedOrderIndex; //SelectedOrderIndex = -1; //m_oTaskGroupPanel.PlottedMovesListBox.SelectedIndex = prevIndex; @@ -562,7 +564,11 @@ private void RemoveButton_Clicked(object sender, EventArgs e) /// private void RemoveAllButton_Clicked(object sender, EventArgs e) { - CurrentTaskGroup.TaskGroupOrders.Clear(); + foreach(Order TGO in CurrentTaskGroup.TaskGroupOrders) + { + CurrentTaskGroup.RemoveOrder(TGO); + } + //CurrentTaskGroup.TaskGroupOrders.Clear(); ClearActionList(); m_oTaskGroupPanel.PlottedMovesListBox.Items.Clear(); CalculateTimeDistance(); From d75ed70ae4ededd8c1c71a5a9d48e3cf284f7cad Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 7 Nov 2015 20:21:01 -0600 Subject: [PATCH 19/40] Implementation of Default orders for survey The only piece left for survey is connecting the UI to the back end so that default orders selected by the user translate into action. --- .../Pulsar4X.Lib/Entities/MessageEntry.cs | 3 + .../Entities/StarSystem/TaskGroup.cs | 123 +++++++++++++++++- Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs | 34 +++++ .../Panels/TaskGroup_Panel.Designer.cs | 35 +++++ 4 files changed, 193 insertions(+), 2 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/MessageEntry.cs b/Pulsar4X/Pulsar4X.Lib/Entities/MessageEntry.cs index 5da9710f3..db08056f0 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/MessageEntry.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/MessageEntry.cs @@ -43,6 +43,9 @@ public enum MessageType MissileMissed, MissileOutOfFuel, + NoGeoSurveyTarget, + NoGravSurveyTarget, + OrdersCompleted, OrdersNotCompleted, diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index 2e9a952a2..ca75a1612 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -3183,10 +3183,129 @@ public void ProcessDefaultOrders() /// switch (DO) { + #region Survey Nearest Body case Constants.ShipTN.DefaultOrders.SurveyNearestBody: - break; + float lowestDistance = -1.0f; + SystemBody ClosestSB = null; + StarSystem CurrentSystem = Contact.Position.System; + + /// + /// Look through every point. If the point is not surveyed, not marked as going to be surveyed then it is available to be considered a survey target. + /// Check to see if it is closer than any other point. This is the greedy method, and a more optimal search pattern can be done, especially for multiple ships. + /// + foreach (Star Stellar in CurrentSystem.Stars) + { + foreach (SystemBody SB in Stellar.Planets) + { + if (SB.GeoSurveyList.ContainsKey(TaskGroupFaction) == true) + { + if (SB.GeoSurveyList[TaskGroupFaction] == true) + { + /// + /// This body is surveyed, move on to the next one. + /// + continue; + } + } + + if (CurrentSystem._SurveyResults.ContainsKey(TaskGroupFaction) == true) + { + if (CurrentSystem._SurveyResults[TaskGroupFaction]._GeoSurveyInProgress.Contains(SB) == false) + { + float distSq = (float)(SB.Position.X * Contact.Position.X) + (float)(SB.Position.Y * Contact.Position.Y); + if (distSq < lowestDistance || lowestDistance == -1.0f) + { + lowestDistance = distSq; + ClosestSB = SB; + } + } + } + else + { + float distSq = (float)(SB.Position.X * Contact.Position.X) + (float)(SB.Position.Y * Contact.Position.Y); + if (distSq < lowestDistance || lowestDistance == -1.0f) + { + lowestDistance = distSq; + ClosestSB = SB; + } + } + } + } + + if (lowestDistance == -1.0f) + { + /// + /// No suitable target was found. + /// + String Entry = String.Format("No suitable geo survey target for {0} in {1}", Name, Contact.Position.System); + MessageEntry NME = new MessageEntry(MessageEntry.MessageType.NoGravSurveyTarget, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); + TaskGroupFaction.MessageLog.Add(NME); + } + else + { + Order SPOrder = new Order(Constants.ShipTN.OrderType.GeoSurvey, -1, -1, 0, ClosestSB); + IssueOrder(SPOrder); + } + break; + #endregion + + #region Survey Nearest Survey Location case Constants.ShipTN.DefaultOrders.SurveyNearestSurveyLocation: - break; + lowestDistance = -1.0f; + SurveyPoint ClosestSP = null; + CurrentSystem = Contact.Position.System; + + /// + /// Look through every point. If the point is not surveyed, not marked as going to be surveyed then it is available to be considered a survey target. + /// Check to see if it is closer than any other point. This is the greedy method, and a more optimal search pattern can be done, especially for multiple ships. + /// + foreach (SurveyPoint SP in CurrentSystem._SurveyPoints) + { + if (CurrentSystem._SurveyResults.ContainsKey(TaskGroupFaction) == true) + { + if (CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyStatus == JPDetection.Status.Complete) + break; + + if (CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyedPoints.Contains(SP) == false) + { + if (CurrentSystem._SurveyResults[TaskGroupFaction]._GravSurveyInProgress.Contains(SP) == false) + { + float distSq = (float)(SP.Position.X * Contact.Position.X) + (float)(SP.Position.Y * Contact.Position.Y); + if (distSq < lowestDistance || lowestDistance == -1.0f) + { + lowestDistance = distSq; + ClosestSP = SP; + } + } + } + } + else + { + float distSq = (float)(SP.Position.X * Contact.Position.X) + (float)(SP.Position.Y * Contact.Position.Y); + if (distSq < lowestDistance || lowestDistance == -1.0f) + { + lowestDistance = distSq; + ClosestSP = SP; + } + } + } + + if (lowestDistance == -1.0f) + { + /// + /// No suitable target was found. + /// + String Entry = String.Format("No suitable grav survey target for {0} in {1}", Name, Contact.Position.System); + MessageEntry NME = new MessageEntry(MessageEntry.MessageType.NoGravSurveyTarget, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); + TaskGroupFaction.MessageLog.Add(NME); + } + else + { + Order SPOrder = new Order(Constants.ShipTN.OrderType.GravSurvey, -1, -1, 0, ClosestSP); + IssueOrder(SPOrder); + } + break; + #endregion } } } diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs index c97b4ef0c..2a9f5d53f 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs @@ -234,6 +234,9 @@ public TaskGroup() m_oTaskGroupPanel.OrgMoveRightButton.Click += new EventHandler(OrgMoveRightButton_Click); #endregion + #region Special Orders Tab + SetupDefaultAndConditionalOrders(); + #endregion /// /// Rename Class Button Handlers: @@ -702,6 +705,37 @@ private void SetupShipDataGrid() } } + /// + /// Fill the combo boxes for default orders, conditional conditions, and conditional orders. + /// Typecasting all these to ints produces shorter lines than going by the enum type. + /// + private void SetupDefaultAndConditionalOrders() + { + for (int defaultOrderIterator = 0; defaultOrderIterator < (int)Constants.ShipTN.DefaultOrders.TypeCount; defaultOrderIterator++) + { + m_oTaskGroupPanel.PrimaryDefaultOrderComboBox.Items.Add((Constants.ShipTN.DefaultOrders)defaultOrderIterator); + m_oTaskGroupPanel.SecondaryDefaultOrderComboBox.Items.Add((Constants.ShipTN.DefaultOrders)defaultOrderIterator); + } + m_oTaskGroupPanel.PrimaryDefaultOrderComboBox.SelectedIndex = 0; + m_oTaskGroupPanel.SecondaryDefaultOrderComboBox.SelectedIndex = 0; + + for (int condIterator = 0; condIterator < (int)Constants.ShipTN.Condition.TypeCount; condIterator++) + { + m_oTaskGroupPanel.ConditionalAConditionComboBox.Items.Add((Constants.ShipTN.Condition)condIterator); + m_oTaskGroupPanel.ConditionalBConditionComboBox.Items.Add((Constants.ShipTN.Condition)condIterator); + } + m_oTaskGroupPanel.ConditionalAConditionComboBox.SelectedIndex = 0; + m_oTaskGroupPanel.ConditionalBConditionComboBox.SelectedIndex = 0; + + for (int condOrderIterator = 0; condOrderIterator < (int)Constants.ShipTN.ConditionalOrders.TypeCount; condOrderIterator++) + { + m_oTaskGroupPanel.ConditionalAOrderComboBox.Items.Add((Constants.ShipTN.ConditionalOrders)condOrderIterator); + m_oTaskGroupPanel.ConditionalBOrderComboBox.Items.Add((Constants.ShipTN.ConditionalOrders)condOrderIterator); + } + m_oTaskGroupPanel.ConditionalAOrderComboBox.SelectedIndex = 0; + m_oTaskGroupPanel.ConditionalBOrderComboBox.SelectedIndex = 0; + } + private void RefreshShipCells() { m_oTaskGroupPanel.TaskGroupDataGrid.Rows.Clear(); diff --git a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs index 80f0981b6..10295a503 100644 --- a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs +++ b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs @@ -261,6 +261,41 @@ public TextBox OrgCurrentTGTextBox #endregion + #region Special Orders Tab + /// + /// The list of primary default orders. these will be done before secondary default orders. + /// + public ComboBox PrimaryDefaultOrderComboBox + { + get { return m_oPrimaryDefaultOrdersComboBox; } + } + public ComboBox SecondaryDefaultOrderComboBox + { + get { return m_oSecondaryDefaultOrdersComboBox; } + } + + /// + /// How should conditionals be handled? should they interrupt orders? + /// + public ComboBox ConditionalAConditionComboBox + { + get { return m_oCondAConditionComboBox; } + } + public ComboBox ConditionalAOrderComboBox + { + get { return m_oCondAOrderComboBox; } + } + + public ComboBox ConditionalBConditionComboBox + { + get { return m_oCondBConditionComboBox; } + } + public ComboBox ConditionalBOrderComboBox + { + get { return m_oCondBOrderComboBox; } + } + #endregion + /// /// Clean up any resources being used. /// From 6ff0c3c88f0c2e3d7be11b21a02282c72c53302f Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 15 Nov 2015 00:35:31 -0600 Subject: [PATCH 20/40] Survey work complete for now Testing is required, but default orders appear to work now, and so ordered craft will look for planets and survey points to survey. --- Pulsar4X/Pulsar4X.Lib/Constants.cs | 8 ++ Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs | 6 ++ .../Entities/StarSystem/TaskGroup.cs | 57 ++++++++++++- Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs | 21 +++++ .../Pulsar4X.UI/SceenGraph/ContactElement.cs | 80 ++++++++++++++----- 5 files changed, 148 insertions(+), 24 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Constants.cs b/Pulsar4X/Pulsar4X.Lib/Constants.cs index 47ff90a31..534548d5b 100644 --- a/Pulsar4X/Pulsar4X.Lib/Constants.cs +++ b/Pulsar4X/Pulsar4X.Lib/Constants.cs @@ -1145,6 +1145,14 @@ public static class JumpEngineTN } + public static class GameConstants + { + /// + /// 10k km is the basic unit of AuroraTN distance that pretty much all calculations will go to. I don't expect this to ever change, but would prefer to keep it as a constant regardless. + /// + public const double BasicUnitOfDistance = 10000.0; + } + /// /// List of game-specific settings. /// Since we don't have save/load yet, I'm just sticking this here. diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs b/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs index cefda9e22..63915085f 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs @@ -642,6 +642,12 @@ public void AdvanceSim(BindingList P, Random RNG, int deltaSeconds) /// /// Adding new taskgroups means adding a loop here to run through them all. /// + if (TaskGroup.TaskGroupOrders.Count == 0 && ( TaskGroup._SpecialOrders._DefaultOrdersList.Count != 0 || TaskGroup._SpecialOrders._ConditionList.Count != 0 )) + { + TaskGroup.ProcessDefaultOrders(); + TaskGroup.ProcessConditionalOrders(); + } + if (TaskGroup.TaskGroupOrders.Count != 0) { TaskGroup.FollowOrders((uint)deltaSeconds); diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index ca75a1612..f8c56dd61 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -3007,6 +3007,14 @@ public uint PerformOrders(uint TimeSlice) SystemBody OB = OrbitingBody as SystemBody; int BodySurveyCost = OB.GetSurveyCost(); + /// + /// This survey was finished on the dot last tick. + /// + if (OB._mineralsGenerated == true) + { + break; + } + float hourFract = (float)TimeSlice / (float)Constants.TimeInSeconds.Hour; _SurveyHourFraction = _SurveyHourFraction + hourFract; int hours = (int)Math.Floor(_SurveyHourFraction); @@ -3069,6 +3077,14 @@ public uint PerformOrders(uint TimeSlice) int SystemSurveyCost = Contact.Position.System.GetSurveyCost(); StarSystem CurrentSystem = Contact.Position.System; + /// + /// This point was surveyed, but the survey ended right on the dot of the last tick. + /// + if (CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyedPoints.Contains(TaskGroupOrders[0].surveyPointOrder) == true) + { + break; + } + float hourFraction = (float)TimeSlice / (float)Constants.TimeInSeconds.Hour; _SurveyHourFraction = _SurveyHourFraction + hourFraction; @@ -3082,6 +3098,11 @@ public uint PerformOrders(uint TimeSlice) int TotalSP = (int)(CalcGravSurveyPoints() * (float)totalHours); + String Entry = String.Format("{0} {1} {2}",TotalSP,RemainderSP,_GravSurveyPoints); + MessageEntry NME = new MessageEntry(MessageEntry.MessageType.NoGravSurveyTarget, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); + TaskGroupFaction.MessageLog.Add(NME); + + if (TotalSP < RemainderSP) { _GravSurveyPoints = _GravSurveyPoints + TotalSP; @@ -3243,8 +3264,13 @@ public void ProcessDefaultOrders() } else { - Order SPOrder = new Order(Constants.ShipTN.OrderType.GeoSurvey, -1, -1, 0, ClosestSB); - IssueOrder(SPOrder); + Order SBOrder = new Order(Constants.ShipTN.OrderType.GeoSurvey, -1, -1, 0, ClosestSB); + IssueOrder(SBOrder); + + /// + /// The order has been issued so cancel out of this function. + /// + return; } break; #endregion @@ -3301,8 +3327,18 @@ public void ProcessDefaultOrders() } else { + + String Entry = String.Format("Order for {0} to survey {1}", Name, ClosestSP); + MessageEntry NME = new MessageEntry(MessageEntry.MessageType.NoGravSurveyTarget, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); + TaskGroupFaction.MessageLog.Add(NME); + Order SPOrder = new Order(Constants.ShipTN.OrderType.GravSurvey, -1, -1, 0, ClosestSP); IssueOrder(SPOrder); + + /// + /// The order has been issued so cancel out of this function. + /// + return; } break; #endregion @@ -3310,6 +3346,23 @@ public void ProcessDefaultOrders() } } + /// + /// Add a default order to be processed by this TG when it has no other business. + /// + /// Default Order to add + /// index order should be placed at + public void AddDefaultOrder(Constants.ShipTN.DefaultOrders OrderToAdd, int index) + { + if (_SpecialOrders._DefaultOrdersList.Count <= index) + { + while (_SpecialOrders._DefaultOrdersList.Count != index) + _SpecialOrders._DefaultOrdersList.Add(Constants.ShipTN.DefaultOrders.NoSpecialOrder); + _SpecialOrders._DefaultOrdersList.Add(OrderToAdd); + } + else + _SpecialOrders._DefaultOrdersList[index] = OrderToAdd; + } + /// /// Same for this function. /// diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs index 2a9f5d53f..b1f8b8951 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs @@ -236,6 +236,8 @@ public TaskGroup() #region Special Orders Tab SetupDefaultAndConditionalOrders(); + m_oTaskGroupPanel.PrimaryDefaultOrderComboBox.SelectedIndexChanged += new EventHandler(PrimaryDefaultOrderComboBox_SelectedIndexChanged); + m_oTaskGroupPanel.SecondaryDefaultOrderComboBox.SelectedIndexChanged += new EventHandler(SecondaryDefaultOrderComboBox_SelectedIndexChanged); #endregion /// @@ -315,6 +317,25 @@ private void SystemLocationListBox_SelectedIndexChanged(object sender, EventArgs BuildActionList(); } + + /// + /// Selecting a primary order will place that order into the taskgroup default orders list. + /// + private void PrimaryDefaultOrderComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + CurrentTaskGroup.AddDefaultOrder((Constants.ShipTN.DefaultOrders)m_oTaskGroupPanel.PrimaryDefaultOrderComboBox.SelectedIndex, 0); + } + + /// + /// Selecting a secondary order will place that order into the taskgroup default orders list. + /// + /// + /// + private void SecondaryDefaultOrderComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + CurrentTaskGroup.AddDefaultOrder((Constants.ShipTN.DefaultOrders)m_oTaskGroupPanel.SecondaryDefaultOrderComboBox.SelectedIndex, 1); + } + /// /// Create a new taskgroup. /// diff --git a/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs b/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs index 4545bd4c6..684cf3bba 100644 --- a/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs +++ b/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs @@ -192,29 +192,65 @@ public override void Render() _SensorContactElements.Remove(SCE); } - if (_SensorContactElements.ContainsKey(TaskGroup.BestEM.pSensorDef.Id) == false && ParentSceen.ShowPassives == true) + if (ParentSceen.ShowPassives == true) { - PassiveSensorDefTN pSensorDef = TaskGroup.BestEM.pSensorDef; -#warning all of these 10000.0's are related to the fact that distance is done by 10k km in Aurora. - double factor = Constants.Units.KmPerAu / 10000.0; - double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; + /// + /// A taskgroup with no sensors still has the default package, so handle that. + /// + if (TaskGroup.BestEM == null) + { - Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); + PassiveSensorDefTN pSensorDef = TaskGroup.TaskGroupFaction.ComponentList.DefaultPassives; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; + double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; - SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Blue, TaskGroup.BestEM.Name, TaskGroup.BestEM, TaskGroup.BestEM.pSensorDef.componentType, ParentSceen); - _SensorContactElements.Add(TaskGroup.BestEM.pSensorDef.Id, NSE); - } + Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); - if (_SensorContactElements.ContainsKey(TaskGroup.BestThermal.pSensorDef.Id) == false && ParentSceen.ShowPassives == true) - { - PassiveSensorDefTN pSensorDef = TaskGroup.BestThermal.pSensorDef; - double factor = Constants.Units.KmPerAu / 10000.0; - double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; + SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Blue, "", null, ComponentTypeTN.PassiveSensor, ParentSceen); - Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); + //definitely a kludge here to make SCE work with default passives. + _SensorContactElements.Add(TaskGroup.Id, NSE); + + } + else if (_SensorContactElements.ContainsKey(TaskGroup.BestEM.pSensorDef.Id) == false) + { + PassiveSensorDefTN pSensorDef = TaskGroup.BestEM.pSensorDef; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; + double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; - SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Red, TaskGroup.BestThermal.Name, TaskGroup.BestThermal, TaskGroup.BestThermal.pSensorDef.componentType, ParentSceen); - _SensorContactElements.Add(TaskGroup.BestThermal.pSensorDef.Id, NSE); + Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); + + SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Blue, TaskGroup.BestEM.Name, TaskGroup.BestEM, TaskGroup.BestEM.pSensorDef.componentType, ParentSceen); + _SensorContactElements.Add(TaskGroup.BestEM.pSensorDef.Id, NSE); + } + + /// + /// A taskgroup with no sensors still has the default package, so handle that. + /// + if (TaskGroup.BestThermal == null) + { + PassiveSensorDefTN pSensorDef = TaskGroup.TaskGroupFaction.ComponentList.DefaultPassives; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; + double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; + + Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); + + SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Red, "", null, ComponentTypeTN.PassiveSensor, ParentSceen); + + //yep, its a kludge. + _SensorContactElements.Add(TaskGroup.Ships[0].Id, NSE); + } + else if (_SensorContactElements.ContainsKey(TaskGroup.BestThermal.pSensorDef.Id) == false) + { + PassiveSensorDefTN pSensorDef = TaskGroup.BestThermal.pSensorDef; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; + double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; + + Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); + + SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Red, TaskGroup.BestThermal.Name, TaskGroup.BestThermal, TaskGroup.BestThermal.pSensorDef.componentType, ParentSceen); + _SensorContactElements.Add(pSensorDef.Id, NSE); + } } @@ -233,7 +269,7 @@ public override void Render() ActiveSensorDefTN SensorDef = Sensor.aSensorDef; - double factor = Constants.Units.KmPerAu / 10000.0; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; double AURadius = (double)SensorDef.maxRange / factor; Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); @@ -264,7 +300,7 @@ public override void Render() #warning if EM strength differs from Thermal handle that here. int ScanStrength = DSTS * Constants.Colony.ThermalDeepSpaceStrength[SensorTech] * 100; - double factor = Constants.Units.KmPerAu / 10000.0; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; double AURadius = (double)ScanStrength * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; Vector3 PopPosition = new Vector3((float)CurrentPop.Contact.Position.X, (float)CurrentPop.Contact.Position.Y, 0.0f); @@ -290,7 +326,7 @@ public override void Render() if (OrdDef.aSD != null && ParentSceen.ShowActives == true) { - double factor = Constants.Units.KmPerAu / 10000.0; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; double AURadius = (double)OrdDef.aSD.maxRange / factor; Vector3 MGPos = new Vector3((float)MissileGroup.contact.Position.X, (float)MissileGroup.contact.Position.Y, 0.0f); @@ -302,7 +338,7 @@ public override void Render() if (OrdDef.tHD != null && ParentSceen.ShowPassives == true) { - double factor = Constants.Units.KmPerAu / 10000.0; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; double AURadius = (double)OrdDef.tHD.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; Vector3 MGPos = new Vector3((float)MissileGroup.contact.Position.X, (float)MissileGroup.contact.Position.Y, 0.0f); @@ -314,7 +350,7 @@ public override void Render() if (OrdDef.eMD != null && ParentSceen.ShowPassives == true) { - double factor = Constants.Units.KmPerAu / 10000.0; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; double AURadius = (double)OrdDef.eMD.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; Vector3 MGPos = new Vector3((float)MissileGroup.contact.Position.X, (float)MissileGroup.contact.Position.Y, 0.0f); From fb90f8b0689d1f07eb354015d7e15d42c1af3269 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 22 Nov 2015 01:37:18 -0600 Subject: [PATCH 21/40] Bugfixes and testing Survey is nearly ready, several bugs remain however. partial JP discovery results are not displayed properly in the TG window. jps are being marked as added to the survey results list when the point opposite the point they belong to is surveyed. gas giants need a specialized mineral generation routine since they are not habitable planets and can only have sorium. Adding engines of a different type can cause problems with size being incorrect for ships, and possibly other things. These will all have to be resolved. --- .../Entities/StarSystem/StarSystem.cs | 6 +++-- .../Entities/StarSystem/TaskGroup.cs | 26 ++++++++----------- Pulsar4X/Pulsar4X.UI/Handlers/SystemMap.cs | 7 +++++ Pulsar4X/Pulsar4X.UI/Program.cs | 6 ++--- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs index 2eab9bd35..ac81e7afa 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs @@ -315,10 +315,12 @@ public int GetSurveyPointArea(double X, double Y) double RingValue = Math.Sqrt(Stars[0].Orbit.MassRelativeToSol) * Constants.SensorTN.EarthRingDistance; double distanceFromPrimary = Math.Sqrt(((X * X) + (Y * Y))); double Angle = (Math.Atan((X / Y)) / Constants.Units.Radian); + if (Angle < 0) + Angle += 360.0; int SurveyIndex = -1; - if (distanceFromPrimary < (3 * RingValue)) + if (distanceFromPrimary >= (2 * RingValue) && distanceFromPrimary < (3 * RingValue)) { /// /// Ring 3 contains survey indices 19 through 30, but these are addressed starting from zero. @@ -358,7 +360,7 @@ public int GetSurveyPointArea(double X, double Y) } } } - else if (distanceFromPrimary < (2 * RingValue)) + else if (distanceFromPrimary >= (RingValue) && distanceFromPrimary < (2 * RingValue)) { /// /// Ring 2 contains survey indices 7 through 18. diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index f8c56dd61..51dbba02c 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -3097,12 +3097,6 @@ public uint PerformOrders(uint TimeSlice) int RemainderSP = SystemSurveyCost - _GravSurveyPoints; int TotalSP = (int)(CalcGravSurveyPoints() * (float)totalHours); - - String Entry = String.Format("{0} {1} {2}",TotalSP,RemainderSP,_GravSurveyPoints); - MessageEntry NME = new MessageEntry(MessageEntry.MessageType.NoGravSurveyTarget, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); - TaskGroupFaction.MessageLog.Add(NME); - - if (TotalSP < RemainderSP) { _GravSurveyPoints = _GravSurveyPoints + TotalSP; @@ -3138,7 +3132,7 @@ public uint PerformOrders(uint TimeSlice) /// /// if 30 points have been surveyed mark the system as totally surveyed. /// - if(CurrentSystem._SurveyResults.Count == Constants.SensorTN.SurveyPointCount) + if (CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyedPoints.Count == Constants.SensorTN.SurveyPointCount) { /// /// All survey work is complete, so free up these pointers. @@ -3158,9 +3152,12 @@ public uint PerformOrders(uint TimeSlice) foreach (JumpPoint JP in CurrentSystem.JumpPoints) { int JPIndex = CurrentSystem.GetSurveyPointArea(JP.Position.X,JP.Position.Y); - if (JPIndex == SPIndex) + if (JPIndex == (SPIndex+1)) { CurrentSystem._SurveyResults[TaskGroupFaction]._DetectedJPs.Add(JP); + String Entry = String.Format("Indexs J:{0}",CurrentSystem._SurveyResults[TaskGroupFaction]._DetectedJPs.Count); + MessageEntry NME = new MessageEntry(MessageEntry.MessageType.Error, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); + TaskGroupFaction.MessageLog.Add(NME); } } } @@ -3296,7 +3293,9 @@ public void ProcessDefaultOrders() { if (CurrentSystem._SurveyResults[TaskGroupFaction]._GravSurveyInProgress.Contains(SP) == false) { - float distSq = (float)(SP.Position.X * Contact.Position.X) + (float)(SP.Position.Y * Contact.Position.Y); + float dX = (float)Math.Abs(SP.Position.X - Contact.Position.X); + float dY = (float)Math.Abs(SP.Position.Y - Contact.Position.Y); + float distSq = (dX * dX) + (dY * dY); if (distSq < lowestDistance || lowestDistance == -1.0f) { lowestDistance = distSq; @@ -3307,7 +3306,9 @@ public void ProcessDefaultOrders() } else { - float distSq = (float)(SP.Position.X * Contact.Position.X) + (float)(SP.Position.Y * Contact.Position.Y); + float dX = (float)Math.Abs(SP.Position.X - Contact.Position.X); + float dY = (float)Math.Abs(SP.Position.Y - Contact.Position.Y); + float distSq = (dX * dX) + (dY * dY); if (distSq < lowestDistance || lowestDistance == -1.0f) { lowestDistance = distSq; @@ -3327,11 +3328,6 @@ public void ProcessDefaultOrders() } else { - - String Entry = String.Format("Order for {0} to survey {1}", Name, ClosestSP); - MessageEntry NME = new MessageEntry(MessageEntry.MessageType.NoGravSurveyTarget, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); - TaskGroupFaction.MessageLog.Add(NME); - Order SPOrder = new Order(Constants.ShipTN.OrderType.GravSurvey, -1, -1, 0, ClosestSP); IssueOrder(SPOrder); diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/SystemMap.cs b/Pulsar4X/Pulsar4X.UI/Handlers/SystemMap.cs index 801ca9eda..09e6def41 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/SystemMap.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/SystemMap.cs @@ -734,6 +734,13 @@ public void RefreshStarSystem() { return; } + else if (m_oCurrnetSystem == null) + { + /// + /// Not even sure how I made it do this. + /// + return; + } // Now we test to see if we have already loaded this system or if it the current one: if (m_oCurrentSceen == null) diff --git a/Pulsar4X/Pulsar4X.UI/Program.cs b/Pulsar4X/Pulsar4X.UI/Program.cs index ede306056..9706f7094 100644 --- a/Pulsar4X/Pulsar4X.UI/Program.cs +++ b/Pulsar4X/Pulsar4X.UI/Program.cs @@ -89,7 +89,7 @@ static void Main() oNewFaction2.Capitol = oNewFaction2.Populations[0]; oNewFaction2.Capitol.Planet.GeoSurveyList.Add(oNewFaction2, true); - oNewFaction2.AddNewTaskGroup("Combat Taskgroup TR", P2, sol); + //oNewFaction2.AddNewTaskGroup("Combat Taskgroup TR", P2, sol); oNewFaction2.FactionColor = System.Drawing.Color.Red; oNewFaction.AddNewShipDesign("Sword"); @@ -150,7 +150,7 @@ static void Main() } oNewFaction.TaskGroups.Last().Ships[2].CurrentMagazineCapacity = oNewFaction.ShipDesigns[1].PreferredOrdnanceSize; - oNewFaction2.AddNewShipDesign("Mace"); + /*oNewFaction2.AddNewShipDesign("Mace"); CL = oNewFaction2.ComponentList; @@ -205,7 +205,7 @@ static void Main() { oNewFaction2.TaskGroups.Last().Ships[2].ShipOrdnance.Add(pair.Key, pair.Value); } - oNewFaction2.TaskGroups.Last().Ships[2].CurrentMagazineCapacity = oNewFaction2.ShipDesigns[1].PreferredOrdnanceSize; + oNewFaction2.TaskGroups.Last().Ships[2].CurrentMagazineCapacity = oNewFaction2.ShipDesigns[1].PreferredOrdnanceSize;*/ oNewFaction.GiveAllTechs(); oNewFaction2.GiveAllTechs(); From a7f3d827c31a33d70984fa477456af83358e0add Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 29 Nov 2015 20:38:40 -0600 Subject: [PATCH 22/40] Still more bugtesting The number of JPs in SystemGen.cs has been uped to 10, be sure to check this. a few pretty horrible math errors have been fixed, but survey is not quite right. Also a terrible memoryleak has been discovered with the main window. --- .../Entities/StarSystem/StarSystem.cs | 20 ++++++++++++++++--- .../Entities/StarSystem/TaskGroup.cs | 6 +++++- Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs | 15 ++++++++------ 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs index ac81e7afa..16967508a 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs @@ -314,7 +314,17 @@ public int GetSurveyPointArea(double X, double Y) { double RingValue = Math.Sqrt(Stars[0].Orbit.MassRelativeToSol) * Constants.SensorTN.EarthRingDistance; double distanceFromPrimary = Math.Sqrt(((X * X) + (Y * Y))); - double Angle = (Math.Atan((X / Y)) / Constants.Units.Radian); + double Angle = (Math.Atan((Y / X)) / Constants.Units.Radian); + + /// + /// Atan will give the same values for -1,-1 as 1,1, so handle this condition. + /// + if (Y < 0 && X < 0) + Angle += 180.0; + + /// + /// Also if the angle is less than 0 add 360 to the angle. I don't know if this is necessary. + /// if (Angle < 0) Angle += 360.0; @@ -387,7 +397,7 @@ public int GetSurveyPointArea(double X, double Y) /// because there are fewer points, each point covers more total area, 60 degrees here instead of 30. /// SurveyIndex = 5; - for (int surveyPointIterator = 300; surveyPointIterator >= 0; surveyPointIterator -= 60) + for (int surveyPointIterator = 330; surveyPointIterator >= 30; surveyPointIterator -= 60) { int highAngle = surveyPointIterator + 30; int lowAngle = surveyPointIterator - 30; @@ -402,7 +412,11 @@ public int GetSurveyPointArea(double X, double Y) } } - return SurveyIndex; + String Entry = String.Format("GetSurveyPointArea({0},{1}):{2},{3},{4},{5}", X,Y,distanceFromPrimary,Angle,(SurveyIndex+1),RingValue); + MessageEntry NME = new MessageEntry(MessageEntry.MessageType.Error, null, null, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); + GameState.Instance.Factions[0].MessageLog.Add(NME); + + return (SurveyIndex+1); } } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index 51dbba02c..35c34bc32 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -3155,7 +3155,11 @@ public uint PerformOrders(uint TimeSlice) if (JPIndex == (SPIndex+1)) { CurrentSystem._SurveyResults[TaskGroupFaction]._DetectedJPs.Add(JP); - String Entry = String.Format("Indexs J:{0}",CurrentSystem._SurveyResults[TaskGroupFaction]._DetectedJPs.Count); + + if (CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyStatus == JPDetection.Status.None) + CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyStatus = JPDetection.Status.Incomplete; + + String Entry = String.Format("Indexs J:{0} Just found {1} at {2} {3},{4}", CurrentSystem._SurveyResults[TaskGroupFaction]._DetectedJPs.Count,JP,SPIndex+1,JP.Position.X,JP.Position.Y); MessageEntry NME = new MessageEntry(MessageEntry.MessageType.Error, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); TaskGroupFaction.MessageLog.Add(NME); } diff --git a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs index eb70c7ed0..90b0de8ba 100644 --- a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs +++ b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs @@ -1621,7 +1621,7 @@ private static void GenerateJumpPoints(StarSystem system, int numJumpPoints = -1 /// if (Constants.GameSettings.Aurora65JPGeneration == true) { - int numJPs = 1; + int numJPs = 10; int BaseJPChance = 90; int JPChance = (BaseJPChance + (int)Math.Round(system.Stars[0].Orbit.MassRelativeToSol)); while (m_RNG.Next(100) < JPChance) @@ -1723,9 +1723,9 @@ private static JumpPoint GenerateJumpPoint(Star star) int angleMax = 30; /// - /// And get the angle for this SP + /// And get the angle for this SP. 0 - 5 for the 1st 6. /// - if (SP <= 6) + if (SP <= 5) { RingFactor = 1; angleMax = 60; @@ -1740,10 +1740,13 @@ private static JumpPoint GenerateJumpPoint(Star star) SPCount++; } } - else if (SP <= 18) + /// + /// 6 through 17 for the next 12 + /// + else if (SP <= 17) { RingFactor = 2; - int SPCount = 7; + int SPCount = 6; for (int surveyPointIterator = 15; surveyPointIterator < 360; surveyPointIterator += 30) { if (SPCount == SP) @@ -1757,7 +1760,7 @@ private static JumpPoint GenerateJumpPoint(Star star) else { RingFactor = 3; - int SPCount = 19; + int SPCount = 18; for (int surveyPointIterator = 0; surveyPointIterator < 360; surveyPointIterator += 30) { if (SPCount == SP) From edac8798958bcadd82a588dc855a274fec51cb52 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Mon, 7 Dec 2015 00:52:51 -0600 Subject: [PATCH 23/40] memory and jp position fixes several sensor display bugs including the memory leak are fixed, and jps should finally be in the correct position, a few more bugs remain to be fixed: the engine addtion bug and gas giant mineral generation. --- .../Entities/StarSystem/StarSystem.cs | 19 +++- .../Pulsar4X.UI/SceenGraph/ContactElement.cs | 91 +++++++++++-------- 2 files changed, 68 insertions(+), 42 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs index 16967508a..bfb7800a2 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs @@ -316,16 +316,27 @@ public int GetSurveyPointArea(double X, double Y) double distanceFromPrimary = Math.Sqrt(((X * X) + (Y * Y))); double Angle = (Math.Atan((Y / X)) / Constants.Units.Radian); + + /// + /// Atan will give the same values for -1,-1 as 1,1, so handle this condition. likewise -1,1 will give 1,1's answer + /// Atan(1) = 45 + /// Atan(-1) = -45 + /// -1,1(135) 1,1(45) + /// -1,-1(225), 1,-1(315) + /// + if (X < 0 && Y < 0) + Angle += 180.0; + /// - /// Atan will give the same values for -1,-1 as 1,1, so handle this condition. + /// -1,1 /// - if (Y < 0 && X < 0) + else if (X < 0) Angle += 180.0; /// - /// Also if the angle is less than 0 add 360 to the angle. I don't know if this is necessary. + /// 1,-1 /// - if (Angle < 0) + else if (Y < 0) Angle += 360.0; int SurveyIndex = -1; diff --git a/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs b/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs index 684cf3bba..1595ceec7 100644 --- a/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs +++ b/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs @@ -162,27 +162,40 @@ public override void Render() /// /// Remove this sensor if it is destroyed, or if it isn't the current best thermal/em sensor. if a sensor is destroyed it should be replaced as the best em/thermal. /// - if (pSensor.isDestroyed == true || ParentSceen.ShowPassives == false) + if (pSensor != null) { - SensorRemoveList.Add(SCE.Key); - } - else - { - if (pSensor.pSensorDef.thermalOrEM == PassiveSensorType.Thermal) + if (pSensor.isDestroyed == true || ParentSceen.ShowPassives == false) { - if (pSensor != TaskGroup.BestThermal) - { - SensorRemoveList.Add(SCE.Key); - } + SensorRemoveList.Add(SCE.Key); } else { - if (pSensor != TaskGroup.BestEM) + if (pSensor.pSensorDef.thermalOrEM == PassiveSensorType.Thermal) + { + if (pSensor != TaskGroup.BestThermal) + { + SensorRemoveList.Add(SCE.Key); + } + } + else { - SensorRemoveList.Add(SCE.Key); + if (pSensor != TaskGroup.BestEM) + { + SensorRemoveList.Add(SCE.Key); + } } } } + else + { + /// + /// default passives will be null, so that should be handled here. if show passives is off, or a better passive shows up, remove the default passives. + /// + if (ParentSceen.ShowPassives == false || TaskGroup.BestThermal != null || TaskGroup.BestEM != null) + { + SensorRemoveList.Add(SCE.Key); + } + } break; } } @@ -197,9 +210,8 @@ public override void Render() /// /// A taskgroup with no sensors still has the default package, so handle that. /// - if (TaskGroup.BestEM == null) + if (TaskGroup.BestEM == null && _SensorContactElements.ContainsKey(TaskGroup.Id) == false) { - PassiveSensorDefTN pSensorDef = TaskGroup.TaskGroupFaction.ComponentList.DefaultPassives; double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; @@ -210,9 +222,8 @@ public override void Render() //definitely a kludge here to make SCE work with default passives. _SensorContactElements.Add(TaskGroup.Id, NSE); - } - else if (_SensorContactElements.ContainsKey(TaskGroup.BestEM.pSensorDef.Id) == false) + else if (TaskGroup.BestEM != null && _SensorContactElements.ContainsKey(TaskGroup.BestEM.pSensorDef.Id) == false) { PassiveSensorDefTN pSensorDef = TaskGroup.BestEM.pSensorDef; double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; @@ -227,7 +238,7 @@ public override void Render() /// /// A taskgroup with no sensors still has the default package, so handle that. /// - if (TaskGroup.BestThermal == null) + if (TaskGroup.BestThermal == null && _SensorContactElements.ContainsKey(TaskGroup.Ships[0].Id) == false) { PassiveSensorDefTN pSensorDef = TaskGroup.TaskGroupFaction.ComponentList.DefaultPassives; double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; @@ -240,7 +251,7 @@ public override void Render() //yep, its a kludge. _SensorContactElements.Add(TaskGroup.Ships[0].Id, NSE); } - else if (_SensorContactElements.ContainsKey(TaskGroup.BestThermal.pSensorDef.Id) == false) + else if (TaskGroup.BestThermal != null && _SensorContactElements.ContainsKey(TaskGroup.BestThermal.pSensorDef.Id) == false) { PassiveSensorDefTN pSensorDef = TaskGroup.BestThermal.pSensorDef; double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; @@ -287,30 +298,35 @@ public override void Render() /// /// Populations only have one sensor element. /// - _SensorContactElements.Clear(); - if (CurrentPop._sensorUpdateAck != _LastSensorUpdateAck && ParentSceen.ShowPassives == true) + if (CurrentPop._sensorUpdateAck != _LastSensorUpdateAck) { - /// - /// This calculates the default detection distance for strength 1000 signatures. - /// - int DSTS = (int)Math.Floor(CurrentPop.Installations[(int)Installation.InstallationType.DeepSpaceTrackingStation].Number); - int SensorTech = CurrentPop.Faction.FactionTechLevel[(int)Faction.FactionTechnology.DSTSSensorStrength]; - if (SensorTech > Constants.Colony.DeepSpaceMax) - SensorTech = Constants.Colony.DeepSpaceMax; + _SensorContactElements.Clear(); + + if (ParentSceen.ShowPassives == true) + { + /// + /// This calculates the default detection distance for strength 1000 signatures. + /// + int DSTS = (int)Math.Floor(CurrentPop.Installations[(int)Installation.InstallationType.DeepSpaceTrackingStation].Number); + int SensorTech = CurrentPop.Faction.FactionTechLevel[(int)Faction.FactionTechnology.DSTSSensorStrength]; + if (SensorTech > Constants.Colony.DeepSpaceMax) + SensorTech = Constants.Colony.DeepSpaceMax; #warning if EM strength differs from Thermal handle that here. - int ScanStrength = DSTS * Constants.Colony.ThermalDeepSpaceStrength[SensorTech] * 100; + int ScanStrength = DSTS * Constants.Colony.ThermalDeepSpaceStrength[SensorTech] * 100; - double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; - double AURadius = (double)ScanStrength * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; + double AURadius = (double)ScanStrength * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; - Vector3 PopPosition = new Vector3((float)CurrentPop.Contact.Position.X, (float)CurrentPop.Contact.Position.Y, 0.0f); + Vector3 PopPosition = new Vector3((float)CurrentPop.Contact.Position.X, (float)CurrentPop.Contact.Position.Y, 0.0f); - /// - /// Type is set to TypeCount because only the taskgroup section requires it. Likewise for CurrentPop, and CurrentPop.Id, these aren't strictly necessary, but the - /// taskgroup section requires more information as more sensor contact elements can be associated with a taskgroup. - /// - SensorElement NSE = new SensorElement(_DefaultEffect, PopPosition, (float)AURadius, System.Drawing.Color.Purple, CurrentPop.Name + " DSTS Coverage", CurrentPop, ComponentTypeTN.TypeCount, ParentSceen); - _SensorContactElements.Add(CurrentPop.Id, NSE); + /// + /// Type is set to TypeCount because only the taskgroup section requires it. Likewise for CurrentPop, and CurrentPop.Id, these aren't strictly necessary, but the + /// taskgroup section requires more information as more sensor contact elements can be associated with a taskgroup. + /// + SensorElement NSE = new SensorElement(_DefaultEffect, PopPosition, (float)AURadius, System.Drawing.Color.Purple, CurrentPop.Name + " DSTS Coverage", CurrentPop, ComponentTypeTN.TypeCount, ParentSceen); + _SensorContactElements.Add(CurrentPop.Id, NSE); + } + _LastSensorUpdateAck = CurrentPop._sensorUpdateAck; } break; case StarSystemEntityType.Missile: @@ -321,7 +337,6 @@ public override void Render() if (_LastSensorUpdateAck != MissileGroup._sensorUpdateAck) { _SensorContactElements.Clear(); - OrdnanceDefTN OrdDef = MissileGroup.missiles[0].missileDef; if (OrdDef.aSD != null && ParentSceen.ShowActives == true) From a9e478919fb3a2632afae8875432293178985c3b Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 12 Dec 2015 10:08:35 -0600 Subject: [PATCH 24/40] Colony assignment works and a few bug fixes Engine replacement should not cause any issues now, and gas giants have their own sorium generation routine. Colonies can be created(except on gas giants, ice giants, and gas dwarves). --- Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs | 15 +- Pulsar4X/Pulsar4X.Lib/Entities/Species.cs | 1 + .../Entities/StarSystem/SystemBody.cs | 80 +++- .../Entities/StarSystem/TaskGroup.cs | 8 +- Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs | 2 +- .../Handlers/SystemGenAndDisplay.cs | 52 ++- .../Panels/MissileDesign.Designer.cs | 344 +++++++++--------- .../Panels/SGaD_Controls.Designer.cs | 23 +- Pulsar4X/Pulsar4X.UI/Panels/SGaD_Controls.cs | 8 + Pulsar4X/Pulsar4X.UI/Program.cs | 2 + .../Properties/Resources.Designer.cs | 46 +-- .../ViewModels/StarSystemViewModel.cs | 23 ++ 12 files changed, 388 insertions(+), 216 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs b/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs index 6f1728676..5701de4ad 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs @@ -1643,13 +1643,26 @@ public void AddOtherComponent(GeneralComponentDefTN Other, short inc) } /// - /// Right now all this function does is overwrite the previous engine entry if switching types. + /// Right now all this function does is overwrite the previous engine entry if switching types. Update: this causes problems. /// I think I'll add a static variable to ComponentDefTN to deal with that. Can subtract. /// /// Engine Definition /// Number of engines to be added. public void AddEngine(EngineDefTN Engine, short inc) { + if (ShipEngineDef != Engine && ShipEngineDef != null) + { + /// + /// The old engine has to be subtracted from the ship, so handle that here. + /// + short OldShipEngineCount = (short)ShipEngineCount; + AddEngine(ShipEngineDef, (short)(OldShipEngineCount * -1)); + + /// + /// Preserve the overall engine count. gah, casting is annoying, I should have just made everything ints. + /// + inc = (short)(inc + OldShipEngineCount); + } ShipEngineDef = Engine; ShipEngineCount = (ushort)((short)ShipEngineCount + inc); diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Species.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Species.cs index 2a58dba79..f698c2c28 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Species.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Species.cs @@ -31,6 +31,7 @@ public enum Respiration /// public Respiration GasToBreathe { get; set; } +#warning Newly created species must have unique names, the tree display for populations relies on a dictionary that will crash if two species have the same name. public Species() : base() { diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs index 6f73f7739..bfe72f0e4 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs @@ -52,6 +52,7 @@ public enum MineralType ManyGood, //Rich world with many high quality mineral deposits, but not truly massive deposits 500k-4M range 4-8 minerals MassiveReserves, //Gargantuan amount of resources, low accessibility. 10-150M 8-11 minerals. Homeworld, //50k-150k of every resource in good amounts. Everything a starting faction will need. + GasGiant, //500k to 50M Sorium only, varying accessibility but not extremely low. Count, } @@ -234,6 +235,9 @@ public SystemBody(OrbitingEntity parent, PlanetType type) Atmosphere = new Atmosphere(this); + + if(Type != PlanetType.GasDwarf && Type != PlanetType.GasGiant && Type != PlanetType.IceGiant) + SupportsPopulations = true; } @@ -421,6 +425,12 @@ public void MassiveMineralGeneration() } } + public void GasGiantMineralGeneration() + { + m_aiMinerialReserves[(int)Constants.Minerals.MinerialNames.Sorium] = 500000.0f + (49500000.0f * ((float)GameState.RNG.Next(0,100000) / 100000.0f)); + m_aiMinerialAccessibility[(int)Constants.Minerals.MinerialNames.Sorium] = 0.4f + ((float)GameState.RNG.Next(0, 6) / 10.0f); + } + /// /// determine what type of world this is with regards to mineral generation and generate those minerals. /// @@ -430,8 +440,36 @@ public void GenerateMinerals(bool isHomeWorld = false) MineralType MType = MineralType.Homeworld; - if(isHomeWorld == false) - MType = (MineralType)GameState.RNG.Next((int)SystemBody.MineralType.NoMinerals, (int)SystemBody.MineralType.Homeworld); + + + if (isHomeWorld == false) + { + int MineralTest = GameState.RNG.Next(0,100); + MType = MineralType.NoMinerals; + + /// + /// Minerals should be generated. + /// + if(MineralTest > 60) + { + if (Type == PlanetType.GasGiant || Type == PlanetType.IceGiant || Type == PlanetType.GasDwarf) + { + MType = SystemBody.MineralType.GasGiant; + } + else if (Type == PlanetType.Comet) + { + MType = SystemBody.MineralType.Comet; + } + else if (Type == PlanetType.Asteroid) + { + MType = MineralType.Asteroid; + } + else + { + MType = (MineralType)GameState.RNG.Next((int)SystemBody.MineralType.FewGood, (int)SystemBody.MineralType.Homeworld); + } + } + } switch (MType) { @@ -455,6 +493,9 @@ public void GenerateMinerals(bool isHomeWorld = false) case SystemBody.MineralType.Homeworld: HomeworldMineralGeneration(); break; + case SystemBody.MineralType.GasGiant: + GasGiantMineralGeneration(); + break; } _MineralsGenerated = true; } @@ -467,6 +508,41 @@ public int GetSurveyCost() { return (int)Math.Floor((float)Constants.SensorTN.EarthSurvey * ((float)Radius / Constants.SensorTN.EarthRadius)); } + + + /// + /// Add a population if possible for the selected faction of species CurrentSpecies. + /// + /// Faction of population. + /// Sensor info needs timeslice I think + /// Species of this population. + public void AddPopulation(Faction PopFaction, int TimeSlice, Species CurrentSpecies) + { + String Entry = String.Format("AddPopulation Run {0} {1}",SupportsPopulations, Populations.Count); + MessageEntry NMG = new MessageEntry(MessageEntry.MessageType.Count, null, null, GameState.Instance.CurrentDate, GameState.Instance.CurrentSecond, Entry); + GameState.Instance.Factions[0].MessageLog.Add(NMG); + /// + /// Some planet types can't host populations. Gas Giants for example. + /// + if (SupportsPopulations == false) + return; + + /// + /// If such a population already exists do not allow duplicates. this will crash if a duplicate is allowed, and it also potentially perverts gameplay mechanics. + /// + foreach (Population CurrentPop in Populations) + { + if (CurrentPop.Faction == PopFaction && CurrentPop.Species == CurrentSpecies) + return; + } + + /// + /// Assuming that we got this far, add the population. + /// + Population NewPopulation = new Population(this, PopFaction, TimeSlice, Name, CurrentSpecies); + Populations.Add(NewPopulation); + PopFaction.Populations.Add(NewPopulation); + } } #region Data Binding diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index 35c34bc32..b2f6affae 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -1012,7 +1012,7 @@ public void SetActiveSensor(int ShipIndex, int ShipSensorIndex, bool state) /// /// Update the taskgroup lookup missile table if this sensor is better than the previous ones for any particular resolution. /// - for (int loop = 0; loop < 15; loop++) + for (int loop = 0; loop < (Constants.OrdnanceTN.MissileResolutionMaximum + 1); loop++) { if (ActiveSensorQue[(ActiveSensorQue.Count - 1)].aSensorDef.lookUpMT[loop] > ActiveSensorQue[TaskGroupLookUpMT[loop]].aSensorDef.lookUpMT[loop]) { @@ -1106,7 +1106,7 @@ public void SetActiveSensor(int ShipIndex, int ShipSensorIndex, bool state) /// /// Missile Table reassignment. /// - for (int loop = 0; loop < 15; loop++) + for (int loop = 0; loop < (Constants.OrdnanceTN.MissileResolutionMaximum + 1); loop++) { if (TaskGroupLookUpMT[loop] == inQue) { @@ -3158,10 +3158,6 @@ public uint PerformOrders(uint TimeSlice) if (CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyStatus == JPDetection.Status.None) CurrentSystem._SurveyResults[TaskGroupFaction]._SurveyStatus = JPDetection.Status.Incomplete; - - String Entry = String.Format("Indexs J:{0} Just found {1} at {2} {3},{4}", CurrentSystem._SurveyResults[TaskGroupFaction]._DetectedJPs.Count,JP,SPIndex+1,JP.Position.X,JP.Position.Y); - MessageEntry NME = new MessageEntry(MessageEntry.MessageType.Error, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); - TaskGroupFaction.MessageLog.Add(NME); } } } diff --git a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs index 90b0de8ba..a3a059b51 100644 --- a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs +++ b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs @@ -1621,7 +1621,7 @@ private static void GenerateJumpPoints(StarSystem system, int numJumpPoints = -1 /// if (Constants.GameSettings.Aurora65JPGeneration == true) { - int numJPs = 10; + int numJPs = 1; int BaseJPChance = 90; int JPChance = (BaseJPChance + (int)Math.Round(system.Stars[0].Orbit.MassRelativeToSol)); while (m_RNG.Next(100) < JPChance) diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/SystemGenAndDisplay.cs b/Pulsar4X/Pulsar4X.UI/Handlers/SystemGenAndDisplay.cs index bd8289b55..2cb356ac9 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/SystemGenAndDisplay.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/SystemGenAndDisplay.cs @@ -36,6 +36,13 @@ public SystemGenAndDisplay() // setup view model: VM = new StarSystemViewModel(); + // bind Faction combo box: + m_oControlsPanel.CurrentFactionComboBox.DataSource = VM.Factions; + m_oControlsPanel.CurrentFactionComboBox.Bind(c => c.SelectedItem, VM, d => d.CurrentFaction, DataSourceUpdateMode.OnPropertyChanged); + m_oControlsPanel.CurrentFactionComboBox.DisplayMember = "Name"; + + m_oControlsPanel.CurrentFactionComboBox.SelectedIndexChanged += (s, args) => m_oControlsPanel.CurrentFactionComboBox.DataBindings["SelectedItem"].WriteValue(); + // bind System Selection combo box: m_oControlsPanel.SystemSelectionComboBox.DataSource = VM.StarSystems; m_oControlsPanel.SystemSelectionComboBox.Bind(c => c.SelectedItem, VM, d => d.CurrentStarSystem, DataSourceUpdateMode.OnPropertyChanged); @@ -109,7 +116,45 @@ void ExportButton_Click(object sender, EventArgs e) void AddColonyButton_Click(object sender, EventArgs e) { - throw new NotImplementedException(); + /// + /// Is there a selection? + /// + if (m_oDataPanel.PlanetsDataGrid.CurrentCell.RowIndex != -1) + { + /// + /// this is kind of wierd, the databinding is effortlessly putting all planets into the list, even if they are moons, and not strictly in the planet list. + /// So I have to count through every planet and moon to get the right index. + /// + int Count = 0; + bool MoonSet = false; + foreach (SystemBody Planet in VM.CurrentStar.Planets) + { + if (m_oDataPanel.PlanetsDataGrid.CurrentCell.RowIndex == Count) + { + VM.CurrentPlanet = Planet; + break; + } + + Count++; + + foreach (SystemBody Moon in Planet.Moons) + { + if (m_oDataPanel.PlanetsDataGrid.CurrentCell.RowIndex == Count) + { + VM.CurrentPlanet = Moon; + MoonSet = true; + break; + } + + Count++; + } + + if (MoonSet == true) + break; + + } + VM.CurrentPlanet.AddPopulation(VM.CurrentFaction, GameState.Instance.CurrentSecond, VM.CurrentFaction.Species); + } } void AutoRenameButton_Click(object sender, EventArgs e) @@ -152,6 +197,11 @@ void StarsDataGrid_SelectionChanged(object sender, EventArgs e) } } + /// + /// This seems to be always failing for some reason. + /// + /// + /// void PlanetsDataGrid_SelectionChanged(object sender, EventArgs e) { var sel = m_oDataPanel.PlanetsDataGrid.SelectedRows; diff --git a/Pulsar4X/Pulsar4X.UI/Panels/MissileDesign.Designer.cs b/Pulsar4X/Pulsar4X.UI/Panels/MissileDesign.Designer.cs index 01e9f2952..ab4a3c475 100644 --- a/Pulsar4X/Pulsar4X.UI/Panels/MissileDesign.Designer.cs +++ b/Pulsar4X/Pulsar4X.UI/Panels/MissileDesign.Designer.cs @@ -524,6 +524,22 @@ private void InitializeComponent() this.m_oEngineLabel = new System.Windows.Forms.Label(); this.m_oMissileEngineComboBox = new System.Windows.Forms.ComboBox(); this.m_oSecondStageGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oMaterialsRichTextBox = new System.Windows.Forms.RichTextBox(); + this.m_oSubTotalCostTextBox = new System.Windows.Forms.TextBox(); + this.m_oSepRangeTextBox = new System.Windows.Forms.TextBox(); + this.m_oSubCostTextBox = new System.Windows.Forms.TextBox(); + this.m_oSubTotalSizeTextBox = new System.Windows.Forms.TextBox(); + this.m_oTotalMCostLabel = new System.Windows.Forms.Label(); + this.m_oSubNumberTextBox = new System.Windows.Forms.TextBox(); + this.m_oSubSizeTextBox = new System.Windows.Forms.TextBox(); + this.m_oMissileCostLabel = new System.Windows.Forms.Label(); + this.m_oSepRangeLabel = new System.Windows.Forms.Label(); + this.m_oMaterialsLabel = new System.Windows.Forms.Label(); + this.m_oTotalMSizeLabel = new System.Windows.Forms.Label(); + this.m_oSubSizeLabel = new System.Windows.Forms.Label(); + this.m_oSubNumberLabel = new System.Windows.Forms.Label(); + this.m_oMissileTypeLabel = new System.Windows.Forms.Label(); + this.m_oSubMunitionComboBox = new System.Windows.Forms.ComboBox(); this.m_oSystemParametersGroupBox = new System.Windows.Forms.GroupBox(); this.m_oCreateButton = new System.Windows.Forms.Button(); this.m_oMissileNameTextBox = new System.Windows.Forms.TextBox(); @@ -538,22 +554,6 @@ private void InitializeComponent() this.m_oSetSeriesButton = new System.Windows.Forms.Button(); this.m_oReplaceAllButton = new System.Windows.Forms.Button(); this.m_oInstantButton = new System.Windows.Forms.Button(); - this.m_oSubMunitionComboBox = new System.Windows.Forms.ComboBox(); - this.m_oMissileTypeLabel = new System.Windows.Forms.Label(); - this.m_oSubNumberLabel = new System.Windows.Forms.Label(); - this.m_oSubSizeLabel = new System.Windows.Forms.Label(); - this.m_oTotalMSizeLabel = new System.Windows.Forms.Label(); - this.m_oMaterialsLabel = new System.Windows.Forms.Label(); - this.m_oSepRangeLabel = new System.Windows.Forms.Label(); - this.m_oMissileCostLabel = new System.Windows.Forms.Label(); - this.m_oTotalMCostLabel = new System.Windows.Forms.Label(); - this.m_oSubTotalSizeTextBox = new System.Windows.Forms.TextBox(); - this.m_oSubNumberTextBox = new System.Windows.Forms.TextBox(); - this.m_oSubSizeTextBox = new System.Windows.Forms.TextBox(); - this.m_oSubTotalCostTextBox = new System.Windows.Forms.TextBox(); - this.m_oSepRangeTextBox = new System.Windows.Forms.TextBox(); - this.m_oSubCostTextBox = new System.Windows.Forms.TextBox(); - this.m_oMaterialsRichTextBox = new System.Windows.Forms.RichTextBox(); this.m_oEmpireGroupBox.SuspendLayout(); this.m_oCompSizeBox.SuspendLayout(); this.m_oParametersGroupBox.SuspendLayout(); @@ -1235,6 +1235,162 @@ private void InitializeComponent() this.m_oSecondStageGroupBox.TabStop = false; this.m_oSecondStageGroupBox.Text = "Second Stage(if desired)"; // + // m_oMaterialsRichTextBox + // + this.m_oMaterialsRichTextBox.Location = new System.Drawing.Point(87, 118); + this.m_oMaterialsRichTextBox.Margin = new System.Windows.Forms.Padding(10); + this.m_oMaterialsRichTextBox.Name = "m_oMaterialsRichTextBox"; + this.m_oMaterialsRichTextBox.ReadOnly = true; + this.m_oMaterialsRichTextBox.Size = new System.Drawing.Size(219, 64); + this.m_oMaterialsRichTextBox.TabIndex = 3; + this.m_oMaterialsRichTextBox.Text = "0x Boronide 0x Corbomite 0x Tritanium 0x Uridium 0x Gallicite 0x Corundium " + + "0x Duranium 0x Neutronium\nNot Yet Implemented"; + // + // m_oSubTotalCostTextBox + // + this.m_oSubTotalCostTextBox.Location = new System.Drawing.Point(262, 92); + this.m_oSubTotalCostTextBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); + this.m_oSubTotalCostTextBox.Name = "m_oSubTotalCostTextBox"; + this.m_oSubTotalCostTextBox.ReadOnly = true; + this.m_oSubTotalCostTextBox.Size = new System.Drawing.Size(44, 20); + this.m_oSubTotalCostTextBox.TabIndex = 42; + this.m_oSubTotalCostTextBox.Text = "0"; + this.m_oSubTotalCostTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // m_oSepRangeTextBox + // + this.m_oSepRangeTextBox.Location = new System.Drawing.Point(262, 40); + this.m_oSepRangeTextBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); + this.m_oSepRangeTextBox.Name = "m_oSepRangeTextBox"; + this.m_oSepRangeTextBox.Size = new System.Drawing.Size(44, 20); + this.m_oSepRangeTextBox.TabIndex = 40; + this.m_oSepRangeTextBox.Text = "150"; + this.m_oSepRangeTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // m_oSubCostTextBox + // + this.m_oSubCostTextBox.Location = new System.Drawing.Point(262, 66); + this.m_oSubCostTextBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); + this.m_oSubCostTextBox.Name = "m_oSubCostTextBox"; + this.m_oSubCostTextBox.ReadOnly = true; + this.m_oSubCostTextBox.Size = new System.Drawing.Size(44, 20); + this.m_oSubCostTextBox.TabIndex = 41; + this.m_oSubCostTextBox.Text = "0"; + this.m_oSubCostTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // m_oSubTotalSizeTextBox + // + this.m_oSubTotalSizeTextBox.Location = new System.Drawing.Point(87, 92); + this.m_oSubTotalSizeTextBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); + this.m_oSubTotalSizeTextBox.Name = "m_oSubTotalSizeTextBox"; + this.m_oSubTotalSizeTextBox.ReadOnly = true; + this.m_oSubTotalSizeTextBox.Size = new System.Drawing.Size(44, 20); + this.m_oSubTotalSizeTextBox.TabIndex = 39; + this.m_oSubTotalSizeTextBox.Text = "0"; + this.m_oSubTotalSizeTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // m_oTotalMCostLabel + // + this.m_oTotalMCostLabel.AutoSize = true; + this.m_oTotalMCostLabel.Location = new System.Drawing.Point(194, 95); + this.m_oTotalMCostLabel.Name = "m_oTotalMCostLabel"; + this.m_oTotalMCostLabel.Size = new System.Drawing.Size(55, 13); + this.m_oTotalMCostLabel.TabIndex = 18; + this.m_oTotalMCostLabel.Text = "Total Cost"; + // + // m_oSubNumberTextBox + // + this.m_oSubNumberTextBox.Location = new System.Drawing.Point(87, 40); + this.m_oSubNumberTextBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); + this.m_oSubNumberTextBox.Name = "m_oSubNumberTextBox"; + this.m_oSubNumberTextBox.Size = new System.Drawing.Size(44, 20); + this.m_oSubNumberTextBox.TabIndex = 37; + this.m_oSubNumberTextBox.Text = "0"; + this.m_oSubNumberTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // m_oSubSizeTextBox + // + this.m_oSubSizeTextBox.Location = new System.Drawing.Point(87, 66); + this.m_oSubSizeTextBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); + this.m_oSubSizeTextBox.Name = "m_oSubSizeTextBox"; + this.m_oSubSizeTextBox.ReadOnly = true; + this.m_oSubSizeTextBox.Size = new System.Drawing.Size(44, 20); + this.m_oSubSizeTextBox.TabIndex = 38; + this.m_oSubSizeTextBox.Text = "0"; + this.m_oSubSizeTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // m_oMissileCostLabel + // + this.m_oMissileCostLabel.AutoSize = true; + this.m_oMissileCostLabel.Location = new System.Drawing.Point(187, 69); + this.m_oMissileCostLabel.Name = "m_oMissileCostLabel"; + this.m_oMissileCostLabel.Size = new System.Drawing.Size(62, 13); + this.m_oMissileCostLabel.TabIndex = 17; + this.m_oMissileCostLabel.Text = "Missile Cost"; + // + // m_oSepRangeLabel + // + this.m_oSepRangeLabel.AutoSize = true; + this.m_oSepRangeLabel.Location = new System.Drawing.Point(144, 43); + this.m_oSepRangeLabel.Name = "m_oSepRangeLabel"; + this.m_oSepRangeLabel.Size = new System.Drawing.Size(105, 13); + this.m_oSepRangeLabel.TabIndex = 16; + this.m_oSepRangeLabel.Text = "Separation Range(k)"; + // + // m_oMaterialsLabel + // + this.m_oMaterialsLabel.AutoSize = true; + this.m_oMaterialsLabel.Location = new System.Drawing.Point(6, 121); + this.m_oMaterialsLabel.Name = "m_oMaterialsLabel"; + this.m_oMaterialsLabel.Size = new System.Drawing.Size(49, 13); + this.m_oMaterialsLabel.TabIndex = 15; + this.m_oMaterialsLabel.Text = "Materials"; + // + // m_oTotalMSizeLabel + // + this.m_oTotalMSizeLabel.AutoSize = true; + this.m_oTotalMSizeLabel.Location = new System.Drawing.Point(6, 95); + this.m_oTotalMSizeLabel.Name = "m_oTotalMSizeLabel"; + this.m_oTotalMSizeLabel.Size = new System.Drawing.Size(54, 13); + this.m_oTotalMSizeLabel.TabIndex = 14; + this.m_oTotalMSizeLabel.Text = "Total Size"; + // + // m_oSubSizeLabel + // + this.m_oSubSizeLabel.AutoSize = true; + this.m_oSubSizeLabel.Location = new System.Drawing.Point(6, 69); + this.m_oSubSizeLabel.Name = "m_oSubSizeLabel"; + this.m_oSubSizeLabel.Size = new System.Drawing.Size(61, 13); + this.m_oSubSizeLabel.TabIndex = 13; + this.m_oSubSizeLabel.Text = "Missile Size"; + // + // m_oSubNumberLabel + // + this.m_oSubNumberLabel.AutoSize = true; + this.m_oSubNumberLabel.Location = new System.Drawing.Point(7, 43); + this.m_oSubNumberLabel.Name = "m_oSubNumberLabel"; + this.m_oSubNumberLabel.Size = new System.Drawing.Size(44, 13); + this.m_oSubNumberLabel.TabIndex = 12; + this.m_oSubNumberLabel.Text = "Number"; + // + // m_oMissileTypeLabel + // + this.m_oMissileTypeLabel.AutoSize = true; + this.m_oMissileTypeLabel.Location = new System.Drawing.Point(6, 16); + this.m_oMissileTypeLabel.Name = "m_oMissileTypeLabel"; + this.m_oMissileTypeLabel.Size = new System.Drawing.Size(65, 13); + this.m_oMissileTypeLabel.TabIndex = 11; + this.m_oMissileTypeLabel.Text = "Missile Type"; + // + // m_oSubMunitionComboBox + // + this.m_oSubMunitionComboBox.FormattingEnabled = true; + this.m_oSubMunitionComboBox.Location = new System.Drawing.Point(87, 13); + this.m_oSubMunitionComboBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); + this.m_oSubMunitionComboBox.Name = "m_oSubMunitionComboBox"; + this.m_oSubMunitionComboBox.Size = new System.Drawing.Size(219, 21); + this.m_oSubMunitionComboBox.TabIndex = 11; + // // m_oSystemParametersGroupBox // this.m_oSystemParametersGroupBox.Controls.Add(this.m_oCreateButton); @@ -1370,162 +1526,6 @@ private void InitializeComponent() this.m_oInstantButton.Text = "Instant"; this.m_oInstantButton.UseVisualStyleBackColor = true; // - // m_oSubMunitionComboBox - // - this.m_oSubMunitionComboBox.FormattingEnabled = true; - this.m_oSubMunitionComboBox.Location = new System.Drawing.Point(87, 13); - this.m_oSubMunitionComboBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); - this.m_oSubMunitionComboBox.Name = "m_oSubMunitionComboBox"; - this.m_oSubMunitionComboBox.Size = new System.Drawing.Size(219, 21); - this.m_oSubMunitionComboBox.TabIndex = 11; - // - // m_oMissileTypeLabel - // - this.m_oMissileTypeLabel.AutoSize = true; - this.m_oMissileTypeLabel.Location = new System.Drawing.Point(6, 16); - this.m_oMissileTypeLabel.Name = "m_oMissileTypeLabel"; - this.m_oMissileTypeLabel.Size = new System.Drawing.Size(65, 13); - this.m_oMissileTypeLabel.TabIndex = 11; - this.m_oMissileTypeLabel.Text = "Missile Type"; - // - // m_oSubNumberLabel - // - this.m_oSubNumberLabel.AutoSize = true; - this.m_oSubNumberLabel.Location = new System.Drawing.Point(7, 43); - this.m_oSubNumberLabel.Name = "m_oSubNumberLabel"; - this.m_oSubNumberLabel.Size = new System.Drawing.Size(44, 13); - this.m_oSubNumberLabel.TabIndex = 12; - this.m_oSubNumberLabel.Text = "Number"; - // - // m_oSubSizeLabel - // - this.m_oSubSizeLabel.AutoSize = true; - this.m_oSubSizeLabel.Location = new System.Drawing.Point(6, 69); - this.m_oSubSizeLabel.Name = "m_oSubSizeLabel"; - this.m_oSubSizeLabel.Size = new System.Drawing.Size(61, 13); - this.m_oSubSizeLabel.TabIndex = 13; - this.m_oSubSizeLabel.Text = "Missile Size"; - // - // m_oTotalMSizeLabel - // - this.m_oTotalMSizeLabel.AutoSize = true; - this.m_oTotalMSizeLabel.Location = new System.Drawing.Point(6, 95); - this.m_oTotalMSizeLabel.Name = "m_oTotalMSizeLabel"; - this.m_oTotalMSizeLabel.Size = new System.Drawing.Size(54, 13); - this.m_oTotalMSizeLabel.TabIndex = 14; - this.m_oTotalMSizeLabel.Text = "Total Size"; - // - // m_oMaterialsLabel - // - this.m_oMaterialsLabel.AutoSize = true; - this.m_oMaterialsLabel.Location = new System.Drawing.Point(6, 121); - this.m_oMaterialsLabel.Name = "m_oMaterialsLabel"; - this.m_oMaterialsLabel.Size = new System.Drawing.Size(49, 13); - this.m_oMaterialsLabel.TabIndex = 15; - this.m_oMaterialsLabel.Text = "Materials"; - // - // m_oSepRangeLabel - // - this.m_oSepRangeLabel.AutoSize = true; - this.m_oSepRangeLabel.Location = new System.Drawing.Point(144, 43); - this.m_oSepRangeLabel.Name = "m_oSepRangeLabel"; - this.m_oSepRangeLabel.Size = new System.Drawing.Size(105, 13); - this.m_oSepRangeLabel.TabIndex = 16; - this.m_oSepRangeLabel.Text = "Separation Range(k)"; - // - // m_oMissileCostLabel - // - this.m_oMissileCostLabel.AutoSize = true; - this.m_oMissileCostLabel.Location = new System.Drawing.Point(187, 69); - this.m_oMissileCostLabel.Name = "m_oMissileCostLabel"; - this.m_oMissileCostLabel.Size = new System.Drawing.Size(62, 13); - this.m_oMissileCostLabel.TabIndex = 17; - this.m_oMissileCostLabel.Text = "Missile Cost"; - // - // m_oTotalMCostLabel - // - this.m_oTotalMCostLabel.AutoSize = true; - this.m_oTotalMCostLabel.Location = new System.Drawing.Point(194, 95); - this.m_oTotalMCostLabel.Name = "m_oTotalMCostLabel"; - this.m_oTotalMCostLabel.Size = new System.Drawing.Size(55, 13); - this.m_oTotalMCostLabel.TabIndex = 18; - this.m_oTotalMCostLabel.Text = "Total Cost"; - // - // m_oSubTotalSizeTextBox - // - this.m_oSubTotalSizeTextBox.Location = new System.Drawing.Point(87, 92); - this.m_oSubTotalSizeTextBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); - this.m_oSubTotalSizeTextBox.Name = "m_oSubTotalSizeTextBox"; - this.m_oSubTotalSizeTextBox.ReadOnly = true; - this.m_oSubTotalSizeTextBox.Size = new System.Drawing.Size(44, 20); - this.m_oSubTotalSizeTextBox.TabIndex = 39; - this.m_oSubTotalSizeTextBox.Text = "0"; - this.m_oSubTotalSizeTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - // - // m_oSubNumberTextBox - // - this.m_oSubNumberTextBox.Location = new System.Drawing.Point(87, 40); - this.m_oSubNumberTextBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); - this.m_oSubNumberTextBox.Name = "m_oSubNumberTextBox"; - this.m_oSubNumberTextBox.Size = new System.Drawing.Size(44, 20); - this.m_oSubNumberTextBox.TabIndex = 37; - this.m_oSubNumberTextBox.Text = "0"; - this.m_oSubNumberTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - // - // m_oSubSizeTextBox - // - this.m_oSubSizeTextBox.Location = new System.Drawing.Point(87, 66); - this.m_oSubSizeTextBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); - this.m_oSubSizeTextBox.Name = "m_oSubSizeTextBox"; - this.m_oSubSizeTextBox.ReadOnly = true; - this.m_oSubSizeTextBox.Size = new System.Drawing.Size(44, 20); - this.m_oSubSizeTextBox.TabIndex = 38; - this.m_oSubSizeTextBox.Text = "0"; - this.m_oSubSizeTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - // - // m_oSubTotalCostTextBox - // - this.m_oSubTotalCostTextBox.Location = new System.Drawing.Point(262, 92); - this.m_oSubTotalCostTextBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); - this.m_oSubTotalCostTextBox.Name = "m_oSubTotalCostTextBox"; - this.m_oSubTotalCostTextBox.ReadOnly = true; - this.m_oSubTotalCostTextBox.Size = new System.Drawing.Size(44, 20); - this.m_oSubTotalCostTextBox.TabIndex = 42; - this.m_oSubTotalCostTextBox.Text = "0"; - this.m_oSubTotalCostTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - // - // m_oSepRangeTextBox - // - this.m_oSepRangeTextBox.Location = new System.Drawing.Point(262, 40); - this.m_oSepRangeTextBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); - this.m_oSepRangeTextBox.Name = "m_oSepRangeTextBox"; - this.m_oSepRangeTextBox.Size = new System.Drawing.Size(44, 20); - this.m_oSepRangeTextBox.TabIndex = 40; - this.m_oSepRangeTextBox.Text = "150"; - this.m_oSepRangeTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - // - // m_oSubCostTextBox - // - this.m_oSubCostTextBox.Location = new System.Drawing.Point(262, 66); - this.m_oSubCostTextBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); - this.m_oSubCostTextBox.Name = "m_oSubCostTextBox"; - this.m_oSubCostTextBox.ReadOnly = true; - this.m_oSubCostTextBox.Size = new System.Drawing.Size(44, 20); - this.m_oSubCostTextBox.TabIndex = 41; - this.m_oSubCostTextBox.Text = "0"; - this.m_oSubCostTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - // - // m_oMaterialsRichTextBox - // - this.m_oMaterialsRichTextBox.Location = new System.Drawing.Point(87, 118); - this.m_oMaterialsRichTextBox.Margin = new System.Windows.Forms.Padding(10); - this.m_oMaterialsRichTextBox.Name = "m_oMaterialsRichTextBox"; - this.m_oMaterialsRichTextBox.ReadOnly = true; - this.m_oMaterialsRichTextBox.Size = new System.Drawing.Size(219, 64); - this.m_oMaterialsRichTextBox.TabIndex = 3; - this.m_oMaterialsRichTextBox.Text = "0x Boronide 0x Corbomite 0x Tritanium 0x Uridium 0x Gallicite 0x Corundium " + - "0x Duranium 0x Neutronium\nNot Yet Implemented"; - // // MissileDesign // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); diff --git a/Pulsar4X/Pulsar4X.UI/Panels/SGaD_Controls.Designer.cs b/Pulsar4X/Pulsar4X.UI/Panels/SGaD_Controls.Designer.cs index 4f5db76c8..ec4c9d403 100644 --- a/Pulsar4X/Pulsar4X.UI/Panels/SGaD_Controls.Designer.cs +++ b/Pulsar4X/Pulsar4X.UI/Panels/SGaD_Controls.Designer.cs @@ -46,6 +46,7 @@ private void InitializeComponent() this.m_oDeleteSystemButton = new System.Windows.Forms.Button(); this.m_oGenGalaxyButton = new System.Windows.Forms.Button(); this.m_oGenSystemButton = new System.Windows.Forms.Button(); + this.m_oCurrentFactionComboBox = new System.Windows.Forms.ComboBox(); this.m_oSystemInfoGroupBox.SuspendLayout(); this.m_oControlsGroupBox.SuspendLayout(); this.m_oSMControlsGroupBox.SuspendLayout(); @@ -54,7 +55,7 @@ private void InitializeComponent() // m_oSystemSelectionComboBox // this.m_oSystemSelectionComboBox.FormattingEnabled = true; - this.m_oSystemSelectionComboBox.Location = new System.Drawing.Point(13, 13); + this.m_oSystemSelectionComboBox.Location = new System.Drawing.Point(12, 39); this.m_oSystemSelectionComboBox.Name = "m_oSystemSelectionComboBox"; this.m_oSystemSelectionComboBox.Size = new System.Drawing.Size(183, 21); this.m_oSystemSelectionComboBox.TabIndex = 0; @@ -69,7 +70,7 @@ private void InitializeComponent() this.m_oSystemInfoGroupBox.Controls.Add(this.m_oAgeTextBox); this.m_oSystemInfoGroupBox.Controls.Add(this.m_oSystemTypeTextBox); this.m_oSystemInfoGroupBox.Controls.Add(this.label1); - this.m_oSystemInfoGroupBox.Location = new System.Drawing.Point(13, 41); + this.m_oSystemInfoGroupBox.Location = new System.Drawing.Point(12, 67); this.m_oSystemInfoGroupBox.Name = "m_oSystemInfoGroupBox"; this.m_oSystemInfoGroupBox.Size = new System.Drawing.Size(183, 139); this.m_oSystemInfoGroupBox.TabIndex = 1; @@ -145,7 +146,7 @@ private void InitializeComponent() this.m_oControlsGroupBox.Controls.Add(this.m_oExportButton); this.m_oControlsGroupBox.Controls.Add(this.m_oAddColonyButton); this.m_oControlsGroupBox.Controls.Add(this.m_oAutoRenameButton); - this.m_oControlsGroupBox.Location = new System.Drawing.Point(13, 186); + this.m_oControlsGroupBox.Location = new System.Drawing.Point(12, 212); this.m_oControlsGroupBox.Name = "m_oControlsGroupBox"; this.m_oControlsGroupBox.Size = new System.Drawing.Size(183, 84); this.m_oControlsGroupBox.TabIndex = 2; @@ -176,7 +177,7 @@ private void InitializeComponent() this.m_oAutoRenameButton.Name = "m_oAutoRenameButton"; this.m_oAutoRenameButton.Size = new System.Drawing.Size(75, 23); this.m_oAutoRenameButton.TabIndex = 0; - this.m_oAutoRenameButton.Text = "Auto Rename"; + this.m_oAutoRenameButton.Text = "Auto Rename\r\n"; this.m_oAutoRenameButton.UseVisualStyleBackColor = true; // // m_oSMControlsGroupBox @@ -184,7 +185,7 @@ private void InitializeComponent() this.m_oSMControlsGroupBox.Controls.Add(this.m_oDeleteSystemButton); this.m_oSMControlsGroupBox.Controls.Add(this.m_oGenGalaxyButton); this.m_oSMControlsGroupBox.Controls.Add(this.m_oGenSystemButton); - this.m_oSMControlsGroupBox.Location = new System.Drawing.Point(13, 276); + this.m_oSMControlsGroupBox.Location = new System.Drawing.Point(12, 302); this.m_oSMControlsGroupBox.Name = "m_oSMControlsGroupBox"; this.m_oSMControlsGroupBox.Size = new System.Drawing.Size(183, 82); this.m_oSMControlsGroupBox.TabIndex = 3; @@ -218,12 +219,21 @@ private void InitializeComponent() this.m_oGenSystemButton.Text = "Gen System"; this.m_oGenSystemButton.UseVisualStyleBackColor = true; // + // m_oCurrentFactionComboBox + // + this.m_oCurrentFactionComboBox.FormattingEnabled = true; + this.m_oCurrentFactionComboBox.Location = new System.Drawing.Point(12, 12); + this.m_oCurrentFactionComboBox.Name = "m_oCurrentFactionComboBox"; + this.m_oCurrentFactionComboBox.Size = new System.Drawing.Size(183, 21); + this.m_oCurrentFactionComboBox.TabIndex = 4; + // // SGaD_Controls // this.AutoHidePortion = 0.2D; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(208, 370); + this.ClientSize = new System.Drawing.Size(208, 397); + this.Controls.Add(this.m_oCurrentFactionComboBox); this.Controls.Add(this.m_oSMControlsGroupBox); this.Controls.Add(this.m_oControlsGroupBox); this.Controls.Add(this.m_oSystemInfoGroupBox); @@ -262,5 +272,6 @@ private void InitializeComponent() private System.Windows.Forms.Button m_oGenSystemButton; private System.Windows.Forms.Label label4; private System.Windows.Forms.TextBox m_oSeedTextBox; + private System.Windows.Forms.ComboBox m_oCurrentFactionComboBox; } } diff --git a/Pulsar4X/Pulsar4X.UI/Panels/SGaD_Controls.cs b/Pulsar4X/Pulsar4X.UI/Panels/SGaD_Controls.cs index a46533969..ff9335310 100644 --- a/Pulsar4X/Pulsar4X.UI/Panels/SGaD_Controls.cs +++ b/Pulsar4X/Pulsar4X.UI/Panels/SGaD_Controls.cs @@ -15,6 +15,14 @@ public partial class SGaD_Controls : DockContent #region Properties + /// + /// What is the currently selected faction + /// + public ComboBox CurrentFactionComboBox + { + get { return m_oCurrentFactionComboBox; } + } + /// /// Combo Box used to select the current star system. /// diff --git a/Pulsar4X/Pulsar4X.UI/Program.cs b/Pulsar4X/Pulsar4X.UI/Program.cs index 9706f7094..af39d2c18 100644 --- a/Pulsar4X/Pulsar4X.UI/Program.cs +++ b/Pulsar4X/Pulsar4X.UI/Program.cs @@ -52,6 +52,7 @@ static void Main() oNewFaction.Populations.Add(new Entities.Population(sol.Stars.FirstOrDefault().Planets[2], oNewFaction, 0)); //.FirstOrDefault() for planets. oNewFaction.Populations[0].Planet.HomeworldMineralGeneration(); oNewFaction.Populations[0].ConventionalStart(); + oNewFaction.KnownSystems.Add(sol); /// /// Add Contact lists. /// @@ -73,6 +74,7 @@ static void Main() oNewFaction2.Populations.Add(new Entities.Population(sol.Stars.FirstOrDefault().Planets[2], oNewFaction2, 0)); //.FirstOrDefault() oNewFaction2.Populations[0].Planet.HomeworldMineralGeneration(); oNewFaction2.Populations[0].ConventionalStart(); + oNewFaction2.KnownSystems.Add(sol); /// /// Add Contact lists. diff --git a/Pulsar4X/Pulsar4X.UI/Properties/Resources.Designer.cs b/Pulsar4X/Pulsar4X.UI/Properties/Resources.Designer.cs index a1d181358..0e35c3df2 100644 --- a/Pulsar4X/Pulsar4X.UI/Properties/Resources.Designer.cs +++ b/Pulsar4X/Pulsar4X.UI/Properties/Resources.Designer.cs @@ -1,17 +1,17 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.269 +// Runtime Version:4.0.30319.233 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Pulsar4X.UI.Properties -{ - - +namespace Pulsar4X.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -22,48 +22,40 @@ namespace Pulsar4X.UI.Properties [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - + internal class Resources { + private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { + internal Resources() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Pulsar4X.UI.Properties.Resources", typeof(Resources).Assembly); + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Pulsar4X.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { + internal static global::System.Globalization.CultureInfo Culture { + get { return resourceCulture; } - set - { + set { resourceCulture = value; } } diff --git a/Pulsar4X/Pulsar4X.UI/ViewModels/StarSystemViewModel.cs b/Pulsar4X/Pulsar4X.UI/ViewModels/StarSystemViewModel.cs index ec961cb8e..6237eda15 100644 --- a/Pulsar4X/Pulsar4X.UI/ViewModels/StarSystemViewModel.cs +++ b/Pulsar4X/Pulsar4X.UI/ViewModels/StarSystemViewModel.cs @@ -14,6 +14,25 @@ namespace Pulsar4X.UI.ViewModels { public class StarSystemViewModel : INotifyPropertyChanged { + private Faction _currentFaction; + public Faction CurrentFaction + { + get { return _currentFaction; } + set + { + _currentFaction = value; + if (_currentFaction == null) + { + return; + } + OnPropertyChanged(() => CurrentFaction); + + CurrentStarSystem = CurrentFaction.KnownSystems[0]; + } + } + + public BindingList Factions { get; set; } + private StarSystem _currentstarsystem; public StarSystem CurrentStarSystem { @@ -146,6 +165,8 @@ public Star CurrentStar public StarSystemViewModel() { + Factions = GameState.Instance.Factions; + // Bind to list of star systems: StarSystems = GameState.Instance.StarSystems; @@ -155,6 +176,8 @@ public StarSystemViewModel() return; } + CurrentFaction = GameState.Instance.Factions.FirstOrDefault(); + CurrentStarSystem = GameState.Instance.StarSystems.FirstOrDefault(); CurrentStar = CurrentStarSystem.Stars.FirstOrDefault(); CurrentPlanet = CurrentStar.Planets.FirstOrDefault(); From 31c6bc1997912992ece72d59dd3ed0c91a8f2f35 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 20 Dec 2015 08:36:51 -0600 Subject: [PATCH 25/40] Geosurvey bugfixes and other UI updates The economics display now updates when the system display updates, an infinite loop in the mineral generation code should be resolved, a sensor bug on transferring craft between taskgroups should be resolved. However many issues have been found: GravSurvey went off to infinity after surveying 7,8 and 9, while targetted on 18. moving the ship back near earth allowed survey of 18 to continue as normal. Geosurvey distance calculations are wrong for nearest body, and the craft was choosing to continually switch between Uranus and Neptune. Commercial shipyard tonnage is either wrong or displayed incorrectly(at 1KT), likewise the mod rates seem wrong, as well as the time to add capacity expansion. UI data between shipyards should be cleared but is not currently. Wierdness is happening with shipyard activity assignments when attempting to override the shipyard assignment. A floating point issue still exists for CI that I'm not sure how to resolve. --- .../Pulsar4X.Lib/Entities/Installation.cs | 2 +- .../Entities/StarSystem/SystemBody.cs | 30 ++++- Pulsar4X/Pulsar4X.UI/Forms/MainForm.cs | 1 + Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 8 ++ Pulsar4X/Pulsar4X.UI/Handlers/SystemMap.cs | 7 ++ .../Pulsar4X.UI/SceenGraph/ContactElement.cs | 103 ++++++++++-------- 6 files changed, 98 insertions(+), 53 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs index d144babe6..95d8c1fab 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs @@ -462,7 +462,7 @@ public ShipyardInformation(Faction CurrentFaction, Constants.ShipyardInfo.SYType { case Constants.ShipyardInfo.SYType.Commercial: Name = "Commercial Yard #" + Number.ToString(); - Tonnage = Constants.ShipyardInfo.BaseShipyardTonnage * Constants.ShipyardInfo.NavalToCommercialRatio; + Tonnage = (Constants.ShipyardInfo.BaseShipyardTonnage * Constants.ShipyardInfo.NavalToCommercialRatio); break; case Constants.ShipyardInfo.SYType.Naval: Name = "Naval Yard #" + Number.ToString(); diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs index bfe72f0e4..bc0196f53 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs @@ -330,12 +330,15 @@ public void AsteroidMineralGeneration() { for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) { - if (GameState.RNG.Next(10) == 1) + if (GameState.RNG.Next(10) == 1 && m_aiMinerialReserves[mineralIterator] == 0.0f) { m_aiMinerialReserves[mineralIterator] = 500.0f + (9500.0f * ((float)GameState.RNG.Next(0, 100000) / 100000.0f)); m_aiMinerialAccessibility[mineralIterator] = 1.0f * ((float)GameState.RNG.Next(8, 10) / 10.0f); mCount--; + + if (mCount == 0) + break; } } } @@ -351,12 +354,15 @@ public void CometMineralGeneration() { for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) { - if (GameState.RNG.Next(10) == 1) + if (GameState.RNG.Next(10) == 1 && m_aiMinerialReserves[mineralIterator] == 0.0f) { m_aiMinerialReserves[mineralIterator] = 10000.0f + (90000.0f * ((float)GameState.RNG.Next(0, 100000) / 100000.0f)); m_aiMinerialAccessibility[mineralIterator] = 1.0f * ((float)GameState.RNG.Next(4, 10) / 10.0f); mCount--; + + if (mCount == 0) + break; } } } @@ -372,12 +378,15 @@ public void LowPlanetMineralGeneration() { for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) { - if (GameState.RNG.Next(10) == 1) + if (GameState.RNG.Next(10) == 1 && m_aiMinerialReserves[mineralIterator] == 0.0f) { m_aiMinerialReserves[mineralIterator] = 500000.0f + (3500000.0f * ((float)GameState.RNG.Next(0, 100000) / 100000.0f)); m_aiMinerialAccessibility[mineralIterator] = 1.0f * ((float)GameState.RNG.Next(2, 10) / 10.0f); mCount--; + + if (mCount == 0) + break; } } } @@ -393,12 +402,15 @@ public void HighPlanetMineralGeneration() { for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) { - if (GameState.RNG.Next(10) == 1) + if (GameState.RNG.Next(10) == 1 && m_aiMinerialReserves[mineralIterator] == 0.0f) { m_aiMinerialReserves[mineralIterator] = 500000.0f + (3500000.0f * ((float)GameState.RNG.Next(0, 100000) / 100000.0f)); m_aiMinerialAccessibility[mineralIterator] = 1.0f * ((float)GameState.RNG.Next(2, 10) / 10.0f); mCount--; + + if (mCount == 0) + break; } } } @@ -414,12 +426,20 @@ public void MassiveMineralGeneration() { for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) { - if (GameState.RNG.Next(10) == 1) + /// + /// randomly pick a mineral to generate, and don't double up on mineral generation. + /// + if (GameState.RNG.Next(10) == 1 && m_aiMinerialReserves[mineralIterator] == 0.0f) { m_aiMinerialReserves[mineralIterator] = 10000000.0f + (140000000.0f * ((float)GameState.RNG.Next(0, 100000) / 100000.0f)); m_aiMinerialAccessibility[mineralIterator] = 0.1f; mCount--; + + /// + /// So important thing: if mCount keeps getting incremented past -1, this can go into an infinite loop. + if (mCount == 0) + break; } } } diff --git a/Pulsar4X/Pulsar4X.UI/Forms/MainForm.cs b/Pulsar4X/Pulsar4X.UI/Forms/MainForm.cs index c52cdb045..22af60b50 100644 --- a/Pulsar4X/Pulsar4X.UI/Forms/MainForm.cs +++ b/Pulsar4X/Pulsar4X.UI/Forms/MainForm.cs @@ -76,6 +76,7 @@ private void MainForm_Load(object sender, EventArgs e) Helpers.UIController.Instance.SystemMap.MainFormReference = this; Helpers.UIController.Instance.Economics.MainFormReference = this; Helpers.UIController.Instance.Economics.SystemMapReference = Helpers.UIController.Instance.SystemMap; + Helpers.UIController.Instance.SystemMap.EconomicsReference = Helpers.UIController.Instance.Economics; } #region MenuAndToolStripEvents diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index ed46fbcfb..7e7396bc4 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -1045,6 +1045,14 @@ public void ActivateSummaryPanel() Helpers.UIController.Instance.SuspendAutoPanelDisplay = false; } + /// + /// The system map needs a way to refresh the economics panel based on the passage of time there, so a way to call SoftRefresh publically is needed. + /// + public void RefreshDisplay() + { + SoftRefresh(); + } + #endregion diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/SystemMap.cs b/Pulsar4X/Pulsar4X.UI/Handlers/SystemMap.cs index 09e6def41..5b9efc43a 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/SystemMap.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/SystemMap.cs @@ -104,6 +104,11 @@ public List SystemSceens /// public Pulsar4X.UI.Forms.MainForm MainFormReference { get; set; } + /// + /// When time is advanced things can move, so I need this to update the Economics display if it is currently in use. + /// + public Pulsar4X.UI.Handlers.Economics EconomicsReference { get; set; } + #endregion public SystemMap() @@ -246,6 +251,8 @@ private void AdvanceTime(int TickValue) MainFormReference.Text = "Pulsar4X - " + GameState.Instance.GameDateTime.ToString(); + EconomicsReference.RefreshDisplay(); + m_oCurrentSceen.Refresh(); } diff --git a/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs b/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs index 1595ceec7..6d0aac76e 100644 --- a/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs +++ b/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs @@ -141,6 +141,12 @@ public override void Render() /// if (TaskGroup.SensorUpdateAck != _LastSensorUpdateAck) { + /// + /// Get rid of all sensors if this taskgroup is empty. a SensorUpdateAck should be sent upon emptying a tg into another tg. + /// + if (TaskGroup.Ships.Count == 0) + _SensorContactElements.Clear(); + /// /// Remove those sensors that are no longer active. /// @@ -207,60 +213,63 @@ public override void Render() if (ParentSceen.ShowPassives == true) { - /// - /// A taskgroup with no sensors still has the default package, so handle that. - /// - if (TaskGroup.BestEM == null && _SensorContactElements.ContainsKey(TaskGroup.Id) == false) + if(TaskGroup.Ships.Count != 0) { - PassiveSensorDefTN pSensorDef = TaskGroup.TaskGroupFaction.ComponentList.DefaultPassives; - double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; - double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; - - Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); - - SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Blue, "", null, ComponentTypeTN.PassiveSensor, ParentSceen); - - //definitely a kludge here to make SCE work with default passives. - _SensorContactElements.Add(TaskGroup.Id, NSE); - } - else if (TaskGroup.BestEM != null && _SensorContactElements.ContainsKey(TaskGroup.BestEM.pSensorDef.Id) == false) - { - PassiveSensorDefTN pSensorDef = TaskGroup.BestEM.pSensorDef; - double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; - double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; - - Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); + /// + /// A taskgroup with no sensors still has the default package, so handle that. A taskgroup with no ships should not have a sensor presence however. + /// + if (TaskGroup.BestEM == null && _SensorContactElements.ContainsKey(TaskGroup.Id) == false) + { + PassiveSensorDefTN pSensorDef = TaskGroup.TaskGroupFaction.ComponentList.DefaultPassives; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; + double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; - SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Blue, TaskGroup.BestEM.Name, TaskGroup.BestEM, TaskGroup.BestEM.pSensorDef.componentType, ParentSceen); - _SensorContactElements.Add(TaskGroup.BestEM.pSensorDef.Id, NSE); - } + Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); - /// - /// A taskgroup with no sensors still has the default package, so handle that. - /// - if (TaskGroup.BestThermal == null && _SensorContactElements.ContainsKey(TaskGroup.Ships[0].Id) == false) - { - PassiveSensorDefTN pSensorDef = TaskGroup.TaskGroupFaction.ComponentList.DefaultPassives; - double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; - double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; + SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Blue, "", null, ComponentTypeTN.PassiveSensor, ParentSceen); - Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); + //definitely a kludge here to make SCE work with default passives. + _SensorContactElements.Add(TaskGroup.Id, NSE); + } + else if (TaskGroup.BestEM != null && _SensorContactElements.ContainsKey(TaskGroup.BestEM.pSensorDef.Id) == false) + { + PassiveSensorDefTN pSensorDef = TaskGroup.BestEM.pSensorDef; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; + double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; - SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Red, "", null, ComponentTypeTN.PassiveSensor, ParentSceen); + Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); - //yep, its a kludge. - _SensorContactElements.Add(TaskGroup.Ships[0].Id, NSE); - } - else if (TaskGroup.BestThermal != null && _SensorContactElements.ContainsKey(TaskGroup.BestThermal.pSensorDef.Id) == false) - { - PassiveSensorDefTN pSensorDef = TaskGroup.BestThermal.pSensorDef; - double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; - double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; + SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Blue, TaskGroup.BestEM.Name, TaskGroup.BestEM, TaskGroup.BestEM.pSensorDef.componentType, ParentSceen); + _SensorContactElements.Add(TaskGroup.BestEM.pSensorDef.Id, NSE); + } - Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); - - SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Red, TaskGroup.BestThermal.Name, TaskGroup.BestThermal, TaskGroup.BestThermal.pSensorDef.componentType, ParentSceen); - _SensorContactElements.Add(pSensorDef.Id, NSE); + /// + /// A taskgroup with no sensors still has the default package, so handle that. + /// + if (TaskGroup.BestThermal == null && _SensorContactElements.ContainsKey(TaskGroup.Ships[0].Id) == false) + { + PassiveSensorDefTN pSensorDef = TaskGroup.TaskGroupFaction.ComponentList.DefaultPassives; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; + double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; + + Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); + + SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Red, "", null, ComponentTypeTN.PassiveSensor, ParentSceen); + + //yep, its a kludge. + _SensorContactElements.Add(TaskGroup.Ships[0].Id, NSE); + } + else if (TaskGroup.BestThermal != null && _SensorContactElements.ContainsKey(TaskGroup.BestThermal.pSensorDef.Id) == false) + { + PassiveSensorDefTN pSensorDef = TaskGroup.BestThermal.pSensorDef; + double factor = Constants.Units.KmPerAu / Constants.GameConstants.BasicUnitOfDistance; + double AURadius = (double)pSensorDef.range * ((float)Constants.SensorTN.DefaultPassiveSignature / (float)ParentSceen.ShowPassiveSignatureRange) / factor; + + Vector3 TGPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); + + SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Red, TaskGroup.BestThermal.Name, TaskGroup.BestThermal, TaskGroup.BestThermal.pSensorDef.componentType, ParentSceen); + _SensorContactElements.Add(pSensorDef.Id, NSE); + } } } From f5aee8700b92bb055c0c6e35f17698621b96b59d Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 26 Dec 2015 21:14:32 -0600 Subject: [PATCH 26/40] Additional fixes The shipyard tonnage bug was fixed, I was setting the tonnage to 1000 after checking for yard specific tonnage. woops. Shipyards can be set to No Activity now, this was an oversight with setActivity that it could not. Geosurvey distances were being calculated incorrectly, they are now fixed. The treeview is now properly selectable, key and mouse press events were happening before the selection was being made, switching to afterSelect resolves this. The agricultural and environmental percentages are spurious and will need to be looked at, and any issue from last update that was not resolved here is likely still a problem --- .../Pulsar4X.Lib/Entities/Installation.cs | 4 +- .../Entities/StarSystem/Population.cs | 2 - .../Entities/StarSystem/SystemBody.cs | 4 +- .../Entities/StarSystem/TaskGroup.cs | 9 +- Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 95 +++++++++---------- 5 files changed, 54 insertions(+), 60 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs index 95d8c1fab..edd629915 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs @@ -479,7 +479,6 @@ public ShipyardInformation(Faction CurrentFaction, Constants.ShipyardInfo.SYType BuildingShips = new BindingList(); CurrentActivity = new ShipyardActivity(); - Tonnage = Constants.ShipyardInfo.BaseShipyardTonnage; Slipways = 1; AssignedClass = null; @@ -538,6 +537,9 @@ public void SetShipyardActivity(Faction CurrentFaction, Constants.ShipyardInfo.S switch (NewActivity) { + case Constants.ShipyardInfo.ShipyardActivity.NoActivity: + CurrentActivity = new ShipyardActivity(); + break; case Constants.ShipyardInfo.ShipyardActivity.AddSlipway: decimal TotalSlipwayCost = 0.0m; for (int MineralIterator = 0; MineralIterator < Constants.Minerals.NO_OF_MINERIALS; MineralIterator++) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs index 219e13239..1d5aab2f3 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs @@ -819,7 +819,6 @@ public void AddInstallation(Installation Inst, float increment) Number++; Installations[Index].SYInfo.Add(SYI); - Adjustment = Adjustment - 1.0f; } break; @@ -837,7 +836,6 @@ public void AddInstallation(Installation Inst, float increment) Number++; Installations[Index].SYInfo.Add(SYI); - Adjustment = Adjustment - 1.0f; } break; diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs index bc0196f53..b6fd82c13 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs @@ -438,6 +438,7 @@ public void MassiveMineralGeneration() /// /// So important thing: if mCount keeps getting incremented past -1, this can go into an infinite loop. + /// if (mCount == 0) break; } @@ -538,9 +539,6 @@ public int GetSurveyCost() /// Species of this population. public void AddPopulation(Faction PopFaction, int TimeSlice, Species CurrentSpecies) { - String Entry = String.Format("AddPopulation Run {0} {1}",SupportsPopulations, Populations.Count); - MessageEntry NMG = new MessageEntry(MessageEntry.MessageType.Count, null, null, GameState.Instance.CurrentDate, GameState.Instance.CurrentSecond, Entry); - GameState.Instance.Factions[0].MessageLog.Add(NMG); /// /// Some planet types can't host populations. Gas Giants for example. /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index b2f6affae..b4ab905a5 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -3037,6 +3037,7 @@ public uint PerformOrders(uint TimeSlice) /// int hoursToComplete = (int)Math.Ceiling((float)RemainderGP / CalcGeoSurveyPoints()); TimeSlice = TimeSlice - ((uint)hoursToComplete * Constants.TimeInSeconds.Hour); + _GeoSurveyPoints = BodySurveyCost; } @@ -3230,7 +3231,9 @@ public void ProcessDefaultOrders() { if (CurrentSystem._SurveyResults[TaskGroupFaction]._GeoSurveyInProgress.Contains(SB) == false) { - float distSq = (float)(SB.Position.X * Contact.Position.X) + (float)(SB.Position.Y * Contact.Position.Y); + float dX = (float)Math.Abs(SB.Position.X - Contact.Position.X); + float dY = (float)Math.Abs(SB.Position.Y - Contact.Position.Y); + float distSq = (dX * dX) + (dY * dY); if (distSq < lowestDistance || lowestDistance == -1.0f) { lowestDistance = distSq; @@ -3240,7 +3243,9 @@ public void ProcessDefaultOrders() } else { - float distSq = (float)(SB.Position.X * Contact.Position.X) + (float)(SB.Position.Y * Contact.Position.Y); + float dX = (float)Math.Abs(SB.Position.X - Contact.Position.X); + float dY = (float)Math.Abs(SB.Position.Y - Contact.Position.Y); + float distSq = (dX * dX) + (dY * dY); if (distSq < lowestDistance || lowestDistance == -1.0f) { lowestDistance = distSq; diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index 7e7396bc4..49624d0ba 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -227,8 +227,8 @@ public Economics() /// /// Tree view /// - m_oSummaryPanel.PopulationTreeView.KeyPress += new KeyPressEventHandler(PopulationTreeView_Input); - m_oSummaryPanel.PopulationTreeView.MouseClick += new MouseEventHandler(PopulationTreeView_Input); + m_oSummaryPanel.PopulationTreeView.AfterSelect += new TreeViewEventHandler(PopulationTreeView_Input); + /// /// Time Advancement Buttons: @@ -426,9 +426,10 @@ private void PopulationTreeView_Input(object sender, EventArgs e) CurrentSYInfo = null; } - RefreshPanels(); + RefreshPanels(true); } } + } /// @@ -1445,7 +1446,7 @@ private void StopRefiningButton_Click(object sender, EventArgs e) /// /// Refresh all the various panels that make up this display. /// - private void RefreshPanels() + private void RefreshPanels(bool skipTree=false) { if (m_oCurrnetFaction != null) { @@ -1461,7 +1462,8 @@ private void RefreshPanels() /// /// Build the population lists. /// - BuildTreeView(); + if(skipTree == false) + BuildTreeView(); /// /// Summary Tab: @@ -1666,17 +1668,21 @@ private void BuildTreeView() { StarSystem CurrentSystem = Pop.Planet.Position.System; - if (m_oSummaryPanel.PopulationTreeView.Nodes[0].Nodes.ContainsKey(CurrentSystem.Name) == false) - { - m_oSummaryPanel.PopulationTreeView.Nodes[0].Nodes.Add(CurrentSystem.Name, CurrentSystem.Name); - } - - /// /// What type of colony is this, and should it be placed into the tree view(no if CMC and CMC are hidden) /// String Class = ""; + /// + /// What key will be put into the display tree? + /// + String Entry = ""; + + /// + /// Which node display should be used? + /// + int DisplayIndex = -1; + /// /// Populated colony, can do basically anything /// @@ -1696,14 +1702,10 @@ private void BuildTreeView() Class = String.Format("{0}: {1:n2}m",Class, Pop.CivilianPopulation); - String Entry = String.Format("{0} - {1}{2}", Pop.Name, Pop.Species.Name, Class); + Entry = String.Format("{0} - {1}{2}", Pop.Name, Pop.Species.Name, Class); #warning DisplayIndex here is kludgy, do a find on the appropriate section? if so alter the adds to include a key string in addition to a text string - int DisplayIndex = 0; - int CurrentSystemIndex = m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes.IndexOfKey(CurrentSystem.Name); - m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes[CurrentSystemIndex].Nodes.Add(Entry, Entry); - - TreeViewDictionary.Add(Entry, Pop); + DisplayIndex = 0; } /// /// Automining colony will only mine, but may have CMCs listening posts, terraforming gear and ruins @@ -1713,13 +1715,9 @@ private void BuildTreeView() int mines = (int)Math.Floor(Pop.Installations[(int)Installation.InstallationType.AutomatedMine].Number); Class = String.Format(": {0}x Auto Mines", mines); - String Entry = String.Format("{0} - {1}{2}", Pop.Name, Pop.Species.Name, Class); - - int DisplayIndex = 1; - int CurrentSystemIndex = m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes.IndexOfKey(CurrentSystem.Name); - m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes[CurrentSystemIndex].Nodes.Add(Entry, Entry); + Entry = String.Format("{0} - {1}{2}", Pop.Name, Pop.Species.Name, Class); - TreeViewDictionary.Add(Entry, Pop); + DisplayIndex = 1; } /// /// CMCs. don't print this one if they should be hidden(by user input request). will also have a DSTS(or should I roll that into the CMC?), and may have terraforming and ruins) @@ -1729,13 +1727,9 @@ private void BuildTreeView() int mines = (int)Math.Floor(Pop.Installations[(int)Installation.InstallationType.CivilianMiningComplex].Number); Class = String.Format(": {0}x Civ Mines", mines); - String Entry = String.Format("{0} - {1}{2}", Pop.Name, Pop.Species.Name, Class); + Entry = String.Format("{0} - {1}{2}", Pop.Name, Pop.Species.Name, Class); - int DisplayIndex = 2; - int CurrentSystemIndex = m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes.IndexOfKey(CurrentSystem.Name); - m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes[CurrentSystemIndex].Nodes.Add(Entry, Entry); - - TreeViewDictionary.Add(Entry, Pop); + DisplayIndex = 2; } /// @@ -1746,15 +1740,11 @@ private void BuildTreeView() int DSTS = (int)Math.Floor(Pop.Installations[(int)Installation.InstallationType.DeepSpaceTrackingStation].Number); Class = String.Format(": {0}x DSTS", DSTS); - String Entry = String.Format("{0} - {1}{2}", Pop.Name, Pop.Species.Name, Class); + Entry = String.Format("{0} - {1}{2}", Pop.Name, Pop.Species.Name, Class); - int DisplayIndex = 2; + DisplayIndex = 2; if (m_oSummaryPanel.HideCMCCheckBox.Checked == false) DisplayIndex = 3; - int CurrentSystemIndex = m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes.IndexOfKey(CurrentSystem.Name); - m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes[CurrentSystemIndex].Nodes.Add(Entry, Entry); - - TreeViewDictionary.Add(Entry, Pop); } /// @@ -1764,15 +1754,11 @@ private void BuildTreeView() { Class = String.Format(" Archeological Dig"); - String Entry = String.Format("{0} - {1}{2}", Pop.Name, Pop.Species.Name, Class); + Entry = String.Format("{0} - {1}{2}", Pop.Name, Pop.Species.Name, Class); - int DisplayIndex = 3; + DisplayIndex = 3; if (m_oSummaryPanel.HideCMCCheckBox.Checked == false) DisplayIndex = 4; - int CurrentSystemIndex = m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes.IndexOfKey(CurrentSystem.Name); - m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes[CurrentSystemIndex].Nodes.Add(Entry, Entry); - - TreeViewDictionary.Add(Entry, Pop); } /// /// Orbital Terraforming modules. a planet with ships in orbit that will terraform it. @@ -1781,15 +1767,11 @@ private void BuildTreeView() { Class = String.Format(": {0:n1}x Orbital Terraform", Pop._OrbitalTerraformModules); - String Entry = String.Format("{0} - {1}{2}", Pop.Name, Pop.Species.Name, Class); + Entry = String.Format("{0} - {1}{2}", Pop.Name, Pop.Species.Name, Class); - int DisplayIndex = 4; + DisplayIndex = 4; if (m_oSummaryPanel.HideCMCCheckBox.Checked == false) DisplayIndex = 5; - int CurrentSystemIndex = m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes.IndexOfKey(CurrentSystem.Name); - m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes[CurrentSystemIndex].Nodes.Add(Entry, Entry); - - TreeViewDictionary.Add(Entry, Pop); } else { @@ -1798,16 +1780,25 @@ private void BuildTreeView() /// If none of the above are true, then the colony is simply dropped into the other colonies category. /// - String Entry = String.Format("{0} - {1}", Pop.Name, Pop.Species.Name); + Entry = String.Format("{0} - {1}", Pop.Name, Pop.Species.Name); - int DisplayIndex = 5; + DisplayIndex = 5; if (m_oSummaryPanel.HideCMCCheckBox.Checked == false) DisplayIndex = 6; - int CurrentSystemIndex = m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes.IndexOfKey(CurrentSystem.Name); - m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes[CurrentSystemIndex].Nodes.Add(Entry, Entry); + } - TreeViewDictionary.Add(Entry, Pop); + /// + /// Every displayIndex node needs to have the current system in it added somewhere, so I'll do it here. + /// + if (m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes.ContainsKey(CurrentSystem.Name) == false) + { + m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes.Add(CurrentSystem.Name, CurrentSystem.Name); } + + int CurrentSystemIndex = m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes.IndexOfKey(CurrentSystem.Name); + m_oSummaryPanel.PopulationTreeView.Nodes[DisplayIndex].Nodes[CurrentSystemIndex].Nodes.Add(Entry, Entry); + + TreeViewDictionary.Add(Entry, Pop); } } else From fdee650692695c9e86c47baff22703cf8f6369fa Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 2 Jan 2016 22:04:02 -0600 Subject: [PATCH 27/40] Colony cost display issue resolved I was not properly writing the categories for infrastructure. Also colony cost related displays are now cut off after two decimal places for appearances sake. --- .../Entities/StarSystem/Population.cs | 2 +- Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 25 ++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs index 1d5aab2f3..608b8767d 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs @@ -550,7 +550,7 @@ public Population(SystemBody a_oPlanet, Faction a_oFaction, int CurrentTimeSlice m_aoInstallations[i] = new Installation((Installation.InstallationType)i); } - CivilianPopulation = 0; + CivilianPopulation = 0.0f; PopulationGrowthRate = 0.1f; FuelStockpile = 0; MaintenanceSupplies = 0; diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index 49624d0ba..4900e9416 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -2113,7 +2113,8 @@ public void RefreshSummaryCells() // need planetary hab rating vs species tolerance double ColCost = CurrentPopulation.Species.GetTNHabRating(CurrentPopulation.Planet); - m_oSummaryPanel.SummaryDataGrid.Rows[2].Cells[1].Value = ColCost.ToString(); + String CCCost = String.Format("{0:N2}",ColCost); + m_oSummaryPanel.SummaryDataGrid.Rows[2].Cells[1].Value = CCCost; m_oSummaryPanel.SummaryDataGrid.Rows[3].Cells[1].Value = CurrentPopulation.AdminRating; /// @@ -2134,11 +2135,11 @@ public void RefreshSummaryCells() if (CurrentPopulation.CivilianPopulation != 0.0f) { - Entry = String.Format(" Agriculture and Enviromental ({0:N2}%)", CurrentPopulation.PopulationWorkingInAgriAndEnviro / CurrentPopulation.CivilianPopulation); + Entry = String.Format(" Agriculture and Enviromental ({0:N2}%)", ((CurrentPopulation.PopulationWorkingInAgriAndEnviro / CurrentPopulation.CivilianPopulation) * 100.0f)); m_oSummaryPanel.SummaryDataGrid.Rows[8].Cells[0].Value = Entry; - Entry = String.Format(" Service Industries ({0:N2}%)", CurrentPopulation.PopulationWorkingInServiceIndustries / CurrentPopulation.CivilianPopulation); + Entry = String.Format(" Service Industries ({0:N2}%)", ((CurrentPopulation.PopulationWorkingInServiceIndustries / CurrentPopulation.CivilianPopulation) * 100.0f)); m_oSummaryPanel.SummaryDataGrid.Rows[9].Cells[0].Value = Entry; - Entry = String.Format(" Manufacturing ({0:N2}%)", CurrentPopulation.PopulationWorkingInManufacturing / CurrentPopulation.CivilianPopulation); + Entry = String.Format(" Manufacturing ({0:N2}%)", ((CurrentPopulation.PopulationWorkingInManufacturing / CurrentPopulation.CivilianPopulation) * 100.0f)); m_oSummaryPanel.SummaryDataGrid.Rows[10].Cells[0].Value = Entry; m_oSummaryPanel.SummaryDataGrid.Rows[11].Cells[0].Value = "Annual Growth Rate"; @@ -2153,14 +2154,26 @@ public void RefreshSummaryCells() Adjust1 = 5; } + else + { + Entry = String.Format("0.0%"); + m_oSummaryPanel.SummaryDataGrid.Rows[11].Cells[1].Value = Entry; + } /// /// Infrastructure information. /// - m_oSummaryPanel.SummaryDataGrid.Rows[8 + Adjust1].Cells[1].Value = (ColCost * 200.0).ToString(); + m_oSummaryPanel.SummaryDataGrid.Rows[8 + Adjust1].Cells[0].Value = "Infrastructure Required per Million Population"; + m_oSummaryPanel.SummaryDataGrid.Rows[9 + Adjust1].Cells[0].Value = "Current Infrastructure"; + m_oSummaryPanel.SummaryDataGrid.Rows[10 + Adjust1].Cells[0].Value = "Population supported by Infrastructure"; + Entry = String.Format("{0:N2}", (ColCost * 200.0)); + m_oSummaryPanel.SummaryDataGrid.Rows[8 + Adjust1].Cells[1].Value = Entry; m_oSummaryPanel.SummaryDataGrid.Rows[9 + Adjust1].Cells[1].Value = CurrentPopulation.Installations[(int)Installation.InstallationType.Infrastructure].Number.ToString(); if (ColCost != 0.0f) - m_oSummaryPanel.SummaryDataGrid.Rows[10 + Adjust1].Cells[1].Value = (CurrentPopulation.Installations[(int)Installation.InstallationType.Infrastructure].Number / (ColCost * 200.0)).ToString(); + { + Entry = String.Format("{0:N2}", (CurrentPopulation.Installations[(int)Installation.InstallationType.Infrastructure].Number / (Math.Round(ColCost) * 200.0))); + m_oSummaryPanel.SummaryDataGrid.Rows[10 + Adjust1].Cells[1].Value = Entry; + } else m_oSummaryPanel.SummaryDataGrid.Rows[10 + Adjust1].Cells[1].Value = "No Maximum"; From 5a380b6dbb1d623277ff5e54cdc1d7e4c3114ec8 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Fri, 8 Jan 2016 23:01:49 -0600 Subject: [PATCH 28/40] Fixed a shipyard display bug, and did pop work switching to a new planet with no shipyards will now properly clear the shipyard grid, and functions for population maximums and required infrastructure have been moved to the population class. hopefully that should keep everything straight on infrastructure requirements. I am not sure if those are implemented yet however. --- .../Entities/StarSystem/Population.cs | 26 ++++++++++++++++++ .../Entities/StarSystem/StarSystem.cs | 4 --- .../Handlers/Eco_ShipyardTabHandler.cs | 11 ++++++++ Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 27 +++++++++++++------ 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs index 608b8767d..9a1f6a83b 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs @@ -980,6 +980,31 @@ public float LoadMissileToStockpile(OrdnanceDefTN Missile, float inc) } } + /// + /// How much infrastructure does this species require for every million inhabitants on this world? + /// + /// + public float GetInfrastructureRequirement() + { + return (float)Math.Round(Species.GetTNHabRating(Planet) * 100.0f); + } + + /// + /// If infrastructure is required for habitation, calculated the required value here. + /// + /// a positive number or zero if infrastructure is present, or -1.0f if no maximum, and -2.0f if the planet is not habitable. + public float GetPopulationMaximum() + { + if (Species.GetTNHabRating(Planet) > 0.0f) + { + return (Installations[(int)Installation.InstallationType.Infrastructure].Number / GetInfrastructureRequirement()); + } + else if (Species.GetTNHabRating(Planet) == -1.0f) + return -2.0f; + else + return -1.0f; + } + #region Sensor Characteristcs /// /// Calculate the thermal signature of this colony @@ -1475,5 +1500,6 @@ public bool OnDamaged(DamageTypeTN TypeOfDamage, ushort Value, ShipTN FiringShip return false; } #endregion + } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs index bfb7800a2..413e4373e 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/StarSystem.cs @@ -423,10 +423,6 @@ public int GetSurveyPointArea(double X, double Y) } } - String Entry = String.Format("GetSurveyPointArea({0},{1}):{2},{3},{4},{5}", X,Y,distanceFromPrimary,Angle,(SurveyIndex+1),RingValue); - MessageEntry NME = new MessageEntry(MessageEntry.MessageType.Error, null, null, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); - GameState.Instance.Factions[0].MessageLog.Add(NME); - return (SurveyIndex+1); } } diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Eco_ShipyardTabHandler.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Eco_ShipyardTabHandler.cs index f31843440..75b44baed 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Eco_ShipyardTabHandler.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Eco_ShipyardTabHandler.cs @@ -156,6 +156,17 @@ public static void RefreshShipyardTab(Panels.Eco_Summary m_oSummaryPanel, Factio RefreshShipyardTasksTab(m_oSummaryPanel, CurrentFaction, CurrentPopulation); } + else if (SYInfo == null) + { + m_oSummaryPanel.ShipyardDataGrid.ClearSelection(); + /// + /// Do not display any rows at all as there is no shipyard for this world. + /// + for (int rowIterator = 0; rowIterator < m_oSummaryPanel.ShipyardDataGrid.Rows.Count; rowIterator++) + { + m_oSummaryPanel.ShipyardDataGrid.Rows[rowIterator].Visible = false; + } + } } /// diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index 4900e9416..9352d5e85 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -1495,6 +1495,7 @@ private void RefreshPanels(bool skipTree=false) m_oSummaryPanel.SYShipNameTextBox.Clear(); + /// /// So. I want the eco_SY tab handler to be able to populate these lists as needed. /// So. they have to be refs. @@ -2165,15 +2166,20 @@ public void RefreshSummaryCells() m_oSummaryPanel.SummaryDataGrid.Rows[8 + Adjust1].Cells[0].Value = "Infrastructure Required per Million Population"; m_oSummaryPanel.SummaryDataGrid.Rows[9 + Adjust1].Cells[0].Value = "Current Infrastructure"; m_oSummaryPanel.SummaryDataGrid.Rows[10 + Adjust1].Cells[0].Value = "Population supported by Infrastructure"; - Entry = String.Format("{0:N2}", (ColCost * 200.0)); + Entry = String.Format("{0:N2}", CurrentPopulation.GetInfrastructureRequirement()); m_oSummaryPanel.SummaryDataGrid.Rows[8 + Adjust1].Cells[1].Value = Entry; m_oSummaryPanel.SummaryDataGrid.Rows[9 + Adjust1].Cells[1].Value = CurrentPopulation.Installations[(int)Installation.InstallationType.Infrastructure].Number.ToString(); - if (ColCost != 0.0f) + if (ColCost > 0.0f) { - Entry = String.Format("{0:N2}", (CurrentPopulation.Installations[(int)Installation.InstallationType.Infrastructure].Number / (Math.Round(ColCost) * 200.0))); + Entry = String.Format("{0:N2}", (CurrentPopulation.GetPopulationMaximum())); m_oSummaryPanel.SummaryDataGrid.Rows[10 + Adjust1].Cells[1].Value = Entry; } + else if (ColCost == -1.0f) + { +#warning Underground infrastructure should be handled here if implemented. + m_oSummaryPanel.SummaryDataGrid.Rows[10 + Adjust1].Cells[1].Value = "Not Habitable"; + } else m_oSummaryPanel.SummaryDataGrid.Rows[10 + Adjust1].Cells[1].Value = "No Maximum"; @@ -4373,11 +4379,16 @@ private void RefreshMiningTab() /// /// 4 is YTD. reserves / mining /// - int YTD = (int)(Math.Floor(m_oCurrnetPopulation.Planet.MinerialReserves[mineralIterator]) / (Math.Floor(m_oCurrnetPopulation.CalcTotalMining() * m_oCurrnetPopulation.Planet.MinerialAccessibility[mineralIterator]))); - if (YTD > YearsToDepletion) - YearsToDepletion = YTD; - if (YTD != 0) - m_oSummaryPanel.MiningDataGrid.Rows[mineralIterator].Cells[4].Value = String.Format("{0}", YTD); + if (m_oCurrnetPopulation.CalcTotalMining() != 0.0f) + { + int YTD = (int)(Math.Floor(m_oCurrnetPopulation.Planet.MinerialReserves[mineralIterator]) / (Math.Floor(m_oCurrnetPopulation.CalcTotalMining() * m_oCurrnetPopulation.Planet.MinerialAccessibility[mineralIterator]))); + if (YTD > YearsToDepletion) + YearsToDepletion = YTD; + if (YTD != 0) + m_oSummaryPanel.MiningDataGrid.Rows[mineralIterator].Cells[4].Value = String.Format("{0}", YTD); + else + m_oSummaryPanel.MiningDataGrid.Rows[mineralIterator].Cells[4].Value = "-"; + } else m_oSummaryPanel.MiningDataGrid.Rows[mineralIterator].Cells[4].Value = "-"; From 1dc82603686d4f7b52aa1187d6e9b6f13b6ea950 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 17 Jan 2016 01:43:21 -0600 Subject: [PATCH 29/40] Fix for temperature, and more data for Sol Atmosphereless body temperatures were being converted to kelvin, and then not being converted back to celsius, this has been fixed. The data for planetary gravity, albedo, and base temperature has been filled in for the solar system, giving plausible data there. lastly uninhabitable bodies are marked as not habitable rather than -1.0 colony cost on the economics page. The solar system should be ready to go now. --- .../Entities/StarSystem/Atmosphere.cs | 1 + Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs | 28 +++++++++++++++++++ Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 17 ++++++++--- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Atmosphere.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Atmosphere.cs index 5f8a1a9be..b52fdd3f7 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Atmosphere.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Atmosphere.cs @@ -210,6 +210,7 @@ public void UpdateState() Pressure = 0; SurfaceTemperature = Temperature.ToKelvin(ParentBody.BaseTemperature); SurfaceTemperature = SurfaceTemperature * (float)Math.Pow(1 - Albedo, 0.25); // We need to raise albedo to the power of 1/4 + SurfaceTemperature = Temperature.ToCelsius(SurfaceTemperature); _atmosphereDescriptionInATM = "None"; _atmosphereDescriptionInPercent = "None"; } diff --git a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs index a3a059b51..b3334d533 100644 --- a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs +++ b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs @@ -210,6 +210,9 @@ public static StarSystem CreateSol() Mercury.Position.System = Sol; Mercury.Position.X = x; Mercury.Position.Y = y; + Mercury.Atmosphere.Albedo = 0.068f; //bond and not geometric albedo. + Mercury.BaseTemperature = (float)CalculateBaseTemperatureOfBody(Sun, Mercury.Orbit.SemiMajorAxis); + Mercury.Atmosphere.UpdateState(); Sun.Planets.Add(Mercury); SystemBody Venus = new SystemBody(Sun, SystemBody.PlanetType.Terrestrial); @@ -220,6 +223,8 @@ public static StarSystem CreateSol() Venus.SurfaceGravity = 8.918f; //from aurora, not necessarily accurate. AddGasToAtmoSafely(Venus.Atmosphere, AtmosphericGas.AtmosphericGases.SelectAt(6), 50.0f); //N, value is from aurora AddGasToAtmoSafely(Venus.Atmosphere, AtmosphericGas.AtmosphericGases.SelectAt(12), 50.0f); //CO2, value is from aurora + Venus.Atmosphere.Albedo = 0.090f; //bond and not geometric albedo. + Venus.BaseTemperature = (float)CalculateBaseTemperatureOfBody(Sun, Venus.Orbit.SemiMajorAxis); Venus.Atmosphere.UpdateState(); Venus.Position.System = Sol; Venus.Position.X = x; @@ -255,6 +260,9 @@ public static StarSystem CreateSol() Moon.Position.System = Sol; Moon.Position.X = Earth.Position.X + x; Moon.Position.Y = Earth.Position.Y + y; + Moon.Atmosphere.Albedo = 0.136f; //not sure if bond or geo. + Moon.BaseTemperature = Temperature.ToCelsius(279.3f); + Moon.Atmosphere.UpdateState(); Earth.Moons.Add(Moon); SystemBody Mars = new SystemBody(Sun, SystemBody.PlanetType.Terrestrial); @@ -286,6 +294,10 @@ public static StarSystem CreateSol() Jupiter.Position.System = Sol; Jupiter.Position.X = x; Jupiter.Position.Y = y; + Jupiter.SurfaceGravity = 24.79f; + Jupiter.Atmosphere.Albedo = 0.343f; + Jupiter.BaseTemperature = (float)CalculateBaseTemperatureOfBody(Sun, Jupiter.Orbit.SemiMajorAxis); + Jupiter.Atmosphere.UpdateState(); Sun.Planets.Add(Jupiter); SystemBody Saturn = new SystemBody(Sun, SystemBody.PlanetType.GasGiant); @@ -296,6 +308,10 @@ public static StarSystem CreateSol() Saturn.Position.System = Sol; Saturn.Position.X = x; Saturn.Position.Y = y; + Saturn.SurfaceGravity = 10.44f; + Saturn.Atmosphere.Albedo = 0.342f; + Saturn.BaseTemperature = (float)CalculateBaseTemperatureOfBody(Sun, Saturn.Orbit.SemiMajorAxis); + Saturn.Atmosphere.UpdateState(); Sun.Planets.Add(Saturn); SystemBody Uranus = new SystemBody(Sun, SystemBody.PlanetType.IceGiant); @@ -306,6 +322,10 @@ public static StarSystem CreateSol() Uranus.Position.System = Sol; Uranus.Position.X = x; Uranus.Position.Y = y; + Uranus.SurfaceGravity = 8.69f; + Uranus.Atmosphere.Albedo = 0.300f; + Uranus.BaseTemperature = (float)CalculateBaseTemperatureOfBody(Sun, Uranus.Orbit.SemiMajorAxis); + Uranus.Atmosphere.UpdateState(); Sun.Planets.Add(Uranus); SystemBody Neptune = new SystemBody(Sun, SystemBody.PlanetType.IceGiant); @@ -316,6 +336,10 @@ public static StarSystem CreateSol() Neptune.Position.System = Sol; Neptune.Position.X = x; Neptune.Position.Y = y; + Neptune.SurfaceGravity = 11.15f; + Neptune.Atmosphere.Albedo = 0.290f; + Neptune.BaseTemperature = (float)CalculateBaseTemperatureOfBody(Sun, Neptune.Orbit.SemiMajorAxis); + Neptune.Atmosphere.UpdateState(); Sun.Planets.Add(Neptune); SystemBody Pluto = new SystemBody(Sun, SystemBody.PlanetType.DwarfPlanet); @@ -326,6 +350,10 @@ public static StarSystem CreateSol() Pluto.Position.System = Sol; Pluto.Position.X = x; Pluto.Position.Y = y; + Pluto.SurfaceGravity = 0.658f; + Pluto.Atmosphere.Albedo = 0.069f; + Pluto.BaseTemperature = (float)CalculateBaseTemperatureOfBody(Sun, Pluto.Orbit.SemiMajorAxis); + Pluto.Atmosphere.UpdateState(); Sun.Planets.Add(Pluto); GenerateJumpPoints(Sol); diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index 9352d5e85..ea9a3f7c0 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -2114,7 +2114,9 @@ public void RefreshSummaryCells() // need planetary hab rating vs species tolerance double ColCost = CurrentPopulation.Species.GetTNHabRating(CurrentPopulation.Planet); - String CCCost = String.Format("{0:N2}",ColCost); + String CCCost = "Not Habitable"; + if(ColCost != -1.0) + CCCost = String.Format("{0:N2}",ColCost); m_oSummaryPanel.SummaryDataGrid.Rows[2].Cells[1].Value = CCCost; m_oSummaryPanel.SummaryDataGrid.Rows[3].Cells[1].Value = CurrentPopulation.AdminRating; @@ -2166,8 +2168,15 @@ public void RefreshSummaryCells() m_oSummaryPanel.SummaryDataGrid.Rows[8 + Adjust1].Cells[0].Value = "Infrastructure Required per Million Population"; m_oSummaryPanel.SummaryDataGrid.Rows[9 + Adjust1].Cells[0].Value = "Current Infrastructure"; m_oSummaryPanel.SummaryDataGrid.Rows[10 + Adjust1].Cells[0].Value = "Population supported by Infrastructure"; - Entry = String.Format("{0:N2}", CurrentPopulation.GetInfrastructureRequirement()); - m_oSummaryPanel.SummaryDataGrid.Rows[8 + Adjust1].Cells[1].Value = Entry; + if (ColCost != -1.0) + { + Entry = String.Format("{0:N2}", CurrentPopulation.GetInfrastructureRequirement()); + m_oSummaryPanel.SummaryDataGrid.Rows[8 + Adjust1].Cells[1].Value = Entry; + } + else + { + m_oSummaryPanel.SummaryDataGrid.Rows[8 + Adjust1].Cells[1].Value = "Underground Infra not implemented"; + } m_oSummaryPanel.SummaryDataGrid.Rows[9 + Adjust1].Cells[1].Value = CurrentPopulation.Installations[(int)Installation.InstallationType.Infrastructure].Number.ToString(); if (ColCost > 0.0f) @@ -2177,7 +2186,7 @@ public void RefreshSummaryCells() } else if (ColCost == -1.0f) { -#warning Underground infrastructure should be handled here if implemented. +#warning Underground infrastructure should be handled here if implemented. as well as further up. m_oSummaryPanel.SummaryDataGrid.Rows[10 + Adjust1].Cells[1].Value = "Not Habitable"; } else From e1c402106ffe6510bf4b0602b14e353c4e8b4895 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 23 Jan 2016 11:17:59 -0600 Subject: [PATCH 30/40] Several more bugfixes duplicate populations were showing up in various places, that has been fixed(this caused issues with the tree view having multiples of the same item added to dictionaries). Gravitational Survey Sensors are now military components, before all survey sensors were civilian. The cost listbox for the currently selected item to build on the economics page is now being refreshed on a softRefresh(time advancement, which does not need a full refresh of the entire page). Designs don't seem to be locking immediately, I'm not sure how to resolve this, it isn't immediately important however. Shipyard eligible classes require all such designs to be locked in order to function. The CI rounding bug is still present, and as with the above, I'm not quite sure what to do about it. --- .../Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs | 8 +++++++- Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs | 6 ++++++ Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs | 8 +++++--- Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 1 + Pulsar4X/Pulsar4X.UI/Program.cs | 4 ++-- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs index b1238a32f..d347d4031 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Components/SurveySensorTN.cs @@ -67,7 +67,13 @@ public SurveySensorDefTN(String Title, SurveySensorType sType, float sStrength) isSalvaged = false; isObsolete = false; - isMilitary = false; + + if (SensorType == SurveySensorType.Geological) + isMilitary = false; + else if(SensorType == SurveySensorType.Gravitational) + isMilitary = true; + + isDivisible = false; isElectronic = false; } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs index 9a1f6a83b..abf2185ec 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs @@ -577,7 +577,13 @@ public Population(SystemBody a_oPlanet, Faction a_oFaction, int CurrentTimeSlice SSEntity = StarSystemEntityType.Population; + /// + /// Not particularly happy with adding these right here, any events will run off and process in the middle of population creation. In particular, SSEntity must be defined before doing this for + /// the display. + /// Planet.Populations.Add(this); // add us to the list of pops on the planet! + a_oFaction.Populations.Add(this); + Planet.Position.System.Populations.Add(this); Contact = new SystemContact(Faction, this); Contact.Position.System = Planet.Position.System; diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs index b6fd82c13..5ef598c67 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/SystemBody.cs @@ -555,11 +555,13 @@ public void AddPopulation(Faction PopFaction, int TimeSlice, Species CurrentSpec } /// - /// Assuming that we got this far, add the population. + /// Assuming that we got this far, add the population. The constructor will add the population to the planet's population list and the faction population list, but this function + /// should prevent duplicate populations from being made if it is always called. /// Population NewPopulation = new Population(this, PopFaction, TimeSlice, Name, CurrentSpecies); - Populations.Add(NewPopulation); - PopFaction.Populations.Add(NewPopulation); + + //Populations.Add(NewPopulation); + //PopFaction.Populations.Add(NewPopulation); } } diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index ea9a3f7c0..01b512a48 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -1560,6 +1560,7 @@ private void SoftRefresh() BuildConstructionLabel(); BuildRefiningLabel(); UpdateBuildTexts(); + BuildCostListBox(); /// /// Mining Tab: diff --git a/Pulsar4X/Pulsar4X.UI/Program.cs b/Pulsar4X/Pulsar4X.UI/Program.cs index af39d2c18..bb471062c 100644 --- a/Pulsar4X/Pulsar4X.UI/Program.cs +++ b/Pulsar4X/Pulsar4X.UI/Program.cs @@ -49,7 +49,7 @@ static void Main() /// /// This following section should probably be moved to the Faction constructor at some point. /// - oNewFaction.Populations.Add(new Entities.Population(sol.Stars.FirstOrDefault().Planets[2], oNewFaction, 0)); //.FirstOrDefault() for planets. + new Entities.Population(sol.Stars.FirstOrDefault().Planets[2], oNewFaction, 0); //.FirstOrDefault() for planets. constructor now adds population to planet and faction listing. oNewFaction.Populations[0].Planet.HomeworldMineralGeneration(); oNewFaction.Populations[0].ConventionalStart(); oNewFaction.KnownSystems.Add(sol); @@ -71,7 +71,7 @@ static void Main() Entities.Faction oNewFaction2 = new Entities.Faction(1); oNewFaction2.Name = "Terran Federation"; - oNewFaction2.Populations.Add(new Entities.Population(sol.Stars.FirstOrDefault().Planets[2], oNewFaction2, 0)); //.FirstOrDefault() + new Entities.Population(sol.Stars.FirstOrDefault().Planets[2], oNewFaction2, 0); //.FirstOrDefault() oNewFaction2.Populations[0].Planet.HomeworldMineralGeneration(); oNewFaction2.Populations[0].ConventionalStart(); oNewFaction2.KnownSystems.Add(sol); From fd23af1c56ae1b4e417d345b68be1a5bd3161379 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 30 Jan 2016 20:24:47 -0600 Subject: [PATCH 31/40] Construction bugfixes the conventional industry rounding issue has been resolved, and hopefully any mine or component rounding issues were preemptively fixed. Date of completion for construction projects is fixed, I was just doing that calculation wrong, and producing spurious time values in the process. Fuel refineries were incorrectly labeled as ordnance factories, and build percentages weren't being capped, those are correctly being done now. Lastly the UI label for which project the player has chosen is now displaying the name of the industrial project in the groupbox. --- .../Entities/ConstructionCycle.cs | 35 ++++----- .../Entities/StarSystem/Population.cs | 77 ++++++++++++++++--- Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 21 ++++- .../Panels/Eco_Summary.Designer.cs | 5 ++ 4 files changed, 104 insertions(+), 34 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs b/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs index 9563619bd..dea36ca14 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs @@ -83,7 +83,9 @@ public static void ConstructionFactoryBuild(Faction CurrentFaction, Population C /// float BPRequirement = (float)Math.Floor(CurrentConstruction.numToBuild) * (float)CurrentConstruction.costPerItem; float DaysInYear = (float)Constants.TimeInSeconds.RealYear / (float)Constants.TimeInSeconds.Day; - float YearsOfProduction = (BPRequirement / CurrentConstruction.buildCapacity); + + float YearlyDevotedIndustry = (CurrentConstruction.buildCapacity / 100.0f) * CurrentPopulation.CalcTotalIndustry(); + float YearsOfProduction = (BPRequirement / YearlyDevotedIndustry); if (CurrentConstruction.buildCapacity != 0.0f && YearsOfProduction < Constants.Colony.TimerYearMax) { @@ -108,6 +110,11 @@ public static void ConstructionFactoryBuild(Faction CurrentFaction, Population C float DevotedIndustry = (CurrentConstruction.buildCapacity / 100.0f) * CurrentIndustry; float Completion = DevotedIndustry / (float)CurrentConstruction.costPerItem; + if ((CurrentConstruction.numToBuild - Completion) < 0.0f) + { + Completion = CurrentConstruction.numToBuild; + } + bool CIRequired = false; bool MineRequired = false; bool CanBuild = false; @@ -205,18 +212,9 @@ public static void ConstructionFactoryBuild(Faction CurrentFaction, Population C CurrentPopulation.HandleBuildItemCost(CurrentConstruction.costPerItem, CurrentConstruction.installationBuild.MinerialsCost, Completion, CIRequired, MineRequired); else if (CIRequired == false && MineRequired == true) CurrentPopulation.HandleBuildItemCost(CurrentConstruction.costPerItem, CurrentConstruction.installationBuild.MinerialsCost, Completion, CIRequired, MineRequired); - CurrentPopulation.AddInstallation(CurrentConstruction.installationBuild, Completion); + CurrentPopulation.AddInstallation(CurrentConstruction.installationBuild, Completion,CurrentConstruction.numToBuild); break; case ConstructionBuildQueueItem.CBType.ShipComponent: - - /// - /// Component issues seem more blatant than construction issues. - /// - if (CurrentConstruction.numToBuild < 0.0f) - { - Completion = Completion + CurrentConstruction.numToBuild; - } - CurrentPopulation.HandleBuildItemCost(CurrentConstruction.costPerItem, CurrentConstruction.componentBuild.minerialsCost, Completion); CurrentPopulation.AddComponentsToStockpile(CurrentConstruction.componentBuild, Completion); break; @@ -229,17 +227,8 @@ public static void ConstructionFactoryBuild(Faction CurrentFaction, Population C case ConstructionBuildQueueItem.CBType.PDCRefit: break; case ConstructionBuildQueueItem.CBType.MaintenanceSupplies: - - /// - /// Component issues seem more blatant than construction issues. - /// - if (CurrentConstruction.numToBuild < 0.0f) - { - Completion = Completion + CurrentConstruction.numToBuild; - } - CurrentPopulation.HandleBuildItemCost(CurrentConstruction.costPerItem, Constants.Colony.MaintenanceMineralCost, Completion); - CurrentPopulation.AddMSP(Completion); + CurrentPopulation.AddMSP(Completion,CurrentConstruction.numToBuild); break; } @@ -293,7 +282,9 @@ public static void OrdnanceFactoryBuild(Faction CurrentFaction, Population Curre /// float BPRequirement = (float)Math.Floor(CurrentConstruction.numToBuild) * (float)CurrentConstruction.costPerItem; float DaysInYear = (float)Constants.TimeInSeconds.RealYear / (float)Constants.TimeInSeconds.Day; - float YearsOfProduction = (BPRequirement / CurrentConstruction.buildCapacity); + + float YearlyDevotedIndustry = (CurrentConstruction.buildCapacity / 100.0f) * CurrentPopulation.CalcTotalIndustry(); + float YearsOfProduction = (BPRequirement / YearlyDevotedIndustry); if (CurrentConstruction.buildCapacity != 0.0f && YearsOfProduction < Constants.Colony.TimerYearMax) { diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs index abf2185ec..2706966bc 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs @@ -81,7 +81,7 @@ public bool inProduction /// Number to build /// Percent of industry to devote to production. /// Is this item paused? - public void UpdateBuildQueueInfo(float BuildNum, float BuildPercent, bool Production, decimal Cost) + public void UpdateBuildQueueInfo(float BuildNum, float BuildPercent, bool Production, decimal Cost, float TotalIndustry) { m_NumToBuild = BuildNum; m_BuildCapcity = BuildPercent; @@ -89,7 +89,11 @@ public void UpdateBuildQueueInfo(float BuildNum, float BuildPercent, bool Produc float BPRequirement = (float)Math.Floor(m_NumToBuild) * (float)Cost; float DaysInYear = (float)Constants.TimeInSeconds.RealYear / (float)Constants.TimeInSeconds.Day; - float YearsOfProduction = (BPRequirement / m_BuildCapcity); + + + float YearlyDevotedIndustry = (m_BuildCapcity / 100.0f) * TotalIndustry; + float YearsOfProduction = (BPRequirement / YearlyDevotedIndustry); + int TimeToBuild = (int)Math.Floor(YearsOfProduction * DaysInYear); /// @@ -764,7 +768,8 @@ public int CalculateLoadTime(int TaskGroupTime) /// /// Component to be added. This is the class all components inherit from, not any particular type of component. /// Number to add to the stockpile. - public void AddComponentsToStockpile(ComponentDefTN ComponentDef, float increment) + /// Total production run(if applicable) + public void AddComponentsToStockpile(ComponentDefTN ComponentDef, float increment, float numToBuild = -10.0f) { if (ComponentStockpileLookup.ContainsKey(ComponentDef.Id) == true) { @@ -776,6 +781,17 @@ public void AddComponentsToStockpile(ComponentDefTN ComponentDef, float incremen ComponentStockpileCount.Add(increment); ComponentStockpileLookup.Add(ComponentDef.Id, ComponentStockpile.IndexOf(ComponentDef)); } + + if (numToBuild != -10.0f && numToBuild <= 0.0f) + { + /// + /// round the installation number if this is the last build, and we are within a thousandth of a point of another component. + /// + if (Math.Ceiling(ComponentStockpileCount[ComponentStockpileLookup[ComponentDef.Id]]) - ComponentStockpileCount[ComponentStockpileLookup[ComponentDef.Id]] < 0.001f) + { + ComponentStockpileCount[ComponentStockpileLookup[ComponentDef.Id]] = (float)Math.Ceiling(ComponentStockpileCount[ComponentStockpileLookup[ComponentDef.Id]]); + } + } } /// @@ -783,7 +799,8 @@ public void AddComponentsToStockpile(ComponentDefTN ComponentDef, float incremen /// /// Installation to be built /// Amount of said installation to be built - public void AddInstallation(Installation Inst, float increment) + /// Total production order from the player, used to check for rounding issues. + public void AddInstallation(Installation Inst, float increment, float numToBuild) { int Index = (int)Inst.Type; switch (Inst.Type) @@ -853,6 +870,17 @@ public void AddInstallation(Installation Inst, float increment) break; } Installations[Index].Number = Installations[Index].Number + increment; + + if (numToBuild <= 0.0f) + { + /// + /// round the installation number if this is the last build, and we are within a thousandth of a point of another installation. + /// + if (Math.Ceiling(Installations[Index].Number) - Installations[Index].Number < 0.001f) + { + Installations[Index].Number = (float)Math.Ceiling(Installations[Index].Number); + } + } } /// @@ -897,9 +925,21 @@ public void UnloadInstallation(Installation.InstallationType iType, int massToUn /// Constructs maintenance supply parts at this population. /// /// number to build. - public void AddMSP(float increment) + /// Number of total MSP the player ordered, used to check for rounding issues when completing a production run. + public void AddMSP(float increment,float numToBuild) { MaintenanceSupplies = MaintenanceSupplies + increment; + + if (numToBuild <= 0.0f) + { + /// + /// round the installation number if this is the last build, and we are within a thousandth of a point of another installation. + /// + if (Math.Ceiling(MaintenanceSupplies) - MaintenanceSupplies < 0.001f) + { + MaintenanceSupplies = (float)Math.Ceiling(MaintenanceSupplies); + } + } } /// @@ -1099,7 +1139,7 @@ public int CalcEMSignature() public void BuildQueueAddInstallation(Installation Install, float BuildAmt, float RequestedBuildPercentage) { ConstructionBuildQueueItem NewCBQItem = new ConstructionBuildQueueItem(Install); - NewCBQItem.UpdateBuildQueueInfo(BuildAmt, RequestedBuildPercentage, true,Install.Cost); + NewCBQItem.UpdateBuildQueueInfo(BuildAmt, RequestedBuildPercentage, true,Install.Cost,CalcTotalIndustry()); ConstructionBuildQueue.Add(NewCBQItem); } @@ -1113,7 +1153,7 @@ public void BuildQueueAddInstallation(Installation Install, float BuildAmt, floa public void BuildQueueAddComponent(ComponentDefTN ComponentDef, float BuildAmt, float RequestedBuildPercentage) { ConstructionBuildQueueItem NewCBQItem = new ConstructionBuildQueueItem(ComponentDef); - NewCBQItem.UpdateBuildQueueInfo(BuildAmt, RequestedBuildPercentage, true,ComponentDef.cost); + NewCBQItem.UpdateBuildQueueInfo(BuildAmt, RequestedBuildPercentage, true,ComponentDef.cost,CalcTotalIndustry()); ConstructionBuildQueue.Add(NewCBQItem); } @@ -1126,7 +1166,7 @@ public void BuildQueueAddComponent(ComponentDefTN ComponentDef, float BuildAmt, public void BuildQueueAddMSP(float BuildAmt, float RequestedBuildPercentage) { ConstructionBuildQueueItem NewCBQItem = new ConstructionBuildQueueItem(); - NewCBQItem.UpdateBuildQueueInfo(BuildAmt, RequestedBuildPercentage, true, Constants.Colony.MaintenanceSupplyCost); + NewCBQItem.UpdateBuildQueueInfo(BuildAmt, RequestedBuildPercentage, true, Constants.Colony.MaintenanceSupplyCost,CalcTotalIndustry()); ConstructionBuildQueue.Add(NewCBQItem); } @@ -1140,7 +1180,7 @@ public void BuildQueueAddMSP(float BuildAmt, float RequestedBuildPercentage) public void BuildQueueAddMissile(OrdnanceDefTN MissileDef, float BuildAmt, float RequestedBuildPercentage) { MissileBuildQueueItem NewMBQItem = new MissileBuildQueueItem(MissileDef); - NewMBQItem.UpdateBuildQueueInfo(BuildAmt, RequestedBuildPercentage, true, MissileDef.cost); + NewMBQItem.UpdateBuildQueueInfo(BuildAmt, RequestedBuildPercentage, true, MissileDef.cost,CalcTotalOrdnanceIndustry()); MissileBuildQueue.Add(NewMBQItem); } @@ -1258,7 +1298,10 @@ public float CalcPopulationGrowth() public bool CIRequirement(float CIReq) { bool ret = false; - if (Installations[(int)Installation.InstallationType.ConventionalIndustry].Number >= CIReq) + /// + /// Occasionally rounding will steal the last CI, so this is an attempt to fix that by adding 0.005f to this calculation. + /// + if ((Installations[(int)Installation.InstallationType.ConventionalIndustry].Number + 0.005f) >= CIReq) { ret = true; } @@ -1273,7 +1316,7 @@ public bool CIRequirement(float CIReq) public bool MineRequirement(float MineReq) { bool ret = false; - if (Installations[(int)Installation.InstallationType.Mine].Number >= MineReq) + if (Installations[(int)Installation.InstallationType.Mine].Number + 0.005f >= MineReq) { ret = true; } @@ -1339,6 +1382,12 @@ public void HandleBuildItemCost(decimal ItemCost, decimal[] MineralCost, float C if (CIConvReq == true) { Installations[(int)Installation.InstallationType.ConventionalIndustry].Number = Installations[(int)Installation.InstallationType.ConventionalIndustry].Number - Completion; + + /// + /// Account for the 0.005 fudge factor introduced above. + /// + if (Installations[(int)Installation.InstallationType.ConventionalIndustry].Number < 0.0f) + Installations[(int)Installation.InstallationType.ConventionalIndustry].Number = 0.0f; } /// @@ -1347,6 +1396,12 @@ public void HandleBuildItemCost(decimal ItemCost, decimal[] MineralCost, float C if (MineConvReq == true) { Installations[(int)Installation.InstallationType.Mine].Number = Installations[(int)Installation.InstallationType.Mine].Number - Completion; + + /// + /// Account for the 0.005 fudge factor introduced above. + /// + if (Installations[(int)Installation.InstallationType.Mine].Number < 0.0f) + Installations[(int)Installation.InstallationType.Mine].Number = 0.0f; } } diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index 01b512a48..42b2fc140 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -1235,6 +1235,13 @@ private void StockpileButton_Click(object sender, EventArgs e) /// private void BuildDataGrid_SelectionChanged(object sender, EventArgs e) { + if (m_oSummaryPanel.BuildDataGrid.CurrentCell != null) + { + if (m_oSummaryPanel.BuildDataGrid.CurrentCell.RowIndex != -1) + { + m_oSummaryPanel.IndustrialProjectGroupBox.Text = String.Format("Create Industrial Project For {0}", m_oSummaryPanel.BuildDataGrid.CurrentCell.Value.ToString()); + } + } BuildCostListBox(); } @@ -1265,6 +1272,12 @@ private void CreateBuildProjButton_Click(object sender, EventArgs e) bool r1 = float.TryParse(m_oSummaryPanel.ItemNumberTextBox.Text, out NumToBuild); bool r2 = float.TryParse(m_oSummaryPanel.ItemPercentTextBox.Text, out PercentCapacity); + if (PercentCapacity < 0.0f) + PercentCapacity = 0.0f; + + if (PercentCapacity > 100.0f) + PercentCapacity = 100.0f; + if (m_oSummaryPanel.BuildDataGrid.CurrentCell.RowIndex != -1 && r1 == true && r2 == true) { List GID = BuildLocationDisplayDict.Keys.ToList(); @@ -1318,6 +1331,12 @@ private void ModifyBuildProjButton_Click(object sender, EventArgs e) bool r1 = float.TryParse(m_oSummaryPanel.ItemNumberTextBox.Text, out NumToBuild); bool r2 = float.TryParse(m_oSummaryPanel.ItemPercentTextBox.Text, out PercentCapacity); + if (PercentCapacity < 0.0f) + PercentCapacity = 0.0f; + + if (PercentCapacity > 100.0f) + PercentCapacity = 100.0f; + int index = m_oSummaryPanel.ConstructionDataGrid.CurrentCell.RowIndex; if (index > 0 && index <= CurrentPopulation.ConstructionBuildQueue.Count) // 1 to Count is CBQ Item { @@ -2494,7 +2513,7 @@ public void RefreshSummaryCells() Entry = String.Format("{0:N2}m", workers); m_oSummaryPanel.SummaryDataGrid.Rows[12 + Adjust1].Cells[1].Value = Entry; - m_oSummaryPanel.SummaryDataGrid.Rows[Adjust2].Cells[2].Value = "Ordnance Factories"; + m_oSummaryPanel.SummaryDataGrid.Rows[Adjust2].Cells[2].Value = "Fuel Refineries"; m_oSummaryPanel.SummaryDataGrid.Rows[Adjust2].Cells[3].Value = Math.Floor(CurrentPopulation.Installations[(int)Installation.InstallationType.FuelRefinery].Number).ToString(); Adjust1++; diff --git a/Pulsar4X/Pulsar4X.UI/Panels/Eco_Summary.Designer.cs b/Pulsar4X/Pulsar4X.UI/Panels/Eco_Summary.Designer.cs index dca62835f..1944f1132 100644 --- a/Pulsar4X/Pulsar4X.UI/Panels/Eco_Summary.Designer.cs +++ b/Pulsar4X/Pulsar4X.UI/Panels/Eco_Summary.Designer.cs @@ -117,6 +117,11 @@ public GroupBox PlanetFighterGroupBox get { return m_oPlanetFighterGroupBox; } } + public GroupBox IndustrialProjectGroupBox + { + get { return m_oIndustrialProjectGroupBox; } + } + public ComboBox InstallationTypeComboBox { get { return m_oInstallationTypeComboBox; } From 7aa61a57eff4e3a5982e2f776486f12379aac733 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 6 Feb 2016 22:32:43 -0600 Subject: [PATCH 32/40] Sensor model fix, construction model fixes The sensor model should now be fully moved over to use currentSecond and currentYear, rather than the old model which was just a tick value. this should clear up any spurious "you detected this" events which were popping up. On the construction front, etas for items with less than 1 item remaining are now fixed, and additional rounding issues have been resolved. --- .../Entities/Components/OrdnanceTN.cs | 151 ++++++++--- .../Entities/ConstructionCycle.cs | 10 +- Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs | 246 +++++++++--------- .../Pulsar4X.Lib/Entities/FactionContact.cs | 177 ++++++++++++- Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs | 105 +++++++- Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs | 1 + .../Entities/StarSystem/Population.cs | 104 +++++++- 7 files changed, 618 insertions(+), 176 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Components/OrdnanceTN.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Components/OrdnanceTN.cs index 16c92c427..fda8764ae 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Components/OrdnanceTN.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Components/OrdnanceTN.cs @@ -867,9 +867,16 @@ public bool onOwnSensors /// What this all means is that on any given tick it is possible to quickly determine whether or not a ship has been detected by a faction. /// I am thinking that ticks will be counted in 5 second intervals, there should not be any issue with this for my code. /// - public BindingList ThermalDetection { get; set; } - public BindingList EMDetection { get; set; } - public BindingList ActiveDetection { get; set; } + private BindingList ThermalDetection { get; set; } + private BindingList EMDetection { get; set; } + private BindingList ActiveDetection { get; set; } + + /// + /// change to how tick works means that year must also be recorded. + /// + private BindingList ThermalYearDetection { get; set; } + private BindingList EMYearDetection { get; set; } + private BindingList ActiveYearDetection { get; set; } /// @@ -901,6 +908,27 @@ public OrdnanceTN(MissileFireControlTN mfCtrl, OrdnanceDefTN definition, ShipTN Separated = false; OnOwnSensors = false; + + /// + /// Missile Detection Statistics: + /// This is the first missile so created, so it is in spot 0. + /// + ThermalDetection = new BindingList(); + EMDetection = new BindingList(); + ActiveDetection = new BindingList(); + ThermalYearDetection = new BindingList(); + EMYearDetection = new BindingList(); + ActiveYearDetection = new BindingList(); + + for (int loop = 0; loop < Constants.Faction.FactionMax; loop++) + { + ThermalDetection.Add(GameState.Instance.CurrentSecond); + EMDetection.Add(GameState.Instance.CurrentSecond); + ActiveDetection.Add(GameState.Instance.CurrentSecond); + ThermalYearDetection.Add(GameState.Instance.CurrentYear); + EMYearDetection.Add(GameState.Instance.CurrentYear); + ActiveYearDetection.Add(GameState.Instance.CurrentYear); + } } /// @@ -1070,6 +1098,92 @@ public bool SetOwnSensors() return OnOwnSensors; } + + #region Sensor detection getting and setting + /// + /// Is this missile detected this tick? + /// + /// by which faction + /// current second + /// current year + /// true = yes, false = no + public bool IsDetectedThermal(int FactionID, int tick, int year) + { + if (ThermalDetection[FactionID] == tick && ThermalYearDetection[FactionID] == year) + { + return true; + } + return false; + } + + /// + /// Is this missile detected this tick? + /// + /// by which faction + /// current second + /// current year + /// true = yes, false = no + public bool IsDetectedEM(int FactionID, int tick, int year) + { + if (EMDetection[FactionID] == tick && EMYearDetection[FactionID] == year) + { + return true; + } + return false; + } + + /// + /// Is this missile detected this tick? + /// + /// by which faction + /// current second + /// current year + /// true = yes, false = no + public bool IsDetectedActive(int FactionID, int tick, int year) + { + if (ActiveDetection[FactionID] == tick && ActiveYearDetection[FactionID] == year) + { + return true; + } + return false; + } + + /// + /// Set this missile as detected + /// + /// faction detecting + /// current second + /// current year + public void SetThermalDetection(int FactionID, int tick, int year) + { + ThermalDetection[FactionID] = tick; + ThermalYearDetection[FactionID] = year; + } + + /// + /// Set this missile as detected + /// + /// faction detecting + /// current second + /// current year + public void SetEMDetection(int FactionID, int tick, int year) + { + EMDetection[FactionID] = tick; + EMYearDetection[FactionID] = year; + } + + /// + /// Set this missile as detected + /// + /// faction detecting + /// current second + /// current year + public void SetActiveDetection(int FactionID, int tick, int year) + { + ActiveDetection[FactionID] = tick; + ActiveYearDetection[FactionID] = year; + } + #endregion } public class OrdnanceGroupTN : StarSystemEntity @@ -1238,21 +1352,6 @@ public OrdnanceGroupTN(TaskGroupTN LaunchedFrom, OrdnanceTN Missile) Missiles = new BindingList(); - /// - /// Missile Detection Statistics: - /// This is the first missile so created, so it is in spot 0. - /// - Missile.ThermalDetection = new BindingList(); - Missile.EMDetection = new BindingList(); - Missile.ActiveDetection = new BindingList(); - - for (int loop = 0; loop < Constants.Faction.FactionMax; loop++) - { - Missile.ThermalDetection.Add(GameState.Instance.CurrentSecond); - Missile.EMDetection.Add(GameState.Instance.CurrentSecond); - Missile.ActiveDetection.Add(GameState.Instance.CurrentSecond); - } - OrdnanceGroupFaction = LaunchedFrom.TaskGroupFaction; Contact.Position.System = LaunchedFrom.Contact.Position.System; @@ -1281,24 +1380,8 @@ public OrdnanceGroupTN(TaskGroupTN LaunchedFrom, OrdnanceTN Missile) /// Missile to add, think of this as the ShipTN to OrdnanceGroupTN's TaskGroupTN public void AddMissile(OrdnanceTN Missile) { - /// - /// Missile Detection Statistics: - /// This is the first missile so created, so it is in spot 0. - /// - Missile.ThermalDetection = new BindingList(); - Missile.EMDetection = new BindingList(); - Missile.ActiveDetection = new BindingList(); - - for (int loop = 0; loop < Constants.Faction.FactionMax; loop++) - { - Missile.ThermalDetection.Add(GameState.Instance.CurrentSecond); - Missile.EMDetection.Add(GameState.Instance.CurrentSecond); - Missile.ActiveDetection.Add(GameState.Instance.CurrentSecond); - } - Missiles.Add(Missile); Missile.missileGroup = this; - } /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs b/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs index dea36ca14..99f220307 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs @@ -81,7 +81,7 @@ public static void ConstructionFactoryBuild(Faction CurrentFaction, Population C /// /// Calculate Completion Estimate: /// - float BPRequirement = (float)Math.Floor(CurrentConstruction.numToBuild) * (float)CurrentConstruction.costPerItem; + float BPRequirement = (float)CurrentConstruction.numToBuild * (float)CurrentConstruction.costPerItem; float DaysInYear = (float)Constants.TimeInSeconds.RealYear / (float)Constants.TimeInSeconds.Day; float YearlyDevotedIndustry = (CurrentConstruction.buildCapacity / 100.0f) * CurrentPopulation.CalcTotalIndustry(); @@ -110,9 +110,13 @@ public static void ConstructionFactoryBuild(Faction CurrentFaction, Population C float DevotedIndustry = (CurrentConstruction.buildCapacity / 100.0f) * CurrentIndustry; float Completion = DevotedIndustry / (float)CurrentConstruction.costPerItem; - if ((CurrentConstruction.numToBuild - Completion) < 0.0f) + if ((CurrentConstruction.numToBuild - Completion) <= 0.0f) { - Completion = CurrentConstruction.numToBuild; + /// + /// floating point errors will sometimes produce a situation where completion, numToBuild and installation.Number may be slightly off by a small delta, this 0.00001f is to correct that. + /// it slightly increases the overall cost of the installation, and slightly gives more of an installation than the player ordered. + /// + Completion = CurrentConstruction.numToBuild + 0.00001f; } bool CIRequired = false; diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs index b5d4291d5..3d50addf5 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs @@ -557,13 +557,13 @@ public void SensorSweep() /// /// iterate through every contact, thermal.Count will be equal to systemContacts.Count /// - for(int detListIterator = 0; detListIterator < System.FactionDetectionLists[FactionID].Thermal.Count; detListIterator++) + for(int detListIterator = 0; detListIterator < System.FactionDetectionLists[FactionID].GetDetectionCount(); detListIterator++) { /// /// This System contact is not owned by my faction, and it isn't fully detected yet. Populations only have thermal and EM detection characteristics here. /// - if (this != System.SystemContactList[detListIterator].faction && (System.FactionDetectionLists[FactionID].Thermal[detListIterator] != GameState.Instance.CurrentSecond || - System.FactionDetectionLists[FactionID].EM[detListIterator] != GameState.Instance.CurrentSecond)) + if (this != System.SystemContactList[detListIterator].faction && + System.FactionDetectionLists[FactionID].CheckIfNotDetected(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear) ) { /// /// Get the distance from the current population to systemContactList[detListIterator] and store it for this tick. @@ -588,7 +588,7 @@ public void SensorSweep() /// /// If this population has already been detected via thermals do not attempt to recalculate whether it has been detected or not. /// - if (System.FactionDetectionLists[FactionID].Thermal[detListIterator] != GameState.Instance.CurrentSecond) + if (System.FactionDetectionLists[FactionID].CheckThermal(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear) == false) { sig = DetectedPopulation.ThermalSignature; double rangeAdj = (((double)sig) / (double)Constants.SensorTN.DefaultPassiveSignature); @@ -613,8 +613,8 @@ public void SensorSweep() /// if (det == true) { - DetectedPopulation.ThermalDetection[FactionID] = GameState.Instance.CurrentSecond; - System.FactionDetectionLists[FactionID].Thermal[detListIterator] = GameState.Instance.CurrentSecond; + DetectedPopulation.SetThermalDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); + System.FactionDetectionLists[FactionID].SetThermalDetection(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetPopList.Contains(DetectedPopulation) == false) DetPopList.Add(DetectedPopulation); } @@ -623,7 +623,7 @@ public void SensorSweep() /// /// if this population has already been detected in EM then obviously there is no need to attempt to find it again. /// - if (System.FactionDetectionLists[FactionID].EM[detListIterator] != GameState.Instance.CurrentSecond) + if (System.FactionDetectionLists[FactionID].CheckEM(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { /// /// As signature can be different, detection should be recalculated. passive population based detection can be put into a table if need be, I am not @@ -640,8 +640,8 @@ public void SensorSweep() if (det == true) { - DetectedPopulation.EMDetection[FactionID] = GameState.Instance.CurrentSecond; - System.FactionDetectionLists[FactionID].EM[detListIterator] = GameState.Instance.CurrentSecond; + DetectedPopulation.SetEMDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); + System.FactionDetectionLists[FactionID].SetEMDetection(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetPopList.Contains(DetectedPopulation) == false) DetPopList.Add(DetectedPopulation); } @@ -659,7 +659,7 @@ public void SensorSweep() bool noDetection = false; bool allDetection = false; #region Population to Taskgroup thermal detection - if (System.FactionDetectionLists[FactionID].Thermal[detListIterator] != GameState.Instance.CurrentSecond) + if (System.FactionDetectionLists[FactionID].CheckThermal(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { /// /// Get the best detection range for thermal signatures in loop. @@ -714,14 +714,14 @@ public void SensorSweep() for (int loop3 = 0; loop3 < DetectedTaskGroup.Ships.Count; loop3++) { - DetectedTaskGroup.Ships[loop3].ThermalDetection[FactionID] = GameState.Instance.CurrentSecond; + DetectedTaskGroup.Ships[loop3].SetThermalDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(DetectedTaskGroup.Ships[loop3]) == false) { DetShipList.Add(DetectedTaskGroup.Ships[loop3]); } } - System.FactionDetectionLists[FactionID].Thermal[detListIterator] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetThermalDetection(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } else if (noDetection == false && allDetection == false) { @@ -737,7 +737,7 @@ public void SensorSweep() { scratch = DetectedTaskGroup.Ships[node.Value]; - if (scratch.ThermalDetection[FactionID] != GameState.Instance.CurrentSecond) + if (scratch.IsDetectedThermal(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = scratch.CurrentThermalSignature; rangeAdj = (((double)sig) / 1000.0); @@ -750,7 +750,7 @@ public void SensorSweep() if (det == true) { - scratch.ThermalDetection[FactionID] = GameState.Instance.CurrentSecond; + scratch.SetThermalDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(scratch) == false) { @@ -784,7 +784,7 @@ public void SensorSweep() #endregion #region Population to taskgroup EM detection - if (System.FactionDetectionLists[FactionID].EM[detListIterator] != GameState.Instance.CurrentSecond) + if (System.FactionDetectionLists[FactionID].CheckEM(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear) == false) { noDetection = false; allDetection = false; @@ -840,14 +840,14 @@ public void SensorSweep() for (int loop3 = 0; loop3 < DetectedTaskGroup.Ships.Count; loop3++) { - DetectedTaskGroup.Ships[loop3].EMDetection[FactionID] = GameState.Instance.CurrentSecond; + DetectedTaskGroup.Ships[loop3].SetEMDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(DetectedTaskGroup.Ships[loop3]) == false) { DetShipList.Add(DetectedTaskGroup.Ships[loop3]); } } - System.FactionDetectionLists[FactionID].EM[detListIterator] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetEMDetection(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } else if (noDetection == false && allDetection == false) { @@ -863,7 +863,7 @@ public void SensorSweep() { scratch = DetectedTaskGroup.Ships[node.Value]; - if (scratch.EMDetection[FactionID] != GameState.Instance.CurrentSecond) + if (scratch.IsDetectedEM(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = scratch.CurrentEMSignature; @@ -880,9 +880,9 @@ public void SensorSweep() /// The last signature we looked at was the ship emitting an EM sig, and this one is not. /// Mark the entire group as "spotted" because no other detection will occur. /// - if (DetectedTaskGroup.Ships[node.Next.Value].EMDetection[FactionID] == GameState.Instance.CurrentSecond) + if (DetectedTaskGroup.Ships[node.Next.Value].IsDetectedEM(FactionID,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear) == true) { - System.FactionDetectionLists[FactionID].EM[detListIterator] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetEMDetection(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); //since the ships aren't actually detected, don't add them to the detected ships list. } break; @@ -895,7 +895,7 @@ public void SensorSweep() if (det == true) { - scratch.EMDetection[FactionID] = GameState.Instance.CurrentSecond; + scratch.SetEMDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(scratch) == false) { @@ -939,7 +939,7 @@ public void SensorSweep() { OrdnanceGroupTN MissileGroup = (System.SystemContactList[detListIterator].Entity as OrdnanceGroupTN); OrdnanceTN Missile = MissileGroup.missiles[0]; - if (System.FactionDetectionLists[FactionID].Thermal[detListIterator] != GameState.Instance.CurrentSecond) + if (System.FactionDetectionLists[FactionID].CheckThermal(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear) == false) { int ThermalScanStrength = DSTS * Constants.Colony.ThermalDeepSpaceStrength[SensorTech]; @@ -965,7 +965,7 @@ public void SensorSweep() { for (int loop3 = 0; loop3 < MissileGroup.missiles.Count; loop3++) { - MissileGroup.missiles[loop3].ThermalDetection[FactionID] = GameState.Instance.CurrentSecond; + MissileGroup.missiles[loop3].SetThermalDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } if (DetMissileList.Contains(MissileGroup) == false) @@ -973,10 +973,10 @@ public void SensorSweep() DetMissileList.Add(MissileGroup); } - System.FactionDetectionLists[FactionID].Thermal[detListIterator] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetThermalDetection(detListIterator,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } } - if (System.FactionDetectionLists[FactionID].EM[detListIterator] != GameState.Instance.CurrentSecond) + if (System.FactionDetectionLists[FactionID].CheckEM(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear) == false) { int EMSignature = 0; if (Missile.missileDef.activeStr != 0.0f) @@ -1003,7 +1003,7 @@ public void SensorSweep() { for (int loop3 = 0; loop3 < MissileGroup.missiles.Count; loop3++) { - MissileGroup.missiles[loop3].EMDetection[FactionID] = GameState.Instance.CurrentSecond; + MissileGroup.missiles[loop3].SetEMDetection(FactionID,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear); } if (DetMissileList.Contains(MissileGroup) == false) @@ -1011,7 +1011,7 @@ public void SensorSweep() DetMissileList.Add(MissileGroup); } - System.FactionDetectionLists[FactionID].EM[detListIterator] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetEMDetection(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } } } @@ -1028,30 +1028,30 @@ public void SensorSweep() #region Faction Taskgroup Loop foreach(TaskGroupTN CurrentTaskGroup in TaskGroups) { + /// - /// This Taskgroup can't perform a sensor sweep until jump sickness is gone. It stands to reason that if ship[0] is sick they all will be, but clever taskgroup reorganizing - /// may thwart that. I'd recommend just banning taskgroup reorganization while jumpsick. + /// A taskgroup with no ships cannot detect anything. /// - if (CurrentTaskGroup.IsJumpSick()) + if (CurrentTaskGroup.Ships.Count == 0) continue; /// - /// A taskgroup with no ships cannot detect anything. + /// This Taskgroup can't perform a sensor sweep until jump sickness is gone. It stands to reason that if ship[0] is sick they all will be, but clever taskgroup reorganizing + /// may thwart that. I'd recommend just banning taskgroup reorganization while jumpsick. /// - if (CurrentTaskGroup.Ships.Count == 0) + if (CurrentTaskGroup.IsJumpSick()) continue; StarSystem System = CurrentTaskGroup.Contact.Position.System; /// /// Loop through the global contacts list for the system. thermal.Count is equal to SystemContacts.Count. or should be. /// - for (int detListIterator = 0; detListIterator < System.FactionDetectionLists[FactionID].Thermal.Count; detListIterator++) + for (int detListIterator = 0; detListIterator < System.FactionDetectionLists[FactionID].GetDetectionCount(); detListIterator++) { /// /// Check if System.SystemContactList[detListIterator] is in the same faction, and it hasn't been fully detected yet. /// - if (this != System.SystemContactList[detListIterator].faction && (System.FactionDetectionLists[FactionID].Thermal[detListIterator] != GameState.Instance.CurrentSecond || - System.FactionDetectionLists[FactionID].EM[detListIterator] != GameState.Instance.CurrentSecond || System.FactionDetectionLists[FactionID].Active[detListIterator] != GameState.Instance.CurrentSecond)) + if (this != System.SystemContactList[detListIterator].faction && System.FactionDetectionLists[FactionID].CheckIfNotDetected(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear) ) { float dist; // Check to see if our distance table is updated for this contact. @@ -1122,7 +1122,7 @@ public void SensorSweep() { #region TaskGroup to Population detection Population Pop = System.SystemContactList[detListIterator].Entity as Population; - if (System.FactionDetectionLists[FactionID].Thermal[detListIterator] != GameState.Instance.CurrentSecond) + if (System.FactionDetectionLists[FactionID].CheckThermal(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear) == false) { sig = Pop.ThermalSignature; detection = CurrentTaskGroup.BestThermal.pSensorDef.GetPassiveDetectionRange(sig); @@ -1137,14 +1137,14 @@ public void SensorSweep() /// if (det == true) { - Pop.ThermalDetection[FactionID] = GameState.Instance.CurrentSecond; - System.FactionDetectionLists[FactionID].Thermal[detListIterator] = GameState.Instance.CurrentSecond; + Pop.SetThermalDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); + System.FactionDetectionLists[FactionID].SetThermalDetection(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetPopList.Contains(Pop) == false) DetPopList.Add(Pop); } } - if (System.FactionDetectionLists[FactionID].EM[detListIterator] != GameState.Instance.CurrentSecond) + if (System.FactionDetectionLists[FactionID].CheckEM(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = Pop.EMSignature; detection = CurrentTaskGroup.BestEM.pSensorDef.GetPassiveDetectionRange(sig); @@ -1153,14 +1153,14 @@ public void SensorSweep() if (det == true) { - Pop.EMDetection[FactionID] = GameState.Instance.CurrentSecond; - System.FactionDetectionLists[FactionID].EM[detListIterator] = GameState.Instance.CurrentSecond; + Pop.SetEMDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); + System.FactionDetectionLists[FactionID].SetEMDetection(detListIterator,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetPopList.Contains(Pop) == false) DetPopList.Add(Pop); } } - if (System.FactionDetectionLists[FactionID].Active[detListIterator] != GameState.Instance.CurrentSecond && CurrentTaskGroup.ActiveSensorQue.Count > 0) + if (System.FactionDetectionLists[FactionID].CheckActive(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false && CurrentTaskGroup.ActiveSensorQue.Count > 0) { sig = Constants.ShipTN.ResolutionMax - 1; /// @@ -1175,8 +1175,8 @@ public void SensorSweep() if (det == true) { - Pop.ActiveDetection[FactionID] = GameState.Instance.CurrentSecond; - System.FactionDetectionLists[FactionID].Active[detListIterator] = GameState.Instance.CurrentSecond; + Pop.SetActiveDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); + System.FactionDetectionLists[FactionID].SetActiveDetection(detListIterator,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetPopList.Contains(Pop) == false) DetPopList.Add(Pop); } @@ -1224,7 +1224,7 @@ public void SensorSweep() /// #region Missile Detection OrdnanceTN Missile = MissileGroup.missiles[0]; - if (System.FactionDetectionLists[FactionID].Thermal[detListIterator] != GameState.Instance.CurrentSecond) + if (System.FactionDetectionLists[FactionID].CheckThermal(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear) == false) { int ThermalSignature = (int)Math.Ceiling(Missile.missileDef.totalThermalSignature); detection = -1; @@ -1253,7 +1253,7 @@ public void SensorSweep() { for (int loop3 = 0; loop3 < MissileGroup.missiles.Count; loop3++) { - MissileGroup.missiles[loop3].ThermalDetection[FactionID] = GameState.Instance.CurrentSecond; + MissileGroup.missiles[loop3].SetThermalDetection(FactionID,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear); } if (DetMissileList.Contains(MissileGroup) == false) @@ -1261,11 +1261,11 @@ public void SensorSweep() DetMissileList.Add(MissileGroup); } - System.FactionDetectionLists[FactionID].Thermal[detListIterator] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetThermalDetection(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear); } } - if (System.FactionDetectionLists[FactionID].EM[detListIterator] != GameState.Instance.CurrentSecond) + if (System.FactionDetectionLists[FactionID].CheckEM(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear) == false) { int EMSignature = 0; if (Missile.missileDef.activeStr != 0.0f) @@ -1297,7 +1297,7 @@ public void SensorSweep() { for (int loop3 = 0; loop3 < MissileGroup.missiles.Count; loop3++) { - MissileGroup.missiles[loop3].EMDetection[FactionID] = GameState.Instance.CurrentSecond; + MissileGroup.missiles[loop3].SetEMDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } if (DetMissileList.Contains(MissileGroup) == false) @@ -1306,12 +1306,12 @@ public void SensorSweep() } - System.FactionDetectionLists[FactionID].EM[detListIterator] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetEMDetection(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear); } } } - if (System.FactionDetectionLists[FactionID].Active[detListIterator] != GameState.Instance.CurrentSecond && CurrentTaskGroup.ActiveSensorQue.Count > 0) + if (System.FactionDetectionLists[FactionID].CheckActive(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear) == false && CurrentTaskGroup.ActiveSensorQue.Count > 0) { int TotalCrossSection_MSP = (int)Math.Ceiling(Missile.missileDef.size); sig = -1; @@ -1346,7 +1346,7 @@ public void SensorSweep() { for (int loop3 = 0; loop3 < MissileGroup.missiles.Count; loop3++) { - MissileGroup.missiles[loop3].ActiveDetection[FactionID] = GameState.Instance.CurrentSecond; + MissileGroup.missiles[loop3].SetActiveDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } if (DetMissileList.Contains(MissileGroup) == false) @@ -1354,7 +1354,7 @@ public void SensorSweep() DetMissileList.Add(MissileGroup); } - System.FactionDetectionLists[FactionID].Active[detListIterator] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetActiveDetection(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear); } } #endregion @@ -1414,13 +1414,12 @@ public void SensorSweep() /// /// Loop through the global contacts list for the system. thermal.Count is equal to SystemContacts.Count. or should be. /// - for (int loop2 = 0; loop2 < System.FactionDetectionLists[FactionID].Thermal.Count; loop2++) + for (int loop2 = 0; loop2 < System.FactionDetectionLists[FactionID].GetDetectionCount(); loop2++) { /// /// I don't own loop2, and it hasn't been fully detected yet. And this missile can actually detect things. /// - if (this != System.SystemContactList[loop2].faction && (System.FactionDetectionLists[FactionID].Thermal[loop2] != GameState.Instance.CurrentSecond || - System.FactionDetectionLists[FactionID].EM[loop2] != GameState.Instance.CurrentSecond || System.FactionDetectionLists[FactionID].Active[loop2] != GameState.Instance.CurrentSecond )&& + if (this != System.SystemContactList[loop2].faction && System.FactionDetectionLists[FactionID].CheckIfNotDetected(loop2, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) && (Missile.missileDef.thermalStr != 0.0f || Missile.missileDef.eMStr != 0.0f || Missile.missileDef.activeStr != 0.0f)) { float dist; @@ -1444,7 +1443,7 @@ public void SensorSweep() /// /// Does this missile have a thermal sensor suite? by default the answer is no, this is different from Aurora which gives them the basic ship suite. /// - if (Missile.missileDef.tHD != null && System.FactionDetectionLists[FactionID].Thermal[loop2] != GameState.Instance.CurrentSecond) + if (Missile.missileDef.tHD != null && System.FactionDetectionLists[FactionID].CheckThermal(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = Pop.ThermalSignature; detection = Missile.missileDef.tHD.GetPassiveDetectionRange(sig); @@ -1456,8 +1455,8 @@ public void SensorSweep() /// if (det == true) { - Pop.ThermalDetection[FactionID] = GameState.Instance.CurrentSecond; - System.FactionDetectionLists[FactionID].Thermal[loop2] = GameState.Instance.CurrentSecond; + Pop.SetThermalDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); + System.FactionDetectionLists[FactionID].SetThermalDetection(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetPopList.Contains(Pop) == false) DetPopList.Add(Pop); } @@ -1466,7 +1465,7 @@ public void SensorSweep() /// /// Does this missile have an EM sensor suite? by default again the answer is no, which is again different from Aurora. /// - if (Missile.missileDef.eMD != null && System.FactionDetectionLists[FactionID].EM[loop2] != GameState.Instance.CurrentSecond) + if (Missile.missileDef.eMD != null && System.FactionDetectionLists[FactionID].CheckEM(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = Pop.EMSignature; detection = Missile.missileDef.eMD.GetPassiveDetectionRange(sig); @@ -1478,8 +1477,8 @@ public void SensorSweep() /// if (det == true) { - Pop.EMDetection[FactionID] = GameState.Instance.CurrentSecond; - System.FactionDetectionLists[FactionID].EM[loop2] = GameState.Instance.CurrentSecond; + Pop.SetEMDetection(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); + System.FactionDetectionLists[FactionID].SetEMDetection(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetPopList.Contains(Pop) == false) DetPopList.Add(Pop); } @@ -1488,7 +1487,7 @@ public void SensorSweep() /// /// Lastly does this missile have an active sensor? /// - if (Missile.missileDef.aSD != null && System.FactionDetectionLists[FactionID].Active[loop2] != GameState.Instance.CurrentSecond) + if (Missile.missileDef.aSD != null && System.FactionDetectionLists[FactionID].CheckActive(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = Constants.ShipTN.ResolutionMax - 1; detection = Missile.missileDef.aSD.GetActiveDetectionRange(sig, -1); @@ -1500,8 +1499,8 @@ public void SensorSweep() /// if (det == true) { - Pop.ActiveDetection[FactionID] = GameState.Instance.CurrentSecond; - System.FactionDetectionLists[FactionID].Active[loop2] = GameState.Instance.CurrentSecond; + Pop.SetActiveDetection(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); + System.FactionDetectionLists[FactionID].SetActiveDetection(loop2, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetPopList.Contains(Pop) == false) DetPopList.Add(Pop); } @@ -1523,7 +1522,7 @@ public void SensorSweep() bool allDetection = false; #region Ship Thermal Detection Code - if (System.FactionDetectionLists[FactionID].Thermal[loop2] != GameState.Instance.CurrentSecond && Missile.missileDef.tHD != null) + if (System.FactionDetectionLists[FactionID].CheckThermal(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false && Missile.missileDef.tHD != null) { int ShipID = TaskGroup.ThermalSortList.Last(); ShipTN scratch = TaskGroup.Ships[ShipID]; @@ -1568,14 +1567,14 @@ public void SensorSweep() for (int loop3 = 0; loop3 < TaskGroup.Ships.Count; loop3++) { - TaskGroup.Ships[loop3].ThermalDetection[FactionID] = GameState.Instance.CurrentSecond; + TaskGroup.Ships[loop3].SetThermalDetection(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(TaskGroup.Ships[loop3]) == false) { DetShipList.Add(TaskGroup.Ships[loop3]); } } - System.FactionDetectionLists[FactionID].Thermal[loop2] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetThermalDetection(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } else if (noDetection == false && allDetection == false) { @@ -1591,7 +1590,7 @@ public void SensorSweep() { scratch = TaskGroup.Ships[node.Value]; - if (scratch.ThermalDetection[FactionID] != GameState.Instance.CurrentSecond) + if (scratch.IsDetectedThermal(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = scratch.CurrentThermalSignature; detection = Missile.missileDef.tHD.GetPassiveDetectionRange(sig); @@ -1603,7 +1602,7 @@ public void SensorSweep() if (det == true) { - scratch.ThermalDetection[FactionID] = GameState.Instance.CurrentSecond; + scratch.SetThermalDetection(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(scratch) == false) { @@ -1637,7 +1636,7 @@ public void SensorSweep() #endregion #region Ship EM Detection Code - if (System.FactionDetectionLists[FactionID].EM[loop2] != GameState.Instance.CurrentSecond && Missile.missileDef.eMD != null) + if (System.FactionDetectionLists[FactionID].CheckEM(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false && Missile.missileDef.eMD != null) { int ShipID = TaskGroup.EMSortList.Last(); ShipTN scratch = TaskGroup.Ships[ShipID]; @@ -1682,14 +1681,14 @@ public void SensorSweep() for (int loop3 = 0; loop3 < TaskGroup.Ships.Count; loop3++) { - TaskGroup.Ships[loop3].EMDetection[FactionID] = GameState.Instance.CurrentSecond; + TaskGroup.Ships[loop3].SetEMDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(TaskGroup.Ships[loop3]) == false) { DetShipList.Add(TaskGroup.Ships[loop3]); } } - System.FactionDetectionLists[FactionID].EM[loop2] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetEMDetection(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } else if (noDetection == false && allDetection == false) { @@ -1705,7 +1704,7 @@ public void SensorSweep() { scratch = TaskGroup.Ships[node.Value]; - if (scratch.EMDetection[FactionID] != GameState.Instance.CurrentSecond) + if (scratch.IsDetectedEM(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = scratch.CurrentEMSignature; @@ -1724,9 +1723,9 @@ public void SensorSweep() /// The last signature we looked at was the ship emitting an EM sig, and this one is not. /// Mark the entire group as "spotted" because no other detection will occur. /// - if (TaskGroup.Ships[node.Next.Value].EMDetection[FactionID] == GameState.Instance.CurrentSecond) + if (TaskGroup.Ships[node.Next.Value].IsDetectedEM(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == true) { - System.FactionDetectionLists[FactionID].EM[loop2] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetEMDetection(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } break; } @@ -1741,7 +1740,7 @@ public void SensorSweep() if (det == true) { - scratch.EMDetection[FactionID] = GameState.Instance.CurrentSecond; + scratch.SetEMDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(scratch) == false) { @@ -1775,7 +1774,7 @@ public void SensorSweep() #endregion #region Ship Active Detection Code - if (System.FactionDetectionLists[FactionID].Active[loop2] != GameState.Instance.CurrentSecond && Missile.missileDef.aSD != null) + if (System.FactionDetectionLists[FactionID].CheckActive(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false && Missile.missileDef.aSD != null) { int ShipID = TaskGroup.ActiveSortList.Last(); ShipTN scratch = TaskGroup.Ships[ShipID]; @@ -1820,14 +1819,14 @@ public void SensorSweep() for (int loop3 = 0; loop3 < TaskGroup.Ships.Count; loop3++) { - TaskGroup.Ships[loop3].ActiveDetection[FactionID] = GameState.Instance.CurrentSecond; + TaskGroup.Ships[loop3].SetActiveDetection(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(TaskGroup.Ships[loop3]) == false) { DetShipList.Add(TaskGroup.Ships[loop3]); } } - System.FactionDetectionLists[FactionID].Active[loop2] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetActiveDetection(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } else if (noDetection == false && allDetection == false) { @@ -1843,7 +1842,7 @@ public void SensorSweep() { scratch = TaskGroup.Ships[node.Value]; - if (scratch.ActiveDetection[FactionID] != GameState.Instance.CurrentSecond) + if (scratch.IsDetectedActive(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = scratch.TotalCrossSection; detection = Missile.missileDef.aSD.GetActiveDetectionRange(sig, -1); @@ -1855,7 +1854,7 @@ public void SensorSweep() if (det == true) { - scratch.ActiveDetection[FactionID] = GameState.Instance.CurrentSecond; + scratch.SetActiveDetection(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(scratch) == false) { @@ -1902,7 +1901,7 @@ public void SensorSweep() /// #region Missile Detection OrdnanceTN MissileTarget = MissileGroup.missiles[0]; - if (System.FactionDetectionLists[FactionID].Thermal[loop2] != GameState.Instance.CurrentSecond && Missile.missileDef.tHD != null) + if (System.FactionDetectionLists[FactionID].CheckThermal(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false && Missile.missileDef.tHD != null) { int ThermalSignature = (int)Math.Ceiling(MissileTarget.missileDef.totalThermalSignature); @@ -1920,7 +1919,7 @@ public void SensorSweep() { for (int loop3 = 0; loop3 < MissileGroup.missiles.Count; loop3++) { - MissileGroup.missiles[loop3].ThermalDetection[FactionID] = GameState.Instance.CurrentSecond; + MissileGroup.missiles[loop3].SetThermalDetection(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } if (DetMissileList.Contains(MissileGroup) == false) @@ -1928,11 +1927,11 @@ public void SensorSweep() DetMissileList.Add(MissileGroup); } - System.FactionDetectionLists[FactionID].Thermal[loop2] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetThermalDetection(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } } - if (System.FactionDetectionLists[FactionID].EM[loop2] != GameState.Instance.CurrentSecond && Missile.missileDef.eMD != null) + if (System.FactionDetectionLists[FactionID].CheckEM(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false && Missile.missileDef.eMD != null) { int EMSignature = 0; if (MissileTarget.missileDef.activeStr != 0.0f && MissileTarget.missileDef.aSD != null) @@ -1953,7 +1952,7 @@ public void SensorSweep() { for (int loop3 = 0; loop3 < MissileGroup.missiles.Count; loop3++) { - MissileGroup.missiles[loop3].EMDetection[FactionID] = GameState.Instance.CurrentSecond; + MissileGroup.missiles[loop3].SetEMDetection(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } if (DetMissileList.Contains(MissileGroup) == false) @@ -1961,12 +1960,12 @@ public void SensorSweep() DetMissileList.Add(MissileGroup); } - System.FactionDetectionLists[FactionID].EM[loop2] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetEMDetection(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } } } - if (System.FactionDetectionLists[FactionID].Active[loop2] != GameState.Instance.CurrentSecond && Missile.missileDef.aSD != null) + if (System.FactionDetectionLists[FactionID].CheckActive(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false && Missile.missileDef.aSD != null) { int TotalCrossSection_MSP = (int)Math.Ceiling(MissileTarget.missileDef.size); sig = -1; @@ -2000,7 +1999,7 @@ public void SensorSweep() { for (int loop3 = 0; loop3 < MissileGroup.missiles.Count; loop3++) { - MissileGroup.missiles[loop3].ActiveDetection[FactionID] = GameState.Instance.CurrentSecond; + MissileGroup.missiles[loop3].SetActiveDetection(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } if (DetMissileList.Contains(MissileGroup) == false) @@ -2008,7 +2007,7 @@ public void SensorSweep() DetMissileList.Add(MissileGroup); } - System.FactionDetectionLists[FactionID].Active[loop2] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetActiveDetection(loop2,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } } #endregion @@ -2049,9 +2048,9 @@ public void SensorSweep() inDict = DetectedContactLists[System].DetectedContacts.ContainsKey(detectedShip); - bool th = (detectedShip.ThermalDetection[FactionID] == GameState.Instance.CurrentSecond); - bool em = (detectedShip.EMDetection[FactionID] == GameState.Instance.CurrentSecond); - bool ac = (detectedShip.ActiveDetection[FactionID] == GameState.Instance.CurrentSecond); + bool th = (detectedShip.IsDetectedThermal(FactionID,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear)); + bool em = (detectedShip.IsDetectedEM(FactionID,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear)); + bool ac = (detectedShip.IsDetectedActive(FactionID,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear)); if (inDict == true) { @@ -2061,7 +2060,7 @@ public void SensorSweep() EMSig = detectedShip.CurrentEMSignature; } - DetectedContactLists[System].DetectedContacts[detectedShip].updateFactionContact(this, th, em, EMSig, ac, (uint)GameState.Instance.CurrentSecond); + DetectedContactLists[System].DetectedContacts[detectedShip].updateFactionContact(this, th, em, EMSig, ac, (uint)GameState.Instance.CurrentSecond, (uint)GameState.Instance.CurrentYear); if (th == false && em == false && ac == false) { @@ -2076,7 +2075,7 @@ public void SensorSweep() EMSig = detectedShip.CurrentEMSignature; } - FactionContact newContact = new FactionContact(this, detectedShip, th, em, EMSig, ac, (uint)GameState.Instance.CurrentSecond); + FactionContact newContact = new FactionContact(this, detectedShip, th, em, EMSig, ac, (uint)GameState.Instance.CurrentSecond, (uint)GameState.Instance.CurrentYear); DetectedContactLists[System].DetectedContacts.Add(detectedShip, newContact); } } @@ -2102,9 +2101,9 @@ public void SensorSweep() inDict = DetectedContactLists[System].DetectedMissileContacts.ContainsKey(Missile.missileGroup); - bool th = (Missile.ThermalDetection[FactionID] == GameState.Instance.CurrentSecond); - bool em = (Missile.EMDetection[FactionID] == GameState.Instance.CurrentSecond); - bool ac = (Missile.ActiveDetection[FactionID] == GameState.Instance.CurrentSecond); + bool th = (Missile.IsDetectedThermal(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear)); + bool em = (Missile.IsDetectedEM(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear)); + bool ac = (Missile.IsDetectedActive(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear)); if (inDict == true) { @@ -2113,7 +2112,7 @@ public void SensorSweep() { EMSig = Missile.missileDef.aSD.gps; } - DetectedContactLists[System].DetectedMissileContacts[Missile.missileGroup].updateFactionContact(this, th, em, EMSig, ac, (uint)GameState.Instance.CurrentSecond); + DetectedContactLists[System].DetectedMissileContacts[Missile.missileGroup].updateFactionContact(this, th, em, EMSig, ac, (uint)GameState.Instance.CurrentSecond, (uint)GameState.Instance.CurrentYear); if (th == false && em == false && ac == false) { @@ -2122,7 +2121,7 @@ public void SensorSweep() } else if (inDict == false && (th == true || em == true || ac == true)) { - FactionContact newContact = new FactionContact(this, Missile.missileGroup, th, em, ac, (uint)GameState.Instance.CurrentSecond); + FactionContact newContact = new FactionContact(this, Missile.missileGroup, th, em, ac, (uint)GameState.Instance.CurrentSecond, (uint)GameState.Instance.CurrentYear); DetectedContactLists[System].DetectedMissileContacts.Add(Missile.missileGroup, newContact); } } @@ -2145,13 +2144,14 @@ public void SensorSweep() inDict = DetectedContactLists[System].DetectedPopContacts.ContainsKey(CurrentPopulation); - bool th = (CurrentPopulation.ThermalDetection[FactionID] == GameState.Instance.CurrentSecond); - bool em = (CurrentPopulation.EMDetection[FactionID] == GameState.Instance.CurrentSecond); - bool ac = (CurrentPopulation.ActiveDetection[FactionID] == GameState.Instance.CurrentSecond); + bool th = (CurrentPopulation.IsDetectedThermal(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear)); + bool em = (CurrentPopulation.IsDetectedEM(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear)); + bool ac = (CurrentPopulation.IsDetectedActive(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear)); + if (inDict == true) { - DetectedContactLists[System].DetectedPopContacts[CurrentPopulation].updateFactionContact(this, th, em, CurrentPopulation.EMSignature, ac, (uint)GameState.Instance.CurrentSecond); + DetectedContactLists[System].DetectedPopContacts[CurrentPopulation].updateFactionContact(this, th, em, CurrentPopulation.EMSignature, ac, (uint)GameState.Instance.CurrentSecond, (uint)GameState.Instance.CurrentYear); if (th == false && em == false && ac == false) { @@ -2160,7 +2160,7 @@ public void SensorSweep() } else if (inDict == false && (th == true || em == true || ac == true)) { - FactionContact newContact = new FactionContact(this, CurrentPopulation, th, em, ac, (uint)GameState.Instance.CurrentSecond); + FactionContact newContact = new FactionContact(this, CurrentPopulation, th, em, ac, (uint)GameState.Instance.CurrentSecond, (uint)GameState.Instance.CurrentYear); DetectedContactLists[System].DetectedPopContacts.Add(CurrentPopulation, newContact); } } @@ -2266,7 +2266,7 @@ public void GiveAllTechs() /// If a ship is detected it must be put into this list for the detectedContactsList later on. private void TaskGroupThermalDetection(StarSystem System, TaskGroupTN CurrentTaskGroup, TaskGroupTN TaskGroupToTest, float dist, int detListIterator) { - if (System.FactionDetectionLists[FactionID].Thermal[detListIterator] != GameState.Instance.CurrentSecond) + if (System.FactionDetectionLists[FactionID].CheckThermal(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { int sig = -1; int detection = -1; @@ -2339,14 +2339,14 @@ private void TaskGroupThermalDetection(StarSystem System, TaskGroupTN CurrentTas for (int loop3 = 0; loop3 < TaskGroupToTest.Ships.Count; loop3++) { - TaskGroupToTest.Ships[loop3].ThermalDetection[FactionID] = GameState.Instance.CurrentSecond; + TaskGroupToTest.Ships[loop3].SetThermalDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(TaskGroupToTest.Ships[loop3]) == false) { DetShipList.Add(TaskGroupToTest.Ships[loop3]); } } - System.FactionDetectionLists[FactionID].Thermal[detListIterator] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetThermalDetection(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } @@ -2365,7 +2365,7 @@ private void TaskGroupThermalDetection(StarSystem System, TaskGroupTN CurrentTas { scratch = TaskGroupToTest.Ships[node.Value]; - if (scratch.ThermalDetection[FactionID] != GameState.Instance.CurrentSecond) + if (scratch.IsDetectedThermal(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = scratch.CurrentThermalSignature; if (CurrentTaskGroup.BestThermalCount != 0) @@ -2384,7 +2384,7 @@ private void TaskGroupThermalDetection(StarSystem System, TaskGroupTN CurrentTas if (det == true) { - scratch.ThermalDetection[FactionID] = GameState.Instance.CurrentSecond; + scratch.SetThermalDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(scratch) == false) { @@ -2432,7 +2432,7 @@ private void TaskGroupThermalDetection(StarSystem System, TaskGroupTN CurrentTas /// If a ship is detected it must be put into this list for the detectedContactsList later on. private void TaskGroupEMDetection(StarSystem System, TaskGroupTN CurrentTaskGroup, TaskGroupTN TaskGroupToTest, float dist, int detListIterator) { - if (System.FactionDetectionLists[FactionID].EM[detListIterator] != GameState.Instance.CurrentSecond) + if (System.FactionDetectionLists[FactionID].CheckEM(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { int sig = -1; int detection = -1; @@ -2501,14 +2501,14 @@ private void TaskGroupEMDetection(StarSystem System, TaskGroupTN CurrentTaskGrou for (int loop3 = 0; loop3 < TaskGroupToTest.Ships.Count; loop3++) { - TaskGroupToTest.Ships[loop3].EMDetection[FactionID] = GameState.Instance.CurrentSecond; + TaskGroupToTest.Ships[loop3].SetEMDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(TaskGroupToTest.Ships[loop3]) == false) { DetShipList.Add(TaskGroupToTest.Ships[loop3]); } } - System.FactionDetectionLists[FactionID].EM[detListIterator] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetEMDetection(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } else if (noDetection == false && allDetection == false) { @@ -2526,7 +2526,7 @@ private void TaskGroupEMDetection(StarSystem System, TaskGroupTN CurrentTaskGrou { scratch = TaskGroupToTest.Ships[node.Value]; - if (scratch.EMDetection[FactionID] != GameState.Instance.CurrentSecond) + if (scratch.IsDetectedEM(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = scratch.CurrentEMSignature; @@ -2543,9 +2543,9 @@ private void TaskGroupEMDetection(StarSystem System, TaskGroupTN CurrentTaskGrou /// The last signature we looked at was the ship emitting an EM sig, and this one is not. /// Mark the entire group as "spotted" because no other detection will occur. /// - if (TaskGroupToTest.Ships[node.Next.Value].EMDetection[FactionID] == GameState.Instance.CurrentSecond) + if (TaskGroupToTest.Ships[node.Next.Value].IsDetectedEM(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == true) { - System.FactionDetectionLists[FactionID].EM[detListIterator] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetEMDetection(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } break; } @@ -2563,7 +2563,7 @@ private void TaskGroupEMDetection(StarSystem System, TaskGroupTN CurrentTaskGrou if (det == true) { - scratch.EMDetection[FactionID] = GameState.Instance.CurrentSecond; + scratch.SetEMDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(scratch) == false) { @@ -2611,7 +2611,7 @@ private void TaskGroupEMDetection(StarSystem System, TaskGroupTN CurrentTaskGrou /// location of the test taskgroup in the detection lists private void TaskGroupActiveDetection(StarSystem System, TaskGroupTN CurrentTaskGroup, TaskGroupTN TaskGroupToTest, float dist, int detListIterator) { - if (System.FactionDetectionLists[FactionID].Active[detListIterator] != GameState.Instance.CurrentSecond && CurrentTaskGroup.ActiveSensorQue.Count > 0) + if (System.FactionDetectionLists[FactionID].CheckActive(detListIterator,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false && CurrentTaskGroup.ActiveSensorQue.Count > 0) { int sig = -1; int detection = -1; @@ -2665,7 +2665,7 @@ private void TaskGroupActiveDetection(StarSystem System, TaskGroupTN CurrentTask for (int loop3 = 0; loop3 < TaskGroupToTest.Ships.Count; loop3++) { - TaskGroupToTest.Ships[loop3].ActiveDetection[FactionID] = GameState.Instance.CurrentSecond; + TaskGroupToTest.Ships[loop3].SetActiveDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(TaskGroupToTest.Ships[loop3]) == false) { @@ -2677,7 +2677,7 @@ private void TaskGroupActiveDetection(StarSystem System, TaskGroupTN CurrentTask /// Be sure to erase the factionDetectionSystem entry first, to track down everywhere this overbloated thing is. /// update, not happening. FactionDetectionList is too important. /// - System.FactionDetectionLists[FactionID].Active[detListIterator] = GameState.Instance.CurrentSecond; + System.FactionDetectionLists[FactionID].SetActiveDetection(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); } else if (noDetection == false && allDetection == false) { @@ -2695,7 +2695,7 @@ private void TaskGroupActiveDetection(StarSystem System, TaskGroupTN CurrentTask { scratch = TaskGroupToTest.Ships[node.Value]; - if (scratch.ActiveDetection[FactionID] != GameState.Instance.CurrentSecond) + if (scratch.IsDetectedActive(FactionID,GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = scratch.TotalCrossSection - 1; @@ -2708,7 +2708,7 @@ private void TaskGroupActiveDetection(StarSystem System, TaskGroupTN CurrentTask if (det == true) { - scratch.ActiveDetection[FactionID] = GameState.Instance.CurrentSecond; + scratch.SetActiveDetection(FactionID, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear); if (DetShipList.Contains(scratch) == false) { diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/FactionContact.cs b/Pulsar4X/Pulsar4X.Lib/Entities/FactionContact.cs index 6fcdb49d5..9d97eea43 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/FactionContact.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/FactionContact.cs @@ -63,6 +63,14 @@ public class FactionContact /// public uint activeTick { get; set; } + /// + /// year detection event took place. tick above refers to second now. + /// + public uint thermalYear { get; set; } + public uint EMYear { get; set; } + public uint activeYear { get; set; } + + /// /// Initializer for detected ship event. FactionContact is the detector side of what is detected, while ShipTN itself stores the detectee side. /// multiple of these can exist, but only 1 per faction hopefully. @@ -72,7 +80,7 @@ public class FactionContact /// Detection via EM? /// Active detection? /// What tick did this detection event occur on? - public FactionContact(Faction CurrentFaction, ShipTN DetectedShip, bool Thermal, bool em, int EMSig, bool Active, uint tick) + public FactionContact(Faction CurrentFaction, ShipTN DetectedShip, bool Thermal, bool em, int EMSig, bool Active, uint tick, uint year) { ship = DetectedShip; missileGroup = null; @@ -87,18 +95,21 @@ public FactionContact(Faction CurrentFaction, ShipTN DetectedShip, bool Thermal, if (thermal == true) { thermalTick = tick; + thermalYear = year; Contact = String.Format("{0} Thermal Signature {1}", Contact, DetectedShip.CurrentThermalSignature); } if (EM == true) { EMTick = tick; + EMYear = year; Contact = String.Format("{0} EM Signature {1}", Contact, EMSignature); } if (active == true) { activeTick = tick; + activeYear = year; Contact = String.Format("{0} TCS {1}", Contact, DetectedShip.TotalCrossSection); } @@ -126,7 +137,7 @@ public FactionContact(Faction CurrentFaction, ShipTN DetectedShip, bool Thermal, /// Detection via EM? /// Active detection? /// What tick did this detection event occur on? - public FactionContact(Faction CurrentFaction, OrdnanceGroupTN DetectedMissileGroup, bool Thermal, bool em, bool Active, uint tick) + public FactionContact(Faction CurrentFaction, OrdnanceGroupTN DetectedMissileGroup, bool Thermal, bool em, bool Active, uint tick, uint year) { missileGroup = DetectedMissileGroup; ship = null; @@ -142,12 +153,14 @@ public FactionContact(Faction CurrentFaction, OrdnanceGroupTN DetectedMissileGro if (thermal == true) { thermalTick = tick; + thermalYear = year; Contact = String.Format("{0} Thermal Signature {1} x{2}", Contact, (int)Math.Ceiling(DetectedMissileGroup.missiles[0].missileDef.totalThermalSignature), DetectedMissileGroup.missiles.Count); } if (EM == true) { EMTick = tick; + EMYear = year; if (DetectedMissileGroup.missiles[0].missileDef.aSD != null) { EMSignature = DetectedMissileGroup.missiles[0].missileDef.aSD.gps; @@ -167,6 +180,7 @@ public FactionContact(Faction CurrentFaction, OrdnanceGroupTN DetectedMissileGro if (active == true) { activeTick = tick; + activeYear = year; Contact = String.Format("{0} TCS {1} x{2}", Contact, (int)Math.Ceiling(DetectedMissileGroup.missiles[0].missileDef.size), DetectedMissileGroup.missiles.Count); } @@ -193,7 +207,7 @@ public FactionContact(Faction CurrentFaction, OrdnanceGroupTN DetectedMissileGro /// Was it detected via em? /// was this population detected via actives? /// Tick this happened on. - public FactionContact(Faction CurrentFaction, Population DetectedPopulation, bool Thermal, bool em, bool Active, uint tick) + public FactionContact(Faction CurrentFaction, Population DetectedPopulation, bool Thermal, bool em, bool Active, uint tick, uint year) { pop = DetectedPopulation; ship = null; @@ -208,18 +222,21 @@ public FactionContact(Faction CurrentFaction, Population DetectedPopulation, boo if (thermal == true) { thermalTick = tick; + thermalYear = year; Contact = String.Format("{0} Thermal Signature {1}", Contact, pop.ThermalSignature); } if (EM == true) { EMTick = tick; + EMYear = year; Contact = String.Format("{0} EM Signature {1}", Contact, EMSignature); } if (active == true) { activeTick = tick; + activeYear = year; Contact = String.Format("{0} Active Ping", Contact); } @@ -244,7 +261,7 @@ public FactionContact(Faction CurrentFaction, Population DetectedPopulation, boo /// Detected on EM? /// Detected by actives? /// Current tick. - public void updateFactionContact(Faction CurrentFaction, bool Thermal, bool Em, int EMSig, bool Active, uint tick) + public void updateFactionContact(Faction CurrentFaction, bool Thermal, bool Em, int EMSig, bool Active, uint tick, uint year) { if (thermal == Thermal && EM == Em && active == Active) { @@ -270,6 +287,7 @@ public void updateFactionContact(Faction CurrentFaction, bool Thermal, bool Em, /// New thermal detection event, message logic should be here. /// thermalTick = tick; + thermalYear = year; if (ship != null) Contact = String.Format("{0} Thermal Signature {1}", Contact, ship.CurrentThermalSignature); @@ -297,6 +315,7 @@ public void updateFactionContact(Faction CurrentFaction, bool Thermal, bool Em, /// New EM detection event, message logic should be here. /// EMTick = tick; + EMYear = year; EMSignature = EMSig; @@ -338,8 +357,7 @@ public void updateFactionContact(Faction CurrentFaction, bool Thermal, bool Em, /// New active detection event, message logic should be here. /// activeTick = tick; - - + activeYear = year; if (ship != null) Contact = String.Format("{0} TCS {1}", Contact, ship.TotalCrossSection); @@ -440,17 +458,24 @@ public class FactionSystemDetection /// /// Last time this contact index was spotted via thermals. /// - public BindingList Thermal { get; set; } + private BindingList Thermal { get; set; } /// /// Last time this contact index was spotted via EM. /// - public BindingList EM { get; set; } + private BindingList EM { get; set; } /// /// Last time this contact index was spotted via Active. /// - public BindingList Active { get; set; } + private BindingList Active { get; set; } + + /// + /// Year value for when this contact index was spotted. change to time value away from ticks and towards actual time necessitates this change. + /// + private BindingList ThermalYear { get; set; } + private BindingList EMYear { get; set; } + private BindingList ActiveYear { get; set; } /// /// Creates a faction contact list for the specified system. @@ -465,24 +490,40 @@ public FactionSystemDetection(Faction Fact, StarSystem system) EM = new BindingList(); Active = new BindingList(); + ThermalYear = new BindingList(); + EMYear = new BindingList(); + ActiveYear = new BindingList(); + Thermal.RaiseListChangedEvents = false; EM.RaiseListChangedEvents = false; Active.RaiseListChangedEvents = false; - + ThermalYear.RaiseListChangedEvents = false; + EMYear.RaiseListChangedEvents = false; + ActiveYear.RaiseListChangedEvents = false; for (int loop = 0; loop < system.SystemContactList.Count; loop++) { Thermal.Add(0); + ThermalYear.Add(0); EM.Add(0); + EMYear.Add(0); Active.Add(0); + ActiveYear.Add(0); } Thermal.RaiseListChangedEvents = true; EM.RaiseListChangedEvents = true; Active.RaiseListChangedEvents = true; + ThermalYear.RaiseListChangedEvents = true; + EMYear.RaiseListChangedEvents = true; + ActiveYear.RaiseListChangedEvents = true; Thermal.ResetBindings(); EM.ResetBindings(); Active.ResetBindings(); + + ThermalYear.ResetBindings(); + EMYear.ResetBindings(); + ActiveYear.ResetBindings(); } /// @@ -491,8 +532,12 @@ public FactionSystemDetection(Faction Fact, StarSystem system) public void AddContact() { Thermal.Add(0); + ThermalYear.Add(0); EM.Add(0); + EMYear.Add(0); Active.Add(0); + ActiveYear.Add(0); + } /// @@ -502,8 +547,120 @@ public void AddContact() public void RemoveContact(int RemIndex) { Thermal.RemoveAt(RemIndex); + ThermalYear.RemoveAt(RemIndex); EM.RemoveAt(RemIndex); + EMYear.RemoveAt(RemIndex); Active.RemoveAt(RemIndex); + ActiveYear.RemoveAt(RemIndex); + } + + /// + /// Check all detection characteristics to see if this contact is detected this tick + /// + /// place of this contact + /// current second + /// current year + /// True if any detection characteristic does not match, meaning this contact has not yet been fully detected this tick. false if this contact has been fully detected, and subsequent detections should not be run. + public bool CheckIfNotDetected(int Index, int tick, int year) + { + if ((Thermal[Index] != tick || ThermalYear[Index] != year) || (EM[Index] != tick || EMYear[Index] != year) || (Active[Index] != tick || ActiveYear[Index] != year)) + { + return true; + } + return false; + } + + /// + /// Was this contact detected via thermal this tick? + /// + /// + /// + /// + /// + public bool CheckThermal(int Index, int tick, int year) + { + if (Thermal[Index] == tick && ThermalYear[Index] == year) + { + return true; + } + return false; + } + + /// + /// Was this contact detected via EM this tick? + /// + /// + /// + /// + /// + public bool CheckEM(int Index, int tick, int year) + { + if (EM[Index] == tick && EMYear[Index] == year) + { + return true; + } + return false; + } + + /// + /// Was this contact detected via active search sensors this tick? + /// + /// + /// + /// + /// + public bool CheckActive(int Index, int tick, int year) + { + if (Active[Index] == tick && ActiveYear[Index] == year) + { + return true; + } + return false; + } + + /// + /// Set this contact as detected via thermal + /// + /// faction detecting + /// current second + /// current year + public void SetThermalDetection(int Index, int tick, int year) + { + Thermal[Index] = tick; + ThermalYear[Index] = year; + } + + /// + /// Set this contact as detected via EM + /// + /// faction detecting + /// current second + /// current year + public void SetEMDetection(int Index, int tick, int year) + { + EM[Index] = tick; + EMYear[Index] = year; + } + + /// + /// Set this contact as detected via active + /// + /// faction detecting + /// current second + /// current year + public void SetActiveDetection(int Index, int tick, int year) + { + Active[Index] = tick; + ActiveYear[Index] = year; + } + + /// + /// How many contacts are there? + /// + /// count of thermal contacts, all should be the same. + public int GetDetectionCount() + { + return Thermal.Count; } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs index ad837a11d..fe6669183 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs @@ -295,6 +295,13 @@ public enum ShipType public BindingList EMDetection { get; set; } public BindingList ActiveDetection { get; set; } + /// + /// change to how tick works means that year must also be recorded. + /// + private BindingList ThermalYearDetection { get; set; } + private BindingList EMYearDetection { get; set; } + private BindingList ActiveYearDetection { get; set; } + /// /// Each ship will store its placement in the overall taskgroup. /// @@ -739,11 +746,18 @@ public ShipTN(ShipClassTN ClassDefinition, int ShipIndex, int CurrentTimeSlice, EMDetection = new BindingList(); ActiveDetection = new BindingList(); + ThermalYearDetection = new BindingList(); + EMYearDetection = new BindingList(); + ActiveYearDetection = new BindingList(); + for (int loop = 0; loop < Constants.Faction.FactionMax; loop++) { ThermalDetection.Add(CurrentTimeSlice); EMDetection.Add(CurrentTimeSlice); ActiveDetection.Add(CurrentTimeSlice); + ThermalYearDetection.Add(GameState.Instance.CurrentYear); + EMYearDetection.Add(GameState.Instance.CurrentYear); + ActiveYearDetection.Add(GameState.Instance.CurrentYear); } ShipCommanded = false; @@ -3449,6 +3463,7 @@ public int RechargeCIWS() } #endregion + #region Ship jump functionality /// /// Reduce the jump sickness of this ship. if it is zero the ship is no longer sick /// @@ -3493,6 +3508,93 @@ public void SquadronTransit() { JumpSickness = Constants.JumpEngineTN.SquadronTransitPenalty; } + #endregion + + #region Ship detection setting and getting + /// + /// Is this ship detected this tick via thermal? + /// + /// by which faction + /// current second + /// current year + /// true = yes, false = no + public bool IsDetectedThermal(int FactionID, int tick, int year) + { + if (ThermalDetection[FactionID] == tick && ThermalYearDetection[FactionID] == year) + { + return true; + } + return false; + } + + /// + /// Is this ship detected this tick via em? + /// + /// by which faction + /// current second + /// current year + /// true = yes, false = no + public bool IsDetectedEM(int FactionID, int tick, int year) + { + if (EMDetection[FactionID] == tick && EMYearDetection[FactionID] == year) + { + return true; + } + return false; + } + + /// + /// Is this ship detected this tick via active? + /// + /// by which faction + /// current second + /// current year + /// true = yes, false = no + public bool IsDetectedActive(int FactionID, int tick, int year) + { + if (ActiveDetection[FactionID] == tick && ActiveYearDetection[FactionID] == year) + { + return true; + } + return false; + } + + /// + /// Set this ship as detected via thermal + /// + /// faction detecting + /// current second + /// current year + public void SetThermalDetection(int FactionID, int tick, int year) + { + ThermalDetection[FactionID] = tick; + ThermalYearDetection[FactionID] = year; + } + + /// + /// Set this ship as detected via em + /// + /// faction detecting + /// current second + /// current year + public void SetEMDetection(int FactionID, int tick, int year) + { + EMDetection[FactionID] = tick; + EMYearDetection[FactionID] = year; + } + + /// + /// Set this ship as detected via active. really should have made detectableEntity a class that ships, populations, and ordnance groups inherit from. + /// + /// faction detecting + /// current second + /// current year + public void SetActiveDetection(int FactionID, int tick, int year) + { + ActiveDetection[FactionID] = tick; + ActiveYearDetection[FactionID] = year; + } + #endregion } /// /// End of ShipTN class @@ -3526,9 +3628,6 @@ public PointDefenseList() PointDefenseType = new Dictionary(); } - -#warning When jump transits are fully implemented, PointDefenseFC listings will have to be moved as appropriate, be sure to handle that. - /// /// Handles adding a new FC to the list. /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs b/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs index 63915085f..124bcbc38 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs @@ -536,6 +536,7 @@ public void AdvanceSim(BindingList P, Random RNG, int deltaSeconds) { GameState.Instance.CurrentSecond += deltaSeconds; ConstructionTick += deltaSeconds; + GameState.Instance.LastTimestep = deltaSeconds; foreach (StarSystem CurrentSystem in GameState.Instance.StarSystems) { diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs index 2706966bc..4d602a408 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs @@ -335,17 +335,24 @@ public enum PoliticalStatus /// /// Which factions have detected a thermal sig from this population? /// - public BindingList ThermalDetection { get; set; } + private BindingList ThermalDetection { get; set; } /// /// Which factions have detected an EM signature? /// - public BindingList EMDetection { get; set; } + private BindingList EMDetection { get; set; } /// /// Any active sensor in range detects a planet. /// - public BindingList ActiveDetection { get; set; } + private BindingList ActiveDetection { get; set; } + + /// + /// change to how tick works means that year must also be recorded. + /// + private BindingList ThermalYearDetection { get; set; } + private BindingList EMYearDetection { get; set; } + private BindingList ActiveYearDetection { get; set; } /// /// Populations with structures tend to emit a thermal signature. 5 per installation I believe. @@ -633,12 +640,18 @@ public Population(SystemBody a_oPlanet, Faction a_oFaction, int CurrentTimeSlice ThermalDetection = new BindingList(); EMDetection = new BindingList(); ActiveDetection = new BindingList(); + ThermalYearDetection = new BindingList(); + EMYearDetection = new BindingList(); + ActiveYearDetection = new BindingList(); for (int loop = 0; loop < Constants.Faction.FactionMax; loop++) { ThermalDetection.Add(CurrentTimeSlice); EMDetection.Add(CurrentTimeSlice); ActiveDetection.Add(CurrentTimeSlice); + ThermalYearDetection.Add(GameState.Instance.CurrentYear); + EMYearDetection.Add(GameState.Instance.CurrentYear); + ActiveYearDetection.Add(GameState.Instance.CurrentYear); } ShipsTargetting = new BindingList(); @@ -1127,6 +1140,91 @@ public int CalcEMSignature() EMSignature = signature; return signature; } + + /// + /// Is this planet detected this tick? + /// + /// by which faction + /// current second + /// current year + /// true = yes, false = no + public bool IsDetectedThermal(int FactionID, int tick, int year) + { + if (ThermalDetection[FactionID] == tick && ThermalYearDetection[FactionID] == year) + { + return true; + } + return false; + } + + /// + /// Is this planet detected this tick? + /// + /// by which faction + /// current second + /// current year + /// true = yes, false = no + public bool IsDetectedEM(int FactionID, int tick, int year) + { + if (EMDetection[FactionID] == tick && EMYearDetection[FactionID] == year) + { + return true; + } + return false; + } + + /// + /// Is this planet detected this tick? + /// + /// by which faction + /// current second + /// current year + /// true = yes, false = no + public bool IsDetectedActive(int FactionID, int tick, int year) + { + if (ActiveDetection[FactionID] == tick && ActiveYearDetection[FactionID] == year) + { + return true; + } + return false; + } + + /// + /// Set this planet as detected + /// + /// faction detecting + /// current second + /// current year + public void SetThermalDetection(int FactionID, int tick, int year) + { + ThermalDetection[FactionID] = tick; + ThermalYearDetection[FactionID] = year; + } + + /// + /// Set this planet as detected + /// + /// faction detecting + /// current second + /// current year + public void SetEMDetection(int FactionID, int tick, int year) + { + EMDetection[FactionID] = tick; + EMYearDetection[FactionID] = year; + } + + /// + /// Set this planet as detected + /// + /// faction detecting + /// current second + /// current year + public void SetActiveDetection(int FactionID, int tick, int year) + { + ActiveDetection[FactionID] = tick; + ActiveYearDetection[FactionID] = year; + } + #endregion #region Build Queue From f73e7f5ec5d0f520f2161b4776657405a0698bd4 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 13 Feb 2016 09:25:57 -0600 Subject: [PATCH 33/40] Jump orders fix and others when jumping to a new system, CanOrder was not properly being set to AcceptOrders, this is fixed. likewise the homeworld mineral generation kludge was removed, and now body mineral generation is handled in systembody.cs for the most part. Construction factories were costing Corrundum instead of vendarite, that is fixed for when that all gets moved to a json file. Ships failing 1 conditional order do not warn if another conditional succeeds now, and warnings for no geosurvey target are now correctly labeled as geosurvey target failures. --- .../Pulsar4X.Lib/Entities/Installation.cs | 4 +- .../Entities/StarSystem/TaskGroup.cs | 77 ++++++++++++++++--- Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs | 4 +- 3 files changed, 68 insertions(+), 17 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs index edd629915..3c0dd0bd8 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs @@ -900,7 +900,7 @@ public Installation(InstallationType a_eType) Cost = 120; m_aiMinerialsCost[(int)Constants.Minerals.MinerialNames.Duranium] = 60; m_aiMinerialsCost[(int)Constants.Minerals.MinerialNames.Tritanium] = 30; - m_aiMinerialsCost[(int)Constants.Minerals.MinerialNames.Corundium] = 30; + m_aiMinerialsCost[(int)Constants.Minerals.MinerialNames.Vendarite] = 30; ThermalSignature = 5; EMSignature = 5; RequiredTechnology = Faction.FactionTechnology.TransNewtonianTech; @@ -929,7 +929,7 @@ public Installation(InstallationType a_eType) Cost = 20; m_aiMinerialsCost[(int)Constants.Minerals.MinerialNames.Duranium] = 10; m_aiMinerialsCost[(int)Constants.Minerals.MinerialNames.Tritanium] = 5; - m_aiMinerialsCost[(int)Constants.Minerals.MinerialNames.Corundium] = 5; + m_aiMinerialsCost[(int)Constants.Minerals.MinerialNames.Vendarite] = 5; ThermalSignature = 5; EMSignature = 5; RequiredTechnology = Faction.FactionTechnology.TransNewtonianTech; diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index b4ab905a5..66e2903ea 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -1909,6 +1909,9 @@ public void IssueOrder(Order OrderToTaskGroup, int index = -1) } else { + /// + /// JPDetection also stores geo survey results. + /// JPDetection NewDetection = new JPDetection(); Contact.Position.System._SurveyResults.Add(TaskGroupFaction, NewDetection); Contact.Position.System._SurveyResults[TaskGroupFaction]._GeoSurveyInProgress.Add(OrderToTaskGroup.body); @@ -1966,6 +1969,24 @@ public void RemoveOrder(int orderIndex, bool SkipCheck = false) } } + /// + /// If we just jumped through an unknown gate, allow orders again, same with following. + /// + if (CanOrder == Constants.ShipTN.OrderState.DisallowOrdersUnknownJump) + { + if (TaskGroupOrders[orderIndex].typeOf == Constants.ShipTN.OrderType.StandardTransit || + TaskGroupOrders[orderIndex].typeOf == Constants.ShipTN.OrderType.SquadronTransit || + TaskGroupOrders[orderIndex].typeOf == Constants.ShipTN.OrderType.TransitAndDivide) + { + CanOrder = Constants.ShipTN.OrderState.AcceptOrders; + } + } + else if (CanOrder == Constants.ShipTN.OrderState.DisallowOrdersFollowingTarget) + { + if (TaskGroupOrders[orderIndex].typeOf == Constants.ShipTN.OrderType.Follow) + CanOrder = Constants.ShipTN.OrderState.AcceptOrders; + } + TaskGroupOrders.RemoveAt(orderIndex); } @@ -1986,6 +2007,24 @@ public void RemoveOrder(Order orderToRemove) } } + /// + /// If we just jumped through an unknown gate, allow orders again, same with following. + /// + if (CanOrder == Constants.ShipTN.OrderState.DisallowOrdersUnknownJump) + { + if (orderToRemove.typeOf == Constants.ShipTN.OrderType.StandardTransit || + orderToRemove.typeOf == Constants.ShipTN.OrderType.SquadronTransit || + orderToRemove.typeOf == Constants.ShipTN.OrderType.TransitAndDivide) + { + CanOrder = Constants.ShipTN.OrderState.AcceptOrders; + } + } + else if (CanOrder == Constants.ShipTN.OrderState.DisallowOrdersFollowingTarget) + { + if (orderToRemove.typeOf == Constants.ShipTN.OrderType.Follow) + CanOrder = Constants.ShipTN.OrderState.AcceptOrders; + } + TaskGroupOrders.Remove(orderToRemove); } @@ -3191,6 +3230,8 @@ public uint PerformOrders(uint TimeSlice) /// public void ProcessDefaultOrders() { + bool noGeo = false; + bool noGrav = false; foreach(Constants.ShipTN.DefaultOrders DO in _SpecialOrders._DefaultOrdersList) { if (DO == Constants.ShipTN.DefaultOrders.NoSpecialOrder) @@ -3257,12 +3298,7 @@ public void ProcessDefaultOrders() if (lowestDistance == -1.0f) { - /// - /// No suitable target was found. - /// - String Entry = String.Format("No suitable geo survey target for {0} in {1}", Name, Contact.Position.System); - MessageEntry NME = new MessageEntry(MessageEntry.MessageType.NoGravSurveyTarget, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); - TaskGroupFaction.MessageLog.Add(NME); + noGeo = true; } else { @@ -3324,12 +3360,7 @@ public void ProcessDefaultOrders() if (lowestDistance == -1.0f) { - /// - /// No suitable target was found. - /// - String Entry = String.Format("No suitable grav survey target for {0} in {1}", Name, Contact.Position.System); - MessageEntry NME = new MessageEntry(MessageEntry.MessageType.NoGravSurveyTarget, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); - TaskGroupFaction.MessageLog.Add(NME); + noGrav = true; } else { @@ -3345,6 +3376,28 @@ public void ProcessDefaultOrders() #endregion } } + + /// + /// If 1 conditional order fails, but another succeeds don't print the warnings yet. this may get bloated. + /// + if (noGeo == true) + { + /// + /// No suitable target was found. + /// + String Entry = String.Format("No suitable geo survey target for {0} in {1}", Name, Contact.Position.System); + MessageEntry NME = new MessageEntry(MessageEntry.MessageType.NoGeoSurveyTarget, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); + TaskGroupFaction.MessageLog.Add(NME); + } + if (noGrav == true) + { + /// + /// No suitable target was found. + /// + String Entry = String.Format("No suitable grav survey target for {0} in {1}", Name, Contact.Position.System); + MessageEntry NME = new MessageEntry(MessageEntry.MessageType.NoGravSurveyTarget, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); + TaskGroupFaction.MessageLog.Add(NME); + } } /// diff --git a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs index b3334d533..f2f9de1cb 100644 --- a/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs +++ b/Pulsar4X/Pulsar4X.Lib/SystemGen/SystemGen.cs @@ -1060,6 +1060,7 @@ private static void SortPlanetList(List list) /// /// Minerials: Currently an ugly hack of using homworld minerials. Note that minerial generation /// functions should be part of the SystemBody class as the player will likly want to re-generate them. + /// Update: mineral generation is done by surveying when the planet is surveyed, not here. see systemBody.cs for details. /// /// /// Moons: If we a generating a planet we genmerate moons using GenerateMoons(). @@ -1113,9 +1114,6 @@ private static void FinalizeSystemBodyGeneration(Star star, SystemBody body, Sys // Generate Ruins, note that it will only do so for suitable planets: GenerateRuins(star, body); - - ///< @todo Generate Minerials Properly instead of this ugly hack: - body.HomeworldMineralGeneration(); // generate moons if required for this body type: if (IsPlanet(body.Type)) From 3901745627bd6f0ee6f06f6b941c58475a4f9b91 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 20 Feb 2016 08:44:07 -0600 Subject: [PATCH 34/40] Installation and Mineral load UI work Now installations and minerals can be selected to be loaded to a freighter, the work to implement such an order is not yet completed however. Also a divide by zero with taskgroup pathing was discovered and fixed. --- Pulsar4X/Pulsar4X.Lib/Constants.cs | 16 ++ .../Entities/StarSystem/TaskGroup.cs | 26 +- Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs | 100 +++++++ .../Panels/TaskGroup_Panel.Designer.cs | 254 ++++++++++-------- 4 files changed, 288 insertions(+), 108 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Constants.cs b/Pulsar4X/Pulsar4X.Lib/Constants.cs index 534548d5b..453c6cdb0 100644 --- a/Pulsar4X/Pulsar4X.Lib/Constants.cs +++ b/Pulsar4X/Pulsar4X.Lib/Constants.cs @@ -361,8 +361,10 @@ public enum OrderType /// LoadInstallation, LoadShipComponent, + LoadPDCPart, UnloadInstallation, UnloadShipComponent, + UnloadPDCPart, UnloadAll, LoadAllMinerals, UnloadAllMinerals, @@ -444,6 +446,20 @@ public enum OrderType TractorSpecifiedShipyard, ReleaseAt, + /// + /// Transport equipped ships + /// + LoadGroundUnit, + UnloadGroundUnit, + + /// + /// Any ship can carry teams or commanders. + /// + LoadCommander, + LoadTeam, + UnloadCommander, + UnloadTeam, + /// /// Number of orders available. /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index 66e2903ea..ea6173854 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -1595,8 +1595,30 @@ public void GetHeading() dY = Contact.Position.Y - TaskGroupOrders[0].target.Position.Y; break; } - - CurrentHeading = Pulsar4X.Helpers.GameMath.Angle.ToDegrees(Math.Atan(dY / dX)); + /// + /// Do yourself a favor and don't divide by zero here. if X is exactly the same then we either want to go up or down, depending on the sign of dY. if dX and dY are both zero then currentHeading + /// doesn't matter and can be set to 0.0. + /// + if (dY == 0.0 && dX == 0.0) + { + CurrentHeading = 0.0; + } + else if (dY == 0.0) + { + if (dX > 0.0) + CurrentHeading = 0.0; + else if (dX < 0.0) + CurrentHeading = 180.0; + } + else + { + if (dX != 0.0) + CurrentHeading = Pulsar4X.Helpers.GameMath.Angle.ToDegrees(Math.Atan(dY / dX)); + else if (dY > 0.0) + CurrentHeading = 270.0; + else if (dY < 0.0) + CurrentHeading = 90.0; + } } else CurrentHeading = 0.0; diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs index b1f8b8951..13a2bea2f 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs @@ -220,6 +220,7 @@ public TaskGroup() m_oTaskGroupPanel.CurrentTDRadioButton.CheckedChanged += new EventHandler(CurrentTDRadioButton_CheckChanged); m_oTaskGroupPanel.AllOrdersTDRadioButton.CheckedChanged += new EventHandler(AllOrdersTDRadioButton_CheckChanged); + m_oTaskGroupPanel.AvailableActionsListBox.MouseClick += new MouseEventHandler(AvailableActionsListBox_MouseClick); m_oTaskGroupPanel.AvailableActionsListBox.MouseDoubleClick += new MouseEventHandler(AddMoveButton_Clicked); m_oTaskGroupPanel.SystemLocationsListBox.MouseDoubleClick += new MouseEventHandler(AddMoveButton_Clicked); m_oTaskGroupPanel.PlottedMovesListBox.MouseDoubleClick += new MouseEventHandler(RemoveButton_Clicked); @@ -539,6 +540,105 @@ private void AddMoveButton_Clicked(object sender, EventArgs e) CalculateTimeDistance(); } + /// + /// If an appropriate action is selected, make the Taskgroup secondary listbox visible and populate it. + /// + /// + /// + private void AvailableActionsListBox_MouseClick(object sender, EventArgs e) + { + /// + /// Planets, Contacts, TG, WP + /// + int PlaceIndex = m_oTaskGroupPanel.SystemLocationsListBox.SelectedIndex; + + /// + /// If AddMove is clicked with no system location it will bomb. + /// + if (PlaceIndex != -1) + { + List GID = SystemLocationGuidDict.Keys.ToList(); + SystemListObject selected = SystemLocationDict[GID[PlaceIndex]]; + + int ActionIndex = m_oTaskGroupPanel.AvailableActionsListBox.SelectedIndex; + if (ActionIndex != -1) + { + Constants.ShipTN.OrderType selected_ordertype = (Constants.ShipTN.OrderType)m_oTaskGroupPanel.AvailableActionsListBox.SelectedItem; + + /// + /// Now figure out what the hell order this would be. + /// + var entity = selected.Entity; + var etype = selected.EntityType; + + switch (selected_ordertype) + { + case Constants.ShipTN.OrderType.LoadInstallation: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Installation"; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Clear(); + foreach (Installation inst in (selected.Entity as Population).Installations) + { + if (inst.Number >= 1.0f && inst.Type != Installation.InstallationType.ConventionalIndustry && + inst.Type != Installation.InstallationType.CivilianMiningComplex && inst.Type != Installation.InstallationType.MilitaryAcademy && + inst.Type != Installation.InstallationType.SectorCommand && inst.Type != Installation.InstallationType.Spaceport && + inst.Type != Installation.InstallationType.CommercialShipyard && inst.Type != Installation.InstallationType.NavalShipyardComplex) + { + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Add(inst.Type); + } + } + break; + case Constants.ShipTN.OrderType.LoadMineral: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Mineral"; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Clear(); + for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) + { + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Add(((Constants.Minerals.MinerialNames)mineralIterator).ToString()); + } + break; +#warning All of the rest of these load types need to be implemented + case Constants.ShipTN.OrderType.LoadMineralWhenX: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Mineral"; + break; + case Constants.ShipTN.OrderType.LoadShipComponent: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Component"; + break; + case Constants.ShipTN.OrderType.LoadPDCPart: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select PDC Part"; + break; + case Constants.ShipTN.OrderType.LoadGroundUnit: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Ground Unit"; + break; + case Constants.ShipTN.OrderType.LoadCommander: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Commander"; + break; + case Constants.ShipTN.OrderType.LoadTeam: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Team"; + break; + default: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = false; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = false; + break; + } + } + } + } + /// /// Removes the selected order. /// diff --git a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs index 10295a503..b201eaa8e 100644 --- a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs +++ b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs @@ -89,6 +89,22 @@ public ListBox PlottedMovesListBox get { return m_oPlottedMoveListBox; } } + /// + /// Secondary orders listbox: minerals, installation, ground units, commanders, teams, pdc parts, and anything else. + /// + public ListBox TaskgroupSecondaryListBox + { + get { return m_oTaskgroupSecondaryListBox; } + } + + /// + /// Secondary orders groupbox: will have text for the above. + /// + public GroupBox TaskgroupSecondaryGroupBox + { + get { return m_oTaskGroupSecondaryGroupBox; } + } + /// /// Should detected contacts be displayed? /// @@ -402,6 +418,8 @@ private void InitializeComponent() this.m_oMatchSpeedsCheckBox = new System.Windows.Forms.CheckBox(); this.m_oCopyOrdersToSubordinateButton = new System.Windows.Forms.Button(); this.m_oCondOrderAGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oCondAOrderLabel = new System.Windows.Forms.Label(); + this.m_oCondACondLabel = new System.Windows.Forms.Label(); this.m_oCondAOrderComboBox = new System.Windows.Forms.ComboBox(); this.m_oCondAConditionComboBox = new System.Windows.Forms.ComboBox(); this.m_oSuperiorFormationGroupBox = new System.Windows.Forms.GroupBox(); @@ -411,12 +429,21 @@ private void InitializeComponent() this.m_oSaveCombineButton = new System.Windows.Forms.Button(); this.m_oCombineTaskgroupsComboBox = new System.Windows.Forms.ComboBox(); this.m_oCondOrderBGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oCondBOrderLabel = new System.Windows.Forms.Label(); + this.m_oCondBCondLabel = new System.Windows.Forms.Label(); this.m_oCondBOrderComboBox = new System.Windows.Forms.ComboBox(); this.m_oCondBConditionComboBox = new System.Windows.Forms.ComboBox(); this.m_oDefaultOrderGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oDefaultSecondaryLabel = new System.Windows.Forms.Label(); + this.m_oDefaultPrimaryLabel = new System.Windows.Forms.Label(); this.m_oSecondaryDefaultOrdersComboBox = new System.Windows.Forms.ComboBox(); this.m_oPrimaryDefaultOrdersComboBox = new System.Windows.Forms.ComboBox(); this.m_oProtectThreatAxisGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oBearingThreatLabel = new System.Windows.Forms.Label(); + this.m_oOffsetthreatLabel = new System.Windows.Forms.Label(); + this.m_oThreatDistanceLabel = new System.Windows.Forms.Label(); + this.m_oTaskGroupThreatLabel = new System.Windows.Forms.Label(); + this.m_oThreatLabel = new System.Windows.Forms.Label(); this.comboBox12 = new System.Windows.Forms.ComboBox(); this.comboBox11 = new System.Windows.Forms.ComboBox(); this.comboBox10 = new System.Windows.Forms.ComboBox(); @@ -470,17 +497,8 @@ private void InitializeComponent() this.m_oAddColonyButton = new System.Windows.Forms.Button(); this.m_oSystemMapButton = new System.Windows.Forms.Button(); this.m_oNewTGButton = new System.Windows.Forms.Button(); - this.m_oDefaultPrimaryLabel = new System.Windows.Forms.Label(); - this.m_oDefaultSecondaryLabel = new System.Windows.Forms.Label(); - this.m_oCondACondLabel = new System.Windows.Forms.Label(); - this.m_oCondAOrderLabel = new System.Windows.Forms.Label(); - this.m_oCondBCondLabel = new System.Windows.Forms.Label(); - this.m_oCondBOrderLabel = new System.Windows.Forms.Label(); - this.m_oThreatLabel = new System.Windows.Forms.Label(); - this.m_oTaskGroupThreatLabel = new System.Windows.Forms.Label(); - this.m_oThreatDistanceLabel = new System.Windows.Forms.Label(); - this.m_oOffsetthreatLabel = new System.Windows.Forms.Label(); - this.m_oBearingThreatLabel = new System.Windows.Forms.Label(); + this.m_oTaskGroupSecondaryGroupBox = new System.Windows.Forms.GroupBox(); + this.m_oTaskgroupSecondaryListBox = new System.Windows.Forms.ListBox(); this.m_oGeneralTGDetailsBox.SuspendLayout(); this.m_oTaskGroupTabControl.SuspendLayout(); this.m_oTaskGroupOrdersTabPage.SuspendLayout(); @@ -513,6 +531,7 @@ private void InitializeComponent() this.m_oCenterShowGF.SuspendLayout(); this.m_oSpeedBox.SuspendLayout(); this.m_oButtonBox.SuspendLayout(); + this.m_oTaskGroupSecondaryGroupBox.SuspendLayout(); this.SuspendLayout(); // // m_oTaskGroupName @@ -932,6 +951,7 @@ private void InitializeComponent() this.m_oTaskGroupOrdersBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); this.m_oTaskGroupOrdersBox.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.m_oTaskGroupOrdersBox.Controls.Add(this.m_oTaskGroupSecondaryGroupBox); this.m_oTaskGroupOrdersBox.Controls.Add(this.m_oRepeatOrdersTextBox); this.m_oTaskGroupOrdersBox.Controls.Add(this.m_oRepeatOrderButton); this.m_oTaskGroupOrdersBox.Controls.Add(this.m_oCycleMovesCheckBox); @@ -1525,6 +1545,24 @@ private void InitializeComponent() this.m_oCondOrderAGroupBox.TabStop = false; this.m_oCondOrderAGroupBox.Text = "Conditional Order A(act on order if condition is met)"; // + // m_oCondAOrderLabel + // + this.m_oCondAOrderLabel.AutoSize = true; + this.m_oCondAOrderLabel.Location = new System.Drawing.Point(6, 61); + this.m_oCondAOrderLabel.Name = "m_oCondAOrderLabel"; + this.m_oCondAOrderLabel.Size = new System.Drawing.Size(33, 13); + this.m_oCondAOrderLabel.TabIndex = 5; + this.m_oCondAOrderLabel.Text = "Order"; + // + // m_oCondACondLabel + // + this.m_oCondACondLabel.AutoSize = true; + this.m_oCondACondLabel.Location = new System.Drawing.Point(6, 26); + this.m_oCondACondLabel.Name = "m_oCondACondLabel"; + this.m_oCondACondLabel.Size = new System.Drawing.Size(51, 13); + this.m_oCondACondLabel.TabIndex = 4; + this.m_oCondACondLabel.Text = "Condition"; + // // m_oCondAOrderComboBox // this.m_oCondAOrderComboBox.FormattingEnabled = true; @@ -1614,6 +1652,24 @@ private void InitializeComponent() this.m_oCondOrderBGroupBox.TabStop = false; this.m_oCondOrderBGroupBox.Text = "Conditional Order B(act on order if condition is met)"; // + // m_oCondBOrderLabel + // + this.m_oCondBOrderLabel.AutoSize = true; + this.m_oCondBOrderLabel.Location = new System.Drawing.Point(6, 61); + this.m_oCondBOrderLabel.Name = "m_oCondBOrderLabel"; + this.m_oCondBOrderLabel.Size = new System.Drawing.Size(33, 13); + this.m_oCondBOrderLabel.TabIndex = 7; + this.m_oCondBOrderLabel.Text = "Order"; + // + // m_oCondBCondLabel + // + this.m_oCondBCondLabel.AutoSize = true; + this.m_oCondBCondLabel.Location = new System.Drawing.Point(6, 24); + this.m_oCondBCondLabel.Name = "m_oCondBCondLabel"; + this.m_oCondBCondLabel.Size = new System.Drawing.Size(51, 13); + this.m_oCondBCondLabel.TabIndex = 6; + this.m_oCondBCondLabel.Text = "Condition"; + // // m_oCondBOrderComboBox // this.m_oCondBOrderComboBox.FormattingEnabled = true; @@ -1645,6 +1701,24 @@ private void InitializeComponent() this.m_oDefaultOrderGroupBox.TabStop = false; this.m_oDefaultOrderGroupBox.Text = "Default Orders(if no other orders are set)"; // + // m_oDefaultSecondaryLabel + // + this.m_oDefaultSecondaryLabel.AutoSize = true; + this.m_oDefaultSecondaryLabel.Location = new System.Drawing.Point(6, 61); + this.m_oDefaultSecondaryLabel.Name = "m_oDefaultSecondaryLabel"; + this.m_oDefaultSecondaryLabel.Size = new System.Drawing.Size(58, 13); + this.m_oDefaultSecondaryLabel.TabIndex = 3; + this.m_oDefaultSecondaryLabel.Text = "Secondary"; + // + // m_oDefaultPrimaryLabel + // + this.m_oDefaultPrimaryLabel.AutoSize = true; + this.m_oDefaultPrimaryLabel.Location = new System.Drawing.Point(6, 26); + this.m_oDefaultPrimaryLabel.Name = "m_oDefaultPrimaryLabel"; + this.m_oDefaultPrimaryLabel.Size = new System.Drawing.Size(41, 13); + this.m_oDefaultPrimaryLabel.TabIndex = 2; + this.m_oDefaultPrimaryLabel.Text = "Primary"; + // // m_oSecondaryDefaultOrdersComboBox // this.m_oSecondaryDefaultOrdersComboBox.FormattingEnabled = true; @@ -1681,6 +1755,51 @@ private void InitializeComponent() this.m_oProtectThreatAxisGroupBox.TabStop = false; this.m_oProtectThreatAxisGroupBox.Text = "Protect Threat Axis(Acts as Highest Priority default order)"; // + // m_oBearingThreatLabel + // + this.m_oBearingThreatLabel.AutoSize = true; + this.m_oBearingThreatLabel.Location = new System.Drawing.Point(6, 144); + this.m_oBearingThreatLabel.Name = "m_oBearingThreatLabel"; + this.m_oBearingThreatLabel.Size = new System.Drawing.Size(43, 13); + this.m_oBearingThreatLabel.TabIndex = 12; + this.m_oBearingThreatLabel.Text = "Bearing"; + // + // m_oOffsetthreatLabel + // + this.m_oOffsetthreatLabel.AutoSize = true; + this.m_oOffsetthreatLabel.Location = new System.Drawing.Point(6, 131); + this.m_oOffsetthreatLabel.Name = "m_oOffsetthreatLabel"; + this.m_oOffsetthreatLabel.Size = new System.Drawing.Size(35, 13); + this.m_oOffsetthreatLabel.TabIndex = 11; + this.m_oOffsetthreatLabel.Text = "Offset"; + // + // m_oThreatDistanceLabel + // + this.m_oThreatDistanceLabel.AutoSize = true; + this.m_oThreatDistanceLabel.Location = new System.Drawing.Point(6, 96); + this.m_oThreatDistanceLabel.Name = "m_oThreatDistanceLabel"; + this.m_oThreatDistanceLabel.Size = new System.Drawing.Size(49, 13); + this.m_oThreatDistanceLabel.TabIndex = 10; + this.m_oThreatDistanceLabel.Text = "Distance"; + // + // m_oTaskGroupThreatLabel + // + this.m_oTaskGroupThreatLabel.AutoSize = true; + this.m_oTaskGroupThreatLabel.Location = new System.Drawing.Point(6, 59); + this.m_oTaskGroupThreatLabel.Name = "m_oTaskGroupThreatLabel"; + this.m_oTaskGroupThreatLabel.Size = new System.Drawing.Size(58, 13); + this.m_oTaskGroupThreatLabel.TabIndex = 9; + this.m_oTaskGroupThreatLabel.Text = "Taskgroup"; + // + // m_oThreatLabel + // + this.m_oThreatLabel.AutoSize = true; + this.m_oThreatLabel.Location = new System.Drawing.Point(6, 26); + this.m_oThreatLabel.Name = "m_oThreatLabel"; + this.m_oThreatLabel.Size = new System.Drawing.Size(38, 13); + this.m_oThreatLabel.TabIndex = 8; + this.m_oThreatLabel.Text = "Threat"; + // // comboBox12 // this.comboBox12.FormattingEnabled = true; @@ -2233,104 +2352,24 @@ private void InitializeComponent() this.m_oNewTGButton.Text = "&New TG"; this.m_oNewTGButton.UseVisualStyleBackColor = true; // - // m_oDefaultPrimaryLabel + // m_oTaskGroupSecondaryGroupBox // - this.m_oDefaultPrimaryLabel.AutoSize = true; - this.m_oDefaultPrimaryLabel.Location = new System.Drawing.Point(6, 26); - this.m_oDefaultPrimaryLabel.Name = "m_oDefaultPrimaryLabel"; - this.m_oDefaultPrimaryLabel.Size = new System.Drawing.Size(41, 13); - this.m_oDefaultPrimaryLabel.TabIndex = 2; - this.m_oDefaultPrimaryLabel.Text = "Primary"; + this.m_oTaskGroupSecondaryGroupBox.Controls.Add(this.m_oTaskgroupSecondaryListBox); + this.m_oTaskGroupSecondaryGroupBox.Location = new System.Drawing.Point(517, 69); + this.m_oTaskGroupSecondaryGroupBox.Name = "m_oTaskGroupSecondaryGroupBox"; + this.m_oTaskGroupSecondaryGroupBox.Size = new System.Drawing.Size(275, 201); + this.m_oTaskGroupSecondaryGroupBox.TabIndex = 45; + this.m_oTaskGroupSecondaryGroupBox.TabStop = false; + this.m_oTaskGroupSecondaryGroupBox.Visible = false; // - // m_oDefaultSecondaryLabel + // m_oTaskgroupSecondaryListBox // - this.m_oDefaultSecondaryLabel.AutoSize = true; - this.m_oDefaultSecondaryLabel.Location = new System.Drawing.Point(6, 61); - this.m_oDefaultSecondaryLabel.Name = "m_oDefaultSecondaryLabel"; - this.m_oDefaultSecondaryLabel.Size = new System.Drawing.Size(58, 13); - this.m_oDefaultSecondaryLabel.TabIndex = 3; - this.m_oDefaultSecondaryLabel.Text = "Secondary"; - // - // m_oCondACondLabel - // - this.m_oCondACondLabel.AutoSize = true; - this.m_oCondACondLabel.Location = new System.Drawing.Point(6, 26); - this.m_oCondACondLabel.Name = "m_oCondACondLabel"; - this.m_oCondACondLabel.Size = new System.Drawing.Size(51, 13); - this.m_oCondACondLabel.TabIndex = 4; - this.m_oCondACondLabel.Text = "Condition"; - // - // m_oCondAOrderLabel - // - this.m_oCondAOrderLabel.AutoSize = true; - this.m_oCondAOrderLabel.Location = new System.Drawing.Point(6, 61); - this.m_oCondAOrderLabel.Name = "m_oCondAOrderLabel"; - this.m_oCondAOrderLabel.Size = new System.Drawing.Size(33, 13); - this.m_oCondAOrderLabel.TabIndex = 5; - this.m_oCondAOrderLabel.Text = "Order"; - // - // m_oCondBCondLabel - // - this.m_oCondBCondLabel.AutoSize = true; - this.m_oCondBCondLabel.Location = new System.Drawing.Point(6, 24); - this.m_oCondBCondLabel.Name = "m_oCondBCondLabel"; - this.m_oCondBCondLabel.Size = new System.Drawing.Size(51, 13); - this.m_oCondBCondLabel.TabIndex = 6; - this.m_oCondBCondLabel.Text = "Condition"; - // - // m_oCondBOrderLabel - // - this.m_oCondBOrderLabel.AutoSize = true; - this.m_oCondBOrderLabel.Location = new System.Drawing.Point(6, 61); - this.m_oCondBOrderLabel.Name = "m_oCondBOrderLabel"; - this.m_oCondBOrderLabel.Size = new System.Drawing.Size(33, 13); - this.m_oCondBOrderLabel.TabIndex = 7; - this.m_oCondBOrderLabel.Text = "Order"; - // - // m_oThreatLabel - // - this.m_oThreatLabel.AutoSize = true; - this.m_oThreatLabel.Location = new System.Drawing.Point(6, 26); - this.m_oThreatLabel.Name = "m_oThreatLabel"; - this.m_oThreatLabel.Size = new System.Drawing.Size(38, 13); - this.m_oThreatLabel.TabIndex = 8; - this.m_oThreatLabel.Text = "Threat"; - // - // m_oTaskGroupThreatLabel - // - this.m_oTaskGroupThreatLabel.AutoSize = true; - this.m_oTaskGroupThreatLabel.Location = new System.Drawing.Point(6, 59); - this.m_oTaskGroupThreatLabel.Name = "m_oTaskGroupThreatLabel"; - this.m_oTaskGroupThreatLabel.Size = new System.Drawing.Size(58, 13); - this.m_oTaskGroupThreatLabel.TabIndex = 9; - this.m_oTaskGroupThreatLabel.Text = "Taskgroup"; - // - // m_oThreatDistanceLabel - // - this.m_oThreatDistanceLabel.AutoSize = true; - this.m_oThreatDistanceLabel.Location = new System.Drawing.Point(6, 96); - this.m_oThreatDistanceLabel.Name = "m_oThreatDistanceLabel"; - this.m_oThreatDistanceLabel.Size = new System.Drawing.Size(49, 13); - this.m_oThreatDistanceLabel.TabIndex = 10; - this.m_oThreatDistanceLabel.Text = "Distance"; - // - // m_oOffsetthreatLabel - // - this.m_oOffsetthreatLabel.AutoSize = true; - this.m_oOffsetthreatLabel.Location = new System.Drawing.Point(6, 131); - this.m_oOffsetthreatLabel.Name = "m_oOffsetthreatLabel"; - this.m_oOffsetthreatLabel.Size = new System.Drawing.Size(35, 13); - this.m_oOffsetthreatLabel.TabIndex = 11; - this.m_oOffsetthreatLabel.Text = "Offset"; - // - // m_oBearingThreatLabel - // - this.m_oBearingThreatLabel.AutoSize = true; - this.m_oBearingThreatLabel.Location = new System.Drawing.Point(6, 144); - this.m_oBearingThreatLabel.Name = "m_oBearingThreatLabel"; - this.m_oBearingThreatLabel.Size = new System.Drawing.Size(43, 13); - this.m_oBearingThreatLabel.TabIndex = 12; - this.m_oBearingThreatLabel.Text = "Bearing"; + this.m_oTaskgroupSecondaryListBox.FormattingEnabled = true; + this.m_oTaskgroupSecondaryListBox.Location = new System.Drawing.Point(6, 19); + this.m_oTaskgroupSecondaryListBox.Name = "m_oTaskgroupSecondaryListBox"; + this.m_oTaskgroupSecondaryListBox.Size = new System.Drawing.Size(263, 147); + this.m_oTaskgroupSecondaryListBox.TabIndex = 0; + this.m_oTaskgroupSecondaryListBox.Visible = false; // // TaskGroup_Panel // @@ -2395,6 +2434,7 @@ private void InitializeComponent() this.m_oSpeedBox.ResumeLayout(false); this.m_oSpeedBox.PerformLayout(); this.m_oButtonBox.ResumeLayout(false); + this.m_oTaskGroupSecondaryGroupBox.ResumeLayout(false); this.ResumeLayout(false); } @@ -2565,5 +2605,7 @@ private void InitializeComponent() private Label m_oThreatDistanceLabel; private Label m_oTaskGroupThreatLabel; private Label m_oThreatLabel; + private GroupBox m_oTaskGroupSecondaryGroupBox; + private ListBox m_oTaskgroupSecondaryListBox; } } \ No newline at end of file From 3b19c09037241ed829d5d0e9cdf9413ed0e7252e Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 27 Feb 2016 09:00:22 -0600 Subject: [PATCH 35/40] Installation backend load work and UI work for unload CargoListEntries were also created for minerals, two bugs with sensors wer fixed, and some legalOrders cleanup was done. --- MITLicense.md | 2 +- .../Entities/Components/CargoTN.cs | 27 +++ Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs | 18 +- Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs | 6 + .../Entities/StarSystem/Population.cs | 54 +++++- .../Entities/StarSystem/TaskGroup.cs | 146 ++++++++++++++- Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs | 170 +++++++++++++++++- .../Pulsar4X.UI/SceenGraph/ContactElement.cs | 4 +- 8 files changed, 403 insertions(+), 24 deletions(-) diff --git a/MITLicense.md b/MITLicense.md index 3960694b9..fc6c84df1 100644 --- a/MITLicense.md +++ b/MITLicense.md @@ -18,6 +18,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Aurora is Copyright Steve Walmsley +Aurora is Copyright Steve Walmsley. The names of the above copyright holders shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization. diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Components/CargoTN.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Components/CargoTN.cs index 2898cf2a4..920852ad9 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Components/CargoTN.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Components/CargoTN.cs @@ -25,6 +25,17 @@ public ComponentDefTN cargoComponentType get { return CargoComponentType; } } + /// + /// What type of mineral is being carried? + /// + private Constants.Minerals.MinerialNames MineralType; + public Constants.Minerals.MinerialNames mineralType + { + get { return MineralType; } + } + +#warning Cargo entries should be reworked to account for the various things that can be held in cargo, there is no PDC holding yet for example. + /// /// Size of Installation being carried. /// @@ -46,11 +57,27 @@ public CargoListEntryTN(Installation.InstallationType Type, int SizeInTons) Tons = SizeInTons; } + /// + /// Constructor for Component transfers. + /// + /// Type of component + /// Tons of said component public CargoListEntryTN(ComponentDefTN Type, int SizeInTons) { CargoComponentType = Type; Tons = SizeInTons; } + + /// + /// This is the constructor for minerals in cargo. + /// + /// Type of mineral + /// Tons of said mineral + public CargoListEntryTN(Constants.Minerals.MinerialNames Type, int SizeInTons) + { + MineralType = Type; + Tons = SizeInTons; + } } /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs index 3d50addf5..0c6678a6d 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs @@ -1125,7 +1125,14 @@ public void SensorSweep() if (System.FactionDetectionLists[FactionID].CheckThermal(detListIterator,GameState.Instance.CurrentSecond,GameState.Instance.CurrentYear) == false) { sig = Pop.ThermalSignature; - detection = CurrentTaskGroup.BestThermal.pSensorDef.GetPassiveDetectionRange(sig); + if (CurrentTaskGroup.BestThermalCount != 0) + { + detection = CurrentTaskGroup.BestThermal.pSensorDef.GetPassiveDetectionRange(sig); + } + else + { + detection = CurrentTaskGroup.TaskGroupFaction.ComponentList.DefaultPassives.GetPassiveDetectionRange(sig); + } /// /// LargeDetection handles determining if dist or detection go beyond INTMAX and acts accordingly. @@ -1147,7 +1154,14 @@ public void SensorSweep() if (System.FactionDetectionLists[FactionID].CheckEM(detListIterator, GameState.Instance.CurrentSecond, GameState.Instance.CurrentYear) == false) { sig = Pop.EMSignature; - detection = CurrentTaskGroup.BestEM.pSensorDef.GetPassiveDetectionRange(sig); + if (CurrentTaskGroup.BestEMCount != 0) + { + detection = CurrentTaskGroup.BestEM.pSensorDef.GetPassiveDetectionRange(sig); + } + else + { + detection = CurrentTaskGroup.TaskGroupFaction.ComponentList.DefaultPassives.GetPassiveDetectionRange(sig); + } bool det = LargeDetection(dist, detection); diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs index fe6669183..cd32ca657 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs @@ -212,6 +212,11 @@ public enum ShipType /// public Dictionary CargoComponentList { get; set; } + /// + /// List of any minerals this ship is holding. + /// + public Dictionary CargoMineralList { get; set; } + /// /// Ships can also have several cryo storage bays and bay types. /// @@ -647,6 +652,7 @@ public ShipTN(ShipClassTN ClassDefinition, int ShipIndex, int CurrentTimeSlice, CurrentCargoTonnage = 0; CargoList = new Dictionary(); CargoComponentList = new Dictionary(); + CargoMineralList = new Dictionary(); /// /// While only colonyships will have the major bays, just about any craft can have an emergency cryo bay. diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs index 4d602a408..0992733ca 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs @@ -674,31 +674,52 @@ public Population(SystemBody a_oPlanet, Faction a_oFaction, int CurrentTimeSlice if (faction == this.Faction) { legalOrders.Add(Constants.ShipTN.OrderType.LoadCrewFromColony); + if (this.FuelStockpile > 0) legalOrders.Add(Constants.ShipTN.OrderType.RefuelFromColony); + if (this.MaintenanceSupplies > 0) legalOrders.Add(Constants.ShipTN.OrderType.ResupplyFromColony); + +#warning check size class here if (Array.Exists(this.Installations, x => x.Type == Installation.InstallationType.MaintenanceFacility)) legalOrders.Add(Constants.ShipTN.OrderType.BeginOverhaul); + if (this.Installations.Count() > 0) legalOrders.Add(Constants.ShipTN.OrderType.LoadInstallation); + legalOrders.Add(Constants.ShipTN.OrderType.UnloadInstallation); + if (this.ComponentStockpile.Count() > 0) legalOrders.Add(Constants.ShipTN.OrderType.LoadShipComponent); - legalOrders.Add(Constants.ShipTN.OrderType.LoadAllMinerals); + legalOrders.Add(Constants.ShipTN.OrderType.UnloadShipComponent); + + for (int minIterator = 0; minIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; minIterator++) + { + if (Minerials[minIterator] > 0.0f) + { + legalOrders.Add(Constants.ShipTN.OrderType.LoadMineral); + legalOrders.Add(Constants.ShipTN.OrderType.LoadAllMinerals); + legalOrders.Add(Constants.ShipTN.OrderType.LoadMineralWhenX); + break; + } + } + legalOrders.Add(Constants.ShipTN.OrderType.UnloadAllMinerals); - legalOrders.Add(Constants.ShipTN.OrderType.LoadMineral); - legalOrders.Add(Constants.ShipTN.OrderType.LoadMineralWhenX); legalOrders.Add(Constants.ShipTN.OrderType.UnloadMineral); legalOrders.Add(Constants.ShipTN.OrderType.LoadOrUnloadMineralsToReserve); + if (this.CivilianPopulation > 0) legalOrders.Add(Constants.ShipTN.OrderType.LoadColonists); legalOrders.Add(Constants.ShipTN.OrderType.UnloadColonists); + legalOrders.Add(Constants.ShipTN.OrderType.UnloadFuelToPlanet); legalOrders.Add(Constants.ShipTN.OrderType.UnloadSuppliesToPlanet); - if (Array.Exists(this.Installations, x => x.Type == Installation.InstallationType.OrdnanceFactory) || this.MissileStockpile.Count > 0) - legalOrders.Add(Constants.ShipTN.OrderType.LoadMineral); - legalOrders.Add(Constants.ShipTN.OrderType.LoadOrdnanceFromColony); + + if (this.MissileStockpile.Count > 0) + legalOrders.Add(Constants.ShipTN.OrderType.LoadOrdnanceFromColony); legalOrders.Add(Constants.ShipTN.OrderType.UnloadOrdnanceToColony); + + legalOrders.Add(Constants.ShipTN.OrderType.UnloadAll); } return legalOrders; } @@ -934,6 +955,27 @@ public void UnloadInstallation(Installation.InstallationType iType, int massToUn } } + /// + /// Handle any issues with loading minerals + /// + /// Mineral type + /// tonnage to load +#warning Check reserves for mineral loading + public void LoadMineral(Constants.Minerals.MinerialNames mType, int massToLoad) + { + Minerials[(int)mType] = Minerials[(int)mType] - (float)massToLoad; + } + + /// + /// Handle any issues with unloading minerals here + /// + /// + /// + public void UnloadMineral(Constants.Minerals.MinerialNames mType, int massToUnload) + { + Minerials[(int)mType] = Minerials[(int)mType] + (float)massToUnload; + } + /// /// Constructs maintenance supply parts at this population. /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index ea6173854..f1fbbfe8d 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -356,6 +356,8 @@ public TaskGroupTN(string Title, Faction FID, OrbitingEntity StartingBody, StarS public override List LegalOrders(Faction faction) { + bool anyUnload = false; + List legalOrders = new List(); legalOrders.AddRange(_legalOrders); ShipTN[] shipsArray = this.Ships.ToArray(); @@ -365,6 +367,28 @@ public TaskGroupTN(string Title, Faction FID, OrbitingEntity StartingBody, StarS legalOrders.Add(Constants.ShipTN.OrderType.ResupplyFromTargetFleet); if (Array.Exists(shipsArray, x => x.ShipClass.IsCollier))//if this fleet is targeted and has a IsCollier. legalOrders.Add(Constants.ShipTN.OrderType.ReloadFromTargetFleet); + if (Array.Exists(shipsArray, x => (x.CargoList.Count() > 0))) + { + legalOrders.Add(Constants.ShipTN.OrderType.UnloadInstallation); + anyUnload = true; + } + if (Array.Exists(shipsArray, x => (x.CargoMineralList.Count() > 0))) + { + legalOrders.Add(Constants.ShipTN.OrderType.UnloadMineral); + legalOrders.Add(Constants.ShipTN.OrderType.UnloadAllMinerals); + anyUnload = true; + } + if (Array.Exists(shipsArray, x => (x.CargoComponentList.Count() > 0))) + { + legalOrders.Add(Constants.ShipTN.OrderType.UnloadShipComponent); + anyUnload = true; + } + + if (anyUnload == true) + { + legalOrders.Add(Constants.ShipTN.OrderType.UnloadAll); + } + return legalOrders; } @@ -3577,7 +3601,7 @@ public void LoadCargo(Population Pop, Installation.InstallationType InstType, in /// /// In this case load as much as possible up to AvailableMass. /// - if (Limit == 0) + if (Limit == 0 || Limit == -1) { MassToLoad = Math.Min(RemainingTaskGroupTonnage, AvailableMass); @@ -3648,7 +3672,7 @@ public void UnloadCargo(Population Pop, Installation.InstallationType InstType, CargoListEntryTN CLE = Ships[loop].CargoList[InstType]; int ShipMassToUnload = 0; - if (Limit == 0) + if (Limit == 0 || Limit == -1) { ShipMassToUnload = CLE.tons; } @@ -3669,7 +3693,117 @@ public void UnloadCargo(Population Pop, Installation.InstallationType InstType, Pop.UnloadInstallation(InstType, ShipMassToUnload); } } + } + + /// + /// Load minerals onto ships in this taskgroup + /// + /// + /// + /// + public void LoadMineral(Population Pop, Constants.Minerals.MinerialNames MinType, int Limit) + { + int RemainingTaskGroupTonnage = TotalCargoTonnage - CurrentCargoTonnage; + int TotalMass = Limit; + int AvailableMass = (int)(Pop.Minerials[(int)MinType]); + + int MassToLoad = 0; + + /// + /// In this case load as much as possible up to AvailableMass. + /// + if (Limit == 0 || Limit == -1) + { + MassToLoad = Math.Min(RemainingTaskGroupTonnage, AvailableMass); + + } + /// + /// In this case only load up to Total mass. + /// + else + { + MassToLoad = Math.Min(RemainingTaskGroupTonnage, TotalMass); + } + + /// + /// Mark the taskgroup total cargo tonnage + /// + CurrentCargoTonnage = CurrentCargoTonnage + MassToLoad; + + /// + /// Decrement the installation count on the planet. + /// + Pop.LoadMineral(MinType, MassToLoad); + + /// + /// Now start loading mass onto each ship. + /// + for (int loop = 0; loop < Ships.Count; loop++) + { + int RemainingShipTonnage = Ships[loop].ShipClass.TotalCargoCapacity - Ships[loop].CurrentCargoTonnage; + if (Ships[loop].ShipClass.TotalCargoCapacity != 0 && RemainingShipTonnage != 0) + { + int ShipMassToLoad = Math.Min(MassToLoad, RemainingShipTonnage); + + /// + /// Load the mass onto the taskgroup as a whole for display purposes. + /// The actual mass will go into the ship cargoholds. + /// + if (Ships[loop].CargoMineralList.ContainsKey(MinType)) + { + CargoListEntryTN CLE = Ships[loop].CargoMineralList[MinType]; + CLE.tons = CLE.tons + ShipMassToLoad; + + } + else + { + CargoListEntryTN CargoListEntry = new CargoListEntryTN(MinType, ShipMassToLoad); + Ships[loop].CargoMineralList.Add(MinType, CargoListEntry); + } + + MassToLoad = MassToLoad - ShipMassToLoad; + Ships[loop].CurrentCargoTonnage = ShipMassToLoad; + } + } + } + /// + /// Unload minerals to the population from the taskgroup. + /// + /// Pop to unload minerals to + /// mineral to unload + /// limit on how many to part with. + public void UnloadMineral(Population Pop, Constants.Minerals.MinerialNames MinType, int Limit) + { + int TotalMass = Limit; + for (int loop = 0; loop < Ships.Count; loop++) + { + if (Ships[loop].ShipClass.TotalCargoCapacity != 0 && Ships[loop].CurrentCargoTonnage != 0 && Ships[loop].CargoMineralList.ContainsKey(MinType) == true) + { + CargoListEntryTN CLE = Ships[loop].CargoMineralList[MinType]; + int ShipMassToUnload = 0; + + if (Limit == 0 || Limit == -1) + { + ShipMassToUnload = CLE.tons; + } + else + { + ShipMassToUnload = Math.Min(CLE.tons, TotalMass); + TotalMass = TotalMass - ShipMassToUnload; + } + + if (ShipMassToUnload == CLE.tons) + { + Ships[loop].CargoMineralList.Remove(MinType); + } + + CLE.tons = CLE.tons - ShipMassToUnload; + CurrentCargoTonnage = CurrentCargoTonnage - ShipMassToUnload; + + Pop.UnloadMineral(MinType, ShipMassToUnload); + } + } } /// @@ -3689,7 +3823,7 @@ public void LoadColonists(Population Pop, int Limit) int RemainingShipCryo = Ships[loop].ShipClass.SpareCryoBerths - Ships[loop].CurrentCryoStorage; int AvailablePopulation = (int)Math.Floor(Pop.CivilianPopulation * 1000000.0f); - if (Limit == 0) + if (Limit == 0 || Limit == -1) { Colonists = Math.Min(RemainingShipCryo, AvailablePopulation); } @@ -3731,7 +3865,7 @@ public void UnloadColonists(Population Pop, int Limit) { int Colonists; - if (Limit == 0) + if (Limit == 0 || Limit == -1) { Colonists = Ships[loop].CurrentCryoStorage; CurrentCryoStorage = CurrentCryoStorage - Ships[loop].CurrentCryoStorage; @@ -3766,7 +3900,7 @@ public void LoadComponents(Population Pop, int ComponentIndex, int Limit) /// /// In this case load as much as possible up to AvailableMass. /// - if (Limit == 0) + if (Limit == 0 || Limit == -1) { MassToLoad = Math.Min(RemainingTonnage, AvailableMass); @@ -3850,7 +3984,7 @@ public void UnloadComponents(Population Pop, ComponentDefTN Component, int Limit /// /// Limit == 0 means unload all, else unload to limit if limit is lower than total tonnage. /// - if (Limit == 0) + if (Limit == 0 || Limit == -1) { ShipMassToUnload = CLE.tons; } diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs index 13a2bea2f..2b5e666fe 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs @@ -488,12 +488,113 @@ private void AddMoveButton_Clicked(object sender, EventArgs e) if (ActionIndex != -1) { Constants.ShipTN.OrderType selected_ordertype = (Constants.ShipTN.OrderType)m_oTaskGroupPanel.AvailableActionsListBox.SelectedItem; + int SecondaryOrder = -1; /// /// Now figure out what the hell order this would be. /// var entity = selected.Entity; var etype = selected.EntityType; + + switch (selected_ordertype) + { + case Constants.ShipTN.OrderType.LoadInstallation: + int InstSelection = m_oTaskGroupPanel.TaskgroupSecondaryListBox.SelectedIndex; + + /// + /// This is a bad order. + /// + if (etype != SystemListObject.ListEntityType.Colonies) + return; + + Population popTargetOfOrder = (Population)entity; + if (InstSelection != -1) + { + int ActualInst = 0; + for (Installation.InstallationType InstIterator = 0; InstIterator < Installation.InstallationType.InstallationCount; InstIterator++) + { + /// + /// Skip over these installations, they should never be loadable. + /// + if ( !(InstIterator == Installation.InstallationType.ConventionalIndustry || InstIterator == Installation.InstallationType.CivilianMiningComplex || + InstIterator == Installation.InstallationType.MilitaryAcademy || InstIterator == Installation.InstallationType.SectorCommand || + InstIterator == Installation.InstallationType.Spaceport || InstIterator == Installation.InstallationType.CommercialShipyard || + InstIterator == Installation.InstallationType.NavalShipyardComplex) ) + { + if (popTargetOfOrder.Installations[(int)InstIterator].Number >= 1.0f) + { + if (ActualInst == InstSelection) + { + SecondaryOrder = (int)InstIterator; + break; + } + ActualInst++; + } + } + } + } + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = false; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = false; + break; + case Constants.ShipTN.OrderType.UnloadInstallation: + break; + case Constants.ShipTN.OrderType.LoadMineral: + int MineralSelection = m_oTaskGroupPanel.TaskgroupSecondaryListBox.SelectedIndex; + /// + /// This is a bad order. + /// + if (etype != SystemListObject.ListEntityType.Colonies) + return; + + popTargetOfOrder = (Population)entity; + if (MineralSelection != -1) + { + for (Constants.Minerals.MinerialNames MinIterator = 0; MinIterator < Constants.Minerals.MinerialNames.MinerialCount; MinIterator++) + { + if (popTargetOfOrder.Minerials[(int)MinIterator] >= 1.0f) + { + if (MineralSelection != -1) + { + SecondaryOrder = (int)MinIterator; + } + } + } + } + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = false; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = false; + break; + case Constants.ShipTN.OrderType.UnloadMineral: + break; + + +#warning All of the rest of these load types need to be implemented + case Constants.ShipTN.OrderType.LoadMineralWhenX: + break; + case Constants.ShipTN.OrderType.LoadShipComponent: + break; + case Constants.ShipTN.OrderType.UnloadShipComponent: + break; + case Constants.ShipTN.OrderType.LoadPDCPart: + break; + case Constants.ShipTN.OrderType.UnloadPDCPart: + break; + case Constants.ShipTN.OrderType.LoadGroundUnit: + break; + case Constants.ShipTN.OrderType.UnloadGroundUnit: + break; + case Constants.ShipTN.OrderType.LoadCommander: + break; + case Constants.ShipTN.OrderType.UnloadCommander: + break; + case Constants.ShipTN.OrderType.LoadTeam: + break; + case Constants.ShipTN.OrderType.UnloadTeam: + break; + default: + break; + } + + #warning handle secondary,tertiary, and order delays. also handle taskgroup split condition for move to contact orders if not already done so. switch (etype) { @@ -505,28 +606,28 @@ private void AddMoveButton_Clicked(object sender, EventArgs e) break; case SystemListObject.ListEntityType.Planets: SystemBody planet = (SystemBody)entity; - NewOrder = new Order(selected_ordertype, -1, -1, 0, planet); + NewOrder = new Order(selected_ordertype, SecondaryOrder, -1, 0, planet); break; case SystemListObject.ListEntityType.JumpPoint: JumpPoint jp = (JumpPoint)entity; - NewOrder = new Order(selected_ordertype, -1, -1, 0, jp); + NewOrder = new Order(selected_ordertype, SecondaryOrder, -1, 0, jp); break; case SystemListObject.ListEntityType.Colonies: Population popTargetOfOrder = (Population)entity; - NewOrder = new Order(selected_ordertype, -1, -1, 0, popTargetOfOrder); + NewOrder = new Order(selected_ordertype, SecondaryOrder, -1, 0, popTargetOfOrder); break; case SystemListObject.ListEntityType.TaskGroups: TaskGroupTN TargetOfOrder = (TaskGroupTN)entity; - NewOrder = new Order(selected_ordertype, -1, -1, 0, TargetOfOrder); + NewOrder = new Order(selected_ordertype, SecondaryOrder, -1, 0, TargetOfOrder); TargetOfOrder.TaskGroupsOrdered.Add(CurrentTaskGroup); break; case SystemListObject.ListEntityType.Waypoints: Waypoint waypoint = (Waypoint)entity; - NewOrder = new Order(selected_ordertype, -1, -1, 0, waypoint); + NewOrder = new Order(selected_ordertype, SecondaryOrder, -1, 0, waypoint); break; case SystemListObject.ListEntityType.SurveyPoints: SurveyPoint SPoint = (SurveyPoint)entity; - NewOrder = new Order(selected_ordertype, -1, -1, 0, SPoint); + NewOrder = new Order(selected_ordertype, SecondaryOrder, -1, 0, SPoint); break; } if (NewOrder != null) @@ -589,6 +690,19 @@ private void AvailableActionsListBox_MouseClick(object sender, EventArgs e) } } break; + case Constants.ShipTN.OrderType.UnloadInstallation: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Installation"; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Clear(); + foreach (ShipTN CurShip in CurrentTaskGroup.Ships) + { + foreach(KeyValuePair pair in CurShip.CargoList) + { + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Add(pair.Key); + } + } + break; case Constants.ShipTN.OrderType.LoadMineral: m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; @@ -596,7 +710,24 @@ private void AvailableActionsListBox_MouseClick(object sender, EventArgs e) m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Clear(); for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++) { - m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Add(((Constants.Minerals.MinerialNames)mineralIterator).ToString()); + if ((selected.Entity as Population).Minerials[mineralIterator] > 0.0f) + { + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Add(((Constants.Minerals.MinerialNames)mineralIterator).ToString()); + } + } + break; + case Constants.ShipTN.OrderType.UnloadMineral: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Mineral"; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Clear(); + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Clear(); + foreach (ShipTN CurShip in CurrentTaskGroup.Ships) + { + foreach (KeyValuePair pair in CurShip.CargoMineralList) + { + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Add(pair.Key); + } } break; #warning All of the rest of these load types need to be implemented @@ -610,26 +741,51 @@ private void AvailableActionsListBox_MouseClick(object sender, EventArgs e) m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Component"; break; + case Constants.ShipTN.OrderType.UnloadShipComponent: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Component"; + break; case Constants.ShipTN.OrderType.LoadPDCPart: m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select PDC Part"; break; + case Constants.ShipTN.OrderType.UnloadPDCPart: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select PDC Part"; + break; case Constants.ShipTN.OrderType.LoadGroundUnit: m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Ground Unit"; break; + case Constants.ShipTN.OrderType.UnloadGroundUnit: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Ground Unit"; + break; case Constants.ShipTN.OrderType.LoadCommander: m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Commander"; break; + case Constants.ShipTN.OrderType.UnloadCommander: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Commander"; + break; case Constants.ShipTN.OrderType.LoadTeam: m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Team"; break; + case Constants.ShipTN.OrderType.UnloadTeam: + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Team"; + break; default: m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = false; m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = false; diff --git a/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs b/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs index 6d0aac76e..a4da53b99 100644 --- a/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs +++ b/Pulsar4X/Pulsar4X.UI/SceenGraph/ContactElement.cs @@ -310,13 +310,13 @@ public override void Render() if (CurrentPop._sensorUpdateAck != _LastSensorUpdateAck) { _SensorContactElements.Clear(); + int DSTS = (int)Math.Floor(CurrentPop.Installations[(int)Installation.InstallationType.DeepSpaceTrackingStation].Number); - if (ParentSceen.ShowPassives == true) + if (ParentSceen.ShowPassives == true && DSTS != 0) { /// /// This calculates the default detection distance for strength 1000 signatures. /// - int DSTS = (int)Math.Floor(CurrentPop.Installations[(int)Installation.InstallationType.DeepSpaceTrackingStation].Number); int SensorTech = CurrentPop.Faction.FactionTechLevel[(int)Faction.FactionTechnology.DSTSSensorStrength]; if (SensorTech > Constants.Colony.DeepSpaceMax) SensorTech = Constants.Colony.DeepSpaceMax; From d3da583d19210eac7729bd33be331778c15e9cb1 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 5 Mar 2016 21:16:06 -0600 Subject: [PATCH 36/40] Load and unload taskgroup instruction work loads and unloads for minerals should now work, with both the ships cargo lists, as well as previous orders being looked at to figure out what to load and unload. It is currently up to the user to not mess up unload orders, if they do it will crash. Also a sensor bug was fixed, and a minor issue with ship naming for elligible classes may have been resolved. --- Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs | 11 ++ .../Entities/StarSystem/TaskGroup.cs | 3 + .../Handlers/Eco_ShipyardTabHandler.cs | 2 +- Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 9 +- Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs | 135 +++++++++++++++++- 5 files changed, 155 insertions(+), 5 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs index cd32ca657..7a392fb60 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs @@ -3600,6 +3600,17 @@ public void SetActiveDetection(int FactionID, int tick, int year) ActiveDetection[FactionID] = tick; ActiveYearDetection[FactionID] = year; } + + /// + /// When ships are moved from taskgroups, their ship index will change in the ships list, the thermal, em, active, and any other detection lists must be updated to reflect this. + /// + /// New index this ship is located at + public void UpdateShipIndex(int NewIndex) + { + ThermalList.Value = NewIndex; + EMList.Value = NewIndex; + ActiveList.Value = NewIndex; + } #endregion } /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index f1fbbfe8d..fc46b2c28 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -636,6 +636,9 @@ public void AddShipTo(ShipTN Ship) { Ships.Add(Ship); + int NewIndexOfShip = Ships.IndexOf(Ship); + Ship.UpdateShipIndex(NewIndexOfShip); + if(Ships.Count == 1) { MaxSpeed = Ship.ShipClass.MaxSpeed; diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Eco_ShipyardTabHandler.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Eco_ShipyardTabHandler.cs index 75b44baed..51b98d346 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Eco_ShipyardTabHandler.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Eco_ShipyardTabHandler.cs @@ -348,7 +348,7 @@ public static void RefreshSYTaskGroupBox(Panels.Eco_Summary m_oSummaryPanel, Fac if (m_oSummaryPanel.SYNewClassComboBox.Items.Count != 0) m_oSummaryPanel.SYNewClassComboBox.SelectedIndex = 0; - int index = CurrentFaction.ShipDesigns.IndexOf(EligibleClassList[0]); + int index = CurrentFaction.ShipDesigns.IndexOf(EligibleClassList[m_oSummaryPanel.SYNewClassComboBox.SelectedIndex]); String Entry = String.Format("{0} {1}", CurrentFaction.ShipDesigns[index].Name, (CurrentFaction.ShipDesigns[index].ShipsInClass.Count + CurrentFaction.ShipDesigns[index].ShipsUnderConstruction + 1)); m_oSummaryPanel.SYShipNameTextBox.Text = Entry; diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index 42b2fc140..484ce4a90 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -763,7 +763,14 @@ private void ExpandCapUntilXTextBox_TextChanged(object sender, EventArgs e) /// private void NewShipClassComboBox_SelectedIndexChanged(object sender, EventArgs e) { - Eco_ShipyardTabHandler.BuildSYCRequiredMinerals(m_oSummaryPanel, CurrentFaction, CurrentPopulation, CurrentSYInfo, PotentialRetoolTargets); + if(m_oSummaryPanel.SYNewClassComboBox.SelectedIndex != -1) + { + Eco_ShipyardTabHandler.BuildSYCRequiredMinerals(m_oSummaryPanel, CurrentFaction, CurrentPopulation, CurrentSYInfo, PotentialRetoolTargets); + int index = CurrentFaction.ShipDesigns.IndexOf(EligibleClassList[m_oSummaryPanel.SYNewClassComboBox.SelectedIndex]); + String Entry = String.Format("{0} {1}", CurrentFaction.ShipDesigns[index].Name, + (CurrentFaction.ShipDesigns[index].ShipsInClass.Count + CurrentFaction.ShipDesigns[index].ShipsUnderConstruction + 1)); + m_oSummaryPanel.SYShipNameTextBox.Text = Entry; + } } /// diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs index 2b5e666fe..dde305ff7 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs @@ -537,6 +537,52 @@ private void AddMoveButton_Clicked(object sender, EventArgs e) m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = false; break; case Constants.ShipTN.OrderType.UnloadInstallation: + InstSelection = m_oTaskGroupPanel.TaskgroupSecondaryListBox.SelectedIndex; + + /// + /// Only unload at colonies. + /// + if (etype != SystemListObject.ListEntityType.Colonies) + return; + + if (InstSelection != -1) + { + /// + /// List out all the taskgroup cargo here. each ship has its own cargoListEntries for what it is carrying and there can be overlap. I only want each thing once in this list. + /// + BindingList TaskGroupCargoList = new BindingList(); + foreach (ShipTN CurShip in CurrentTaskGroup.Ships) + { + foreach (KeyValuePair pair in CurShip.CargoList) + { + if (TaskGroupCargoList.Contains(pair.Key) == false) + TaskGroupCargoList.Add(pair.Key); + } + } + /// + /// Be sure to check to see if the unload order is coming from a previous load instruction as well. It is right now up to the player to make sure this doesn't bomb. + /// + foreach (Order TGOrder in CurrentTaskGroup.TaskGroupOrders) + { + if (TGOrder.typeOf == Constants.ShipTN.OrderType.LoadInstallation) + { + if (TaskGroupCargoList.Contains((Installation.InstallationType)TGOrder.secondary) == false) + TaskGroupCargoList.Add((Installation.InstallationType)TGOrder.secondary); + } + } + int ActualInst = 0; + foreach (Installation.InstallationType iType in TaskGroupCargoList) + { + if (ActualInst == InstSelection) + { + SecondaryOrder = (int)iType; + break; + } + ActualInst++; + } + } + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = false; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = false; break; case Constants.ShipTN.OrderType.LoadMineral: int MineralSelection = m_oTaskGroupPanel.TaskgroupSecondaryListBox.SelectedIndex; @@ -564,6 +610,53 @@ private void AddMoveButton_Clicked(object sender, EventArgs e) m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = false; break; case Constants.ShipTN.OrderType.UnloadMineral: + MineralSelection = m_oTaskGroupPanel.TaskgroupSecondaryListBox.SelectedIndex; + + /// + /// Only unload at colonies. + /// + if (etype != SystemListObject.ListEntityType.Colonies) + return; + + if (MineralSelection != -1) + { + /// + /// List out all the taskgroup cargo here. each ship has its own cargoListEntries for what it is carrying and there can be overlap. I only want each thing once in this list. + /// + BindingList TaskGroupCargoList = new BindingList(); + foreach (ShipTN CurShip in CurrentTaskGroup.Ships) + { + foreach (KeyValuePair pair in CurShip.CargoMineralList) + { + if (TaskGroupCargoList.Contains(pair.Key) == false) + TaskGroupCargoList.Add(pair.Key); + } + } + /// + /// Be sure to check to see if the unload order is coming from a previous load instruction as well. It is right now up to the player to make sure this doesn't bomb. + /// + foreach (Order TGOrder in CurrentTaskGroup.TaskGroupOrders) + { + if (TGOrder.typeOf == Constants.ShipTN.OrderType.LoadMineral) + { + if (TaskGroupCargoList.Contains((Constants.Minerals.MinerialNames)TGOrder.secondary) == false) + TaskGroupCargoList.Add((Constants.Minerals.MinerialNames)TGOrder.secondary); + } + } + int ActualInst = 0; + foreach (Constants.Minerals.MinerialNames mType in TaskGroupCargoList) + { + if (ActualInst == MineralSelection) + { + SecondaryOrder = (int)mType; + break; + } + ActualInst++; + } + } + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = false; + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = false; + break; @@ -695,11 +788,31 @@ private void AvailableActionsListBox_MouseClick(object sender, EventArgs e) m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Installation"; m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Clear(); + /// + /// Check for existing entries in the ship cargo list, and also check the orders to load installations. + /// foreach (ShipTN CurShip in CurrentTaskGroup.Ships) { foreach(KeyValuePair pair in CurShip.CargoList) { - m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Add(pair.Key); + /// + /// there can and will be duplicates here, so avoid that issue. + /// + if(m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Contains(pair.Key) == false) + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Add(pair.Key); + } + } + /// + /// If the player has made a load order for this item, put it in the unload category as well. For now it is up to the player to not mess this one up. + /// + foreach (Order TGOrder in CurrentTaskGroup.TaskGroupOrders) + { + if (TGOrder.typeOf == Constants.ShipTN.OrderType.LoadInstallation) + { + if (m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Contains((Installation.InstallationType)TGOrder.secondary) == false) + { + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Add((Installation.InstallationType)TGOrder.secondary); + } } } break; @@ -721,12 +834,28 @@ private void AvailableActionsListBox_MouseClick(object sender, EventArgs e) m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = true; m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Text = "Select Mineral"; m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Clear(); - m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Clear(); + /// + /// Check for existing entries in the ship cargo list, and also check orders to load minerals. + /// foreach (ShipTN CurShip in CurrentTaskGroup.Ships) { foreach (KeyValuePair pair in CurShip.CargoMineralList) { - m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Add(pair.Key); + if(m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Contains(pair.Key) == false) + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Add(pair.Key); + } + } + /// + /// If the player has made a load order for this item, put it in the unload category as well. For now it is up to the player to not mess this one up. + /// + foreach (Order TGOrder in CurrentTaskGroup.TaskGroupOrders) + { + if (TGOrder.typeOf == Constants.ShipTN.OrderType.LoadMineral) + { + if (m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Contains((Constants.Minerals.MinerialNames)TGOrder.secondary) == false) + { + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Add((Constants.Minerals.MinerialNames)TGOrder.secondary); + } } } break; From 5275d84fac39cf1cc3ff6bb2b31c60b39a843de6 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 12 Mar 2016 09:50:46 -0600 Subject: [PATCH 37/40] UI and Colony bugfixes Colonists and Infrastructure can now be moved from one colony to another, but there are no repeating orders just yet. Also the annual growth rate for colonies is not negative if they exceed their infrastructure. Other minor issues to look at are that costs for cap expansion for shipyards may be off, and double clicking on an item in the secondary orders listbox should issue an order. --- .../Entities/StarSystem/TaskGroup.cs | 1 + .../Handlers/Eco_ShipyardTabHandler.cs | 8 +++-- Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 35 ++++++++++++++++--- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index fc46b2c28..e1db56559 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -3692,6 +3692,7 @@ public void UnloadCargo(Population Pop, Installation.InstallationType InstType, CLE.tons = CLE.tons - ShipMassToUnload; CurrentCargoTonnage = CurrentCargoTonnage - ShipMassToUnload; + Ships[loop].CurrentCargoTonnage = Ships[loop].CurrentCargoTonnage - ShipMassToUnload; Pop.UnloadInstallation(InstType, ShipMassToUnload); } diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Eco_ShipyardTabHandler.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Eco_ShipyardTabHandler.cs index 51b98d346..d93dfca22 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Eco_ShipyardTabHandler.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Eco_ShipyardTabHandler.cs @@ -138,6 +138,10 @@ public static void RefreshShipyardTab(Panels.Eco_Summary m_oSummaryPanel, Factio DamagedShipList = new BindingList(); ClassesInOrbit = new BindingList(); + GetEligibleClassList(CurrentFaction, SYInfo, ref EligibleClassList); + GetDamagedShipList(CurrentFaction, CurrentPopulation, ref DamagedShipList); + GetShipClassesInOrbit(CurrentFaction, CurrentPopulation, ref ClassesInOrbit); + if (CurrentFaction != null && CurrentPopulation != null && SYInfo != null) { RefreshShipyardDataGrid(m_oSummaryPanel, CurrentFaction, CurrentPopulation); @@ -1051,9 +1055,9 @@ private static void GetDamagedShipList(Faction CurrentFaction, Population Curren /// Current faction from the economics handler. /// Currently selected shipyard. /// List of shipclasses that this shipyard can produce. - private static void GetEligibleClassList(Faction CurrentFaction, Installation.ShipyardInformation SYInfo, ref BindingList EligibleClassList) + public static void GetEligibleClassList(Faction CurrentFaction, Installation.ShipyardInformation SYInfo, ref BindingList EligibleClassList) { - if (SYInfo.AssignedClass == null) + if (SYInfo == null || SYInfo.AssignedClass == null) { return; } diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index 484ce4a90..332546d45 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -312,6 +312,7 @@ public Economics() m_oSummaryPanel.ShipyardDataGrid.SelectionChanged += new EventHandler(ShipyardDataGrid_SelectionChanged); m_oSummaryPanel.ExpandCapUntilXTextBox.TextChanged += new EventHandler(ExpandCapUntilXTextBox_TextChanged); m_oSummaryPanel.NewShipClassComboBox.SelectedIndexChanged += new EventHandler(NewShipClassComboBox_SelectedIndexChanged); + m_oSummaryPanel.SYNewClassComboBox.SelectedIndexChanged += new EventHandler(SYNewClassComboBox_SelectedIndexChanged); m_oSummaryPanel.RepairRefitScrapClassComboBox.SelectedIndexChanged += new EventHandler(RepairRefitScrapClassComboBox_SelectedIndexChanged); m_oSummaryPanel.AddTaskButton.Click += new EventHandler(AddTaskButton_Click); @@ -707,6 +708,11 @@ private void ShipyardDataGrid_SelectionChanged(object sender, EventArgs e) m_oSummaryPanel.ShipyardCreateTaskGroupBox.Text = Entry; } + if(m_oSummaryPanel.SYNewClassComboBox.Items.Count > 0 && m_oSummaryPanel.SYNewClassComboBox.SelectedIndex != -1) + m_oSummaryPanel.SYNewClassComboBox.Items[m_oSummaryPanel.SYNewClassComboBox.SelectedIndex] = ""; + m_oSummaryPanel.SYNewClassComboBox.Items.Clear(); + m_oSummaryPanel.SYShipNameTextBox.Text = ""; + /// /// So. I want the eco_SY tab handler to be able to populate these lists as needed. /// So. they have to be refs. @@ -763,13 +769,32 @@ private void ExpandCapUntilXTextBox_TextChanged(object sender, EventArgs e) /// private void NewShipClassComboBox_SelectedIndexChanged(object sender, EventArgs e) { - if(m_oSummaryPanel.SYNewClassComboBox.SelectedIndex != -1) + if (m_oSummaryPanel.NewClassComboBox.SelectedIndex != -1) { Eco_ShipyardTabHandler.BuildSYCRequiredMinerals(m_oSummaryPanel, CurrentFaction, CurrentPopulation, CurrentSYInfo, PotentialRetoolTargets); - int index = CurrentFaction.ShipDesigns.IndexOf(EligibleClassList[m_oSummaryPanel.SYNewClassComboBox.SelectedIndex]); - String Entry = String.Format("{0} {1}", CurrentFaction.ShipDesigns[index].Name, - (CurrentFaction.ShipDesigns[index].ShipsInClass.Count + CurrentFaction.ShipDesigns[index].ShipsUnderConstruction + 1)); - m_oSummaryPanel.SYShipNameTextBox.Text = Entry; + } + } + + /// + /// be sure to change the name of the ship currently selected. + /// + /// + /// + private void SYNewClassComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (m_oSummaryPanel.SYNewClassComboBox.SelectedIndex != -1) + { + Eco_ShipyardTabHandler.BuildSYCRequiredMinerals(m_oSummaryPanel, CurrentFaction, CurrentPopulation, CurrentSYInfo, PotentialRetoolTargets); + BindingList ECL = EligibleClassList; + Eco_ShipyardTabHandler.GetEligibleClassList(CurrentFaction, CurrentSYInfo, ref ECL); + EligibleClassList = ECL; + if (EligibleClassList.Count != 0) + { + int index = CurrentFaction.ShipDesigns.IndexOf(EligibleClassList[m_oSummaryPanel.SYNewClassComboBox.SelectedIndex]); + String Entry = String.Format("{0} {1}", CurrentFaction.ShipDesigns[index].Name, + (CurrentFaction.ShipDesigns[index].ShipsInClass.Count + CurrentFaction.ShipDesigns[index].ShipsUnderConstruction + 1)); + m_oSummaryPanel.SYShipNameTextBox.Text = Entry; + } } } From 482b09c6e4aa2cb395b921e56ac0f4af773d969f Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 19 Mar 2016 11:43:58 -0500 Subject: [PATCH 38/40] Last of the UI fixes for now Shipclass summary will now update properly, adding new ship construction tasks should increment the name counter properly, cycle moves has been added, ships that attempt and fail a load order will now cancel all orders and wait, and a few other fixes. --- .../Entities/ConstructionCycle.cs | 19 +++++ .../Pulsar4X.Lib/Entities/Installation.cs | 11 +++ .../Pulsar4X.Lib/Entities/MessageEntry.cs | 2 + Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs | 27 ++++++ .../Entities/StarSystem/Population.cs | 4 +- .../Entities/StarSystem/TaskGroup.cs | 83 ++++++++++++++++--- Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 20 ++++- Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs | 19 ++++- .../Panels/TaskGroup_Panel.Designer.cs | 8 ++ 9 files changed, 176 insertions(+), 17 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs b/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs index 99f220307..204ae851f 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs @@ -541,12 +541,21 @@ public static void TerraformPlanets(Faction CurrentFaction, Population pop) /// /// Terraforming will go over the limit specified by the user. /// + bool limit = false; if (CurrentTerraforming + CurrentGasAmt > pop._GasAmt) { CurrentTerraforming = pop._GasAmt - CurrentGasAmt; + limit = true; } pop.Planet.Atmosphere.AddGas(pop._GasToAdd, CurrentTerraforming); + + if (limit == true) + { + pop._GasAmt = 0.0f; + pop._GasToAdd = null; + pop._GasAddSubtract = false; + } } } else if (pop._GasAddSubtract == false) @@ -558,11 +567,20 @@ public static void TerraformPlanets(Faction CurrentFaction, Population pop) /// /// Terraforming will go under the limit specified by the user. /// + bool limit = false; if (CurrentTerraforming - CurrentGasAmt < pop._GasAmt) { CurrentTerraforming = CurrentGasAmt - pop._GasAmt; + limit = true; } pop.Planet.Atmosphere.AddGas(pop._GasToAdd, CurrentTerraforming); + + if (limit == true) + { + pop._GasAmt = 0.0f; + pop._GasToAdd = null; + pop._GasAddSubtract = false; + } } } } @@ -689,6 +707,7 @@ private static void BuildShips(Faction CurrentFaction, Population CurrentPopulat case Constants.ShipyardInfo.Task.Construction: Task.AssignedTaskGroup.AddShip(Task.ConstructRefitTarget, Task.Title); CurrentPopulation.FuelStockpile = Task.AssignedTaskGroup.Ships[Task.AssignedTaskGroup.Ships.Count - 1].Refuel(CurrentPopulation.FuelStockpile); + Task.AssignedTaskGroup.Ships[Task.AssignedTaskGroup.Ships.Count - 1].ShipClass.ShipsUnderConstruction--; break; case Constants.ShipyardInfo.Task.Repair: /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs index 3c0dd0bd8..670fb4ce3 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs @@ -691,6 +691,17 @@ public int CalcShipBuildRate(Faction CurrentFaction, Population CurrentPopulatio return Constants.ShipyardInfo.ShipProductionRate[BuildTech]; } + /// + /// Make a new task and add it to this Shipyard, as well as to the Current Population. + /// + public void AddTask(Population CurrentPopulation, ShipTN CurrentShip, Constants.ShipyardInfo.Task SYITask, TaskGroupTN TargetTG, int BaseBuildRate, string TextBox, ShipClassTN ConstructRefit) + { + Installation.ShipyardInformation.ShipyardTask NewTask = new Installation.ShipyardInformation.ShipyardTask(CurrentShip, SYITask, TargetTG, BaseBuildRate, TextBox, ConstructRefit); + BuildingShips.Add(NewTask); + CurrentPopulation.ShipyardTasks.Add(NewTask, this); + ConstructRefit.ShipsUnderConstruction++; + } + /// /// Helper function for repetitive code. /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/MessageEntry.cs b/Pulsar4X/Pulsar4X.Lib/Entities/MessageEntry.cs index db08056f0..dcfce8baf 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/MessageEntry.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/MessageEntry.cs @@ -24,6 +24,8 @@ public enum MessageType ContactUpdate, ContactLost, + FailureToLoad, + Firing, FiringHit, FiringMissed, diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs b/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs index 5701de4ad..66ab6a5fd 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/ShipClass.cs @@ -2656,6 +2656,33 @@ public void BuildClassSummary() Summary = String.Format("{0}{1}", Summary, Entry); + bool didCarrying = false; + if (ShipCargoDef.Count != 0) + { + Entry = String.Format("Cargo {0} ", TotalCargoCapacity); + Summary = String.Format("{0}{1}", Summary, Entry); + didCarrying = true; + } + + if (ShipColonyDef.Count != 0) + { + Entry = String.Format("Cyrogenic Berths {0} ", SpareCryoBerths); + Summary = String.Format("{0}{1}", Summary, Entry); + didCarrying = true; + } + + if (ShipCHSDef.Count != 0) + { + Entry = String.Format("Cargo Handling Multiplier {0} ", TractorMultiplier); + Summary = String.Format("{0}{1}", Summary, Entry); + didCarrying = true; + } + + if (didCarrying == true) + { + Summary = String.Format("{0}\n", Summary, Entry); + } + if (ShipMagazineDef.Count != 0) { Entry = String.Format("Magazine {0}\n", TotalMagazineCapacity); diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs index 0992733ca..596024976 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs @@ -924,7 +924,7 @@ public void AddInstallation(Installation Inst, float increment, float numToBuild /// Total mass of the installation of type iType to take from the planet. public void LoadInstallation(Installation.InstallationType iType, int massToLoad) { - Installations[(int)iType].Number =Installations[(int)iType].Number - (float)(massToLoad / Faction.InstallationTypes[(int)iType].Mass); + Installations[(int)iType].Number =Installations[(int)iType].Number - (float)((float)massToLoad / Faction.InstallationTypes[(int)iType].Mass); switch (iType) { case Installation.InstallationType.DeepSpaceTrackingStation: @@ -943,7 +943,7 @@ public void LoadInstallation(Installation.InstallationType iType, int massToLoad /// Total mass of said installation to unload. this can result in fractional changes to installation[].number public void UnloadInstallation(Installation.InstallationType iType, int massToUnload) { - Installations[(int)iType].Number = Installations[(int)iType].Number + (float)(massToUnload / Faction.InstallationTypes[(int)iType].Mass); + Installations[(int)iType].Number = Installations[(int)iType].Number + (float)((float)massToUnload / Faction.InstallationTypes[(int)iType].Mass); switch(iType) { case Installation.InstallationType.DeepSpaceTrackingStation: diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index e1db56559..421fa709c 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -224,6 +224,11 @@ public class TaskGroupTN : StarSystemEntity /// public ConditionalOrders _SpecialOrders { get; set; } + /// + /// Should this TG repeat completed orders(by placing them at the bottom of the orders list)? + /// + public bool CycleMoves { get; set; } + /// /// Constructor for the taskgroup, sets name, faction, planet the TG starts in orbit of. /// @@ -334,6 +339,8 @@ public TaskGroupTN(string Title, Faction FID, OrbitingEntity StartingBody, StarS _GravSurveyPoints = 0; _SurveyHourFraction = 0.0f; + CycleMoves = false; + //add default legal order for targeting TGs. _legalOrders.Add(Constants.ShipTN.OrderType.Follow); _legalOrders.Add(Constants.ShipTN.OrderType.Join); @@ -2200,10 +2207,20 @@ public void FollowOrders(uint TimeSlice) } /// - /// This order was completed successfully, so do not bother checking it for any conditions. + /// This order was completed successfully, add it back in if CycleMoves is true. no special conditions need to be checked for, hence skipCheck = true. + /// Don't repeat single orders by accident. /// - RemoveOrder(0, true); - //TaskGroupOrders.RemoveAt(0); + if (CycleMoves == true && TaskGroupOrders.Count > 1) + { + Order TGOrder = TaskGroupOrders[0]; + RemoveOrder(0, true); + TaskGroupOrders.Add(TGOrder); + } + else + { + RemoveOrder(0, true); + } + if (TaskGroupOrders.Count > 0) { @@ -2363,7 +2380,15 @@ public uint PerformOrders(uint TimeSlice) { TimeSlice = TimeSlice - (uint)TaskGroupOrders[0].orderTimeRequirement; TaskGroupOrders[0].orderTimeRequirement = 0; - LoadCargo(TaskGroupOrders[0].pop, (Installation.InstallationType)TaskGroupOrders[0].secondary, TaskGroupOrders[0].tertiary); + if(!LoadCargo(TaskGroupOrders[0].pop, (Installation.InstallationType)TaskGroupOrders[0].secondary, TaskGroupOrders[0].tertiary)) + { + String Entry = String.Format("No installations could be loaded to cargoships in {1} at {0}, orders have been cleared.", TaskGroupOrders[0].pop, Name); + MessageEntry NME = new MessageEntry(MessageEntry.MessageType.FailureToLoad, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); + TaskGroupFaction.MessageLog.Add(NME); + for (int orderIterator = 0; orderIterator < TaskGroupOrders.Count; orderIterator++) + RemoveOrder(0, false); + CycleMoves = false; + } CanOrder = Constants.ShipTN.OrderState.AcceptOrders; } else @@ -2392,7 +2417,15 @@ public uint PerformOrders(uint TimeSlice) { TimeSlice = TimeSlice - (uint)TaskGroupOrders[0].orderTimeRequirement; TaskGroupOrders[0].orderTimeRequirement = 0; - LoadComponents(TaskGroupOrders[0].pop, TaskGroupOrders[0].secondary, TaskGroupOrders[0].tertiary); + if (!LoadComponents(TaskGroupOrders[0].pop, TaskGroupOrders[0].secondary, TaskGroupOrders[0].tertiary)) + { + String Entry = String.Format("No components could be loaded to cargoships in {1} at {0}, orders have been cleared.", TaskGroupOrders[0].pop,Name); + MessageEntry NME = new MessageEntry(MessageEntry.MessageType.FailureToLoad, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); + TaskGroupFaction.MessageLog.Add(NME); + for (int orderIterator = 0; orderIterator < TaskGroupOrders.Count; orderIterator++) + RemoveOrder(0, false); + CycleMoves = false; + } CanOrder = Constants.ShipTN.OrderState.AcceptOrders; } else @@ -2505,7 +2538,15 @@ public uint PerformOrders(uint TimeSlice) { TimeSlice = TimeSlice - (uint)TaskGroupOrders[0].orderTimeRequirement; TaskGroupOrders[0].orderTimeRequirement = 0; - LoadColonists(TaskGroupOrders[0].pop, TaskGroupOrders[0].tertiary); + if(!LoadColonists(TaskGroupOrders[0].pop, TaskGroupOrders[0].tertiary)) + { + String Entry = String.Format("No Colonists could be loaded to colonyships in {1} at {0}, orders have been cleared.", TaskGroupOrders[0].pop, Name); + MessageEntry NME = new MessageEntry(MessageEntry.MessageType.FailureToLoad, Contact.Position.System, Contact, GameState.Instance.GameDateTime, GameState.Instance.CurrentSecond, Entry); + TaskGroupFaction.MessageLog.Add(NME); + for (int orderIterator = 0; orderIterator < TaskGroupOrders.Count; orderIterator++) + RemoveOrder(0, false); + CycleMoves = false; + } CanOrder = Constants.ShipTN.OrderState.AcceptOrders; } else @@ -3534,6 +3575,7 @@ public void clearAllOrders() TaskGroupOrders.Clear(); TimeRequirement = 0; TotalOrderDistance = 0; + CycleMoves = false; } @@ -3593,12 +3635,15 @@ bool ContainsCollier() /// Population to load from. /// installation type to load. /// Limit in number of facilities to load. - public void LoadCargo(Population Pop, Installation.InstallationType InstType, int Limit) + public bool LoadCargo(Population Pop, Installation.InstallationType InstType, int Limit) { int RemainingTaskGroupTonnage = TotalCargoTonnage - CurrentCargoTonnage; int TotalMass = TaskGroupFaction.InstallationTypes[(int)InstType].Mass * Limit; int AvailableMass = (int)(Pop.Installations[(int)InstType].Number * (float)TaskGroupFaction.InstallationTypes[(int)InstType].Mass); + if (AvailableMass == 0) + return false; + int MassToLoad = 0; /// @@ -3657,6 +3702,7 @@ public void LoadCargo(Population Pop, Installation.InstallationType InstType, in Ships[loop].CurrentCargoTonnage = ShipMassToLoad; } } + return true; } /// @@ -3705,12 +3751,15 @@ public void UnloadCargo(Population Pop, Installation.InstallationType InstType, /// /// /// - public void LoadMineral(Population Pop, Constants.Minerals.MinerialNames MinType, int Limit) + public bool LoadMineral(Population Pop, Constants.Minerals.MinerialNames MinType, int Limit) { int RemainingTaskGroupTonnage = TotalCargoTonnage - CurrentCargoTonnage; int TotalMass = Limit; int AvailableMass = (int)(Pop.Minerials[(int)MinType]); + if (AvailableMass == 0) + return false; + int MassToLoad = 0; /// @@ -3769,6 +3818,7 @@ public void LoadMineral(Population Pop, Constants.Minerals.MinerialNames MinType Ships[loop].CurrentCargoTonnage = ShipMassToLoad; } } + return true; } /// @@ -3815,8 +3865,11 @@ public void UnloadMineral(Population Pop, Constants.Minerals.MinerialNames MinTy /// /// Population to load from. /// Limit on colonists who can be put onto taskgroup. - public void LoadColonists(Population Pop, int Limit) + public bool LoadColonists(Population Pop, int Limit) { + if (Pop.CivilianPopulation == 0.0f) + return false; + for (int loop = 0; loop < Ships.Count; loop++) { if (Ships[loop].ShipClass.SpareCryoBerths != 0) @@ -3851,6 +3904,8 @@ public void LoadColonists(Population Pop, int Limit) Pop.CivilianPopulation = Pop.CivilianPopulation - ((float)Colonists / 1000000.0f); } } + + return true; } /// @@ -3893,12 +3948,18 @@ public void UnloadColonists(Population Pop, int Limit) /// Population of the component pickup. /// location in pop.ComponentStockpile. /// Number of said components to pick up if not all of them. - public void LoadComponents(Population Pop, int ComponentIndex, int Limit) + public bool LoadComponents(Population Pop, int ComponentIndex, int Limit) { + if (Pop.ComponentStockpile.Count <= ComponentIndex) + return false; + int RemainingTonnage = TotalCargoTonnage - CurrentCargoTonnage; int TotalMass = (int)(Pop.ComponentStockpile[ComponentIndex].size * Constants.ShipTN.TonsPerHS * (float)Limit); int AvailableMass = (int)(Pop.ComponentStockpile[ComponentIndex].size * Constants.ShipTN.TonsPerHS * Pop.ComponentStockpileCount[ComponentIndex]); + if (AvailableMass == 0) + return false; + int MassToLoad = 0; /// @@ -3966,6 +4027,8 @@ public void LoadComponents(Population Pop, int ComponentIndex, int Limit) MassToLoad = MassToLoad - ShipMassToLoad; } } + + return true; } /// diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index 332546d45..4ace29daa 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -908,9 +908,7 @@ private void AddTaskButton_Click(object sender, EventArgs e) /// if (CurrentSYInfo.Slipways > CurrentSYInfo.BuildingShips.Count) { - Installation.ShipyardInformation.ShipyardTask NewTask = new Installation.ShipyardInformation.ShipyardTask(CurrentShip, SYITask, TargetTG, BaseBuildRate, m_oSummaryPanel.SYShipNameTextBox.Text, ConstructRefit); - CurrentSYInfo.BuildingShips.Add(NewTask); - CurrentPopulation.ShipyardTasks.Add(NewTask, CurrentSYInfo); + CurrentSYInfo.AddTask(CurrentPopulation, CurrentShip, SYITask, TargetTG, BaseBuildRate, m_oSummaryPanel.SYShipNameTextBox.Text, ConstructRefit); /// /// Cost display for the new order. @@ -4512,6 +4510,22 @@ private void BuildTerraformingTab() { SystemBody CurrentPlanet = CurrentPopulation.Planet; Atmosphere CurrentAtmosphere = CurrentPlanet.Atmosphere; + + m_oSummaryPanel.TerraformingAddGasCheckBox.Checked = CurrentPopulation._GasAddSubtract; + m_oSummaryPanel.TerraformingMaxGasTextBox.Text = CurrentPopulation._GasAmt.ToString(); + + if (m_oSummaryPanel.TerraformingGasComboBox.Items.Count != 0) + { + m_oSummaryPanel.TerraformingGasComboBox.SelectedIndex = 0; + for (int gasIterator = 0; gasIterator < m_oSummaryPanel.TerraformingGasComboBox.Items.Count; gasIterator++) + { + if (m_oSummaryPanel.TerraformingGasComboBox.Items[gasIterator] == CurrentPopulation._GasToAdd) + { + m_oSummaryPanel.TerraformingGasComboBox.SelectedIndex = gasIterator; + } + } + } + m_oSummaryPanel.TerraformingAtmosphereListBox.Items.Clear(); float TotalGas = CurrentAtmosphere.Pressure; String Entry = "N/A"; diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs index dde305ff7..2a45825d3 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs @@ -229,6 +229,8 @@ public TaskGroup() m_oTaskGroupPanel.PlottedMovesListBox.MouseDown += new MouseEventHandler(PlottedMovesListBox_MouseDown); SelectedOrderIndex = m_oTaskGroupPanel.PlottedMovesListBox.SelectedIndex; + m_oTaskGroupPanel.CycleMovesCheckBox.CheckStateChanged += new EventHandler(CycleMovesCheckBox_CheckStateChanged); + #region Organization Tab m_oTaskGroupPanel.OrgSelectedTGComboBox.SelectedIndexChanged += new EventHandler(OrgSelectedTGComboBox_SelectedIndexChanged); m_oTaskGroupPanel.OrgMoveLeftButton.Click += new EventHandler(OrgMoveLeftButton_Click); @@ -308,6 +310,16 @@ private void AllOrdersTDRadioButton_CheckChanged(object sender, EventArgs e) CalculateTimeDistance(); } + /// + /// Set the currently selected taskgroup to cycle its own moves. + /// + /// + /// + private void CycleMovesCheckBox_CheckStateChanged(object sender, EventArgs e) + { + CurrentTaskGroup.CycleMoves = m_oTaskGroupPanel.CycleMovesCheckBox.Checked; + } + /// /// If a location is chosen build the action list. /// @@ -315,6 +327,9 @@ private void AllOrdersTDRadioButton_CheckChanged(object sender, EventArgs e) /// private void SystemLocationListBox_SelectedIndexChanged(object sender, EventArgs e) { + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Items.Clear(); + m_oTaskGroupPanel.TaskgroupSecondaryListBox.Visible = false; + m_oTaskGroupPanel.TaskgroupSecondaryGroupBox.Visible = false; BuildActionList(); } @@ -456,7 +471,7 @@ private void MaxSpeedButton_Clicked(object sender, EventArgs e) /// /// Adds the selected order to the task group's list of orders. This function is going to get giant. - /// Not handled: Order filtering, delays, secondary and tertiary orders. + /// Not handled: Order filtering, delays, secondary and tertiary orders. secondaries partially done now. /// As for adding new things here, look at the logic for how they were added to the SystemLocationListBox to derive how to get to them for this code. /// Don't forget filtering of destinations by survey status. /// @@ -1336,7 +1351,6 @@ private void BuildSystemLocationList() /// private void PlottedMovesListBox_MouseDown(object sender, MouseEventArgs e) { - if (m_oTaskGroupPanel.PlottedMovesListBox.SelectedIndex != -1) { var rect = m_oTaskGroupPanel.PlottedMovesListBox.GetItemRectangle(m_oTaskGroupPanel.PlottedMovesListBox.SelectedIndex); @@ -2034,6 +2048,7 @@ private void RefreshTGPanel() { if (CurrentTaskGroup != null) { + m_oTaskGroupPanel.CycleMovesCheckBox.Checked = CurrentTaskGroup.CycleMoves; m_oTaskGroupPanel.TaskGroupLocationTextBox.Text = CurrentTaskGroup.Contact.Position.System.Name; m_oTaskGroupPanel.SetSpeedTextBox.Text = CurrentTaskGroup.CurrentSpeed.ToString(); m_oTaskGroupPanel.MaxSpeedTextBox.Text = CurrentTaskGroup.MaxSpeed.ToString(); diff --git a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs index b201eaa8e..7d27fb79b 100644 --- a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs +++ b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs @@ -153,6 +153,14 @@ public CheckBox ExcludeSurveyedCheckBox get { return m_oExcludeSurveyedCheckBox; } } + /// + /// Place any completed orders back in the order list so that a taskgroup will repeatedly perform an order cycle such as "go to here, get a mine, go to there, drop it off" + /// + public CheckBox CycleMovesCheckBox + { + get { return m_oCycleMovesCheckBox; } + } + /// /// creates a new task group. /// From 9d3470b57e6408ca7ac6e584b8ea86199959b95a Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 27 Mar 2016 10:25:18 -0500 Subject: [PATCH 39/40] more testing and bugfixes I lied on the last update apparently. --- .../Entities/ConstructionCycle.cs | 3 + .../Pulsar4X.Lib/Entities/Installation.cs | 4 +- .../Entities/StarSystem/AtmosphericGas.cs | 4 +- .../Entities/StarSystem/Population.cs | 162 +++++++++++++++++- Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 90 +++++++--- Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs | 69 +++++++- .../Panels/TaskGroup_Panel.Designer.cs | 8 + 7 files changed, 311 insertions(+), 29 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs b/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs index 204ae851f..54121cfe9 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/ConstructionCycle.cs @@ -634,6 +634,9 @@ public static void PopulationGrowth(Faction CurrentFaction, Population CurrentPo #warning Is this ok for the dieoff calculation for population? float CurrentDieoff = -1.0f *( ((float)CurrentInfrastructure / (float)TotalInfraRequirement) * Constants.Colony.ConstructionCycleFraction); + if (CurrentInfrastructure == 0) + CurrentDieoff = -1.0f * (CurrentPopulation.CivilianPopulation * 0.1f); + CurrentPopulation.AddPopulation(CurrentDieoff); } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs index 670fb4ce3..947ea8450 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Installation.cs @@ -1023,7 +1023,8 @@ public Installation(InstallationType a_eType) } case InstallationType.ConvertMineToAutomated: { - Name = "Convert mine to Automated"; + Name = "Convert Mine to Automated"; + Cost = 150; m_aiMinerialsCost[(int)Constants.Minerals.MinerialNames.Duranium] = 75; m_aiMinerialsCost[(int)Constants.Minerals.MinerialNames.Corundium] = 75; ThermalSignature = 5; @@ -1294,6 +1295,7 @@ public bool IsBuildable(Faction Fact, Population Pop) return false; } + /// /// Technology Check /// diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/AtmosphericGas.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/AtmosphericGas.cs index f3c5ad717..0a50cb30d 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/AtmosphericGas.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/AtmosphericGas.cs @@ -298,7 +298,7 @@ public AtmosphericGas(string name, string chemicalSym, bool isToxic, bool hazard HazardOne = false, HazardTwo = false, MeltingPoint = 0, - BoilingPoint = 100, + BoilingPoint = -300, //if SGG ever won't work, that is bad. GreenhouseEffect = 1 }}, @@ -310,7 +310,7 @@ public AtmosphericGas(string name, string chemicalSym, bool isToxic, bool hazard HazardOne = false, HazardTwo = false, MeltingPoint = 0, - BoilingPoint = 100, + BoilingPoint = -300, GreenhouseEffect = -1 }} }; diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs index 596024976..0845f8148 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/Population.cs @@ -924,7 +924,14 @@ public void AddInstallation(Installation Inst, float increment, float numToBuild /// Total mass of the installation of type iType to take from the planet. public void LoadInstallation(Installation.InstallationType iType, int massToLoad) { - Installations[(int)iType].Number =Installations[(int)iType].Number - (float)((float)massToLoad / Faction.InstallationTypes[(int)iType].Mass); + Installations[(int)iType].Number = Installations[(int)iType].Number - (float)((float)massToLoad / Faction.InstallationTypes[(int)iType].Mass); + + /// + /// floating points! + /// + if (Installations[(int)iType].Number < 0.00001f) + Installations[(int)iType].Number = 0.0f; + switch (iType) { case Installation.InstallationType.DeepSpaceTrackingStation: @@ -1335,6 +1342,7 @@ public float CalcTotalIndustry() #warning No Governor,Sector, Tech bonuses, and no engineering squad additions. likewise activation and deactivation of industry should be handled. also efficiencies. also for OF and FF, mining and refining. #warning implement radiation in addition to governor/sector bonuses. industrial penalty is Rad / 100(45 = -0.45%) float BP = (float)Math.Floor(Installations[(int)Installation.InstallationType.ConstructionFactory].Number) * 10.0f + (float)Math.Floor(Installations[(int)Installation.InstallationType.ConventionalIndustry].Number); + BP = BP * ModifierManfacturing; return BP; } @@ -1345,6 +1353,7 @@ public float CalcTotalIndustry() public float CalcTotalOrdnanceIndustry() { float BP = (float)(Math.Floor(Installations[(int)Installation.InstallationType.OrdnanceFactory].Number) * 10.0f); + BP = BP * ModifierManfacturing; return BP; } @@ -1355,6 +1364,7 @@ public float CalcTotalOrdnanceIndustry() public float CalcTotalFighterIndustry() { float BP = (float)(Math.Floor(Installations[(int)Installation.InstallationType.FighterFactory].Number) * 10.0f); + BP = BP * ModifierManfacturing; return BP; } @@ -1366,6 +1376,7 @@ public float CalcTotalMining() { float MP = (float)(Math.Floor(Installations[(int)Installation.InstallationType.Mine].Number) * 10.0f) + (float)(Math.Floor(Installations[(int)Installation.InstallationType.AutomatedMine].Number) * 10.0f) + (float)(Math.Floor(Installations[(int)Installation.InstallationType.ConventionalIndustry].Number)); + MP = MP * ModifierManfacturing; return MP; } @@ -1378,6 +1389,7 @@ public float CalcTotalRefining() { float BP = (float)(Math.Floor(Installations[(int)Installation.InstallationType.FuelRefinery].Number) * Constants.Colony.SoriumToFuel * 10.0f) + (float)Math.Floor(Installations[(int)Installation.InstallationType.ConventionalIndustry].Number * Constants.Colony.SoriumToFuel); + BP = BP * ModifierManfacturing; return BP; } @@ -1389,6 +1401,7 @@ public float CalcTotalTerraforming() { int modules = (int)Math.Floor(_OrbitalTerraformModules); float TP = (float)((int)Math.Floor(Installations[(int)Installation.InstallationType.TerraformingInstallation].Number) + modules) * Constants.Colony.TerraformRate[0]; + TP = TP * ModifierManfacturing; return TP; } @@ -1577,6 +1590,153 @@ public void HandleShipyardCost(decimal ItemCost, decimal[] MineralCost, float Co public void AddPopulation(float Growth) { CivilianPopulation = CivilianPopulation + Growth; + + float TotalWorkerReq = 0.0f; + int iShipyards = (int)(Installations[(int)Installation.InstallationType.CommercialShipyard].Number + Installations[(int)Installation.InstallationType.NavalShipyardComplex].Number); + +#warning Magic numbers here for worker calculations same as in economics.cs + float ShipyardWorkers = 1000000.0f * iShipyards; + + int iSlipways = 0; + for (int CSYIterator = 0; CSYIterator < (int)Installations[(int)Installation.InstallationType.CommercialShipyard].Number; CSYIterator++) + { + int slips = Installations[(int)Installation.InstallationType.CommercialShipyard].SYInfo[CSYIterator].Slipways; + int tons = Installations[(int)Installation.InstallationType.CommercialShipyard].SYInfo[CSYIterator].Tonnage; + + /// + /// Manpower requirement = 1,000,000 + num_slipways * capacity_per_slipway_in_tons * 100 / DIVISOR. DIVISOR is 1 for military yards and 10 for commercial yards. Thus, the flat 1,000,000 manpower required is not reduced for commercial yards, only the capacity-based component. + /// + ShipyardWorkers = ShipyardWorkers + (slips * tons * 100 / 10); + } + + for (int NSYIterator = 0; NSYIterator < (int)Installations[(int)Installation.InstallationType.NavalShipyardComplex].Number; NSYIterator++) + { + int slips = Installations[(int)Installation.InstallationType.NavalShipyardComplex].SYInfo[NSYIterator].Slipways; + int tons = Installations[(int)Installation.InstallationType.NavalShipyardComplex].SYInfo[NSYIterator].Tonnage; + /// + /// Manpower requirement = 1,000,000 + num_slipways * capacity_per_slipway_in_tons * 100 / DIVISOR. DIVISOR is 1 for military yards and 10 for commercial yards. Thus, the flat 1,000,000 manpower required is not reduced for commercial yards, only the capacity-based component. + /// + ShipyardWorkers = ShipyardWorkers + (slips * tons * 100 / 1); + } + + /// + /// Shipyards + /// + if (iShipyards != 0) + { + TotalWorkerReq = TotalWorkerReq + (ShipyardWorkers / 1000000.0f); + } + + /// + /// Maintenance Facility Workers. This is separate from Maintenance factories above as shipyards needed to be calculated first for offset adjustment. + /// = 1.0f) + { + float workers = 0.05f * (float)Math.Floor(Installations[(int)Installation.InstallationType.MaintenanceFacility].Number); + TotalWorkerReq = TotalWorkerReq + workers; + } + + /// + /// Construction Factories + /// + if (Installations[(int)Installation.InstallationType.ConstructionFactory].Number >= 1.0f) + { + float workers = 0.05f * (float)Math.Floor(Installations[(int)Installation.InstallationType.ConstructionFactory].Number); + /// + /// Conventional Industry worker adjustment. + /// + if (Installations[(int)Installation.InstallationType.ConventionalIndustry].Number >= 1.0f) + { + workers = workers + (0.05f * (float)Math.Floor(Installations[(int)Installation.InstallationType.ConventionalIndustry].Number)); + } + TotalWorkerReq = TotalWorkerReq + workers; + } + + /// + /// Conventional Industry + /// + if (Installations[(int)Installation.InstallationType.ConventionalIndustry].Number >= 1.0f) + { + if (Installations[(int)Installation.InstallationType.ConstructionFactory].Number < 1.0f) + { + float workers = 0.05f * (float)Math.Floor(Installations[(int)Installation.InstallationType.ConventionalIndustry].Number); + TotalWorkerReq = TotalWorkerReq + workers; + } + } + + + /// + /// Ordnance Factories + /// + if (Installations[(int)Installation.InstallationType.OrdnanceFactory].Number >= 1.0f) + { + float workers = 0.05f * (float)Math.Floor(Installations[(int)Installation.InstallationType.OrdnanceFactory].Number); + TotalWorkerReq = TotalWorkerReq + workers; + } + + /// + /// Fighter Factories + /// + if (Installations[(int)Installation.InstallationType.FighterFactory].Number >= 1.0f) + { + float workers = 0.05f * (float)Math.Floor(Installations[(int)Installation.InstallationType.FighterFactory].Number); + TotalWorkerReq = TotalWorkerReq + workers; + } + + /// + /// Refineries + /// + if (Installations[(int)Installation.InstallationType.FuelRefinery].Number >= 1.0f) + { + float workers = 0.05f * (float)Math.Floor(Installations[(int)Installation.InstallationType.FuelRefinery].Number); + TotalWorkerReq = TotalWorkerReq + workers; + + + } + + /// + /// Financial Centre Workers + /// + if (Installations[(int)Installation.InstallationType.FinancialCentre].Number >= 1.0f) + { + float workers = 0.05f * (float)Math.Floor(Installations[(int)Installation.InstallationType.FinancialCentre].Number); + TotalWorkerReq = TotalWorkerReq + workers; + } + + /// + /// mines + /// + if (Installations[(int)Installation.InstallationType.Mine].Number >= 1.0f) + { + float workers = 0.05f * (float)Math.Floor(Installations[(int)Installation.InstallationType.Mine].Number); + TotalWorkerReq = TotalWorkerReq + workers; + } + + /// + /// Terraformers + /// + if (Installations[(int)Installation.InstallationType.TerraformingInstallation].Number >= 1.0f) + { + float workers = 0.25f * (float)Math.Floor(Installations[(int)Installation.InstallationType.TerraformingInstallation].Number); + TotalWorkerReq = TotalWorkerReq + workers; + } + + /// + /// Research labs + /// + if (Installations[(int)Installation.InstallationType.ResearchLab].Number >= 1.0f) + { + float workers = 1.0f * (float)Math.Floor(Installations[(int)Installation.InstallationType.ResearchLab].Number); + TotalWorkerReq = TotalWorkerReq + workers; + } + + + if (TotalWorkerReq > PopulationWorkingInManufacturing) + { + ModifierManfacturing = PopulationWorkingInManufacturing / TotalWorkerReq; + } + else + ModifierManfacturing = 1.0f; } #endregion diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index 4ace29daa..ea9440c0c 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -345,6 +345,7 @@ public Economics() #region Terraforming Tab m_oSummaryPanel.TerraformingSaveAtmButton.Click += new EventHandler(TerraformingSaveAtmButton_Click); + m_oSummaryPanel.TerraformingGasComboBox.Items.Add("Terraforming Inactive"); foreach (WeightedValue Gas in AtmosphericGas.AtmosphericGases) { m_oSummaryPanel.TerraformingGasComboBox.Items.Add(Gas.Value.Name); @@ -1022,25 +1023,27 @@ private void SYARaisePriorityButton_Click(object sender, EventArgs e) /// private void TerraformingSaveAtmButton_Click(object sender, EventArgs e) { - /// - /// True = add gas, false = subtract gas. - /// - if (m_oSummaryPanel.TerraformingAddGasCheckBox.Checked == true) - CurrentPopulation._GasAddSubtract = true; - else - CurrentPopulation._GasAddSubtract = false; + //index zero is inactive terraforming + if (m_oSummaryPanel.TerraformingGasComboBox.SelectedIndex != -1 && m_oSummaryPanel.TerraformingGasComboBox.SelectedIndex != 0) + { + /// + /// True = add gas, false = subtract gas. + /// + if (m_oSummaryPanel.TerraformingAddGasCheckBox.Checked == true) + CurrentPopulation._GasAddSubtract = true; + else + CurrentPopulation._GasAddSubtract = false; - float getAtm; - bool r1 = float.TryParse(m_oSummaryPanel.TerraformingMaxGasTextBox.Text, out getAtm); + float getAtm; + bool r1 = float.TryParse(m_oSummaryPanel.TerraformingMaxGasTextBox.Text, out getAtm); - if (r1 == true) - { - CurrentPopulation._GasAmt = getAtm; - } + if (r1 == true) + { + CurrentPopulation._GasAmt = getAtm; + } - if (m_oSummaryPanel.TerraformingGasComboBox.SelectedIndex != -1) - { - int Count = 0; + + int Count = 1; foreach (WeightedValue Gas in AtmosphericGas.AtmosphericGases) { if (Count == m_oSummaryPanel.TerraformingGasComboBox.SelectedIndex) @@ -1588,11 +1591,20 @@ private void SoftRefresh() { if (m_oCurrnetFaction != null) { + /// + /// Update population growth and new colonies. + /// + BuildTreeView(); + /// /// Summary Tab: /// RefreshSummaryCells(); + /// + /// after finishing building things that require CI, the ability to select them should go away. + RefreshIndustryTab(); + /// /// Refresh the construction queue: /// @@ -2203,6 +2215,31 @@ public void RefreshSummaryCells() Entry = String.Format("{0:N2}m", CurrentPopulation.PopulationWorkingInManufacturing); m_oSummaryPanel.SummaryDataGrid.Rows[10].Cells[1].Value = Entry; Entry = String.Format("{0:N2}%", CurrentPopulation.PopulationGrowthRate); + + if (ColCost != 0.0) + { + /// + /// How much Infra does this colony need per 1M colonists? + /// + int InfrastructureRequirement = (int)Math.Floor(ColCost * 100.0f); + + /// + /// How much infra is currently on the planet? + /// + int CurrentInfrastructure = (int)Math.Floor(CurrentPopulation.Installations[(int)Installation.InstallationType.Infrastructure].Number); + + /// + /// How much does this planet need? if the planet does need some it should generate a little on its own. + /// + int TotalInfraRequirement = (int)Math.Floor(InfrastructureRequirement * CurrentPopulation.CivilianPopulation); + + if (TotalInfraRequirement > CurrentInfrastructure) + { + Entry = "Population Dieoff"; + } + } + + m_oSummaryPanel.SummaryDataGrid.Rows[11].Cells[1].Value = Entry; Adjust1 = 5; @@ -2686,7 +2723,9 @@ public void RefreshSummaryCells() m_oSummaryPanel.SummaryDataGrid.Rows[13 + Adjust1].Cells[1].Value = null; //CurrentPopulation.SystemBody.PlanetaryTectonics; if (CurrentPopulation.Planet.GeoSurveyList.ContainsKey(CurrentFaction) == true) { - Entry = "Completed"; +#warning this needs to be reworked for the addition of geo teams. right now it is checking whether a survey ship has surveyed from orbit, not the team surveying. + //Entry = "Completed"; + Entry = "No"; } else { @@ -4438,7 +4477,7 @@ private void RefreshMiningTab() /// /// 4 is YTD. reserves / mining /// - if (m_oCurrnetPopulation.CalcTotalMining() != 0.0f) + if (m_oCurrnetPopulation.CalcTotalMining() != 0.0f && m_oCurrnetPopulation.Planet.MinerialReserves[mineralIterator] != 0.0f) { int YTD = (int)(Math.Floor(m_oCurrnetPopulation.Planet.MinerialReserves[mineralIterator]) / (Math.Floor(m_oCurrnetPopulation.CalcTotalMining() * m_oCurrnetPopulation.Planet.MinerialAccessibility[mineralIterator]))); if (YTD > YearsToDepletion) @@ -4517,13 +4556,22 @@ private void BuildTerraformingTab() if (m_oSummaryPanel.TerraformingGasComboBox.Items.Count != 0) { m_oSummaryPanel.TerraformingGasComboBox.SelectedIndex = 0; - for (int gasIterator = 0; gasIterator < m_oSummaryPanel.TerraformingGasComboBox.Items.Count; gasIterator++) + + int count = 1; + bool gasSet = false; + foreach (WeightedValue Gas in AtmosphericGas.AtmosphericGases) { - if (m_oSummaryPanel.TerraformingGasComboBox.Items[gasIterator] == CurrentPopulation._GasToAdd) + if (CurrentPopulation._GasToAdd == Gas.Value) { - m_oSummaryPanel.TerraformingGasComboBox.SelectedIndex = gasIterator; + gasSet = true; + break; } + + count++; } + + if (gasSet == true) + m_oSummaryPanel.TerraformingGasComboBox.SelectedIndex = count; } m_oSummaryPanel.TerraformingAtmosphereListBox.Items.Clear(); diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs index 2a45825d3..b7972a14c 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/TaskGroup.cs @@ -208,6 +208,7 @@ public TaskGroup() m_oTaskGroupPanel.OrderFilteringCheckBox.CheckStateChanged += new EventHandler(OrderFilteringCheckBox_CheckChanged); m_oTaskGroupPanel.DisplaySurveyLocationsCheckBox.CheckStateChanged += new EventHandler(DisplayCheckBox_CheckChanged); m_oTaskGroupPanel.ExcludeSurveyedCheckBox.CheckStateChanged += new EventHandler(DisplayCheckBox_CheckChanged); + m_oTaskGroupPanel.DisplayMoonsCheckBox.CheckStateChanged += new EventHandler(DisplayCheckBox_CheckChanged); m_oTaskGroupPanel.NewTaskGroupButton.Click += new EventHandler(NewTaskGroupButton_Click); m_oTaskGroupPanel.RenameTaskGroupButton.Click += new EventHandler(RenameTaskGroupButton_Click); @@ -614,10 +615,8 @@ private void AddMoveButton_Clicked(object sender, EventArgs e) { if (popTargetOfOrder.Minerials[(int)MinIterator] >= 1.0f) { - if (MineralSelection != -1) - { - SecondaryOrder = (int)MinIterator; - } + SecondaryOrder = (int)MinIterator; + break; } } } @@ -1510,6 +1509,44 @@ private void AddPlanetsToList(StarSystem starsystem) SystemLocationGuidDict.Add(entObj.Id, keyName); SystemLocationDict.Add(entObj.Id, valueObj); } + + if (m_oTaskGroupPanel.DisplayMoonsCheckBox.Checked == true) + { + foreach (SystemBody moon in planet.Moons) + { + PopCount = 0; + keyName = "N/A"; + foreach (Population CurrentPopulation in moon.Populations) + { + if (CurrentPopulation.Faction == CurrentFaction) + { + keyName = string.Format("{0} - {1}", CurrentPopulation.Name, CurrentPopulation.Species.Name); + if (CurrentFaction.Capitol == CurrentPopulation) + keyName = string.Format("{0}(Capitol)", keyName); + + keyName = string.Format("{0}: {1:n2}m", keyName, CurrentPopulation.CivilianPopulation); + + StarSystemEntity entObj = CurrentPopulation; + SystemListObject.ListEntityType entType = SystemListObject.ListEntityType.Colonies; + SystemListObject valueObj = new SystemListObject(entType, entObj); + SystemLocationGuidDict.Add(entObj.Id, keyName); + SystemLocationDict.Add(entObj.Id, valueObj); + + PopCount++; + } + } + + if (PopCount == 0) + { + keyName = moon.Name; + StarSystemEntity entObj = moon; + SystemListObject.ListEntityType entType = SystemListObject.ListEntityType.Planets; //moons are in the planets category + SystemListObject valueObj = new SystemListObject(entType, entObj); + SystemLocationGuidDict.Add(entObj.Id, keyName); + SystemLocationDict.Add(entObj.Id, valueObj); + } + } + } } } } @@ -2041,6 +2078,29 @@ private void BuildOrgSelectedTGList() } #endregion + #region Special Orders Tab + private void BuildSpecialOrdersTab() + { +#warning the special orders system can be substantially improved, and the rest of the conditional orders aren't done at all. + if (CurrentTaskGroup._SpecialOrders._DefaultOrdersList.Count == 0 && m_oTaskGroupPanel.PrimaryDefaultOrderComboBox.Items.Count != 0 && m_oTaskGroupPanel.SecondaryDefaultOrderComboBox.Items.Count != 0) + { + m_oTaskGroupPanel.PrimaryDefaultOrderComboBox.SelectedIndex = 0; + m_oTaskGroupPanel.SecondaryDefaultOrderComboBox.SelectedIndex = 0; + } + else + { + if (CurrentTaskGroup._SpecialOrders._DefaultOrdersList.Count == 1) + m_oTaskGroupPanel.PrimaryDefaultOrderComboBox.SelectedIndex = (int)CurrentTaskGroup._SpecialOrders._DefaultOrdersList[0]; + if (CurrentTaskGroup._SpecialOrders._DefaultOrdersList.Count == 2) + { + m_oTaskGroupPanel.PrimaryDefaultOrderComboBox.SelectedIndex = (int)CurrentTaskGroup._SpecialOrders._DefaultOrdersList[0]; + m_oTaskGroupPanel.SecondaryDefaultOrderComboBox.SelectedIndex = (int)CurrentTaskGroup._SpecialOrders._DefaultOrdersList[1]; + } + + } + } + #endregion + /// /// Refresh the TG page. /// @@ -2061,6 +2121,7 @@ private void RefreshTGPanel() BuildOrgSelectedTGList(); BuildOrganizationTab(); + BuildSpecialOrdersTab(); } } diff --git a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs index 7d27fb79b..f15e2729f 100644 --- a/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs +++ b/Pulsar4X/Pulsar4X.UI/Panels/TaskGroup_Panel.Designer.cs @@ -113,6 +113,14 @@ public CheckBox DisplayContactsCheckBox get { return m_oContactsCheckBox; } } + /// + /// Should moons be destinations? + /// + public CheckBox DisplayMoonsCheckBox + { + get { return m_oMoonsCheckBox; } + } + /// /// display taskgroups checkbox. /// From 6cab8576bfab65631d22d42c56bd28996894c4e7 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sat, 2 Apr 2016 08:42:30 -0500 Subject: [PATCH 40/40] Economics UI fix and cargolist fix infrastructure display is rounded, and cargolists now don't add items of 0 tons to cargo ships. --- .../Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs | 15 +++++++++++++++ Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs index 421fa709c..2c57d09dc 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/StarSystem/TaskGroup.cs @@ -3681,6 +3681,7 @@ public bool LoadCargo(Population Pop, Installation.InstallationType InstType, in if (Ships[loop].ShipClass.TotalCargoCapacity != 0 && RemainingShipTonnage != 0) { int ShipMassToLoad = Math.Min(MassToLoad, RemainingShipTonnage); + /// /// Load the mass onto the taskgroup as a whole for display purposes. @@ -3701,6 +3702,8 @@ public bool LoadCargo(Population Pop, Installation.InstallationType InstType, in MassToLoad = MassToLoad - ShipMassToLoad; Ships[loop].CurrentCargoTonnage = ShipMassToLoad; } + if (MassToLoad == 0) + break; } return true; } @@ -3740,6 +3743,14 @@ public void UnloadCargo(Population Pop, Installation.InstallationType InstType, CurrentCargoTonnage = CurrentCargoTonnage - ShipMassToUnload; Ships[loop].CurrentCargoTonnage = Ships[loop].CurrentCargoTonnage - ShipMassToUnload; + /// + /// Extra sanity check + /// + if (CLE.tons == 0 && Ships[loop].CargoList.ContainsKey(InstType) == true) + { + Ships[loop].CargoList.Remove(InstType); + } + Pop.UnloadInstallation(InstType, ShipMassToUnload); } } @@ -3817,6 +3828,8 @@ public bool LoadMineral(Population Pop, Constants.Minerals.MinerialNames MinType MassToLoad = MassToLoad - ShipMassToLoad; Ships[loop].CurrentCargoTonnage = ShipMassToLoad; } + if (MassToLoad == 0) + break; } return true; } @@ -4026,6 +4039,8 @@ public bool LoadComponents(Population Pop, int ComponentIndex, int Limit) MassToLoad = MassToLoad - ShipMassToLoad; } + if (MassToLoad == 0) + break; } return true; diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs index ea9440c0c..a947430c7 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Economics.cs @@ -2264,7 +2264,8 @@ public void RefreshSummaryCells() { m_oSummaryPanel.SummaryDataGrid.Rows[8 + Adjust1].Cells[1].Value = "Underground Infra not implemented"; } - m_oSummaryPanel.SummaryDataGrid.Rows[9 + Adjust1].Cells[1].Value = CurrentPopulation.Installations[(int)Installation.InstallationType.Infrastructure].Number.ToString(); + Entry = String.Format("{0:N2}", CurrentPopulation.Installations[(int)Installation.InstallationType.Infrastructure].Number); + m_oSummaryPanel.SummaryDataGrid.Rows[9 + Adjust1].Cells[1].Value = Entry; if (ColCost > 0.0f) {