Skip to content

Commit

Permalink
Merge pull request evemondevteam#87 from avianrr/master
Browse files Browse the repository at this point in the history
Active/alpha skill level and better alpha/omega detection.
  • Loading branch information
peterhaneve authored Oct 7, 2018
2 parents 94cd153 + a3d3341 commit e12ff20
Show file tree
Hide file tree
Showing 20 changed files with 371 additions and 80 deletions.
3 changes: 2 additions & 1 deletion src/EVEMon.Common/Constants/EveConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ 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;

/// <summary>
/// Represents a "region" range.
/// </summary>
public const int RegionRange = 32767;

}
}
}
25 changes: 11 additions & 14 deletions src/EVEMon.Common/Data/StaticSkill.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ private StaticSkill()
SecondaryAttribute = EveAttribute.None;
Group = StaticSkillGroup.UnknownStaticSkillGroup;
FormattedCost = Cost.ToNumericString(0);
}
AlphaLimit = 0;
}

/// <summary>
/// Deserialization constructor from datafiles.
Expand All @@ -54,11 +55,11 @@ 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<StaticSkillLevel>();
FormattedCost = Cost.ToNumericString(0);
AlphaLimit = src.AlphaLimit;
}

#endregion
Expand All @@ -76,15 +77,6 @@ internal void CompleteInitialization(IEnumerable<SerializableSkillPrerequisite>

// 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
Expand Down Expand Up @@ -143,9 +135,14 @@ internal void CompleteInitialization(IEnumerable<SerializableSkillPrerequisite>
public EveAttribute SecondaryAttribute { get; }

/// <summary>
/// Get whether skill is trainable on a trial account.
/// Get whether skill is trainable on a alpha account.
/// </summary>
public bool AlphaFriendly { get { return AlphaLimit > 0; } }

/// <summary>
/// Get the level limit for an alpha clone.
/// </summary>
public bool IsTrainableOnTrialAccount { get; private set; }
public long AlphaLimit { get; private set; }

/// <summary>
/// Gets the prerequisites a character must satisfy before it can be trained.
Expand Down Expand Up @@ -278,4 +275,4 @@ public Skill ToCharacter(Character character)

#endregion
}
}
}
5 changes: 3 additions & 2 deletions src/EVEMon.Common/Enumerations/PlanEntrySort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public enum PlanEntrySort
TimeDifference,
PlanType,
Notes,
SkillPointsRequired
SkillPointsRequired,
OmegaRequired
}
}
}
6 changes: 3 additions & 3 deletions src/EVEMon.Common/Enumerations/SkillFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
18 changes: 16 additions & 2 deletions src/EVEMon.Common/Helpers/CharacterScratchpad.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,22 @@ public CharacterScratchpad(BaseCharacter character)
Reset();
}

/// <summary>
/// Gets Alpha/Omega status for this character.
/// </summary>
public override AccountStatus CharacterStatus {
get
{
if(m_character != null)
{
return m_character.CharacterStatus;
}
return base.CharacterStatus;
}
protected set => base.CharacterStatus = value;
}

#region Attributes
#region Attributes

/// <summary>
/// Gets the intelligence of the character.
Expand Down Expand Up @@ -419,4 +433,4 @@ public IDisposable BeginTemporaryChanges()

#endregion
}
}
}
11 changes: 10 additions & 1 deletion src/EVEMon.Common/Helpers/PlanEntrySorter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/// <summary>
/// Compares by clone state required.
/// </summary>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
/// <returns></returns>
public static int CompareByOmegaRequired(PlanEntry x, PlanEntry y)
=> x.OmegaRequired.CompareTo(y.OmegaRequired);

/// <summary>
/// Compares by skill group duration.
/// </summary>
Expand Down Expand Up @@ -297,4 +306,4 @@ private static TimeSpan GetSkillGroupDuration(StaticSkillGroup group, IEnumerabl

#endregion
}
}
}
5 changes: 4 additions & 1 deletion src/EVEMon.Common/Helpers/PlanScratchpad.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ internal void SimpleSort(PlanEntrySort sort, bool reverseOrder)
case PlanEntrySort.SkillPointsRequired:
Items.StableSort(PlanEntrySorter.CompareBySkillPointsRequired);
break;
case PlanEntrySort.OmegaRequired:
Items.StableSort(PlanEntrySorter.CompareByOmegaRequired);
break;
default:
throw new NotImplementedException();
}
Expand All @@ -191,4 +194,4 @@ internal void SimpleSort(PlanEntrySort sort, bool reverseOrder)

#endregion
}
}
}
17 changes: 16 additions & 1 deletion src/EVEMon.Common/Models/BaseCharacter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -22,6 +27,10 @@ public abstract class BaseCharacter

#endregion

/// <summary>
/// Gets Alpha/Omega status for this character.
/// </summary>
public virtual AccountStatus CharacterStatus { get; protected set; }

#region Computation methods

Expand All @@ -38,7 +47,13 @@ public abstract class BaseCharacter
/// <exception cref="System.ArgumentNullException">skill</exception>
public virtual float GetBaseSPPerHour(StaticSkill skill)
{
return GetOmegaSPPerHour(skill);
float spPerHour = GetOmegaSPPerHour(skill);
if (CharacterStatus != null)
{
spPerHour *= CharacterStatus.TrainingRate;
}

return spPerHour;
}

/// <summary>
Expand Down
63 changes: 40 additions & 23 deletions src/EVEMon.Common/Models/Character.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,29 +93,50 @@ 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;
var rate = (int)Math.Round(GetOmegaSPPerHour(skill.Skill) / spPerHour, 0);
switch (rate)
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)
{
case 1:
statusType = AccountStatus.AccountStatusType.Omega;
break;
case 2:
statusType = AccountStatus.AccountStatusType.Alpha;
break;
default:
statusType = AccountStatus.AccountStatusType.Unknown;
break;
// 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;
}
}
}
}

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);
}

Expand Down Expand Up @@ -373,10 +394,6 @@ public Station LastKnownStation
public SolarSystem LastKnownSolarSystem => StaticGeography.GetSolarSystemByID(
LastKnownLocation?.SolarSystemID ?? 0);

/// <summary>
/// Gets Alpha/Omega status for this character.
/// </summary>
public AccountStatus CharacterStatus { get; private set; }
#endregion


Expand Down Expand Up @@ -514,7 +531,7 @@ public override Int64 GetSkillPoints(StaticSkill skill)
/// <returns>Skill points earned per hour when training this skill</returns>
public override float GetBaseSPPerHour(StaticSkill skill)
{
return CharacterStatus.TrainingRate * base.GetBaseSPPerHour(skill);
return CharacterStatus.TrainingRate * base.GetOmegaSPPerHour(skill);
}

#endregion
Expand Down Expand Up @@ -855,7 +872,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);
}
Expand Down
9 changes: 8 additions & 1 deletion src/EVEMon.Common/Models/PlanEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,13 @@ private static StaticSkill GetSkill(SerializablePlanEntry serial)
/// <returns>True if the given item's skill is a prerequisite of this one or if it is a lower level of the same skill.</returns>
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

Expand Down Expand Up @@ -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);
}
}
}
20 changes: 15 additions & 5 deletions src/EVEMon.Common/Models/Skill.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}

/// <summary>
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -215,11 +219,6 @@ public bool HasBookInAssets
/// </summary>
public SkillGroup Group { get; }

/// <summary>
/// Gets whether this skill and all its prereqs are trainable on a trial account.
/// </summary>
public bool IsTrainableOnTrialAccount => StaticData.IsTrainableOnTrialAccount;

/// <summary>
/// Gets true if this is a public skill.
/// </summary>
Expand Down Expand Up @@ -270,6 +269,17 @@ public Int64 Level
}
}

/// <summary>
/// Get the last reported active level.
/// </summary>
public Int64 ActiveLevel
{
get
{
return m_activeLevel;
}
}

/// <summary>
/// Gets the level gotten from CCP during the last update.
/// </summary>
Expand Down
Loading

0 comments on commit e12ff20

Please sign in to comment.