/// <summary> /// Determines if a TaskGroup has the ability to jump through this JumpPoint. /// Ensures a connection, and checks Gate, Gate Ownership, and JumpDrives. /// </summary> /// <param name="TransitTG">TG requesting Transit.</param> /// <param name="IsStandardTransit">True if StandardTransit, False if SquadronTransit</param> /// <returns>True if TG is capable of doing this jump.</returns> public bool CanJump(TaskGroupTN TransitTG, bool IsStandardTransit) { // Ensure we have a connection, if not create one. if (Connect == null) { CreateConnection(); } if (IsGated) { if (Constants.GameSettings.AllowHostileGateJump || AllowHostileJumps) { // Gate/Game settings are not setup to allow blocking of hostiles. return(true); } if (GateOwner == null || GateOwner == TransitTG.TaskGroupFaction) { // Nobody owns the gate, or we do, allow the jump. // TODO: Check if a friendly faction owns the gate, and allow. return(true); } } // TODO: Expand this to take into account JumpDrives. // Currently, JumpDrives don't exist, so how could we possibly jump? return(false); }
/// <summary> /// creates a new post sceen creation contact element. /// </summary> /// <param name="a_oDefaultEffect">default effect, I don't know what these are really.</param> /// <param name="oContact">The system contact to be created.</param> public void AddContactElement(GLEffect a_oDefaultEffect, SystemContact oContact) { SceenElement oContactElement; Vector3 v3ContactPos; GLUtilities.GLFont oNameLable; GLUtilities.GLQuad oContactQuad; switch (oContact.SSEntity) { case StarSystemEntityType.TaskGroup: TaskGroupTN TaskGroup = oContact.Entity as TaskGroupTN; oContactElement = new ContactElement(a_oDefaultEffect, oContact); oContactElement.EntityID = oContact.Id; v3ContactPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); oContactQuad = new GLUtilities.GLQuad(a_oDefaultEffect, v3ContactPos, new Vector2(0.0001f, 0.0001f), // what size is a task groug anyway??? oContact.faction.FactionColor, UIConstants.Textures.DEFAULT_TASKGROUP_ICON); oNameLable = new GLUtilities.GLFont(a_oDefaultEffect, v3ContactPos, UIConstants.DEFAULT_TEXT_SIZE, oContact.faction.FactionColor, UIConstants.Textures.DEFAULT_GLFONT2, TaskGroup.Name); oContactElement.Lable = oNameLable; oContactElement.PrimaryPrimitive = oContactQuad; oContactElement.AddPrimitive(oContactQuad); oContactElement.RealSize = new Vector2(0.0001f, 0.0001f); this.AddElement(oContactElement); (oContactElement as ContactElement).ParentSceen = this; break; case StarSystemEntityType.Missile: OrdnanceGroupTN MissileGroup = oContact.Entity as OrdnanceGroupTN; oContactElement = new ContactElement(a_oDefaultEffect, oContact); oContactElement.EntityID = oContact.Id; v3ContactPos = new Vector3((float)MissileGroup.contact.Position.X, (float)MissileGroup.contact.Position.Y, 0.0f); oContactQuad = new GLUtilities.GLQuad(a_oDefaultEffect, v3ContactPos, new Vector2(0.0001f, 0.0001f), // what size is a missile? oContact.faction.FactionColor, UIConstants.Textures.DEFAULT_TASKGROUP_ICON); oNameLable = new GLUtilities.GLFont(a_oDefaultEffect, v3ContactPos, UIConstants.DEFAULT_TEXT_SIZE, oContact.faction.FactionColor, UIConstants.Textures.DEFAULT_GLFONT2, MissileGroup.Name); oContactElement.Lable = oNameLable; oContactElement.PrimaryPrimitive = oContactQuad; oContactElement.AddPrimitive(oContactQuad); oContactElement.RealSize = new Vector2(0.0001f, 0.0001f); this.AddElement(oContactElement); (oContactElement as ContactElement).ParentSceen = this; break; } }
/// <summary> /// Constructor for TGViewModel. Initialization is to faction 0 task group 0. /// Later functionality will handle updating faction and taskgroup indices. /// </summary> public TaskGroupViewModel() { _CurrentFaction = GameState.Instance.Factions[0]; Factions = GameState.Instance.Factions; if (GameState.Instance.Factions[0].TaskGroups.Count != 0) { _CurrentTaskGroup = GameState.Instance.Factions[0].TaskGroups[0]; } TaskGroups = GameState.Instance.Factions[0].TaskGroups; }
/// <summary> /// Constructor for TaskGroup related orders /// </summary> /// <param name="TypeOrder">Type</param> /// <param name="SecondaryOrder">Any secondary order specification such as installation type.</param> /// <param name="TertiaryOrder"> Any Tertiary order such as limits.</param> /// <param name="Delay">Delay in seconds before performing this order.</param> /// <param name="TaskGroupOrder">The TaskGroup in question.</param> public Orders(Constants.ShipTN.OrderType TypeOrder, int SecondaryOrder, int TertiaryOrder, int Delay, TaskGroupTN TaskGroupOrder) { TypeOf = TypeOrder; Target = TaskGroupOrder.Contact; Secondary = SecondaryOrder; Tertiary = TertiaryOrder; TaskGroup = TaskGroupOrder; OrderDelay = Delay; OrderTimeRequirement = -1; Name = TypeOrder.ToString() + " " + TaskGroupOrder.Name.ToString(); }
private void OnFactionChanged() { TaskGroups = GameState.Instance.Factions[_CurrentFaction.FactionID].TaskGroups; if (TaskGroups.Count != 0) { _CurrentTaskGroup = TaskGroups[0]; } if (FactionChanged != null) { FactionChanged(this, new EventArgs()); } }
/// <summary> /// Creates a new system contact. /// </summary> /// <param name="Fact">Faction of contact.</param> /// <param name="TG">Type of contact.</param> public SystemContact(Faction Fact, TaskGroupTN TG) { Id = Guid.NewGuid(); faction = Fact; XSystem = TG.XSystem; YSystem = TG.YSystem; LastXSystem = XSystem; LastYSystem = YSystem; TaskGroup = TG; SSEntity = StarSystemEntityType.TaskGroup; DistanceTable = new BindingList <float>(); DistanceUpdate = new BindingList <int>(); ContactElementCreated = CEState.NotCreated; }
/// <summary> /// Simple transits happen here. Civilian ships, and military ships that are simply travelling will use this function. /// there is a higher penalty associated with a standard transit, ships appear directly on the JP, but there is no TG size limitation. /// </summary> /// <param name="TransitTG"> Transiting TG</param> /// <returns>Success or failure of transit as an integer code.</returns> public int StandardTransit(TaskGroupTN TransitTG) { /// <summary> /// Jump Engine/Gate logic needs to be done here. /// </summary> /// System.RemoveContact(TransitTG.Contact); Connect.System.AddContact(TransitTG.Contact); TransitTG.Contact.UpdateLocationInSystem(Connect.XSystem, Connect.YSystem); /// <summary> /// Likewise, set Standard transit penalties for the TG /// </summary> return(1); }
public List <Constants.ShipTN.OrderType> EnablesTypeOf() { List <Constants.ShipTN.OrderType> enabledType = new List <Constants.ShipTN.OrderType>(); switch (this.TypeOf) { case Constants.ShipTN.OrderType.Absorb: //add list of possible orders target fleet enables. TaskGroupTN targettg = (TaskGroupTN)Target; enabledType = targettg.LegalOrdersTG(); break; case Constants.ShipTN.OrderType.LoadAllMinerals: case Constants.ShipTN.OrderType.LoadMineral: case Constants.ShipTN.OrderType.LoadMineralWhenX: case Constants.ShipTN.OrderType.LoadOrUnloadMineralsToReserve: enabledType.Add(Constants.ShipTN.OrderType.UnloadAllMinerals); enabledType.Add(Constants.ShipTN.OrderType.UnloadMineral); enabledType.Add(Constants.ShipTN.OrderType.UnloadAll); enabledType.Add(Constants.ShipTN.OrderType.LoadOrUnloadMineralsToReserve); break; case Constants.ShipTN.OrderType.LoadColonists: enabledType.Add(Constants.ShipTN.OrderType.UnloadColonists); enabledType.Add(Constants.ShipTN.OrderType.UnloadAll); break; case Constants.ShipTN.OrderType.LoadInstallation: enabledType.Add(Constants.ShipTN.OrderType.UnloadInstallation); enabledType.Add(Constants.ShipTN.OrderType.UnloadAll); break; case Constants.ShipTN.OrderType.LoadShipComponent: enabledType.Add(Constants.ShipTN.OrderType.UnloadShipComponent); enabledType.Add(Constants.ShipTN.OrderType.UnloadAll); break; case Constants.ShipTN.OrderType.TractorSpecifiedShip: case Constants.ShipTN.OrderType.TractorSpecifiedShipyard: enabledType.Add(Constants.ShipTN.OrderType.ReleaseAt); break; } return(enabledType); }
/// <summary> /// Military Squadron jumps into a system are handled here. Ships jump away from the jp, and have a lower transit penalty than a standard transit, /// but only the squadron size may make the jump. /// </summary> /// <param name="TransitTG">Transiting TG</param> /// <returns>Success or failure of transit as an integer code.</returns> public int SquadronTransit(TaskGroupTN TransitTG) { /// <summary> /// Check Jump Engine logic here. /// </summary> System.RemoveContact(TransitTG.Contact); Connect.System.AddContact(TransitTG.Contact); /// <summary> /// Add/subtract offset to X/Y for this. /// <summary> TransitTG.Contact.UpdateLocationInSystem(Connect.XSystem, Connect.YSystem); /// <summary> /// Set Squadron Transit penalties here /// </summary> return(1); }
/// <summary> /// Constructor for missile groups. /// </summary> /// <param name="LaunchedFrom">TG this launched from. additional missiles may be added this tick but afterwards no more.</param> /// <param name="Missile">Initial missile that prompted the creation of this ordnance group.</param> /// <param name="MissileTarget">The target this group is aimed at.</param> public OrdnanceGroupTN(TaskGroupTN LaunchedFrom, OrdnanceTN Missile) { Name = String.Format("Ordnance Group #{0}", LaunchedFrom.TaskGroupFaction.MissileGroups.Count); Id = Guid.NewGuid(); if (LaunchedFrom.IsOrbiting == true) { LaunchedFrom.GetPositionFromOrbit(); } SSEntity = StarSystemEntityType.Missile; Position.X = LaunchedFrom.Contact.Position.X; Position.Y = LaunchedFrom.Contact.Position.Y; Contact = new SystemContact(LaunchedFrom.TaskGroupFaction, this); Missiles = new BindingList<OrdnanceTN>(); /// <summary> /// Missile Detection Statistics: /// This is the first missile so created, so it is in spot 0. /// </summary> Missile.ThermalDetection = new BindingList<int>(); Missile.EMDetection = new BindingList<int>(); Missile.ActiveDetection = new BindingList<int>(); 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; LaunchedFrom.Position.System.SystemContactList.Add(Contact); DrawTravelLine = 0; ShipsTargetting = new BindingList<ShipTN>(); Missiles.Add(Missile); Missile.missileGroup = this; MissilesDestroyed = 0; OrdGroupsTargetting = new BindingList<OrdnanceGroupTN>(); /// <summary> /// Tell the sensor contact element to determine what if any sensors should be displayed. /// </summary> _SensorUpdateAck = 1; }
/// <summary> /// Fire this MFC in point defense mode. /// </summary> /// <param name="TG">Taskgroup the MFC is in</param> /// <param name="FiredFrom">Ship the MFC is on</param> /// <param name="Target">Target of point defense fire.</param> /// <param name="MissilesToFire">Number of missiles to fire at it</param> /// <returns></returns> public int FireWeaponsPD(TaskGroupTN TG, ShipTN FiredFrom, OrdnanceGroupTN Target, int MissilesToFire) { /// <summary> /// simple stupid sanity check. /// </summary> if (MissilesToFire == 0) { return(0); } int LaunchCount = 0; /// <summary> /// Just a temporary variable for this function. /// </summary> BindingList <OrdnanceGroupTN> LocalMissileGroups = new BindingList <OrdnanceGroupTN>(); foreach (MissileLauncherTN LaunchTube in m_lLinkedWeapons) //int loop = 0; loop < LinkedWeapons.Count; loop++) { if (LaunchTube.isDestroyed == false && LaunchTube.loadTime == 0 && LaunchTube.loadedOrdnance != null) { if (FiredFrom.ShipOrdnance.ContainsKey(LaunchTube.loadedOrdnance) == true) { OrdnanceTN newMissile = new OrdnanceTN(this, LaunchTube.loadedOrdnance, FiredFrom); /// <summary> /// Point defense does not go by MFC targetting. have to add target here. /// </summary> newMissile.target = new TargetTN(Target); LaunchCount++; /// <summary> /// Create a new missile group /// </summary> if (LocalMissileGroups.Count == 0) { OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile); LocalMissileGroups.Add(newMissileGroup); TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup); /// <summary> /// Add this ordnance group to the ord groups targetting list for the intended target missile group. /// This is only necessary here as Manually fired MFC missiles are connected to their MFC. /// </summary> Target.ordGroupsTargetting.Add(newMissileGroup); } /// <summary> /// An existing missile group may be useable. /// </summary> else { bool foundGroup = false; foreach (OrdnanceGroupTN OrdGroup in LocalMissileGroups) { /// <summary> /// All Missile groups should be composed of just 1 type of missile for convienence. if (OrdGroup.missiles[0].missileDef.Id == LaunchTube.loadedOrdnance.Id) { OrdGroup.AddMissile(newMissile); foundGroup = true; break; } } /// <summary> /// Have to create a new missile group after all. /// </summary> if (foundGroup == false) { OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile); LocalMissileGroups.Add(newMissileGroup); TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup); /// <summary> /// Add this ordnance group to the ord groups targetting list for the intended target missile group. /// This is only necessary here as Manually fired MFC missiles are connected to their MFC. /// </summary> Target.ordGroupsTargetting.Add(newMissileGroup); } } /// <summary> /// Decrement the loaded ordnance count, and remove the type entirely if this was the last one. /// </summary> FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] = FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] - 1; if (FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] == 0) { FiredFrom.ShipOrdnance.Remove(LaunchTube.loadedOrdnance); } /// <summary> /// Set the launch tube cooldown time as a missile was just fired from it. /// </summary> LaunchTube.loadTime = LaunchTube.missileLauncherDef.rateOfFire; if (LaunchCount == MissilesToFire) { break; } } else { String Msg = String.Format("No ordnance {0} on ship {1} is available for Launch Tube {2} in PD Mode", LaunchTube.Name, FiredFrom.Name, LaunchTube.Name); MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoAvailableOrdnance, TG.Contact.Position.System, TG.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg); TG.TaskGroupFaction.MessageLog.Add(newMessage); } } else if (LaunchTube.isDestroyed == true) { String Msg = String.Format("Destroyed launch tube {0} is still attached to {1}'s MFC in PD Mode", LaunchTube.Name, FiredFrom.Name); MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.Error, TG.Contact.Position.System, TG.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg); TG.TaskGroupFaction.MessageLog.Add(newMessage); } else if (LaunchTube.loadedOrdnance == null) { String Msg = String.Format("No loaded ordnance for launch tube {0} on ship {1} in PD Mode", LaunchTube.Name, FiredFrom.Name); MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoLoadedOrdnance, TG.Contact.Position.System, TG.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg); TG.TaskGroupFaction.MessageLog.Add(newMessage); } } return(LaunchCount); }
/// <summary> /// Fire Weapons spawns new missiles groups or adds missiles to existing ones. /// </summary> /// <param name="TG">Taskgroup this MFC is in.</param> /// <param name="FiredFrom">Ship these missiles were fired from.</param> /// <returns>If missiles were fired at all from this MFC. true = atleast 1 missile(and therefore missile group, false = no missiles.</returns> public bool FireWeapons(TaskGroupTN TG, ShipTN FiredFrom) { bool retv = false; if (m_oTarget != null) { /// <summary> /// Just a temporary variable for this function. /// </summary> BindingList <OrdnanceGroupTN> LocalMissileGroups = new BindingList <OrdnanceGroupTN>(); foreach (MissileLauncherTN LaunchTube in m_lLinkedWeapons) { if (LaunchTube.isDestroyed == false && LaunchTube.loadTime == 0 && LaunchTube.loadedOrdnance != null) { if (FiredFrom.ShipOrdnance.ContainsKey(LaunchTube.loadedOrdnance) == true) { OrdnanceTN newMissile = new OrdnanceTN(this, LaunchTube.loadedOrdnance, FiredFrom); /// <summary> /// Create a new missile group /// </summary> if (LocalMissileGroups.Count == 0) { OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile); LocalMissileGroups.Add(newMissileGroup); TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup); } /// <summary> /// An existing missile group may be useable. /// </summary> else { bool foundGroup = false; foreach (OrdnanceGroupTN OrdGroup in LocalMissileGroups) { /// <summary> /// All Missile groups should be composed of just 1 type of missile for convienence. if (OrdGroup.missiles[0].missileDef.Id == LaunchTube.loadedOrdnance.Id) { OrdGroup.AddMissile(newMissile); foundGroup = true; break; } } /// <summary> /// Have to create a new missile group after all. /// </summary> if (foundGroup == false) { OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile); LocalMissileGroups.Add(newMissileGroup); TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup); } } /// <summary> /// Decrement the loaded ordnance count, and remove the type entirely if this was the last one. /// </summary> FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] = FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] - 1; if (FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] == 0) { FiredFrom.ShipOrdnance.Remove(LaunchTube.loadedOrdnance); } /// <summary> /// Set the launch tube cooldown time as a missile was just fired from it. /// </summary> LaunchTube.loadTime = LaunchTube.missileLauncherDef.rateOfFire; /// <summary> /// return that a missile was launched. /// </summary> retv = true; } else { String Msg = String.Format("No ordnance {0} on ship {1} is available for Launch Tube {2}", LaunchTube.Name, FiredFrom.Name, LaunchTube.Name); MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoAvailableOrdnance, TG.Contact.Position.System, TG.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg); TG.TaskGroupFaction.MessageLog.Add(newMessage); } } else if (LaunchTube.isDestroyed == true) { String Msg = String.Format("Destroyed launch tube {0} is still attached to {1}'s MFC", LaunchTube.Name, FiredFrom.Name); MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.Error, TG.Contact.Position.System, TG.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg); TG.TaskGroupFaction.MessageLog.Add(newMessage); } else if (LaunchTube.loadedOrdnance == null) { String Msg = String.Format("No loaded ordnance for launch tube {0} on ship {1}", LaunchTube.Name, FiredFrom.Name); MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoLoadedOrdnance, TG.Contact.Position.System, TG.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg); TG.TaskGroupFaction.MessageLog.Add(newMessage); } } return(retv); } else { return(false); } }
/// <summary> /// Fire this MFC in point defense mode. /// </summary> /// <param name="TG">Taskgroup the MFC is in</param> /// <param name="FiredFrom">Ship the MFC is on</param> /// <param name="Target">Target of point defense fire.</param> /// <param name="MissilesToFire">Number of missiles to fire at it</param> /// <returns></returns> public int FireWeaponsPD(TaskGroupTN TG, ShipTN FiredFrom, OrdnanceGroupTN Target, int MissilesToFire) { /// <summary> /// simple stupid sanity check. /// </summary> if (MissilesToFire == 0) { return 0; } int LaunchCount = 0; /// <summary> /// Just a temporary variable for this function. /// </summary> BindingList<OrdnanceGroupTN> LocalMissileGroups = new BindingList<OrdnanceGroupTN>(); foreach (MissileLauncherTN LaunchTube in m_lLinkedWeapons) //int loop = 0; loop < LinkedWeapons.Count; loop++) { if (LaunchTube.isDestroyed == false && LaunchTube.loadTime == 0 && LaunchTube.loadedOrdnance != null) { if (FiredFrom.ShipOrdnance.ContainsKey(LaunchTube.loadedOrdnance) == true) { OrdnanceTN newMissile = new OrdnanceTN(this, LaunchTube.loadedOrdnance, FiredFrom); /// <summary> /// Point defense does not go by MFC targetting. have to add target here. /// </summary> newMissile.target = new TargetTN(Target); LaunchCount++; /// <summary> /// Create a new missile group /// </summary> if (LocalMissileGroups.Count == 0) { OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile); LocalMissileGroups.Add(newMissileGroup); TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup); /// <summary> /// Add this ordnance group to the ord groups targetting list for the intended target missile group. /// This is only necessary here as Manually fired MFC missiles are connected to their MFC. /// </summary> Target.ordGroupsTargetting.Add(newMissileGroup); } /// <summary> /// An existing missile group may be useable. /// </summary> else { bool foundGroup = false; foreach (OrdnanceGroupTN OrdGroup in LocalMissileGroups) { /// <summary> /// All Missile groups should be composed of just 1 type of missile for convienence. if (OrdGroup.missiles[0].missileDef.Id == LaunchTube.loadedOrdnance.Id) { OrdGroup.AddMissile(newMissile); foundGroup = true; break; } } /// <summary> /// Have to create a new missile group after all. /// </summary> if (foundGroup == false) { OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile); LocalMissileGroups.Add(newMissileGroup); TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup); /// <summary> /// Add this ordnance group to the ord groups targetting list for the intended target missile group. /// This is only necessary here as Manually fired MFC missiles are connected to their MFC. /// </summary> Target.ordGroupsTargetting.Add(newMissileGroup); } } /// <summary> /// Decrement the loaded ordnance count, and remove the type entirely if this was the last one. /// </summary> FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] = FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] - 1; if (FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] == 0) { FiredFrom.ShipOrdnance.Remove(LaunchTube.loadedOrdnance); } /// <summary> /// Set the launch tube cooldown time as a missile was just fired from it. /// </summary> LaunchTube.loadTime = LaunchTube.missileLauncherDef.rateOfFire; if (LaunchCount == MissilesToFire) break; } else { String Msg = String.Format("No ordnance {0} on ship {1} is available for Launch Tube {2} in PD Mode", LaunchTube.Name, FiredFrom.Name, LaunchTube.Name); MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoAvailableOrdnance, TG.Contact.Position.System, TG.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg); TG.TaskGroupFaction.MessageLog.Add(newMessage); } } else if (LaunchTube.isDestroyed == true) { String Msg = String.Format("Destroyed launch tube {0} is still attached to {1}'s MFC in PD Mode", LaunchTube.Name, FiredFrom.Name); MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.Error, TG.Contact.Position.System, TG.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg); TG.TaskGroupFaction.MessageLog.Add(newMessage); } else if (LaunchTube.loadedOrdnance == null) { String Msg = String.Format("No loaded ordnance for launch tube {0} on ship {1} in PD Mode", LaunchTube.Name, FiredFrom.Name); MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoLoadedOrdnance, TG.Contact.Position.System, TG.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg); TG.TaskGroupFaction.MessageLog.Add(newMessage); } } return LaunchCount; }
/// <summary> /// Fire Weapons spawns new missiles groups or adds missiles to existing ones. /// </summary> /// <param name="TG">Taskgroup this MFC is in.</param> /// <param name="FiredFrom">Ship these missiles were fired from.</param> /// <returns>If missiles were fired at all from this MFC. true = atleast 1 missile(and therefore missile group, false = no missiles.</returns> public bool FireWeapons(TaskGroupTN TG, ShipTN FiredFrom) { bool retv = false; if (m_oTarget != null) { /// <summary> /// Just a temporary variable for this function. /// </summary> BindingList<OrdnanceGroupTN> LocalMissileGroups = new BindingList<OrdnanceGroupTN>(); foreach (MissileLauncherTN LaunchTube in m_lLinkedWeapons) { if (LaunchTube.isDestroyed == false && LaunchTube.loadTime == 0 && LaunchTube.loadedOrdnance != null) { if (FiredFrom.ShipOrdnance.ContainsKey(LaunchTube.loadedOrdnance) == true) { OrdnanceTN newMissile = new OrdnanceTN(this, LaunchTube.loadedOrdnance, FiredFrom); /// <summary> /// Create a new missile group /// </summary> if (LocalMissileGroups.Count == 0) { OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile); LocalMissileGroups.Add(newMissileGroup); TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup); } /// <summary> /// An existing missile group may be useable. /// </summary> else { bool foundGroup = false; foreach (OrdnanceGroupTN OrdGroup in LocalMissileGroups) { /// <summary> /// All Missile groups should be composed of just 1 type of missile for convienence. if (OrdGroup.missiles[0].missileDef.Id == LaunchTube.loadedOrdnance.Id) { OrdGroup.AddMissile(newMissile); foundGroup = true; break; } } /// <summary> /// Have to create a new missile group after all. /// </summary> if (foundGroup == false) { OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile); LocalMissileGroups.Add(newMissileGroup); TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup); } } /// <summary> /// Decrement the loaded ordnance count, and remove the type entirely if this was the last one. /// </summary> FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] = FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] - 1; if (FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] == 0) { FiredFrom.ShipOrdnance.Remove(LaunchTube.loadedOrdnance); } /// <summary> /// Set the launch tube cooldown time as a missile was just fired from it. /// </summary> LaunchTube.loadTime = LaunchTube.missileLauncherDef.rateOfFire; /// <summary> /// return that a missile was launched. /// </summary> retv = true; } else { String Msg = String.Format("No ordnance {0} on ship {1} is available for Launch Tube {2}", LaunchTube.Name, FiredFrom.Name, LaunchTube.Name); MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoAvailableOrdnance, TG.Contact.Position.System, TG.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg); TG.TaskGroupFaction.MessageLog.Add(newMessage); } } else if (LaunchTube.isDestroyed == true) { String Msg = String.Format("Destroyed launch tube {0} is still attached to {1}'s MFC", LaunchTube.Name, FiredFrom.Name); MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.Error, TG.Contact.Position.System, TG.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg); TG.TaskGroupFaction.MessageLog.Add(newMessage); } else if (LaunchTube.loadedOrdnance == null) { String Msg = String.Format("No loaded ordnance for launch tube {0} on ship {1}", LaunchTube.Name, FiredFrom.Name); MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoLoadedOrdnance, TG.Contact.Position.System, TG.Contact, GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg); TG.TaskGroupFaction.MessageLog.Add(newMessage); } } return retv; } else { return false; } }
public override void Refresh(float a_fZoomScaler) { // Adjust the size of the Primary Sprite (the TG icon) if necessary. if (MinimumSize.X > 0 && MinimumSize.Y > 0) { // calc size in pixels given current zoom factor: Vector2 v2CurrSize = RealSize * a_fZoomScaler; if (MinimumSize.X > v2CurrSize.X && MinimumSize.Y > v2CurrSize.Y) { // then it is too small, make it display at a proper size: PrimaryPrimitive.SetSize(MinimumSize / a_fZoomScaler); } else { // we want to draw to scale: PrimaryPrimitive.SetSize(RealSize); } } /// <summary> /// update position of the selected contact and its travelline: /// </summary> Vector3 pos = Vector3.Zero, lastPos = Vector3.Zero; switch (m_oSystemContect.SSEntity) { case StarSystemEntityType.TaskGroup: pos = new Vector3((float)m_oSystemContect.Position.X, (float)m_oSystemContect.Position.Y, 0.0f); lastPos = new Vector3((float)m_oSystemContect.LastPosition.X, (float)m_oSystemContect.LastPosition.Y, 0.0f); TaskGroupTN TaskGroup = m_oSystemContect.Entity as TaskGroupTN; if (TaskGroup.DrawTravelLine != 3) { m_oTravelLine.StartPos = lastPos; m_oTravelLine.EndPos = pos; } else if (TaskGroup.DrawTravelLine == 3) { m_oTravelLine.StartPos = pos; m_oTravelLine.EndPos = pos; } if (TaskGroup.DrawTravelLine == 2) { TaskGroup.DrawTravelLine = 3; } break; case StarSystemEntityType.Population: break; case StarSystemEntityType.Missile: pos = new Vector3((float)m_oSystemContect.Position.X, (float)m_oSystemContect.Position.Y, 0.0f); lastPos = new Vector3((float)m_oSystemContect.LastPosition.X, (float)m_oSystemContect.LastPosition.Y, 0.0f); OrdnanceGroupTN MissileGroup = m_oSystemContect.Entity as OrdnanceGroupTN; if (MissileGroup.DrawTravelLine != 3) { m_oTravelLine.StartPos = lastPos; m_oTravelLine.EndPos = pos; } else if (MissileGroup.DrawTravelLine == 3) { m_oTravelLine.StartPos = pos; m_oTravelLine.EndPos = pos; } if (MissileGroup.DrawTravelLine == 2) { MissileGroup.DrawTravelLine = 3; } break; } PrimaryPrimitive.Position = pos; Lable.Position = pos; // Adjust the size of the text so it is always 10 point: Lable.Size = UIConstants.DEFAULT_TEXT_SIZE / a_fZoomScaler; switch (m_oSystemContect.SSEntity) { case StarSystemEntityType.TaskGroup: Lable.Text = m_oSystemContect.Entity.Name; break; } // loop through any children: foreach (SceenElement oElement in m_lChildren) { oElement.Refresh(a_fZoomScaler); } }
/// <summary> /// Determines if a TaskGroup has the ability to jump through this JumpPoint. /// Ensures a connection, and checks Gate, Gate Ownership, and JumpDrives. /// </summary> /// <param name="TransitTG">TG requesting Transit.</param> /// <param name="IsStandardTransit">True if StandardTransit, False if SquadronTransit</param> /// <returns>True if TG is capable of doing this jump.</returns> public bool CanJump(TaskGroupTN TransitTG, bool IsStandardTransit, out Dictionary <JumpEngineTN, ShipTN> usedJumpEngines) { usedJumpEngines = null; // Ensure we have a connection, if not create one. if (Connect == null) { CreateConnection(); } if (IsGated && IsStandardTransit == true) { if (Constants.GameSettings.AllowHostileGateJump || AllowHostileJumps) { // Gate/Game settings are not setup to allow blocking of hostiles. return(true); } if (GateOwner == null || GateOwner == TransitTG.TaskGroupFaction) { // Nobody owns the gate, or we do, allow the jump. ///< @todo Check if a friendly faction owns the gate, and allow. return(true); } } /// <summary> /// jump Transit code: /// </summary> int ComCount = 0; int MilCount = 0; float ComMaxHS = 0; float MilMaxHS = 0; int MilAccom = 0; int ComAccom = 0; /// <summary> /// For every ship: /// How many of each type of ship are there? /// What are the largest ship sizes in HS? /// Go through every jump engine /// Is this jump engine ready? /// Can this jump engine accomodate the other ships in the taskgroup? /// </summary> TransitTG.CountShips(out MilCount, out ComCount, out MilMaxHS, out ComMaxHS); /// <summary> /// if one ship can be accomodated all can be. /// </summary> if (IsStandardTransit == true) { if (MilCount > 1) { MilCount = 1; } if (ComCount > 1) { ComCount = 1; } } TransitTG.GetJDAccom(MilMaxHS, MilCount, ComMaxHS, ComCount, out MilAccom, out ComAccom, out usedJumpEngines); /// <summary> /// This jump can happen. /// </summary> if (MilAccom >= MilCount && ComAccom >= ComCount) { return(true); } /// <summary> /// Something caused this jump to fail, will need to find out what for the faction messagelog though. /// </summary> return(false); }
/// <summary> /// list of legal orders a taskgroup or unit can use againsed this entity ie when this entity is the target. /// </summary> public List <Constants.ShipTN.OrderType> LegalOrders(Faction faction) { List <Constants.ShipTN.OrderType> legalOrders = new List <Constants.ShipTN.OrderType>(); //generic orders a selected tg targeting anything will have all these options if the selecteed tg can do these. legalOrders.Add(Constants.ShipTN.OrderType.MoveTo); legalOrders.Add(Constants.ShipTN.OrderType.ExtendedOrbit); legalOrders.Add(Constants.ShipTN.OrderType.Picket); legalOrders.Add(Constants.ShipTN.OrderType.SendMessage); legalOrders.Add(Constants.ShipTN.OrderType.EqualizeFuel); legalOrders.Add(Constants.ShipTN.OrderType.EqualizeMSP); legalOrders.Add(Constants.ShipTN.OrderType.ActivateTransponder); legalOrders.Add(Constants.ShipTN.OrderType.DeactivateTransponder); legalOrders.Add(Constants.ShipTN.OrderType.ActivateSensors); legalOrders.Add(Constants.ShipTN.OrderType.DeactivateSensors); legalOrders.Add(Constants.ShipTN.OrderType.ActivateShields); legalOrders.Add(Constants.ShipTN.OrderType.DeactivateShields); legalOrders.Add(Constants.ShipTN.OrderType.DivideFleetToSingleShips); legalOrders.Add(Constants.ShipTN.OrderType.DetachNonGeoSurvey); legalOrders.Add(Constants.ShipTN.OrderType.DetachNonGravSurvey); legalOrders.Add(Constants.ShipTN.OrderType.RefuelFromOwnTankers); legalOrders.Add(Constants.ShipTN.OrderType.DetachTankers); legalOrders.Add(Constants.ShipTN.OrderType.ResupplyFromOwnSupplyShips); legalOrders.Add(Constants.ShipTN.OrderType.DetachSupplyShips); legalOrders.Add(Constants.ShipTN.OrderType.ReloadFromOwnColliers); legalOrders.Add(Constants.ShipTN.OrderType.DetachColliers); legalOrders.Add(Constants.ShipTN.OrderType.ReleaseAt); if (this is JumpPoint) { JumpPoint thisjp = (JumpPoint)this; legalOrders.Add(Constants.ShipTN.OrderType.StandardTransit); legalOrders.Add(Constants.ShipTN.OrderType.TransitAndDivide); legalOrders.Add(Constants.ShipTN.OrderType.SquadronTransit); if (!thisjp.IsGated) { legalOrders.Add(Constants.ShipTN.OrderType.BuildJumpGate); } } if (this is Planet) { Planet planet = (Planet)this; if (planet.GeoSurveyList.ContainsKey(faction) == true) { if (planet.GeoSurveyList[faction] == false) { legalOrders.Add(Constants.ShipTN.OrderType.GeoSurvey); } } } if (this is Population) { Population pop = (Population)this; if (faction == pop.Faction) { legalOrders.Add(Constants.ShipTN.OrderType.LoadCrewFromColony); if (pop.FuelStockpile > 0) { legalOrders.Add(Constants.ShipTN.OrderType.RefuelFromColony); } if (pop.MaintenanceSupplies > 0) { legalOrders.Add(Constants.ShipTN.OrderType.ResupplyFromColony); } if (Array.Exists(pop.Installations, x => x.Type == Installation.InstallationType.MaintenanceFacility)) { legalOrders.Add(Constants.ShipTN.OrderType.BeginOverhaul); } if (pop.Installations.Count() > 0) { legalOrders.Add(Constants.ShipTN.OrderType.LoadInstallation); } if (pop.ComponentStockpile.Count() > 0) { legalOrders.Add(Constants.ShipTN.OrderType.LoadShipComponent); } legalOrders.Add(Constants.ShipTN.OrderType.LoadAllMinerals); 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 (pop.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(pop.Installations, x => x.Type == Installation.InstallationType.OrdnanceFactory) || pop.MissileStockpile.Count > 0) { legalOrders.Add(Constants.ShipTN.OrderType.LoadMineral); } legalOrders.Add(Constants.ShipTN.OrderType.LoadOrdnanceFromColony); legalOrders.Add(Constants.ShipTN.OrderType.UnloadOrdnanceToColony); } } if (this is SystemContact) { legalOrders.Add(Constants.ShipTN.OrderType.Follow); } if (this is TaskGroupTN) { TaskGroupTN tg = (TaskGroupTN)this; ShipTN[] shipsArray = tg.Ships.ToArray(); legalOrders.Add(Constants.ShipTN.OrderType.Follow); legalOrders.Add(Constants.ShipTN.OrderType.Join); legalOrders.Add(Constants.ShipTN.OrderType.Absorb); legalOrders.Add(Constants.ShipTN.OrderType.RefuelTargetFleet); legalOrders.Add(Constants.ShipTN.OrderType.ResupplyTargetFleet); legalOrders.Add(Constants.ShipTN.OrderType.ReloadTargetFleet); if (Array.Exists(shipsArray, x => x.ShipClass.IsTanker)) //if this fleet is targeted and has a IsTanker. { legalOrders.Add(Constants.ShipTN.OrderType.RefuelFromTargetFleet); } if (Array.Exists(shipsArray, x => x.ShipClass.IsSupply))//if this fleet is targeted and has a IsSupply. { 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); } legalOrders.Add(Constants.ShipTN.OrderType.LandOnAssignedMothership); legalOrders.Add(Constants.ShipTN.OrderType.LandOnMotherShipNoAssign); legalOrders.Add(Constants.ShipTN.OrderType.LandOnMothershipAssign); legalOrders.Add(Constants.ShipTN.OrderType.TractorSpecifiedShip); legalOrders.Add(Constants.ShipTN.OrderType.TractorSpecifiedShipyard); } return(legalOrders); }
/// <summary> /// creates a new post sceen creation contact element. /// </summary> /// <param name="a_oDefaultEffect">default effect, I don't know what these are really.</param> /// <param name="oContact">The system contact to be created.</param> public void AddContactElement(GLEffect a_oDefaultEffect, SystemContact oContact) { SceenElement oContactElement; Vector3 v3ContactPos; GLUtilities.GLFont oNameLable; GLUtilities.GLQuad oContactQuad; switch (oContact.SSEntity) { case StarSystemEntityType.TaskGroup: TaskGroupTN TaskGroup = oContact.Entity as TaskGroupTN; oContactElement = new ContactElement(a_oDefaultEffect, oContact); oContactElement.EntityID = oContact.Id; v3ContactPos = new Vector3((float)TaskGroup.Contact.Position.X, (float)TaskGroup.Contact.Position.Y, 0.0f); oContactQuad = new GLUtilities.GLQuad(a_oDefaultEffect, v3ContactPos, new Vector2(0.0001f, 0.0001f), // what size is a task groug anyway??? oContact.faction.FactionColor, UIConstants.Textures.DEFAULT_TASKGROUP_ICON); oNameLable = new GLUtilities.GLFont(a_oDefaultEffect, v3ContactPos, UIConstants.DEFAULT_TEXT_SIZE, oContact.faction.FactionColor, UIConstants.Textures.DEFAULT_GLFONT2, TaskGroup.Name); oContactElement.Lable = oNameLable; oContactElement.Lable.Size = UIConstants.DEFAULT_TEXT_SIZE / m_fZoomScaler; //Initial taskgroup names weren't being scaled properly for whatever reason. oContactElement.PrimaryPrimitive = oContactQuad; oContactElement.AddPrimitive(oContactQuad); oContactElement.RealSize = new Vector2(0.0001f, 0.0001f); this.AddElement(oContactElement); (oContactElement as ContactElement).ParentSceen = this; break; case StarSystemEntityType.Missile: OrdnanceGroupTN MissileGroup = oContact.Entity as OrdnanceGroupTN; oContactElement = new ContactElement(a_oDefaultEffect, oContact); oContactElement.EntityID = oContact.Id; v3ContactPos = new Vector3((float)MissileGroup.contact.Position.X, (float)MissileGroup.contact.Position.Y, 0.0f); oContactQuad = new GLUtilities.GLQuad(a_oDefaultEffect, v3ContactPos, new Vector2(0.0001f, 0.0001f), // what size is a missile? oContact.faction.FactionColor, UIConstants.Textures.DEFAULT_TASKGROUP_ICON); oNameLable = new GLUtilities.GLFont(a_oDefaultEffect, v3ContactPos, UIConstants.DEFAULT_TEXT_SIZE, oContact.faction.FactionColor, UIConstants.Textures.DEFAULT_GLFONT2, MissileGroup.Name); oContactElement.Lable = oNameLable; oContactElement.Lable.Size = UIConstants.DEFAULT_TEXT_SIZE / m_fZoomScaler; //Same problem may exist with missile labels. oContactElement.PrimaryPrimitive = oContactQuad; oContactElement.AddPrimitive(oContactQuad); oContactElement.RealSize = new Vector2(0.0001f, 0.0001f); this.AddElement(oContactElement); (oContactElement as ContactElement).ParentSceen = this; break; case StarSystemEntityType.Population: Population CurrentPopulation = oContact.Entity as Population; oContactElement = new ContactElement(a_oDefaultEffect, oContact); oContactElement.EntityID = oContact.Id; v3ContactPos = new Vector3((float)CurrentPopulation.Contact.Position.X, (float)CurrentPopulation.Contact.Position.Y, 0.0f); oContactQuad = new GLUtilities.GLQuad(a_oDefaultEffect, v3ContactPos, new Vector2(0.0001f, 0.0001f), // what size is a population? oContact.faction.FactionColor, UIConstants.Textures.DEFAULT_TASKGROUP_ICON); oNameLable = new GLUtilities.GLFont(a_oDefaultEffect, v3ContactPos, UIConstants.DEFAULT_TEXT_SIZE, oContact.faction.FactionColor, UIConstants.Textures.DEFAULT_GLFONT2, CurrentPopulation.Name); oContactElement.Lable = oNameLable; oContactElement.Lable.Size = UIConstants.DEFAULT_TEXT_SIZE / m_fZoomScaler; //Same problem may exist with population labels. oContactElement.PrimaryPrimitive = oContactQuad; oContactElement.AddPrimitive(oContactQuad); oContactElement.RealSize = new Vector2(0.0001f, 0.0001f); this.AddElement(oContactElement); (oContactElement as ContactElement).ParentSceen = this; break; } }
public override void Render() { switch (m_oSystemContect.SSEntity) { case StarSystemEntityType.TaskGroup: TaskGroupTN TaskGroup = m_oSystemContect.Entity as TaskGroupTN; /// <summary> /// Update this contact's sensor elements. /// </summary> if (TaskGroup.SensorUpdateAck != _LastSensorUpdateAck) { /// <summary> /// Get rid of all sensors if this taskgroup is empty. a SensorUpdateAck should be sent upon emptying a tg into another tg. /// </summary> if (TaskGroup.Ships.Count == 0) { _SensorContactElements.Clear(); } /// <summary> /// Remove those sensors that are no longer active. /// </summary> BindingList <Guid> SensorRemoveList = new BindingList <Guid>(); foreach (KeyValuePair <Guid, SensorElement> SCE in _SensorContactElements) { switch (SCE.Value._sensorType) { case ComponentTypeTN.ActiveSensor: ActiveSensorTN aSensor = (SCE.Value.SceenEntity as ActiveSensorTN); if (aSensor.isActive == false || aSensor.isDestroyed == true || ParentSceen.ShowActives == false) { SensorRemoveList.Add(SCE.Key); } break; case ComponentTypeTN.PassiveSensor: PassiveSensorTN pSensor = (SCE.Value.SceenEntity as PassiveSensorTN); /// <summary> /// 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. /// </summary> if (pSensor != null) { if (pSensor.isDestroyed == true || ParentSceen.ShowPassives == false) { SensorRemoveList.Add(SCE.Key); } else { if (pSensor.pSensorDef.thermalOrEM == PassiveSensorType.Thermal) { if (pSensor != TaskGroup.BestThermal) { SensorRemoveList.Add(SCE.Key); } } else { if (pSensor != TaskGroup.BestEM) { SensorRemoveList.Add(SCE.Key); } } } } else { /// <summary> /// 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. /// </summary> if (ParentSceen.ShowPassives == false || TaskGroup.BestThermal != null || TaskGroup.BestEM != null) { SensorRemoveList.Add(SCE.Key); } } break; } } if (SensorRemoveList.Count != 0) { foreach (Guid SCE in SensorRemoveList) { _SensorContactElements.Remove(SCE); } } if (ParentSceen.ShowPassives == true) { if (TaskGroup.Ships.Count != 0) { /// <summary> /// 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. /// </summary> 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; 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); 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); } /// <summary> /// A taskgroup with no sensors still has the default package, so handle that. /// </summary> 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); } } } /// <summary> /// Check for newly activated sensors. /// </summary> if (ParentSceen.ShowActives == true) { foreach (ActiveSensorTN Sensor in TaskGroup.ActiveSensorQue) { /// <summary> /// This sensor survived the above cleanup, and is in the sensor contact element list, so don't re check whether it should be here. /// </summary> if (_SensorContactElements.ContainsKey(Sensor.aSensorDef.Id) == true) { continue; } ActiveSensorDefTN SensorDef = Sensor.aSensorDef; 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); SensorElement NSE = new SensorElement(_DefaultEffect, TGPos, (float)AURadius, System.Drawing.Color.Turquoise, Sensor.Name, Sensor, Sensor.aSensorDef.componentType, ParentSceen); _SensorContactElements.Add(SensorDef.Id, NSE); } } _LastSensorUpdateAck = TaskGroup.SensorUpdateAck; } break; case StarSystemEntityType.Population: Population CurrentPop = (m_oSystemContect.Entity as Population); /// <summary> /// Populations only have one sensor element. /// </summary> if (CurrentPop._sensorUpdateAck != _LastSensorUpdateAck) { _SensorContactElements.Clear(); int DSTS = (int)Math.Floor(CurrentPop.Installations[(int)Installation.InstallationType.DeepSpaceTrackingStation].Number); if (ParentSceen.ShowPassives == true && DSTS != 0) { /// <summary> /// This calculates the default detection distance for strength 1000 signatures. /// </summary> 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; 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); /// <summary> /// 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. /// </summary> 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: OrdnanceGroupTN MissileGroup = (m_oSystemContect.Entity as OrdnanceGroupTN); /// <summary> /// This ordnance group was just created, so check whether or not any sensors need to be displayed. Or the display could request that passives or actives not be displayed. /// </summary> if (_LastSensorUpdateAck != MissileGroup._sensorUpdateAck) { _SensorContactElements.Clear(); OrdnanceDefTN OrdDef = MissileGroup.missiles[0].missileDef; if (OrdDef.aSD != null && ParentSceen.ShowActives == true) { 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); SensorElement NSE = new SensorElement(_DefaultEffect, MGPos, (float)AURadius, System.Drawing.Color.Turquoise, MissileGroup.missiles[0].missileDef.Name + " Active Sensor", MissileGroup, ComponentTypeTN.TypeCount, ParentSceen); _SensorContactElements.Add(OrdDef.aSD.Id, NSE); } if (OrdDef.tHD != null && ParentSceen.ShowPassives == true) { 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); SensorElement NSE = new SensorElement(_DefaultEffect, MGPos, (float)AURadius, System.Drawing.Color.Red, MissileGroup.missiles[0].missileDef.Name + " Thermal Sensor", MissileGroup, ComponentTypeTN.TypeCount, ParentSceen); _SensorContactElements.Add(OrdDef.tHD.Id, NSE); } if (OrdDef.eMD != null && ParentSceen.ShowPassives == true) { 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); SensorElement NSE = new SensorElement(_DefaultEffect, MGPos, (float)AURadius, System.Drawing.Color.Blue, MissileGroup.missiles[0].missileDef.Name + " EM Sensor", MissileGroup, ComponentTypeTN.TypeCount, ParentSceen); _SensorContactElements.Add(OrdDef.eMD.Id, NSE); } _LastSensorUpdateAck = MissileGroup._sensorUpdateAck; } break; } foreach (GLPrimitive oPrimitive in m_lPrimitives) { oPrimitive.Render(); } /// <summary> /// Adding sensor elements to children causes wierd behavior that I'd rather not deal with. /// </summary> foreach (KeyValuePair <Guid, SensorElement> sElement in _SensorContactElements) { sElement.Value.Render(); } if (RenderChildren == true) { foreach (SceenElement oElement in m_lChildren) { oElement.Render(); } } // render lable: if (m_oLable != null) { m_oLable.Render(); } }