From 1c5b690bb4b3306759c97c9191c804a586131b66 Mon Sep 17 00:00:00 2001 From: Rob R Date: Sat, 29 Sep 2018 21:30:13 -0500 Subject: [PATCH 01/13] Added active level to skill list data. Added check against active level to help find alpha/omega state. --- src/EVEMon.Common/Data/StaticSkill.cs | 189 +++++++++++++++++- src/EVEMon.Common/Models/Character.cs | 23 ++- src/EVEMon.Common/Models/Skill.cs | 15 ++ .../Serialization/Esi/EsiSkillListItem.cs | 3 +- .../Eve/SerializableCharacterSkill.cs | 5 +- 5 files changed, 231 insertions(+), 4 deletions(-) diff --git a/src/EVEMon.Common/Data/StaticSkill.cs b/src/EVEMon.Common/Data/StaticSkill.cs index 0c6dad5bb..aee4fb0e7 100644 --- a/src/EVEMon.Common/Data/StaticSkill.cs +++ b/src/EVEMon.Common/Data/StaticSkill.cs @@ -194,6 +194,193 @@ public IEnumerable AllPrerequisites /// public static StaticSkill UnknownStaticSkill => s_unknownStaticSkill ?? (s_unknownStaticSkill = new StaticSkill()); + private static Dictionary alphaLimit = new Dictionary() + { + {3339, 4}, // Amarr Battleship + {33095, 4}, // Amarr Battlecruiser + {3335, 4}, // Amarr Cruiser + {33091, 4}, // Amarr Destroyer + {3331, 4}, // Amarr Frigate + {3343, 1}, // Amarr Industrial + {3338, 4}, // Caldari Battleship + {33096, 4}, // Caldari Battlecruiser + {3334, 4}, // Caldari Cruiser + {33092, 4}, // Caldari Destroyer + {3330, 4}, // Caldari Frigate + {3342, 1}, // Caldari Industrial + {3336, 4}, // Gallente Battleship + {33097, 4}, // Gallente Battlecruiser + {3332, 4}, // Gallente Cruiser + {33093, 4}, // Gallente Destroyer + {3328, 4}, // Gallente Frigate + {3340, 1}, // Gallente Industrial + {3337, 4}, // Minmatar Battleship + {33098, 4}, // Minmatar Battlecruiser + {3333, 4}, // Minmatar Cruiser + {33094, 4}, // Minmatar Destroyer + {3329, 4}, // Minmatar Frigate + {3341, 1}, // Minmatar Industrial + {32918, 4}, // Mining Frigate + {3327, 4}, // Spaceship Command + {3452, 3}, // Acceleration Control + {3450, 3}, // Afterburner + {3453, 3}, // Evasive Maneuvering + {3454, 3}, // High Speed Maneuvering + {3449, 4}, // Navigation + {3455, 3}, // Warp Drive Operation + {11207, 3}, // Advanced Weapon Upgrades + {3426, 5}, // CPU Management + {3423, 4}, // Capacitor Emission Systems + {3418, 4}, // Capacitor Management + {3417, 3}, // Capacitor Systems Operation + {3432, 5}, // Electronics Upgrades + {3424, 5}, // Energy Grid Upgrades + {3421, 2}, // Energy Pulse Weapons + {3413, 5}, // Power Grid Management + {28164, 4}, // Thermodynamics + {3318, 5}, // Weapon Upgrades + {33078, 1}, // Armor Layering + {22806, 2}, // EM Armor Compensation + {22807, 2}, // Explosive Armor Compensation + {3394, 5}, // Hull Upgrades + {22808, 2}, // Kinetic Armor Compensation + {3392, 5}, // Mechanics + {16069, 3}, // Remote Armor Repair Systems + {27902, 2}, // Remote Hull Repair Systems + {3393, 5}, // Repair Systems + {22809, 2}, // Thermal Armor Compensation + {12365, 2}, // EM Shield Compensation + {12367, 2}, // Explosive Shield Compensation + {12366, 2}, // Kinetic Shield Compensation + {3422, 3}, // Shield Emission Systems + {21059, 4}, // Shield Compensation + {3419, 4}, // Shield Management + {3416, 4}, // Shield Operation + {3425, 4}, // Shield Upgrades + {3420, 4}, // Tactical Shield Manipulation + {11566, 2}, // Thermal Shield Compensation + {3428, 3}, // Long Range Targeting + {3431, 3}, // Signature Analysis + {3429, 4}, // Target Management + {3316, 4}, // Controlled bursts + {3300, 5}, // Gunnery + {3309, 4}, // Large Energy Turret + {3307, 4}, // Large Hybrid Turret + {3308, 4}, // Large Projectile Turret + {12202, 3}, // Medium Artillery Specialization + {12208, 3}, // Medium Autocannon Specialization + {12204, 3}, // Medium Beam Laser Specialization + {12211, 3}, // Medium Blaster Specialization + {3306, 5}, // Medium Energy Turret + {3304, 5}, // Medium Hybrid Turret + {3305, 5}, // Medium Projectile Turret + {12214, 3}, // Medium Pulse Laser Specialization + {12206, 3}, // Medium Rail Specialization + {3312, 4}, // Motion Prediction + {3310, 4}, // Rapid Firing + {3311, 4}, // Sharpshooter + {12201, 3}, // Small Artillery Specialization + {11084, 3}, // Small Autocannon Specialization + {11083, 3}, // Small Beam Laser Specialization + {12210, 3}, // Small Blaster Specialization + {3303, 5}, // Small Energy Turret + {3301, 5}, // Small Hybrid Turret + {3302, 5}, // Small Projectile Turret + {12213, 3}, // Small Pulse Laser Specialization + {11082, 3}, // Small Rail Specialization + {3315, 4}, // Surgical Strike + {3317, 4}, // Trajectory Analysis + {3326, 4}, // Cruise Missiles + {20312, 3}, // Guided Missile Precision + {25718, 3}, // Heavy Assault Missile Specialization + {25719, 5}, // Heavy Assault Missiles + {20211, 3}, // Heavy Missile Specialization + {3324, 5}, // Heavy Missiles + {20210, 3}, // Light Missile Specialization + {3321, 5}, // Light Missiles + {12441, 4}, // Missile Bombardment + {3319, 5}, // Missile Launcher Operation + {12442, 2}, // Missile Projection + {21071, 4}, // Rapid Launch + {20209, 3}, // Rocket Specialization + {3320, 5}, // Rockets + {20314, 3}, // Target Navigation Prediction + {3325, 4}, // Torpedoes + {20315, 3}, // Warhead Upgrades + {3437, 4}, // Drone Avionics + {23618, 4}, // Drone Durability + {3442, 4}, // Drone Interfacing + {12305, 4}, // Drone Navigation + {23606, 4}, // drone Sharpshooting + {3436, 5}, // Drones + {24241, 5}, // Light Drone Operation + {33699, 5}, // Medium Drone Operation + {3439, 2}, // Repair Drone Operation + {3441, 4}, // Heavy Drone Operation + {12484, 2}, // Amarr Drone Specialization + {12487, 2}, // Caldari Drone Specialization + {12486, 2}, // Gallente Drone Specialization + {12485, 2}, // Minmatar Drone Specialization + {3427, 4}, // Electronic Warfare + {3435, 4}, // Propulsion Jamming + {3434, 4}, // Weapon Disruption + {3433, 3}, // Sensor Linking + {19921, 3}, // Target Painting + {13278, 3}, // Archaeology + {25811, 2}, // Astrometric Acquisition + {25739, 2}, // Astrometric Rangefinding + {3412, 3}, // Astrometrics + {21718, 3}, // Hacking + {3551, 3}, // Survey + {26253, 3}, // Armor Rigging + {26254, 3}, // Astronautics Rigging + {26259, 3}, // Hybrid Weapon Rigging + {26260, 3}, // Launcher Rigging + {26257, 3}, // Shield Rigging + {26261, 3}, // Projectile Weapon Rigging + {26255, 3}, // Drones Rigging + {26256, 3}, // Electronic superiority Rigging + {26258, 3}, // Energy Weapon Rigging + {26252, 3}, // Jury Rigging + {3359, 2}, // Connections + {3361, 2}, // Criminal Connections + {3357, 3}, // Diplomacy + {3894, 2}, // Distribution Connections + {3893, 2}, // Mining Connections + {3356, 2}, // Negotiation + {3895, 2}, // Security Connections + {3355, 3}, // Social + {3348, 3}, // Leadership + {3363, 1}, // Corporation Management + {3446, 2}, // Broker Relations + {16598, 2}, // Marketing + {3443, 3}, // Trade + {3405, 3}, // Biology + {3411, 3}, // Cybernetics + {24242, 1}, // Infomorph Psychology + {3380, 5}, // Industry + {3387, 3}, // Mass Production + {3402, 4}, // Science + {3386, 4}, // Mining + {16281, 2}, // Ice Harvesting + {22578, 4}, // Mining Upgrades + {3358, 3}, // Reprocessing + {25544, 2}, // Gas Cloud Harvesting + {25863, 3}, // Salvaging + {11584, 1} // Anchoring + }; + + public long AlphaLimit { + get + { + if(alphaLimit.ContainsKey(ID)) + { + return alphaLimit[ID]; + } + return 0; + } + } + #endregion @@ -278,4 +465,4 @@ public Skill ToCharacter(Character character) #endregion } -} \ No newline at end of file +} diff --git a/src/EVEMon.Common/Models/Character.cs b/src/EVEMon.Common/Models/Character.cs index 9cb3fb84c..fe3a079ad 100644 --- a/src/EVEMon.Common/Models/Character.cs +++ b/src/EVEMon.Common/Models/Character.cs @@ -113,6 +113,27 @@ public void UpdateAccountStatus(AccountStatus.AccountStatusType statusType = } } + if (statusType != AccountStatus.AccountStatusType.Omega) + { + foreach(var sk in Skills) + { + // Is the skill level being limited by alpha status? + if(sk.ActiveLevel < sk.Level) + { + // Active level is being limited by alpha status. + statusType = AccountStatus.AccountStatusType.Alpha; + break; + } + // Has the skill alpha limit been exceeded? + if(sk.ActiveLevel > sk.StaticData.AlphaLimit) + { + // Active level is greater than alpha limit, only on Omega. + statusType = AccountStatus.AccountStatusType.Omega; + break; + } + } + } + CharacterStatus = new AccountStatus(statusType); } @@ -846,7 +867,7 @@ internal void Import(EsiAPISkills skills, EsiAPISkillQueue queue) { // Queued skill is completed, so make sure the imported skill is // updated - skill.ActiveLevel = Math.Max(skill.ActiveLevel, queuedSkill.Level); + //skill.ActiveLevel = Math.Max(skill.ActiveLevel, queuedSkill.Level); skill.Level = Math.Max(skill.Level, queuedSkill.Level); skill.Skillpoints = Math.Max(skill.Skillpoints, queuedSkill.EndSP); } diff --git a/src/EVEMon.Common/Models/Skill.cs b/src/EVEMon.Common/Models/Skill.cs index bf575184b..927248017 100644 --- a/src/EVEMon.Common/Models/Skill.cs +++ b/src/EVEMon.Common/Models/Skill.cs @@ -25,6 +25,7 @@ public sealed class Skill : IStaticSkill // Previous dev of EVEMon made these longs, when patently unnecessary private long m_skillLevel; private long m_level; + private long m_activeLevel; private bool m_owned; private bool m_known; @@ -77,6 +78,7 @@ internal void Import(SerializableCharacterSkill src, bool fromCCP) SkillPoints = src.Skillpoints; LastConfirmedLvl = src.Level; m_level = Math.Min(s_maxLevel, src.Level); + m_activeLevel = Math.Min(s_maxLevel, src.ActiveLevel); } /// @@ -89,6 +91,7 @@ internal void Reset(bool importFromCCP) SkillPoints = 0; LastConfirmedLvl = 0; m_level = 0; + m_activeLevel = 0; // Are we reloading the settings ? if (!importFromCCP) @@ -134,6 +137,7 @@ internal SerializableCharacterSkill Export() ID = StaticData.ID, Name = StaticData.Name, Level = m_level, + ActiveLevel = m_activeLevel, Skillpoints = m_currentSkillPoints, OwnsBook = IsOwned, IsKnown = m_known @@ -270,6 +274,17 @@ public Int64 Level } } + /// + /// Get the last reported active level. + /// + public Int64 ActiveLevel + { + get + { + return m_activeLevel; + } + } + /// /// Gets the level gotten from CCP during the last update. /// diff --git a/src/EVEMon.Common/Serialization/Esi/EsiSkillListItem.cs b/src/EVEMon.Common/Serialization/Esi/EsiSkillListItem.cs index e0f141620..ced67f374 100644 --- a/src/EVEMon.Common/Serialization/Esi/EsiSkillListItem.cs +++ b/src/EVEMon.Common/Serialization/Esi/EsiSkillListItem.cs @@ -27,7 +27,8 @@ public SerializableCharacterSkill ToXMLItem() return new SerializableCharacterSkill() { ID = ID, - Level = Math.Min(ActiveLevel, Level), + Level = Level, + ActiveLevel = ActiveLevel, Skillpoints = Skillpoints, OwnsBook = true, IsKnown = true diff --git a/src/EVEMon.Common/Serialization/Eve/SerializableCharacterSkill.cs b/src/EVEMon.Common/Serialization/Eve/SerializableCharacterSkill.cs index 795bd2544..40db243d9 100644 --- a/src/EVEMon.Common/Serialization/Eve/SerializableCharacterSkill.cs +++ b/src/EVEMon.Common/Serialization/Eve/SerializableCharacterSkill.cs @@ -17,6 +17,9 @@ public sealed class SerializableCharacterSkill [XmlAttribute("level")] public Int64 Level { get; set; } + [XmlAttribute("activelevel")] + public Int64 ActiveLevel { get; set; } + [XmlAttribute("skillpoints")] public Int64 Skillpoints { get; set; } @@ -26,4 +29,4 @@ public sealed class SerializableCharacterSkill [XmlAttribute("isKnown")] public bool IsKnown { get; set; } } -} \ No newline at end of file +} From c502626a4d95b068f70da6229d50f7d8ae42db2e Mon Sep 17 00:00:00 2001 From: Rob R Date: Sun, 30 Sep 2018 09:47:34 -0500 Subject: [PATCH 02/13] Added alpha coloring to skill level bar of skills list. --- .../CharacterSkillsList.cs | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs b/src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs index b9a996fbf..e091d242a 100644 --- a/src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs +++ b/src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs @@ -35,8 +35,8 @@ internal sealed partial class CharacterSkillsList : UserControl private const byte PadRight = 7; // Skills drawing - Boxes - private const byte BoxWidth = 57; - private const byte BoxHeight = 14; + private const byte BoxWidth = 60; + private const byte BoxHeight = 16; private const byte LowerBoxHeight = 8; private const byte BoxHPad = 6; private const byte BoxVPad = 2; @@ -414,18 +414,43 @@ private static void DrawProgressionBar(Skill skill, DrawItemEventArgs e) private void DrawBoxes(Skill skill, DrawItemEventArgs e) { Graphics g = e.Graphics; + bool isAlpha = (skill.Character.CharacterStatus.CurrentStatus == AccountStatus.AccountStatusType.Alpha); + int alphaPad = 0; - g.DrawRectangle(Pens.Black, + // Invert background for better visibility of alpha colors. + g.FillRectangle(Brushes.Black, new Rectangle(e.Bounds.Right - BoxWidth - PadRight, e.Bounds.Top + PadTop, BoxWidth, BoxHeight)); + // Draw border around levels. + g.DrawRectangle(Pens.White, + new Rectangle(e.Bounds.Right - BoxWidth - PadRight + 1, e.Bounds.Top + PadTop + 1, BoxWidth - 3, BoxHeight - 3)); - const int LevelBoxWidth = (BoxWidth - 4 - 3) / 5; + const int LevelBoxWidth = (BoxWidth - 4 - 3 - 2) / 5; for (int level = 1; level <= 5; level++) { + Brush brush = Brushes.DarkGray; + if (isAlpha && level > skill.StaticData.AlphaLimit) + { + // This is alpha, draw smaller gold square to indicate cannot be trained. + brush = Brushes.Gold; + alphaPad = 2; + } + if (level <= skill.Level) + { + // This is a trained level. + brush = Brushes.White; + if(alphaPad > 0) + { + // This is an inactive trained level. + brush = Brushes.Gold; + alphaPad = 0; + } + } + Rectangle brect = new Rectangle( - e.Bounds.Right - BoxWidth - PadRight + 2 + LevelBoxWidth * (level - 1) + (level - 1), - e.Bounds.Top + PadTop + 2, LevelBoxWidth, BoxHeight - 3); + e.Bounds.Right - BoxWidth - PadRight + 2 + LevelBoxWidth * (level - 1) + (level - 1) + alphaPad + 1, + e.Bounds.Top + PadTop + 2 + alphaPad + 1, LevelBoxWidth - (alphaPad * 2), BoxHeight - 3 - (alphaPad * 2) - 3); - g.FillRectangle(level <= skill.Level ? Brushes.Black : Brushes.DarkGray, brect); + g.FillRectangle(brush, brect); // Color indicator for a queued level CCPCharacter ccpCharacter = Character as CCPCharacter; From 944a57dcd19bc19d7c80aeefd5416c5111f9b756 Mon Sep 17 00:00:00 2001 From: Rob R Date: Sun, 30 Sep 2018 10:37:18 -0500 Subject: [PATCH 03/13] Performance improvement. Stopped using dictionary lookup on every alpha limit check, set only once durring init. --- src/EVEMon.Common/Data/StaticSkill.cs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/EVEMon.Common/Data/StaticSkill.cs b/src/EVEMon.Common/Data/StaticSkill.cs index aee4fb0e7..c7b286b09 100644 --- a/src/EVEMon.Common/Data/StaticSkill.cs +++ b/src/EVEMon.Common/Data/StaticSkill.cs @@ -36,7 +36,11 @@ private StaticSkill() SecondaryAttribute = EveAttribute.None; Group = StaticSkillGroup.UnknownStaticSkillGroup; FormattedCost = Cost.ToNumericString(0); - } + if (alphaLimit.ContainsKey(ID)) + { + AlphaLimit = alphaLimit[ID]; + } + } /// /// Deserialization constructor from datafiles. @@ -59,6 +63,10 @@ internal StaticSkill(StaticSkillGroup group, SerializableSkill src, int arrayInd Group = group; Prerequisites = new Collection(); FormattedCost = Cost.ToNumericString(0); + if (alphaLimit.ContainsKey(ID)) + { + AlphaLimit = alphaLimit[ID]; + } } #endregion @@ -147,6 +155,11 @@ internal void CompleteInitialization(IEnumerable /// public bool IsTrainableOnTrialAccount { get; private set; } + /// + /// Get the level limit for an alpha clone. + /// + public long AlphaLimit { get; private set; } + /// /// Gets the prerequisites a character must satisfy before it can be trained. /// @@ -370,17 +383,6 @@ public IEnumerable AllPrerequisites {11584, 1} // Anchoring }; - public long AlphaLimit { - get - { - if(alphaLimit.ContainsKey(ID)) - { - return alphaLimit[ID]; - } - return 0; - } - } - #endregion From ee0c0e4063c10fdc7b33df7154eeaa364a1733f0 Mon Sep 17 00:00:00 2001 From: Rob R Date: Sun, 30 Sep 2018 10:38:27 -0500 Subject: [PATCH 04/13] Added IsAlpha convience property to character. --- src/EVEMon.Common/Models/Character.cs | 11 +++++++++++ src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/EVEMon.Common/Models/Character.cs b/src/EVEMon.Common/Models/Character.cs index fe3a079ad..a1326a0a2 100644 --- a/src/EVEMon.Common/Models/Character.cs +++ b/src/EVEMon.Common/Models/Character.cs @@ -389,6 +389,17 @@ public Station LastKnownStation /// Gets Alpha/Omega status for this character. /// public AccountStatus CharacterStatus { get; private set; } + + /// + /// Check if the character is in an alpha state. + /// + public bool IsAlpha + { + get + { + return CharacterStatus.CurrentStatus == AccountStatus.AccountStatusType.Alpha; + } + } #endregion diff --git a/src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs b/src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs index e091d242a..287774476 100644 --- a/src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs +++ b/src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs @@ -414,7 +414,7 @@ private static void DrawProgressionBar(Skill skill, DrawItemEventArgs e) private void DrawBoxes(Skill skill, DrawItemEventArgs e) { Graphics g = e.Graphics; - bool isAlpha = (skill.Character.CharacterStatus.CurrentStatus == AccountStatus.AccountStatusType.Alpha); + bool isAlpha = (skill.Character.IsAlpha); int alphaPad = 0; // Invert background for better visibility of alpha colors. From 8207ef6900b1a606a694762c90da06b9b7df3743 Mon Sep 17 00:00:00 2001 From: Rob R Date: Sun, 30 Sep 2018 10:44:48 -0500 Subject: [PATCH 05/13] Added notation for Omega clone only to skill browser level times. --- src/EVEMon/SkillPlanner/SkillBrowserControl.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/EVEMon/SkillPlanner/SkillBrowserControl.cs b/src/EVEMon/SkillPlanner/SkillBrowserControl.cs index 38a3d0271..ef6e26054 100644 --- a/src/EVEMon/SkillPlanner/SkillBrowserControl.cs +++ b/src/EVEMon/SkillPlanner/SkillBrowserControl.cs @@ -302,6 +302,10 @@ private void UpdateLevelLabel(Control label, int level) sb.Append($" ({percentDone:P0} complete)"); } } + if(level > m_selectedSkill.StaticData.AlphaLimit) + { + sb.Append("(Omega only)"); + } label.Text = sb.ToString(); } From b831c896341426d32cac6e0557eb1341d1401f7c Mon Sep 17 00:00:00 2001 From: Rob R Date: Sun, 30 Sep 2018 13:45:52 -0500 Subject: [PATCH 06/13] Fixed a type-o in the alpha limits table. --- src/EVEMon.Common/Data/StaticSkill.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EVEMon.Common/Data/StaticSkill.cs b/src/EVEMon.Common/Data/StaticSkill.cs index c7b286b09..7e740b6f6 100644 --- a/src/EVEMon.Common/Data/StaticSkill.cs +++ b/src/EVEMon.Common/Data/StaticSkill.cs @@ -377,7 +377,7 @@ public IEnumerable AllPrerequisites {3386, 4}, // Mining {16281, 2}, // Ice Harvesting {22578, 4}, // Mining Upgrades - {3358, 3}, // Reprocessing + {3385, 3}, // Reprocessing {25544, 2}, // Gas Cloud Harvesting {25863, 3}, // Salvaging {11584, 1} // Anchoring From 32d5c8ca72f805d2b91c0f779edc222f42412550 Mon Sep 17 00:00:00 2001 From: Rob R Date: Sun, 30 Sep 2018 14:03:29 -0500 Subject: [PATCH 07/13] Corrected SP rate calculation to apply clone rate. Improved clone state test. --- .../Helpers/CharacterScratchpad.cs | 30 +++++++++++- src/EVEMon.Common/Models/BaseCharacter.cs | 13 +++++- src/EVEMon.Common/Models/Character.cs | 46 ++++++++----------- 3 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/EVEMon.Common/Helpers/CharacterScratchpad.cs b/src/EVEMon.Common/Helpers/CharacterScratchpad.cs index 88ebb56ce..6dc3c43de 100644 --- a/src/EVEMon.Common/Helpers/CharacterScratchpad.cs +++ b/src/EVEMon.Common/Helpers/CharacterScratchpad.cs @@ -44,6 +44,34 @@ public CharacterScratchpad(BaseCharacter character) Reset(); } + /// + /// Check for alpha clone state. + /// + public bool IsAlpha + { + get + { + Character chr = GetSourceCharacter(); + return (chr?.IsAlpha == true); + } + } + + /// + /// Get the caracter this scratchpad is bassed from. + /// + /// The character or null + public Character GetSourceCharacter() + { + if(m_character is Character) + { + return m_character as Character; + } + if(m_character is CharacterScratchpad) + { + return (m_character as CharacterScratchpad).GetSourceCharacter(); + } + return null; + } #region Attributes @@ -419,4 +447,4 @@ public IDisposable BeginTemporaryChanges() #endregion } -} \ No newline at end of file +} diff --git a/src/EVEMon.Common/Models/BaseCharacter.cs b/src/EVEMon.Common/Models/BaseCharacter.cs index 237d57c42..2ab492cf5 100644 --- a/src/EVEMon.Common/Models/BaseCharacter.cs +++ b/src/EVEMon.Common/Models/BaseCharacter.cs @@ -38,7 +38,18 @@ public abstract class BaseCharacter /// skill public virtual float GetBaseSPPerHour(StaticSkill skill) { - return GetOmegaSPPerHour(skill); + float spPerHour = GetOmegaSPPerHour(skill); + Character chr = this as Character; + if (this is CharacterScratchpad && chr == null) + { + chr = (this as CharacterScratchpad).GetSourceCharacter(); + } + if(chr != null) + { + spPerHour *= chr.CharacterStatus.TrainingRate; + } + + return spPerHour; } /// diff --git a/src/EVEMon.Common/Models/Character.cs b/src/EVEMon.Common/Models/Character.cs index a1326a0a2..4299cfb45 100644 --- a/src/EVEMon.Common/Models/Character.cs +++ b/src/EVEMon.Common/Models/Character.cs @@ -97,40 +97,34 @@ public void UpdateAccountStatus(AccountStatus.AccountStatusType statusType = { // spPerHour must be greater than zero since numerator and denominator are var spPerHour = spToTrain / hoursToTrain; - var rate = (int)Math.Round(GetOmegaSPPerHour(skill.Skill) / spPerHour, 0); - switch (rate) + double rate = GetOmegaSPPerHour(skill.Skill) / spPerHour; + // Allow for small margin of error, important on skills nearing completion. + if (rate < 1.2 && rate > 0.8) { - case 1: statusType = AccountStatus.AccountStatusType.Omega; - break; - case 2: + } + else if(rate < 0.9) + { statusType = AccountStatus.AccountStatusType.Alpha; - break; - default: - statusType = AccountStatus.AccountStatusType.Unknown; - break; } } } - if (statusType != AccountStatus.AccountStatusType.Omega) + foreach(var sk in Skills) { - foreach(var sk in Skills) + // Is the skill level being limited by alpha status? + if(sk.ActiveLevel < sk.Level) { - // Is the skill level being limited by alpha status? - if(sk.ActiveLevel < sk.Level) - { - // Active level is being limited by alpha status. - statusType = AccountStatus.AccountStatusType.Alpha; - break; - } - // Has the skill alpha limit been exceeded? - if(sk.ActiveLevel > sk.StaticData.AlphaLimit) - { - // Active level is greater than alpha limit, only on Omega. - statusType = AccountStatus.AccountStatusType.Omega; - break; - } + // Active level is being limited by alpha status. + statusType = AccountStatus.AccountStatusType.Alpha; + break; + } + // Has the skill alpha limit been exceeded? + if(sk.ActiveLevel > sk.StaticData.AlphaLimit) + { + // Active level is greater than alpha limit, only on Omega. + statusType = AccountStatus.AccountStatusType.Omega; + break; } } @@ -537,7 +531,7 @@ public override Int64 GetSkillPoints(StaticSkill skill) /// Skill points earned per hour when training this skill public override float GetBaseSPPerHour(StaticSkill skill) { - return CharacterStatus.TrainingRate * base.GetBaseSPPerHour(skill); + return CharacterStatus.TrainingRate * base.GetOmegaSPPerHour(skill); } #endregion From bc9438237f4681af42efe562bed09b218c6074f7 Mon Sep 17 00:00:00 2001 From: Rob R Date: Tue, 2 Oct 2018 12:42:44 -0500 Subject: [PATCH 08/13] Fixed error in alpha clone detection. --- src/EVEMon.Common/Models/Character.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EVEMon.Common/Models/Character.cs b/src/EVEMon.Common/Models/Character.cs index 4299cfb45..bd6dd4cd7 100644 --- a/src/EVEMon.Common/Models/Character.cs +++ b/src/EVEMon.Common/Models/Character.cs @@ -103,7 +103,7 @@ public void UpdateAccountStatus(AccountStatus.AccountStatusType statusType = { statusType = AccountStatus.AccountStatusType.Omega; } - else if(rate < 0.9) + else if(rate > 1.1) { statusType = AccountStatus.AccountStatusType.Alpha; } From a69ab016f1e741cdf109ee3ce2b5038d2f3a02bf Mon Sep 17 00:00:00 2001 From: Rob R Date: Tue, 2 Oct 2018 12:44:02 -0500 Subject: [PATCH 09/13] Added Omega clone required column to skill planner. --- src/EVEMon.Common/Enumerations/PlanEntrySort.cs | 5 +++-- src/EVEMon.Common/Helpers/PlanEntrySorter.cs | 11 ++++++++++- src/EVEMon.Common/Helpers/PlanScratchpad.cs | 5 ++++- src/EVEMon.Common/Models/PlanEntry.cs | 9 ++++++++- src/EVEMon.Common/SettingsObjects/PlanColumn.cs | 8 ++++++-- src/EVEMon/SkillPlanner/PlanEditorControl.cs | 4 ++++ 6 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/EVEMon.Common/Enumerations/PlanEntrySort.cs b/src/EVEMon.Common/Enumerations/PlanEntrySort.cs index 52b864bdc..c43676491 100644 --- a/src/EVEMon.Common/Enumerations/PlanEntrySort.cs +++ b/src/EVEMon.Common/Enumerations/PlanEntrySort.cs @@ -21,6 +21,7 @@ public enum PlanEntrySort TimeDifference, PlanType, Notes, - SkillPointsRequired + SkillPointsRequired, + OmegeRequired } -} \ No newline at end of file +} diff --git a/src/EVEMon.Common/Helpers/PlanEntrySorter.cs b/src/EVEMon.Common/Helpers/PlanEntrySorter.cs index 7dd31df37..7dd84b5de 100644 --- a/src/EVEMon.Common/Helpers/PlanEntrySorter.cs +++ b/src/EVEMon.Common/Helpers/PlanEntrySorter.cs @@ -258,6 +258,15 @@ public static int CompareByPercentCompleted(PlanEntry x, PlanEntry y) public static int CompareBySkillPointsRequired(PlanEntry x, PlanEntry y) => x.SkillPointsRequired.CompareTo(y.SkillPointsRequired); + /// + /// Compares by clone state required. + /// + /// The x. + /// The y. + /// + public static int CompareByOmegaRequired(PlanEntry x, PlanEntry y) + => x.OmegaRequired.CompareTo(y.OmegaRequired); + /// /// Compares by skill group duration. /// @@ -297,4 +306,4 @@ private static TimeSpan GetSkillGroupDuration(StaticSkillGroup group, IEnumerabl #endregion } -} \ No newline at end of file +} diff --git a/src/EVEMon.Common/Helpers/PlanScratchpad.cs b/src/EVEMon.Common/Helpers/PlanScratchpad.cs index c8dddbb5b..c8f047c90 100644 --- a/src/EVEMon.Common/Helpers/PlanScratchpad.cs +++ b/src/EVEMon.Common/Helpers/PlanScratchpad.cs @@ -180,6 +180,9 @@ internal void SimpleSort(PlanEntrySort sort, bool reverseOrder) case PlanEntrySort.SkillPointsRequired: Items.StableSort(PlanEntrySorter.CompareBySkillPointsRequired); break; + case PlanEntrySort.OmegeRequired: + Items.StableSort(PlanEntrySorter.CompareByOmegaRequired); + break; default: throw new NotImplementedException(); } @@ -191,4 +194,4 @@ internal void SimpleSort(PlanEntrySort sort, bool reverseOrder) #endregion } -} \ No newline at end of file +} diff --git a/src/EVEMon.Common/Models/PlanEntry.cs b/src/EVEMon.Common/Models/PlanEntry.cs index 79c5f4fc7..f82985366 100644 --- a/src/EVEMon.Common/Models/PlanEntry.cs +++ b/src/EVEMon.Common/Models/PlanEntry.cs @@ -214,6 +214,13 @@ private static StaticSkill GetSkill(SerializablePlanEntry serial) /// True if the given item's skill is a prerequisite of this one or if it is a lower level of the same skill. public bool IsDependentOf(ISkillLevel level) => ((StaticSkillLevel)this).IsDependentOf(level); + public bool OmegaRequired + { + get + { + return m_level > m_skill.AlphaLimit; + } + } #region Computations done when UpdateTrainingTime is called @@ -343,4 +350,4 @@ internal PlanEntry Clone(BasePlan plan) public static implicit operator StaticSkillLevel(PlanEntry entry) => entry == null ? null : new StaticSkillLevel(entry.Skill, entry.Level); } -} \ No newline at end of file +} diff --git a/src/EVEMon.Common/SettingsObjects/PlanColumn.cs b/src/EVEMon.Common/SettingsObjects/PlanColumn.cs index 60dbd0a46..c9db011d5 100644 --- a/src/EVEMon.Common/SettingsObjects/PlanColumn.cs +++ b/src/EVEMon.Common/SettingsObjects/PlanColumn.cs @@ -84,6 +84,10 @@ public enum PlanColumn [Header("Skill Points Required")] [Description("Skill Points Required")] - SkillPointsRequired = 18 + SkillPointsRequired = 18, + + [Header("Omega Clone Required")] + [Description("Omega Clone Required")] + OmegaRequired = 19 } -} \ No newline at end of file +} diff --git a/src/EVEMon/SkillPlanner/PlanEditorControl.cs b/src/EVEMon/SkillPlanner/PlanEditorControl.cs index 1a9f23a7f..40321c280 100644 --- a/src/EVEMon/SkillPlanner/PlanEditorControl.cs +++ b/src/EVEMon/SkillPlanner/PlanEditorControl.cs @@ -750,6 +750,8 @@ private static string GetColumnTextForItem(PlanEntry entry, PlanColumn column, s } case PlanColumn.SkillPointsRequired: return entry.SkillPointsRequired.ToNumericString(0); + case PlanColumn.OmegaRequired: + return entry.OmegaRequired ? "Omega Only" : "Alpha"; default: throw new NotImplementedException(); } @@ -1336,6 +1338,8 @@ private static PlanEntrySort GetPlanSort(ColumnHeader header) return PlanEntrySort.PlanType; case PlanColumn.SkillPointsRequired: return PlanEntrySort.SkillPointsRequired; + case PlanColumn.OmegaRequired: + return PlanEntrySort.OmegeRequired; default: return PlanEntrySort.None; } From fd3d5122dffa5ccfd920e0a952482bd8dd61bed0 Mon Sep 17 00:00:00 2001 From: Rob R Date: Tue, 2 Oct 2018 13:41:10 -0500 Subject: [PATCH 10/13] Changed skill browser trainable on trial option to Alpha clone option. --- src/EVEMon.Common/Data/StaticSkill.cs | 14 ++------------ src/EVEMon.Common/Enumerations/SkillFilter.cs | 6 +++--- src/EVEMon.Common/Models/Skill.cs | 5 ----- .../Serialization/Datafiles/SerializableSkill.cs | 11 +---------- src/EVEMon/SkillPlanner/SkillSelectControl.cs | 6 +++--- tools/XmlGenerator/Datafiles/Skills.cs | 2 -- 6 files changed, 9 insertions(+), 35 deletions(-) diff --git a/src/EVEMon.Common/Data/StaticSkill.cs b/src/EVEMon.Common/Data/StaticSkill.cs index 7e740b6f6..e658f3eeb 100644 --- a/src/EVEMon.Common/Data/StaticSkill.cs +++ b/src/EVEMon.Common/Data/StaticSkill.cs @@ -58,7 +58,6 @@ internal StaticSkill(StaticSkillGroup group, SerializableSkill src, int arrayInd Description = src.Description; PrimaryAttribute = src.PrimaryAttribute; SecondaryAttribute = src.SecondaryAttribute; - IsTrainableOnTrialAccount = src.CanTrainOnTrial; ArrayIndex = arrayIndex; Group = group; Prerequisites = new Collection(); @@ -84,15 +83,6 @@ internal void CompleteInitialization(IEnumerable // Create the prerequisites list Prerequisites.AddRange(prereqs.Select(x => new StaticSkillLevel(x.GetSkill(), x.Level))); - - if (!IsTrainableOnTrialAccount) - return; - - // Check trainableOnTrialAccount on its childrens to be sure it's really trainable - if (Prerequisites.All(prereq => prereq.Skill.IsTrainableOnTrialAccount)) - return; - - IsTrainableOnTrialAccount = false; } #endregion @@ -151,9 +141,9 @@ internal void CompleteInitialization(IEnumerable public EveAttribute SecondaryAttribute { get; } /// - /// Get whether skill is trainable on a trial account. + /// Get whether skill is trainable on a alpha account. /// - public bool IsTrainableOnTrialAccount { get; private set; } + public bool AlphaFriendly { get { return AlphaLimit > 0; } } /// /// Get the level limit for an alpha clone. diff --git a/src/EVEMon.Common/Enumerations/SkillFilter.cs b/src/EVEMon.Common/Enumerations/SkillFilter.cs index 821582dd6..1bfd07ae1 100644 --- a/src/EVEMon.Common/Enumerations/SkillFilter.cs +++ b/src/EVEMon.Common/Enumerations/SkillFilter.cs @@ -52,7 +52,7 @@ public enum SkillFilter [Description("Trainable (All)")] Trainable = 14, - [Description("Trainable on trial account")] - TrialAccountFriendly = 15 + [Description("Trainable on alpha account")] + AlphaFriendly = 15 } -} \ No newline at end of file +} diff --git a/src/EVEMon.Common/Models/Skill.cs b/src/EVEMon.Common/Models/Skill.cs index 927248017..4ef2bee66 100644 --- a/src/EVEMon.Common/Models/Skill.cs +++ b/src/EVEMon.Common/Models/Skill.cs @@ -219,11 +219,6 @@ public bool HasBookInAssets /// public SkillGroup Group { get; } - /// - /// Gets whether this skill and all its prereqs are trainable on a trial account. - /// - public bool IsTrainableOnTrialAccount => StaticData.IsTrainableOnTrialAccount; - /// /// Gets true if this is a public skill. /// diff --git a/src/EVEMon.Common/Serialization/Datafiles/SerializableSkill.cs b/src/EVEMon.Common/Serialization/Datafiles/SerializableSkill.cs index 41d904842..ce59f424a 100644 --- a/src/EVEMon.Common/Serialization/Datafiles/SerializableSkill.cs +++ b/src/EVEMon.Common/Serialization/Datafiles/SerializableSkill.cs @@ -80,15 +80,6 @@ public SerializableSkill() [XmlAttribute("cost")] public long Cost { get; set; } - /// - /// Gets or sets a value indicating whether this instance can train on trial. - /// - /// - /// true if this instance can train on trial; otherwise, false. - /// - [XmlAttribute("canTrainOnTrial")] - public bool CanTrainOnTrial { get; set; } - /// /// Gets the skill prerequisites. /// @@ -96,4 +87,4 @@ public SerializableSkill() [XmlElement("prereq")] public Collection SkillPrerequisites => m_skillPrereqs; } -} \ No newline at end of file +} diff --git a/src/EVEMon/SkillPlanner/SkillSelectControl.cs b/src/EVEMon/SkillPlanner/SkillSelectControl.cs index b286fe43b..b21a25035 100644 --- a/src/EVEMon/SkillPlanner/SkillSelectControl.cs +++ b/src/EVEMon/SkillPlanner/SkillSelectControl.cs @@ -217,7 +217,7 @@ private void InitializeFilterControl() { cbSkillFilter.Items.RemoveAt(Index); } - cbSkillFilter.Items.Add(SkillFilter.TrialAccountFriendly.GetDescription()); + cbSkillFilter.Items.Add(SkillFilter.AlphaFriendly.GetDescription()); } /// @@ -593,8 +593,8 @@ private Func GetFilter() return x => x.PrimaryAttribute == primary && x.SecondaryAttribute == secondary; case SkillFilter.Known: return x => x.IsKnown; - case SkillFilter.TrialAccountFriendly: - return x => x.IsTrainableOnTrialAccount; + case SkillFilter.AlphaFriendly: + return x => x.StaticData.AlphaFriendly; case SkillFilter.Unknown: return x => !x.IsKnown; case SkillFilter.UnknownAndNotOwned: diff --git a/tools/XmlGenerator/Datafiles/Skills.cs b/tools/XmlGenerator/Datafiles/Skills.cs index 509492085..56700155b 100644 --- a/tools/XmlGenerator/Datafiles/Skills.cs +++ b/tools/XmlGenerator/Datafiles/Skills.cs @@ -93,8 +93,6 @@ private static IEnumerable ExportSkillsInGroup(IHasID group) ? IntToEveAttribute( skillAttributes[DBConstants.SecondaryAttributePropertyID]) : EveAttribute.None; - singleSkill.CanTrainOnTrial = !skillAttributes.ContainsKey(DBConstants.CanNotBeTrainedOnTrialPropertyID) || - skillAttributes[DBConstants.CanNotBeTrainedOnTrialPropertyID] == 0; // Export prerequesities List listOfPrerequisites = new List(); From f19c7d3e3349e805bf3ebbd332f8f19c4909f479 Mon Sep 17 00:00:00 2001 From: Rob R Date: Tue, 2 Oct 2018 14:16:24 -0500 Subject: [PATCH 11/13] Moved hard coded data for Alpha skill limits to the XML Generator. --- src/EVEMon.Common/Data/StaticSkill.cs | 186 +----------------- .../Datafiles/SerializableSkill.cs | 6 + tools/XmlGenerator/Datafiles/Skills.cs | 181 +++++++++++++++++ 3 files changed, 189 insertions(+), 184 deletions(-) diff --git a/src/EVEMon.Common/Data/StaticSkill.cs b/src/EVEMon.Common/Data/StaticSkill.cs index e658f3eeb..5aa77268f 100644 --- a/src/EVEMon.Common/Data/StaticSkill.cs +++ b/src/EVEMon.Common/Data/StaticSkill.cs @@ -36,10 +36,7 @@ private StaticSkill() SecondaryAttribute = EveAttribute.None; Group = StaticSkillGroup.UnknownStaticSkillGroup; FormattedCost = Cost.ToNumericString(0); - if (alphaLimit.ContainsKey(ID)) - { - AlphaLimit = alphaLimit[ID]; - } + AlphaLimit = 0; } /// @@ -62,10 +59,7 @@ internal StaticSkill(StaticSkillGroup group, SerializableSkill src, int arrayInd Group = group; Prerequisites = new Collection(); FormattedCost = Cost.ToNumericString(0); - if (alphaLimit.ContainsKey(ID)) - { - AlphaLimit = alphaLimit[ID]; - } + AlphaLimit = src.AlphaLimit; } #endregion @@ -197,182 +191,6 @@ public IEnumerable AllPrerequisites /// public static StaticSkill UnknownStaticSkill => s_unknownStaticSkill ?? (s_unknownStaticSkill = new StaticSkill()); - private static Dictionary alphaLimit = new Dictionary() - { - {3339, 4}, // Amarr Battleship - {33095, 4}, // Amarr Battlecruiser - {3335, 4}, // Amarr Cruiser - {33091, 4}, // Amarr Destroyer - {3331, 4}, // Amarr Frigate - {3343, 1}, // Amarr Industrial - {3338, 4}, // Caldari Battleship - {33096, 4}, // Caldari Battlecruiser - {3334, 4}, // Caldari Cruiser - {33092, 4}, // Caldari Destroyer - {3330, 4}, // Caldari Frigate - {3342, 1}, // Caldari Industrial - {3336, 4}, // Gallente Battleship - {33097, 4}, // Gallente Battlecruiser - {3332, 4}, // Gallente Cruiser - {33093, 4}, // Gallente Destroyer - {3328, 4}, // Gallente Frigate - {3340, 1}, // Gallente Industrial - {3337, 4}, // Minmatar Battleship - {33098, 4}, // Minmatar Battlecruiser - {3333, 4}, // Minmatar Cruiser - {33094, 4}, // Minmatar Destroyer - {3329, 4}, // Minmatar Frigate - {3341, 1}, // Minmatar Industrial - {32918, 4}, // Mining Frigate - {3327, 4}, // Spaceship Command - {3452, 3}, // Acceleration Control - {3450, 3}, // Afterburner - {3453, 3}, // Evasive Maneuvering - {3454, 3}, // High Speed Maneuvering - {3449, 4}, // Navigation - {3455, 3}, // Warp Drive Operation - {11207, 3}, // Advanced Weapon Upgrades - {3426, 5}, // CPU Management - {3423, 4}, // Capacitor Emission Systems - {3418, 4}, // Capacitor Management - {3417, 3}, // Capacitor Systems Operation - {3432, 5}, // Electronics Upgrades - {3424, 5}, // Energy Grid Upgrades - {3421, 2}, // Energy Pulse Weapons - {3413, 5}, // Power Grid Management - {28164, 4}, // Thermodynamics - {3318, 5}, // Weapon Upgrades - {33078, 1}, // Armor Layering - {22806, 2}, // EM Armor Compensation - {22807, 2}, // Explosive Armor Compensation - {3394, 5}, // Hull Upgrades - {22808, 2}, // Kinetic Armor Compensation - {3392, 5}, // Mechanics - {16069, 3}, // Remote Armor Repair Systems - {27902, 2}, // Remote Hull Repair Systems - {3393, 5}, // Repair Systems - {22809, 2}, // Thermal Armor Compensation - {12365, 2}, // EM Shield Compensation - {12367, 2}, // Explosive Shield Compensation - {12366, 2}, // Kinetic Shield Compensation - {3422, 3}, // Shield Emission Systems - {21059, 4}, // Shield Compensation - {3419, 4}, // Shield Management - {3416, 4}, // Shield Operation - {3425, 4}, // Shield Upgrades - {3420, 4}, // Tactical Shield Manipulation - {11566, 2}, // Thermal Shield Compensation - {3428, 3}, // Long Range Targeting - {3431, 3}, // Signature Analysis - {3429, 4}, // Target Management - {3316, 4}, // Controlled bursts - {3300, 5}, // Gunnery - {3309, 4}, // Large Energy Turret - {3307, 4}, // Large Hybrid Turret - {3308, 4}, // Large Projectile Turret - {12202, 3}, // Medium Artillery Specialization - {12208, 3}, // Medium Autocannon Specialization - {12204, 3}, // Medium Beam Laser Specialization - {12211, 3}, // Medium Blaster Specialization - {3306, 5}, // Medium Energy Turret - {3304, 5}, // Medium Hybrid Turret - {3305, 5}, // Medium Projectile Turret - {12214, 3}, // Medium Pulse Laser Specialization - {12206, 3}, // Medium Rail Specialization - {3312, 4}, // Motion Prediction - {3310, 4}, // Rapid Firing - {3311, 4}, // Sharpshooter - {12201, 3}, // Small Artillery Specialization - {11084, 3}, // Small Autocannon Specialization - {11083, 3}, // Small Beam Laser Specialization - {12210, 3}, // Small Blaster Specialization - {3303, 5}, // Small Energy Turret - {3301, 5}, // Small Hybrid Turret - {3302, 5}, // Small Projectile Turret - {12213, 3}, // Small Pulse Laser Specialization - {11082, 3}, // Small Rail Specialization - {3315, 4}, // Surgical Strike - {3317, 4}, // Trajectory Analysis - {3326, 4}, // Cruise Missiles - {20312, 3}, // Guided Missile Precision - {25718, 3}, // Heavy Assault Missile Specialization - {25719, 5}, // Heavy Assault Missiles - {20211, 3}, // Heavy Missile Specialization - {3324, 5}, // Heavy Missiles - {20210, 3}, // Light Missile Specialization - {3321, 5}, // Light Missiles - {12441, 4}, // Missile Bombardment - {3319, 5}, // Missile Launcher Operation - {12442, 2}, // Missile Projection - {21071, 4}, // Rapid Launch - {20209, 3}, // Rocket Specialization - {3320, 5}, // Rockets - {20314, 3}, // Target Navigation Prediction - {3325, 4}, // Torpedoes - {20315, 3}, // Warhead Upgrades - {3437, 4}, // Drone Avionics - {23618, 4}, // Drone Durability - {3442, 4}, // Drone Interfacing - {12305, 4}, // Drone Navigation - {23606, 4}, // drone Sharpshooting - {3436, 5}, // Drones - {24241, 5}, // Light Drone Operation - {33699, 5}, // Medium Drone Operation - {3439, 2}, // Repair Drone Operation - {3441, 4}, // Heavy Drone Operation - {12484, 2}, // Amarr Drone Specialization - {12487, 2}, // Caldari Drone Specialization - {12486, 2}, // Gallente Drone Specialization - {12485, 2}, // Minmatar Drone Specialization - {3427, 4}, // Electronic Warfare - {3435, 4}, // Propulsion Jamming - {3434, 4}, // Weapon Disruption - {3433, 3}, // Sensor Linking - {19921, 3}, // Target Painting - {13278, 3}, // Archaeology - {25811, 2}, // Astrometric Acquisition - {25739, 2}, // Astrometric Rangefinding - {3412, 3}, // Astrometrics - {21718, 3}, // Hacking - {3551, 3}, // Survey - {26253, 3}, // Armor Rigging - {26254, 3}, // Astronautics Rigging - {26259, 3}, // Hybrid Weapon Rigging - {26260, 3}, // Launcher Rigging - {26257, 3}, // Shield Rigging - {26261, 3}, // Projectile Weapon Rigging - {26255, 3}, // Drones Rigging - {26256, 3}, // Electronic superiority Rigging - {26258, 3}, // Energy Weapon Rigging - {26252, 3}, // Jury Rigging - {3359, 2}, // Connections - {3361, 2}, // Criminal Connections - {3357, 3}, // Diplomacy - {3894, 2}, // Distribution Connections - {3893, 2}, // Mining Connections - {3356, 2}, // Negotiation - {3895, 2}, // Security Connections - {3355, 3}, // Social - {3348, 3}, // Leadership - {3363, 1}, // Corporation Management - {3446, 2}, // Broker Relations - {16598, 2}, // Marketing - {3443, 3}, // Trade - {3405, 3}, // Biology - {3411, 3}, // Cybernetics - {24242, 1}, // Infomorph Psychology - {3380, 5}, // Industry - {3387, 3}, // Mass Production - {3402, 4}, // Science - {3386, 4}, // Mining - {16281, 2}, // Ice Harvesting - {22578, 4}, // Mining Upgrades - {3385, 3}, // Reprocessing - {25544, 2}, // Gas Cloud Harvesting - {25863, 3}, // Salvaging - {11584, 1} // Anchoring - }; - #endregion diff --git a/src/EVEMon.Common/Serialization/Datafiles/SerializableSkill.cs b/src/EVEMon.Common/Serialization/Datafiles/SerializableSkill.cs index ce59f424a..9b84361bd 100644 --- a/src/EVEMon.Common/Serialization/Datafiles/SerializableSkill.cs +++ b/src/EVEMon.Common/Serialization/Datafiles/SerializableSkill.cs @@ -86,5 +86,11 @@ public SerializableSkill() /// The skill prerequisites. [XmlElement("prereq")] public Collection SkillPrerequisites => m_skillPrereqs; + + /// + /// The highest level the skill can be trained on an alpha clone. + /// + /// The level. + public int AlphaLimit { get; set; } } } diff --git a/tools/XmlGenerator/Datafiles/Skills.cs b/tools/XmlGenerator/Datafiles/Skills.cs index 56700155b..fed97c423 100644 --- a/tools/XmlGenerator/Datafiles/Skills.cs +++ b/tools/XmlGenerator/Datafiles/Skills.cs @@ -74,6 +74,7 @@ private static IEnumerable ExportSkillsInGroup(IHasID group) Description = skill.Description, Public = skill.Published, Cost = (long)skill.BasePrice, + AlphaLimit = (alphaLimit.ContainsKey(skill.ID)) ? alphaLimit[skill.ID] : 0, }; // Export skill atributes @@ -147,5 +148,185 @@ private static EveAttribute IntToEveAttribute(Int64 attributeValue) return EveAttribute.None; } } + + /// + /// Hard coded list of alpha limits, since this is not available anywhere in the SDE or from ESI. + /// + private static Dictionary alphaLimit = new Dictionary() + { + {3339, 4}, // Amarr Battleship + {33095, 4}, // Amarr Battlecruiser + {3335, 4}, // Amarr Cruiser + {33091, 4}, // Amarr Destroyer + {3331, 4}, // Amarr Frigate + {3343, 1}, // Amarr Industrial + {3338, 4}, // Caldari Battleship + {33096, 4}, // Caldari Battlecruiser + {3334, 4}, // Caldari Cruiser + {33092, 4}, // Caldari Destroyer + {3330, 4}, // Caldari Frigate + {3342, 1}, // Caldari Industrial + {3336, 4}, // Gallente Battleship + {33097, 4}, // Gallente Battlecruiser + {3332, 4}, // Gallente Cruiser + {33093, 4}, // Gallente Destroyer + {3328, 4}, // Gallente Frigate + {3340, 1}, // Gallente Industrial + {3337, 4}, // Minmatar Battleship + {33098, 4}, // Minmatar Battlecruiser + {3333, 4}, // Minmatar Cruiser + {33094, 4}, // Minmatar Destroyer + {3329, 4}, // Minmatar Frigate + {3341, 1}, // Minmatar Industrial + {32918, 4}, // Mining Frigate + {3327, 4}, // Spaceship Command + {3452, 3}, // Acceleration Control + {3450, 3}, // Afterburner + {3453, 3}, // Evasive Maneuvering + {3454, 3}, // High Speed Maneuvering + {3449, 4}, // Navigation + {3455, 3}, // Warp Drive Operation + {11207, 3}, // Advanced Weapon Upgrades + {3426, 5}, // CPU Management + {3423, 4}, // Capacitor Emission Systems + {3418, 4}, // Capacitor Management + {3417, 3}, // Capacitor Systems Operation + {3432, 5}, // Electronics Upgrades + {3424, 5}, // Energy Grid Upgrades + {3421, 2}, // Energy Pulse Weapons + {3413, 5}, // Power Grid Management + {28164, 4}, // Thermodynamics + {3318, 5}, // Weapon Upgrades + {33078, 1}, // Armor Layering + {22806, 2}, // EM Armor Compensation + {22807, 2}, // Explosive Armor Compensation + {3394, 5}, // Hull Upgrades + {22808, 2}, // Kinetic Armor Compensation + {3392, 5}, // Mechanics + {16069, 3}, // Remote Armor Repair Systems + {27902, 2}, // Remote Hull Repair Systems + {3393, 5}, // Repair Systems + {22809, 2}, // Thermal Armor Compensation + {12365, 2}, // EM Shield Compensation + {12367, 2}, // Explosive Shield Compensation + {12366, 2}, // Kinetic Shield Compensation + {3422, 3}, // Shield Emission Systems + {21059, 4}, // Shield Compensation + {3419, 4}, // Shield Management + {3416, 4}, // Shield Operation + {3425, 4}, // Shield Upgrades + {3420, 4}, // Tactical Shield Manipulation + {11566, 2}, // Thermal Shield Compensation + {3428, 3}, // Long Range Targeting + {3431, 3}, // Signature Analysis + {3429, 4}, // Target Management + {3316, 4}, // Controlled bursts + {3300, 5}, // Gunnery + {3309, 4}, // Large Energy Turret + {3307, 4}, // Large Hybrid Turret + {3308, 4}, // Large Projectile Turret + {12202, 3}, // Medium Artillery Specialization + {12208, 3}, // Medium Autocannon Specialization + {12204, 3}, // Medium Beam Laser Specialization + {12211, 3}, // Medium Blaster Specialization + {3306, 5}, // Medium Energy Turret + {3304, 5}, // Medium Hybrid Turret + {3305, 5}, // Medium Projectile Turret + {12214, 3}, // Medium Pulse Laser Specialization + {12206, 3}, // Medium Rail Specialization + {3312, 4}, // Motion Prediction + {3310, 4}, // Rapid Firing + {3311, 4}, // Sharpshooter + {12201, 3}, // Small Artillery Specialization + {11084, 3}, // Small Autocannon Specialization + {11083, 3}, // Small Beam Laser Specialization + {12210, 3}, // Small Blaster Specialization + {3303, 5}, // Small Energy Turret + {3301, 5}, // Small Hybrid Turret + {3302, 5}, // Small Projectile Turret + {12213, 3}, // Small Pulse Laser Specialization + {11082, 3}, // Small Rail Specialization + {3315, 4}, // Surgical Strike + {3317, 4}, // Trajectory Analysis + {3326, 4}, // Cruise Missiles + {20312, 3}, // Guided Missile Precision + {25718, 3}, // Heavy Assault Missile Specialization + {25719, 5}, // Heavy Assault Missiles + {20211, 3}, // Heavy Missile Specialization + {3324, 5}, // Heavy Missiles + {20210, 3}, // Light Missile Specialization + {3321, 5}, // Light Missiles + {12441, 4}, // Missile Bombardment + {3319, 5}, // Missile Launcher Operation + {12442, 2}, // Missile Projection + {21071, 4}, // Rapid Launch + {20209, 3}, // Rocket Specialization + {3320, 5}, // Rockets + {20314, 3}, // Target Navigation Prediction + {3325, 4}, // Torpedoes + {20315, 3}, // Warhead Upgrades + {3437, 4}, // Drone Avionics + {23618, 4}, // Drone Durability + {3442, 4}, // Drone Interfacing + {12305, 4}, // Drone Navigation + {23606, 4}, // drone Sharpshooting + {3436, 5}, // Drones + {24241, 5}, // Light Drone Operation + {33699, 5}, // Medium Drone Operation + {3439, 2}, // Repair Drone Operation + {3441, 4}, // Heavy Drone Operation + {12484, 2}, // Amarr Drone Specialization + {12487, 2}, // Caldari Drone Specialization + {12486, 2}, // Gallente Drone Specialization + {12485, 2}, // Minmatar Drone Specialization + {3427, 4}, // Electronic Warfare + {3435, 4}, // Propulsion Jamming + {3434, 4}, // Weapon Disruption + {3433, 3}, // Sensor Linking + {19921, 3}, // Target Painting + {13278, 3}, // Archaeology + {25811, 2}, // Astrometric Acquisition + {25739, 2}, // Astrometric Rangefinding + {3412, 3}, // Astrometrics + {21718, 3}, // Hacking + {3551, 3}, // Survey + {26253, 3}, // Armor Rigging + {26254, 3}, // Astronautics Rigging + {26259, 3}, // Hybrid Weapon Rigging + {26260, 3}, // Launcher Rigging + {26257, 3}, // Shield Rigging + {26261, 3}, // Projectile Weapon Rigging + {26255, 3}, // Drones Rigging + {26256, 3}, // Electronic superiority Rigging + {26258, 3}, // Energy Weapon Rigging + {26252, 3}, // Jury Rigging + {3359, 2}, // Connections + {3361, 2}, // Criminal Connections + {3357, 3}, // Diplomacy + {3894, 2}, // Distribution Connections + {3893, 2}, // Mining Connections + {3356, 2}, // Negotiation + {3895, 2}, // Security Connections + {3355, 3}, // Social + {3348, 3}, // Leadership + {3363, 1}, // Corporation Management + {3446, 2}, // Broker Relations + {16598, 2}, // Marketing + {3443, 3}, // Trade + {3405, 3}, // Biology + {3411, 3}, // Cybernetics + {24242, 1}, // Infomorph Psychology + {3380, 5}, // Industry + {3387, 3}, // Mass Production + {3402, 4}, // Science + {3386, 4}, // Mining + {16281, 2}, // Ice Harvesting + {22578, 4}, // Mining Upgrades + {3385, 3}, // Reprocessing + {25544, 2}, // Gas Cloud Harvesting + {25863, 3}, // Salvaging + {11584, 1} // Anchoring + }; + } } From 33f515e03d43576982b76855f709c8b1a2d60c89 Mon Sep 17 00:00:00 2001 From: Rob R Date: Fri, 5 Oct 2018 04:13:02 -0500 Subject: [PATCH 12/13] Moved clone state info from Character to BaseCharacter. Added Alpha trainable SP limit and test to alpha clone check. --- src/EVEMon.Common/Constants/EveConstants.cs | 3 +- .../Helpers/CharacterScratchpad.cs | 32 ++++-------- src/EVEMon.Common/Models/BaseCharacter.cs | 18 ++++--- src/EVEMon.Common/Models/Character.cs | 49 ++++++++----------- .../CharacterSkillsList.cs | 2 +- 5 files changed, 43 insertions(+), 61 deletions(-) diff --git a/src/EVEMon.Common/Constants/EveConstants.cs b/src/EVEMon.Common/Constants/EveConstants.cs index 459490764..8bcd9ba53 100644 --- a/src/EVEMon.Common/Constants/EveConstants.cs +++ b/src/EVEMon.Common/Constants/EveConstants.cs @@ -11,6 +11,7 @@ public static class EveConstants public const float TransactionTaxBase = 0.02f; public const float BrokerFeeBase = 0.03f; public const int MaxSkillsInQueue = 50; + public const int MaxAlphaSkillTraining = 5000000; /// /// Represents a "region" range. @@ -18,4 +19,4 @@ public static class EveConstants public const int RegionRange = 32767; } -} \ No newline at end of file +} diff --git a/src/EVEMon.Common/Helpers/CharacterScratchpad.cs b/src/EVEMon.Common/Helpers/CharacterScratchpad.cs index 6dc3c43de..f629caa58 100644 --- a/src/EVEMon.Common/Helpers/CharacterScratchpad.cs +++ b/src/EVEMon.Common/Helpers/CharacterScratchpad.cs @@ -45,35 +45,21 @@ public CharacterScratchpad(BaseCharacter character) } /// - /// Check for alpha clone state. + /// Gets Alpha/Omega status for this character. /// - public bool IsAlpha - { + public override AccountStatus CharacterStatus { get { - Character chr = GetSourceCharacter(); - return (chr?.IsAlpha == true); - } - } - - /// - /// Get the caracter this scratchpad is bassed from. - /// - /// The character or null - public Character GetSourceCharacter() - { - if(m_character is Character) - { - return m_character as Character; - } - if(m_character is CharacterScratchpad) - { - return (m_character as CharacterScratchpad).GetSourceCharacter(); + if(m_character != null) + { + return m_character.CharacterStatus; + } + return base.CharacterStatus; } - return null; + protected set => base.CharacterStatus = value; } - #region Attributes + #region Attributes /// /// Gets the intelligence of the character. diff --git a/src/EVEMon.Common/Models/BaseCharacter.cs b/src/EVEMon.Common/Models/BaseCharacter.cs index 2ab492cf5..69a1001f0 100644 --- a/src/EVEMon.Common/Models/BaseCharacter.cs +++ b/src/EVEMon.Common/Models/BaseCharacter.cs @@ -10,6 +10,11 @@ namespace EVEMon.Common.Models { public abstract class BaseCharacter { + public BaseCharacter() + { + CharacterStatus = new AccountStatus(AccountStatus.AccountStatusType.Unknown); + } + #region Abstract methods and properties protected abstract Int64 TotalSkillPoints { get; } @@ -22,6 +27,10 @@ public abstract class BaseCharacter #endregion + /// + /// Gets Alpha/Omega status for this character. + /// + public virtual AccountStatus CharacterStatus { get; protected set; } #region Computation methods @@ -39,14 +48,9 @@ public abstract class BaseCharacter public virtual float GetBaseSPPerHour(StaticSkill skill) { float spPerHour = GetOmegaSPPerHour(skill); - Character chr = this as Character; - if (this is CharacterScratchpad && chr == null) - { - chr = (this as CharacterScratchpad).GetSourceCharacter(); - } - if(chr != null) + if (CharacterStatus != null) { - spPerHour *= chr.CharacterStatus.TrainingRate; + spPerHour *= CharacterStatus.TrainingRate; } return spPerHour; diff --git a/src/EVEMon.Common/Models/Character.cs b/src/EVEMon.Common/Models/Character.cs index bd6dd4cd7..a8c3ee1ce 100644 --- a/src/EVEMon.Common/Models/Character.cs +++ b/src/EVEMon.Common/Models/Character.cs @@ -90,22 +90,28 @@ public void UpdateAccountStatus(AccountStatus.AccountStatusType statusType = if (skill != null && skill.IsTraining) { - // Try to determine account status based on training time - var hoursToTrain = (skill.EndTime - skill.StartTime).TotalHours; - var spToTrain = skill.EndSP - skill.StartSP; - if (hoursToTrain > 0 && spToTrain > 0) + if(SkillPoints > EveConstants.MaxAlphaSkillTraining) { - // spPerHour must be greater than zero since numerator and denominator are - var spPerHour = spToTrain / hoursToTrain; - double rate = GetOmegaSPPerHour(skill.Skill) / spPerHour; - // Allow for small margin of error, important on skills nearing completion. - if (rate < 1.2 && rate > 0.8) - { - statusType = AccountStatus.AccountStatusType.Omega; - } - else if(rate > 1.1) + statusType = AccountStatus.AccountStatusType.Omega; + } + else { + // Try to determine account status based on training time + var hoursToTrain = (skill.EndTime - skill.StartTime).TotalHours; + var spToTrain = skill.EndSP - skill.StartSP; + if (hoursToTrain > 0 && spToTrain > 0) { - statusType = AccountStatus.AccountStatusType.Alpha; + // spPerHour must be greater than zero since numerator and denominator are + var spPerHour = spToTrain / hoursToTrain; + double rate = GetOmegaSPPerHour(skill.Skill) / spPerHour; + // Allow for small margin of error, important on skills nearing completion. + if (rate < 1.2 && rate > 0.8) + { + statusType = AccountStatus.AccountStatusType.Omega; + } + else if (rate > 1.1) + { + statusType = AccountStatus.AccountStatusType.Alpha; + } } } } @@ -379,21 +385,6 @@ public Station LastKnownStation public SolarSystem LastKnownSolarSystem => StaticGeography.GetSolarSystemByID( LastKnownLocation?.SolarSystemID ?? 0); - /// - /// Gets Alpha/Omega status for this character. - /// - public AccountStatus CharacterStatus { get; private set; } - - /// - /// Check if the character is in an alpha state. - /// - public bool IsAlpha - { - get - { - return CharacterStatus.CurrentStatus == AccountStatus.AccountStatusType.Alpha; - } - } #endregion diff --git a/src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs b/src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs index 287774476..5c15bb33a 100644 --- a/src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs +++ b/src/EVEMon/CharacterMonitoring/CharacterSkillsList.cs @@ -414,7 +414,7 @@ private static void DrawProgressionBar(Skill skill, DrawItemEventArgs e) private void DrawBoxes(Skill skill, DrawItemEventArgs e) { Graphics g = e.Graphics; - bool isAlpha = (skill.Character.IsAlpha); + bool isAlpha = (skill.Character.CharacterStatus?.CurrentStatus == AccountStatus.AccountStatusType.Alpha); int alphaPad = 0; // Invert background for better visibility of alpha colors. From a3d3341a89f34e5833de2f9e7a4af830b668c538 Mon Sep 17 00:00:00 2001 From: Rob R Date: Fri, 5 Oct 2018 12:10:53 -0500 Subject: [PATCH 13/13] Corrected spelling error. --- src/EVEMon.Common/Enumerations/PlanEntrySort.cs | 2 +- src/EVEMon.Common/Helpers/PlanScratchpad.cs | 2 +- src/EVEMon/SkillPlanner/PlanEditorControl.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/EVEMon.Common/Enumerations/PlanEntrySort.cs b/src/EVEMon.Common/Enumerations/PlanEntrySort.cs index c43676491..4e5383880 100644 --- a/src/EVEMon.Common/Enumerations/PlanEntrySort.cs +++ b/src/EVEMon.Common/Enumerations/PlanEntrySort.cs @@ -22,6 +22,6 @@ public enum PlanEntrySort PlanType, Notes, SkillPointsRequired, - OmegeRequired + OmegaRequired } } diff --git a/src/EVEMon.Common/Helpers/PlanScratchpad.cs b/src/EVEMon.Common/Helpers/PlanScratchpad.cs index c8f047c90..5ebc56b70 100644 --- a/src/EVEMon.Common/Helpers/PlanScratchpad.cs +++ b/src/EVEMon.Common/Helpers/PlanScratchpad.cs @@ -180,7 +180,7 @@ internal void SimpleSort(PlanEntrySort sort, bool reverseOrder) case PlanEntrySort.SkillPointsRequired: Items.StableSort(PlanEntrySorter.CompareBySkillPointsRequired); break; - case PlanEntrySort.OmegeRequired: + case PlanEntrySort.OmegaRequired: Items.StableSort(PlanEntrySorter.CompareByOmegaRequired); break; default: diff --git a/src/EVEMon/SkillPlanner/PlanEditorControl.cs b/src/EVEMon/SkillPlanner/PlanEditorControl.cs index 40321c280..db123079e 100644 --- a/src/EVEMon/SkillPlanner/PlanEditorControl.cs +++ b/src/EVEMon/SkillPlanner/PlanEditorControl.cs @@ -1339,7 +1339,7 @@ private static PlanEntrySort GetPlanSort(ColumnHeader header) case PlanColumn.SkillPointsRequired: return PlanEntrySort.SkillPointsRequired; case PlanColumn.OmegaRequired: - return PlanEntrySort.OmegeRequired; + return PlanEntrySort.OmegaRequired; default: return PlanEntrySort.None; }