From b35617476561f9546f21685da30f4a76b3f0bb87 Mon Sep 17 00:00:00 2001 From: Nathan Hittinger Date: Sun, 15 Dec 2013 14:46:46 -0600 Subject: [PATCH] Basic Messagelogging complete Combat data is printed to the faction message log, and on the temporary event log in individual ship details. --- .../Entities/Components/ActiveSensor.cs | 6 +- .../Entities/Components/BeamFireControlTN.cs | 38 ++- .../Entities/Components/OrdnanceTN.cs | 16 +- Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs | 163 +++++++++---- Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs | 220 +++++++++++++++++- Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs | 25 +- Pulsar4X/Pulsar4X.Lib/Entities/TaskGroup.cs | 2 +- Pulsar4X/Pulsar4X.Tests/ShipTests.cs | 16 +- Pulsar4X/Pulsar4X.UI/Handlers/Ships.cs | 11 +- 9 files changed, 423 insertions(+), 74 deletions(-) diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Components/ActiveSensor.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Components/ActiveSensor.cs index 1d4338053..ed8b5b3d2 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Components/ActiveSensor.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Components/ActiveSensor.cs @@ -581,7 +581,7 @@ public OrdnanceTargetTN getTarget() /// /// Taskgroup this MFC is in. /// to be decided upon. - public bool FireWeapons(TaskGroupTN TG) + public bool FireWeapons(TaskGroupTN TG, ShipTN FiredFrom) { @@ -595,7 +595,7 @@ public bool FireWeapons(TaskGroupTN TG) { if (TG.AttachedMissileGroups[loop2].missiles[0].missileDef.maxSpeed == LinkedWeapons[loop].loadedOrdnance.maxSpeed) { - OrdnanceTN newMissile = new OrdnanceTN(this, LinkedWeapons[loop].loadedOrdnance); + OrdnanceTN newMissile = new OrdnanceTN(this, LinkedWeapons[loop].loadedOrdnance,FiredFrom); TG.AttachedMissileGroups[loop].AddMissile(newMissile); LinkedWeapons[loop].loadTime = LinkedWeapons[loop].missileLauncherDef.rateOfFire; @@ -606,7 +606,7 @@ public bool FireWeapons(TaskGroupTN TG) if (used == false) { - OrdnanceTN newMissile = new OrdnanceTN(this, LinkedWeapons[loop].loadedOrdnance); + OrdnanceTN newMissile = new OrdnanceTN(this, LinkedWeapons[loop].loadedOrdnance, FiredFrom); newMissile.target = Target; OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile); TG.AttachedMissileGroups.Add(newMissileGroup); diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Components/BeamFireControlTN.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Components/BeamFireControlTN.cs index 57505826e..90046f8dc 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Components/BeamFireControlTN.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Components/BeamFireControlTN.cs @@ -420,6 +420,14 @@ public bool FireWeapons(float DistanceToTarget, Random RNG, int track, ShipTN Fi { if (DistanceToTarget > BeamFireControlDef.range || LinkedWeapons.Count == 0 || isDestroyed == true) { + if (DistanceToTarget > BeamFireControlDef.range) + { + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringZeroHitChance, FiringShip.ShipsTaskGroup.Contact.CurrentSystem, FiringShip.ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), (this.Name + " Zero % chance to hit.")); + + FiringShip.ShipsFaction.MessageLog.Add(NMsg); + } + return false; } else @@ -524,7 +532,6 @@ public bool FireWeapons(float DistanceToTarget, Random RNG, int track, ShipTN Fi if (weaponFired == true) { - for (int loop2 = 0; loop2 < LinkedWeapons[loop].beamDef.shotCount; loop2++) { @@ -532,8 +539,17 @@ public bool FireWeapons(float DistanceToTarget, Random RNG, int track, ShipTN Fi if (toHit >= Hit) { + + String WeaponFireS = String.Format("{0} hit {1} damage at {2}% tohit", LinkedWeapons[loop].Name, LinkedWeapons[loop].beamDef.damage[RangeIncrement],toHit); + + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringHit, FiringShip.ShipsTaskGroup.Contact.CurrentSystem, FiringShip.ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), WeaponFireS); + + FiringShip.ShipsFaction.MessageLog.Add(NMsg); + + ushort location = (ushort)RNG.Next(0, Columns); - bool ShipDest = Target.OnDamaged(LinkedWeapons[loop].beamDef.damageType, LinkedWeapons[loop].beamDef.damage[RangeIncrement], location); + bool ShipDest = Target.OnDamaged(LinkedWeapons[loop].beamDef.damageType, LinkedWeapons[loop].beamDef.damage[RangeIncrement], location, FiringShip); if (ShipDest == true) { @@ -542,8 +558,26 @@ public bool FireWeapons(float DistanceToTarget, Random RNG, int track, ShipTN Fi return weaponFired; } } + else + { + String WeaponFireS = String.Format("{0} missed at {2}% tohit", LinkedWeapons[loop].Name, LinkedWeapons[loop].beamDef.damage[RangeIncrement],toHit); + + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringMissed, FiringShip.ShipsTaskGroup.Contact.CurrentSystem, FiringShip.ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), WeaponFireS); + + FiringShip.ShipsFaction.MessageLog.Add(NMsg); + } } } + else if(LinkedWeapons[loop].isDestroyed == false) + { + String WeaponFireS = String.Format("{0} Recharging {1}/{2} Power", LinkedWeapons[loop].Name, LinkedWeapons[loop].currentCapacitor, LinkedWeapons[loop].beamDef.weaponCapacitor); + + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringRecharging, FiringShip.ShipsTaskGroup.Contact.CurrentSystem, FiringShip.ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), WeaponFireS); + + FiringShip.ShipsFaction.MessageLog.Add(NMsg); + } } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Components/OrdnanceTN.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Components/OrdnanceTN.cs index 812ebf9f6..d549b26c4 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Components/OrdnanceTN.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Components/OrdnanceTN.cs @@ -804,17 +804,29 @@ public float fuel set { Fuel = value; } } + /// + /// Which ship fired this missile? + /// + private ShipTN FiringShip; + public ShipTN firingShip + { + get { return FiringShip; } + set { FiringShip = value; } + } + /// /// Constructor for missiles. /// /// MFC directing this missile. /// definition of the missile. - public OrdnanceTN(MissileFireControlTN mfCtrl, OrdnanceDefTN definition) + public OrdnanceTN(MissileFireControlTN mfCtrl, OrdnanceDefTN definition, ShipTN ShipFiredFrom) { MFC = mfCtrl; Target = MFC.target; + FiringShip = ShipFiredFrom; + MissileDef = definition; /// @@ -1089,7 +1101,7 @@ public void ProcessOrder(uint TimeSlice, Random RNG) /// ///Missile damage type always? laser damage type if implemented will need to change this. /// - bool ShipDest = Missiles[loop].target.ship.OnDamaged(DamageTypeTN.Missile, (ushort)Missiles[loop].missileDef.warhead, location); + bool ShipDest = Missiles[loop].target.ship.OnDamaged(DamageTypeTN.Missile, (ushort)Missiles[loop].missileDef.warhead, location,Missiles[loop].firingShip); /// /// Handle ship destruction at the ship level, to inform all incoming missiles that they need a new target. diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs index 02e41f81b..abbb948cf 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Faction.cs @@ -16,7 +16,7 @@ public class FactionContact /// /// The detected ship. /// - public ShipTN Ship{ get; set; } + public ShipTN ship{ get; set; } /// /// Detected via thermal. @@ -58,20 +58,38 @@ public class FactionContact /// Detection via EM? /// Active detection? /// What tick did this detection event occur on? - public FactionContact(ShipTN DetectedShip, bool Thermal, bool em, bool Active, uint tick) + public FactionContact(Faction CurrentFaction, ShipTN DetectedShip, bool Thermal, bool em, bool Active, uint tick) { + ship = DetectedShip; thermal = Thermal; EM = em; active = Active; + String Contact = "New contact detected:"; + if (thermal == true) + { thermalTick = tick; + Contact = String.Format("{0} Thermal Signature {1}", Contact, DetectedShip.CurrentThermalSignature); + } if (EM == true) + { EMTick = tick; + Contact = String.Format("{0} EM Signature {1}", Contact, DetectedShip.CurrentEMSignature); + } if (active == true) + { activeTick = tick; + Contact = String.Format("{0} TCS {1}", Contact, DetectedShip.TotalCrossSection); + } + + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ContactNew, DetectedShip.ShipsTaskGroup.Contact.CurrentSystem, DetectedShip.ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), Contact); + + CurrentFaction.MessageLog.Add(NMsg); + } /// @@ -81,50 +99,84 @@ public FactionContact(ShipTN DetectedShip, bool Thermal, bool em, bool Active, u /// Detected on EM? /// Detected by actives? /// Current tick. - public void updateFactionContact(bool Thermal, bool Em, bool Active, uint tick) + public void updateFactionContact(Faction CurrentFaction, bool Thermal, bool Em, bool Active, uint tick) { - if (thermal == false && Thermal == true) + if (thermal == Thermal && EM == Em && active == Active) { - /// - /// New thermal detection event, message logic should be here. - /// - thermalTick = tick; - } - else if (thermal == true && Thermal == false) - { - /// - /// Thermal contact lost. - /// + return; } - if (EM == false && Em == true) - { - /// - /// New EM detection event, message logic should be here. - /// - EMTick = tick; - } - if (EM == true && Em == false) - { - /// - /// EM contact lost. - /// - } + String Contact = "N/A"; + MessageEntry.MessageType type = MessageEntry.MessageType.Count; - if (active == false && Active == true) + if (Thermal == false && Em == false && Active == false) { - /// - /// New active detection event, message logic should be here. - /// - activeTick = tick; + Contact = "Existing contact lost"; + type = MessageEntry.MessageType.ContactLost; } - if (active == true && Active == false) + else { - /// - /// Active contact lost. - /// + Contact = "Update on existing contact:"; + type = MessageEntry.MessageType.ContactUpdate; + + if (thermal == false && Thermal == true) + { + /// + /// New thermal detection event, message logic should be here. + /// + thermalTick = tick; + + Contact = String.Format("{0} Thermal Signature {1}", Contact, ship.CurrentThermalSignature); + } + else if (thermal == true && Thermal == false) + { + /// + /// Thermal contact lost. + /// + Contact = String.Format("{0} Thermal contact lost", Contact); + } + + if (EM == false && Em == true) + { + /// + /// New EM detection event, message logic should be here. + /// + EMTick = tick; + + Contact = String.Format("{0} EM Signature {1}", Contact, ship.CurrentEMSignature); + } + if (EM == true && Em == false) + { + /// + /// EM contact lost. + /// + Contact = String.Format("{0} EM contact lost", Contact); + } + + if (active == false && Active == true) + { + /// + /// New active detection event, message logic should be here. + /// + activeTick = tick; + + Contact = String.Format("{0} TCS {1}", Contact, ship.TotalCrossSection); + } + if (active == true && Active == false) + { + /// + /// Active contact lost. + /// + + Contact = String.Format("{0} Active contact lost", Contact); + } + } + MessageEntry NMsg = new MessageEntry(type, ship.ShipsTaskGroup.Contact.CurrentSystem, ship.ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), Contact); + + CurrentFaction.MessageLog.Add(NMsg); thermal = Thermal; EM = Em; @@ -218,6 +270,37 @@ public void RemoveContact(int RemIndex) public class MessageEntry { + /// + /// Message types that will be printed to the event log. + /// + public enum MessageType + { + ContactNew, + ContactUpdate, + ContactLost, + + FiringHit, + FiringMissed, + FiringRecharging, + FiringZeroHitChance, + + OrdersCompleted, + OrdersNotCompleted, + + ShieldRecharge, + + ShipDamage, + ShipDamageReport, + + Error, + Count + } + + /// + /// What specific type of message is this? + /// + public MessageType TypeOf { get; set; } + /// /// which starsystem does this message occur in. /// @@ -236,7 +319,6 @@ public class MessageEntry /// /// How long since the last time increment? /// - public int TimeSlice { get; set; } /// /// Text of the message for the log. @@ -252,8 +334,9 @@ public class MessageEntry /// Game time of message. /// Time since last increment. /// text of the message. - public MessageEntry(StarSystem Loc, StarSystemEntity Ref, DateTime Time, int timeSlice, string text) + public MessageEntry(MessageType Type, StarSystem Loc, StarSystemEntity Ref, DateTime Time, int timeSlice, string text) { + TypeOf = Type; Location = Loc; entity = Ref; TimeOfMessage = Time; @@ -1310,7 +1393,7 @@ public void SensorSweep(int YearTickValue) if (inDict == true) { - DetectedContacts[detectedShip].updateFactionContact(th, em, ac, (uint)YearTickValue); + DetectedContacts[detectedShip].updateFactionContact(this, th, em, ac, (uint)YearTickValue); if (th == false && em == false && ac == false) { @@ -1319,7 +1402,7 @@ public void SensorSweep(int YearTickValue) } else if (inDict == false && (th == true || em == true || ac == true)) { - FactionContact newContact = new FactionContact(detectedShip, th, em, ac, (uint)YearTickValue); + FactionContact newContact = new FactionContact(this,detectedShip, th, em, ac, (uint)YearTickValue); DetectedContacts.Add(detectedShip, newContact); } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs b/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs index a5b4ca2ef..f350898a8 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/Ship.cs @@ -12,11 +12,29 @@ namespace Pulsar4X.Entities { public class ShipTN : GameEntity { + /// + /// Ships may be standard crewed vessels, organic lifeforms, or completely machine run solid state vessels. + /// + public enum ShipType + { + Standard, + Organic, + SolidState, + Count + } + + /// /// Class of this ship. /// public ShipClassTN ShipClass { get; set; } + + /// + /// What type of ship is this? + /// + public ShipType TypeOf { get; set; } + /// /// Taskgroup the ship is part of. /// @@ -392,6 +410,11 @@ public ShipTN(ShipClassTN ClassDefinition, int ShipIndex, int CurrentTimeSlice, /// Inform the class that it has a new member. /// ClassDefinition.ShipsInClass.Add(this); + + /// + /// Ships are standard crewed vessels for now. + /// + TypeOf = ShipType.Standard; /// /// Tell the Ship which TG it is a part of. @@ -928,10 +951,13 @@ public int SetSpeed(int Speed) /// How much damage is being done. /// Where Armor damage is inflicted. Temporary argument for the time being. remove these when rngs are resolved. /// Whether or not the ship was destroyed as a result of this action. - public bool OnDamaged(DamageTypeTN Type, ushort Value, ushort HitLocation) + public bool OnDamaged(DamageTypeTN Type, ushort Value, ushort HitLocation, ShipTN FiringShip) { ushort Damage = Value; ushort internalDamage = 0; + ushort startDamage = Value; + bool ColumnPenetration = false; + int LastColumnValue = ShipArmor.armorDef.depth; if (Type != DamageTypeTN.Meson) { @@ -975,6 +1001,7 @@ public bool OnDamaged(DamageTypeTN Type, ushort Value, ushort HitLocation) else { Damage = (ushort)(Damage - (ushort)Math.Floor(CurrentShieldPool)); + CurrentShieldPool = 0.0f; } } @@ -983,7 +1010,29 @@ public bool OnDamaged(DamageTypeTN Type, ushort Value, ushort HitLocation) /// Shields absorbed all damage. /// if (Damage == 0) + { + String DamageString = String.Format("All damage to {0} absorbed by shields", Name); + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), DamageString); + + ShipsFaction.MessageLog.Add(NMsg); + return false; + } + else + { + + if ((startDamage - Damage) > 0) + { + String DamageString = String.Format("{0} damage to {1} absorbed by shields", (startDamage - Damage), Name); + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), DamageString); + + ShipsFaction.MessageLog.Add(NMsg); + } + } + + startDamage = Damage; if (Type != DamageTypeTN.Microwave) { @@ -1015,10 +1064,36 @@ public bool OnDamaged(DamageTypeTN Type, ushort Value, ushort HitLocation) } left = (short)(HitLocation - 1); right = (short)(HitLocation + 1); + + if (ShipArmor.isDamaged == true) + { + LastColumnValue = ShipArmor.armorColumns[HitLocation]; + } + internalDamage = (ushort)ShipArmor.SetDamage(Columns, ShipArmor.armorDef.depth, HitLocation, Table.damageTemplate[Table.hitPoint]); + + if (LastColumnValue != 0 && internalDamage != 0) + { + ColumnPenetration = true; + } + + if (Type == DamageTypeTN.Plasma && Table.hitPoint + 1 < Table.damageTemplate.Count) { + + if (ShipArmor.isDamaged == true) + { + LastColumnValue = ShipArmor.armorColumns[(HitLocation + 1)]; + } + internalDamage = (ushort)((ushort)internalDamage + (ushort)ShipArmor.SetDamage(Columns, ShipArmor.armorDef.depth, (ushort)(HitLocation + 1), Table.damageTemplate[Table.hitPoint + 1])); + + + if (LastColumnValue != 0 && internalDamage != 0) + { + ColumnPenetration = true; + } + right++; } @@ -1038,20 +1113,80 @@ public bool OnDamaged(DamageTypeTN Type, ushort Value, ushort HitLocation) /// if (Table.hitPoint - loop >= 0) { + if (ShipArmor.isDamaged == true) + { + LastColumnValue = ShipArmor.armorColumns[left]; + } + if (ImpactLevel - Table.damageTemplate[Table.hitPoint - loop] < ShipArmor.armorColumns[left]) internalDamage = (ushort)((ushort)internalDamage + (ushort)ShipArmor.SetDamage(Columns, ShipArmor.armorDef.depth, (ushort)left, Table.damageTemplate[Table.hitPoint - loop])); + + if (LastColumnValue != 0 && internalDamage != 0) + { + ColumnPenetration = true; + } + } if (Table.hitPoint + loop < Table.damageTemplate.Count) { + if (ShipArmor.isDamaged == true) + { + LastColumnValue = ShipArmor.armorColumns[right]; + } + if (ImpactLevel - Table.damageTemplate[Table.hitPoint + loop] < ShipArmor.armorColumns[right]) internalDamage = (ushort)((ushort)internalDamage + (ushort)ShipArmor.SetDamage(Columns, ShipArmor.armorDef.depth, (ushort)right, Table.damageTemplate[Table.hitPoint + loop])); + + if (LastColumnValue != 0 && internalDamage != 0) + { + ColumnPenetration = true; + } + } left--; right++; } + if ((startDamage - internalDamage) > 0) + { + + String DamageString = String.Format("{0} damage to {1} absorbed by Armour", (startDamage - internalDamage), Name); + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), DamageString); + + ShipsFaction.MessageLog.Add(NMsg); + } + + if (ColumnPenetration == true) + { + + String DamageString = "N/A"; + + /// + /// Need a switch here for organic or solid state ships to change or remove this message. + /// + switch (TypeOf) + { + case ShipType.Standard : + DamageString = String.Format("{0} is streaming atmosphere", Name); + break; + case ShipType.Organic : + DamageString = String.Format("{0} is streaming fluid", Name); + break; + } + + if (TypeOf == ShipType.Standard || TypeOf == ShipType.Organic) + { + + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamageReport, FiringShip.ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), DamageString); + + FiringShip.ShipsFaction.MessageLog.Add(NMsg); + } + } + } else { @@ -1110,6 +1245,28 @@ public bool OnDamaged(DamageTypeTN Type, ushort Value, ushort HitLocation) int DamageDone = DestroyComponent(ShipClass.ListOfComponentDefs[loop].componentType, loop, internalDamage, destroy, DacRNG); + if (DamageDone != -1) + { + int ID = ComponentDefIndex[loop] + destroy; + + if (ShipComponents[ID].isDestroyed == true) + { + String DamageString = String.Format("{0} hit by {1} damage and was destroyed", ShipComponents[ID].Name, DamageDone); + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), DamageString); + + ShipsFaction.MessageLog.Add(NMsg); + } + else + { + String DamageString = String.Format("{0} Absorbed {1} damage", ShipComponents[ID].Name, DamageDone); + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), DamageString); + + ShipsFaction.MessageLog.Add(NMsg); + } + } + /// /// No components are left to destroy, so short circuit the loops,destroy the ship, and create a wreck. /// @@ -1147,6 +1304,14 @@ public bool OnDamaged(DamageTypeTN Type, ushort Value, ushort HitLocation) if (Attempts == 20) { + String DamageString = String.Format("{0} Destroyed", Name); + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), DamageString); + + ShipsFaction.MessageLog.Add(NMsg); + FiringShip.ShipsFaction.MessageLog.Add(NMsg); + + IsDestroyed = true; return true; } @@ -1222,6 +1387,40 @@ public bool OnDamaged(DamageTypeTN Type, ushort Value, ushort HitLocation) if (hardCheck < hardValue) { DamageDone = DestroyComponent(list.Key.componentType, CI, internalDamage, destroy, DacRNG); + + if (DamageDone != -1) + { + int ID = ComponentDefIndex[CI] + destroy; + + if (ShipComponents[ID].isDestroyed == true) + { + String DamageString = String.Format("{0} hit by {1} damage and was destroyed", ShipComponents[ID].Name, DamageDone); + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), DamageString); + + ShipsFaction.MessageLog.Add(NMsg); + } + else + { + String DamageString = String.Format("{0} Absorbed {1} damage. Electronic Components shouldn't resist damage like this", ShipComponents[ID].Name, DamageDone); + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), DamageString); + + ShipsFaction.MessageLog.Add(NMsg); + } + } + } + else + { + + int ID = ComponentDefIndex[CI] + destroy; + String DamageString = String.Format("{0} Absorbed {1} damage", ShipComponents[ID].Name, DamageDone); + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), DamageString); + + ShipsFaction.MessageLog.Add(NMsg); + + DamageDone = 0; } } @@ -1993,7 +2192,7 @@ public bool ShipFireWeapons(int CurrentTick,Random RNG) /// Oops. How did we get here? We don't know if the ship can even detect its targets, so it had better not fire on them. /// String Fire = String.Format("{0} : {1}. Was sensor detection routine run this tick? see Ship.cs ShipFireWeapons().", CurrentTick, ShipsTaskGroup.Contact.DistanceUpdate[targetID]); - MessageEntry Entry = new MessageEntry(ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, GameState.Instance.GameDateTime, (int)CurrentTick, Fire); + MessageEntry Entry = new MessageEntry(MessageEntry.MessageType.Error,ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, GameState.Instance.GameDateTime, (int)CurrentTick, Fire); ShipsFaction.MessageLog.Add(Entry); @@ -2040,13 +2239,13 @@ public bool ShipFireWeapons(int CurrentTick,Random RNG) /// Oops. How did we get here? We don't know if the ship can even detect its targets, so it had better not fire on them. /// String Fire = String.Format("{0} : {1}. Was sensor detection routine run this tick? see Ship.cs ShipFireWeapons().", CurrentTick, ShipsTaskGroup.Contact.DistanceUpdate[targetID]); - MessageEntry Entry = new MessageEntry(ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, GameState.Instance.GameDateTime, (int)CurrentTick, Fire); + MessageEntry Entry = new MessageEntry(MessageEntry.MessageType.Error,ShipsTaskGroup.Contact.CurrentSystem, ShipsTaskGroup.Contact, GameState.Instance.GameDateTime, (int)CurrentTick, Fire); ShipsFaction.MessageLog.Add(Entry); return false; } - fired = ShipMFC[loop].FireWeapons(ShipsTaskGroup); + fired = ShipMFC[loop].FireWeapons(ShipsTaskGroup,this); } } } @@ -2090,20 +2289,29 @@ public void SetShields(bool Active) /// Tick is the value in seconds the sim is being advanced by. 1 day = 86400 seconds. smallest practical value is 5. public void RechargeShields(uint tick) { - if (ShieldIsActive == true) + if (ShieldIsActive == true && CurrentShieldPool != CurrentShieldPoolMax) { + String Charge = "Shield Recharge: "; float amt = (float)tick / 5.0f; float ShieldRecharge = CurrentShieldGen * amt; if (CurrentShieldPool + ShieldRecharge >= CurrentShieldPoolMax) { - CurrentShieldPool = CurrentShieldPoolMax; + ShieldRecharge = CurrentShieldPoolMax - CurrentShieldPool; + CurrentShieldPool = CurrentShieldPoolMax; } else { CurrentShieldPool = CurrentShieldPool + ShieldRecharge; } + + Charge = String.Format("{0} {1} points", Charge, ShieldRecharge); + + MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShieldRecharge, this.ShipsTaskGroup.Contact.CurrentSystem, this.ShipsTaskGroup.Contact, GameState.Instance.GameDateTime, + (GameState.SE.CurrentTick - GameState.SE.lastTick), Charge); + + ShipsFaction.MessageLog.Add(NMsg); } } diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs b/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs index c5db26621..a381e7db1 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/SimEntity.cs @@ -326,14 +326,6 @@ public void AdvanceSim(BindingList P, Random RNG, int tickValue) lastTick = CurrentTick; CurrentTick += tickValue; - /// - /// Do sensor sweeps here. - /// - for (int loop = factionStart; loop < factionCount; loop++) - { - P[loop].SensorSweep(CurrentTick); - } - /// /// Follow orders here. /// @@ -349,6 +341,14 @@ public void AdvanceSim(BindingList P, Random RNG, int tickValue) } } + /// + /// Do sensor sweeps here. Sensors must be done after movement, not before. + /// + for (int loop = factionStart; loop < factionCount; loop++) + { + P[loop].SensorSweep(CurrentTick); + } + /// /// attempt to fire weapons at target here. /// Initiative will have to be implemented here for "fairness". right now lower P numbers have the advantage. @@ -366,7 +366,8 @@ public void AdvanceSim(BindingList P, Random RNG, int tickValue) /// /// Open fire and not destroyed. /// - if (pair.Value.ShipBFC[pair.Key.componentIndex].openFire == true && pair.Value.ShipBFC[pair.Key.componentIndex].isDestroyed == false) + if (pair.Value.ShipBFC[pair.Key.componentIndex].openFire == true && pair.Value.ShipBFC[pair.Key.componentIndex].isDestroyed == false && + pair.Value.ShipBFC[pair.Key.componentIndex].target != null) { ShipTN Target = pair.Value.ShipBFC[pair.Key.componentIndex].target; @@ -489,7 +490,8 @@ public void AdvanceSim(BindingList P, Random RNG, int tickValue) /// String Entry = String.Format("Taskgroup {0} cannot find target, orders canceled.",pair.Key.TaskGroupsOrdered[loop4].Name); - MessageEntry Entry2 = new MessageEntry(pair.Key.TaskGroupsOrdered[loop4].Contact.CurrentSystem, pair.Key.TaskGroupsOrdered[loop4].Contact, GameState.Instance.GameDateTime, GameState.Instance.YearTickValue, Entry); + MessageEntry Entry2 = new MessageEntry(MessageEntry.MessageType.OrdersNotCompleted,pair.Key.TaskGroupsOrdered[loop4].Contact.CurrentSystem, pair.Key.TaskGroupsOrdered[loop4].Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), Entry); pair.Key.TaskGroupsOrdered[loop4].TaskGroupFaction.MessageLog.Add(Entry2); int lastOrder = pair.Key.TaskGroupsOrdered[loop4].TaskGroupOrders.Count - 1; @@ -533,7 +535,8 @@ public void AdvanceSim(BindingList P, Random RNG, int tickValue) /// String Entry = String.Format("Taskgroup {0} cannot find target, orders canceled.", pair.Key.ShipsTaskGroup.TaskGroupsOrdered[loop4].Name); - MessageEntry Entry2 = new MessageEntry(pair.Key.ShipsTaskGroup.TaskGroupsOrdered[loop4].Contact.CurrentSystem, pair.Key.ShipsTaskGroup.TaskGroupsOrdered[loop4].Contact, GameState.Instance.GameDateTime, GameState.Instance.YearTickValue, Entry); + MessageEntry Entry2 = new MessageEntry(MessageEntry.MessageType.OrdersNotCompleted, pair.Key.ShipsTaskGroup.TaskGroupsOrdered[loop4].Contact.CurrentSystem, pair.Key.ShipsTaskGroup.TaskGroupsOrdered[loop4].Contact, + GameState.Instance.GameDateTime, (GameState.SE.CurrentTick - GameState.SE.lastTick), Entry); pair.Key.ShipsTaskGroup.TaskGroupsOrdered[loop4].TaskGroupFaction.MessageLog.Add(Entry2); int lastOrder = pair.Key.ShipsTaskGroup.TaskGroupsOrdered[loop4].TaskGroupOrders.Count - 1; diff --git a/Pulsar4X/Pulsar4X.Lib/Entities/TaskGroup.cs b/Pulsar4X/Pulsar4X.Lib/Entities/TaskGroup.cs index 88af05318..05669b4b7 100644 --- a/Pulsar4X/Pulsar4X.Lib/Entities/TaskGroup.cs +++ b/Pulsar4X/Pulsar4X.Lib/Entities/TaskGroup.cs @@ -1390,7 +1390,7 @@ public void FollowOrders(uint TimeSlice) { String Entry = String.Format("Ship Error, no TaskGroupsOrdered found for TG {0} in Faction {1}, {2} has completed an order to move.",TaskGroupOrders[0].taskGroup.Name, TaskGroupOrders[0].taskGroup.TaskGroupFaction.Name, Name); - MessageEntry NME = new MessageEntry(Contact.CurrentSystem, Contact, GameState.Instance.GameDateTime, GameState.Instance.YearTickValue, Entry); + MessageEntry NME = new MessageEntry(MessageEntry.MessageType.Error,Contact.CurrentSystem, Contact, GameState.Instance.GameDateTime, GameState.Instance.YearTickValue, Entry); TaskGroupFaction.MessageLog.Add(NME); } } diff --git a/Pulsar4X/Pulsar4X.Tests/ShipTests.cs b/Pulsar4X/Pulsar4X.Tests/ShipTests.cs index 8c7cc98c2..48a398e44 100644 --- a/Pulsar4X/Pulsar4X.Tests/ShipTests.cs +++ b/Pulsar4X/Pulsar4X.Tests/ShipTests.cs @@ -1290,11 +1290,11 @@ public void ShipDamageModel() Random Gen = new Random(); ushort HitLocation = (ushort)Gen.Next(0, Columns); - PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Missile, 4, HitLocation); + PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Missile, 4, HitLocation, PlayerFaction1.TaskGroups[0].Ships[0]); HitLocation = (ushort)Gen.Next(0, Columns); - PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Missile, 4, HitLocation); + PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Missile, 4, HitLocation, PlayerFaction1.TaskGroups[0].Ships[0]); HitLocation = (ushort)Gen.Next(0, Columns); - PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Missile, 4, HitLocation); + PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Missile, 4, HitLocation, PlayerFaction1.TaskGroups[0].Ships[0]); Console.WriteLine("Damage Template:"); for (int loop = 0; loop < DamageValuesTN.MissileTable[3].damageTemplate.Count; loop++) @@ -1804,25 +1804,25 @@ public void MesonMicrowaveShieldTest() Random Gen = new Random(); ushort HitLocation = (ushort)Gen.Next(0, Columns); - PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Microwave, 1, HitLocation); + PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Microwave, 1, HitLocation, PlayerFaction1.TaskGroups[0].Ships[0]); Console.WriteLine("{0} {1}", PlayerFaction1.TaskGroups[0].Ships[0].CurrentShieldPool, PlayerFaction1.TaskGroups[0].Ships[0].CurrentShieldPoolMax); HitLocation = (ushort)Gen.Next(0, Columns); - PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Microwave, 1, HitLocation); + PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Microwave, 1, HitLocation, PlayerFaction1.TaskGroups[0].Ships[0]); Console.WriteLine("{0} {1}", PlayerFaction1.TaskGroups[0].Ships[0].CurrentShieldPool, PlayerFaction1.TaskGroups[0].Ships[0].CurrentShieldPoolMax); HitLocation = (ushort)Gen.Next(0, Columns); - PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Microwave, 1, HitLocation); + PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Microwave, 1, HitLocation, PlayerFaction1.TaskGroups[0].Ships[0]); Console.WriteLine("{0} {1}", PlayerFaction1.TaskGroups[0].Ships[0].CurrentShieldPool, PlayerFaction1.TaskGroups[0].Ships[0].CurrentShieldPoolMax); HitLocation = (ushort)Gen.Next(0, Columns); - PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Microwave, 1, HitLocation); + PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Microwave, 1, HitLocation, PlayerFaction1.TaskGroups[0].Ships[0]); Console.WriteLine("{0} {1} {2}", PlayerFaction1.TaskGroups[0].Ships[0].CurrentShieldPool, PlayerFaction1.TaskGroups[0].Ships[0].CurrentShieldPoolMax, PlayerFaction1.TaskGroups[0].Ships[0].DestroyedComponents.Count); @@ -1833,7 +1833,7 @@ public void MesonMicrowaveShieldTest() HitLocation = (ushort)Gen.Next(0, Columns); - PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Meson, 1, HitLocation); + PlayerFaction1.TaskGroups[0].Ships[0].OnDamaged(DamageTypeTN.Meson, 1, HitLocation, PlayerFaction1.TaskGroups[0].Ships[0]); Console.WriteLine("{0} {1} {2}", PlayerFaction1.TaskGroups[0].Ships[0].CurrentShieldPool, PlayerFaction1.TaskGroups[0].Ships[0].CurrentShieldPoolMax, PlayerFaction1.TaskGroups[0].Ships[0].DestroyedComponents.Count); diff --git a/Pulsar4X/Pulsar4X.UI/Handlers/Ships.cs b/Pulsar4X/Pulsar4X.UI/Handlers/Ships.cs index b5ebe1df9..f2472c379 100644 --- a/Pulsar4X/Pulsar4X.UI/Handlers/Ships.cs +++ b/Pulsar4X/Pulsar4X.UI/Handlers/Ships.cs @@ -1196,9 +1196,18 @@ private void TEMPBuildMessageLog() { m_oDetailsPanel.TEMPPRINTTextBox.Clear(); + if (_CurrnetFaction.MessageLog.Count > 200) + { + while (_CurrnetFaction.MessageLog.Count > 200) + { + _CurrnetFaction.MessageLog.RemoveAt(0); + } + } + + for (int loop = 0; loop < _CurrnetFaction.MessageLog.Count; loop++) { - String Entry = String.Format("{0} - {1}: {2}\n", _CurrnetFaction.MessageLog[loop].Location, _CurrnetFaction.MessageLog[loop].TimeSlice, _CurrnetFaction.MessageLog[loop].Text); + String Entry = String.Format("{0} | {1} | {2} - {3}: {4}\n", _CurrnetFaction.MessageLog[loop].TypeOf, _CurrnetFaction.MessageLog[loop].TimeOfMessage, _CurrnetFaction.MessageLog[loop].Location, _CurrnetFaction.MessageLog[loop].TimeSlice, _CurrnetFaction.MessageLog[loop].Text); m_oDetailsPanel.TEMPPRINTTextBox.AppendText(Entry); }