Skip to content

Commit

Permalink
Add Eureka/Bozja ClassJob
Browse files Browse the repository at this point in the history
  • Loading branch information
Robbie committed Jul 8, 2024
1 parent 4d21f40 commit 1cb0f26
Show file tree
Hide file tree
Showing 3 changed files with 262 additions and 3 deletions.
16 changes: 13 additions & 3 deletions NetStone/Model/Parseables/Character/ClassJob/CharacterClassJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ public CharacterClassJob(HtmlNode rootNode, CharacterClassJobDefinition definiti
this.definition = definition;
}

/// <summary>
/// Information about the Eureka class.
/// </summary>
public ClassJobEureka? Eureka => new ClassJobEureka(this.RootNode, this.definition.Eureka).GetOptional();

/// <summary>
/// Information about the Bozja class.
/// </summary>
public ClassJobBozja? Bozja => new ClassJobBozja(this.RootNode, this.definition.Bozja).GetOptional();

/// <summary>
/// Information about the Paladin class.
/// </summary>
Expand Down Expand Up @@ -65,7 +75,7 @@ public CharacterClassJob(HtmlNode rootNode, CharacterClassJobDefinition definiti
/// Information about the Reaper class.
/// </summary>
public ClassJobEntry Reaper => new(this.RootNode, this.definition.Reaper);

/// <summary>
/// Information about the Viper class.
/// </summary>
Expand Down Expand Up @@ -214,7 +224,7 @@ public CharacterClassJob(HtmlNode rootNode, CharacterClassJobDefinition definiti
{ StaticData.ClassJob.Samurai, this.Samurai },

{ StaticData.ClassJob.Reaper, this.Reaper },

{ StaticData.ClassJob.Viper, this.Viper },

{ StaticData.ClassJob.Conjurer, this.WhiteMage },
Expand All @@ -239,7 +249,7 @@ public CharacterClassJob(HtmlNode rootNode, CharacterClassJobDefinition definiti
{ StaticData.ClassJob.BlackMage, this.BlackMage },

{ StaticData.ClassJob.RedMage, this.RedMage },

{ StaticData.ClassJob.Pictomancer, this.Pictomancer },

{ StaticData.ClassJob.BlueMage, this.BlueMage },
Expand Down
125 changes: 125 additions & 0 deletions NetStone/Model/Parseables/Character/ClassJob/ClassJobBozja.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
using System.Linq;
using System.Text.RegularExpressions;
using HtmlAgilityPack;
using NetStone.Definitions.Model.Character;

namespace NetStone.Model.Parseables.Character.ClassJob;

/// <summary>
/// Entry for Bozja Field Operation of a character
/// </summary>
public class ClassJobBozja : LodestoneParseable, IOptionalParseable<ClassJobBozja>
{
private readonly ClassJobBozjaDefinition definition;

/// <summary>
/// Constructs a new class entry
/// </summary>
/// <param name="rootNode">Root node of this entry</param>
/// <param name="definition">Parser definition</param>
public ClassJobBozja(HtmlNode rootNode, ClassJobBozjaDefinition definition) : base(rootNode)
{
this.definition = definition;
}

/// <summary>
/// The name of this class and job combo.
/// </summary>
public string Name => ParseTooltip(this.definition.NAME);

/// <summary>
/// Value indicating whether this class has its job unlocked.
/// </summary>
public bool IsJobUnlocked => this.Name.Contains("/");

/// <summary>
/// The level this class or job is at.
/// </summary>
public int Level
{
get
{
var level = Parse(this.definition.LEVEL);
return level == "-" ? 0 : int.Parse(level);
}
}

private string ExpString => ParseInnerText(this.definition.METTLE);

private long? expCurrentVal;

/// <summary>
/// The amount of current achieved EXP on this level.
/// </summary>
public long ExpCurrent
{
get
{
if (!this.expCurrentVal.HasValue)
ParseExp();

return this.expCurrentVal!.Value;
}
}

private long? expMaxVal;

/// <summary>
/// The amount of EXP to be reached to gain the next level.
/// </summary>
public long ExpMax
{
get
{
if (!this.expCurrentVal.HasValue)
ParseExp();

return this.expMaxVal!.Value;
}
}

/// <summary>
/// The outstanding amount of EXP to go to the next level.
/// </summary>
public long ExpToGo => this.ExpMax - this.ExpCurrent;

private void ParseExp()
{
if (!this.Exists)
{
this.expCurrentVal = 0;
this.expMaxVal = 0;

return;
}

var expVals = this.ExpString.Split(" / ").Select(x => x.Replace(",", string.Empty)).ToArray();

if (expVals[0] == "--")
{
this.expCurrentVal = 0;
this.expMaxVal = 0;

return;
}

this.expCurrentVal = long.Parse(Regex.Match(expVals[0], @"\d+").Value);
this.expMaxVal = long.Parse(Regex.Match(expVals[1], @"\d+").Value);
}

/// <summary>
/// Value indicating if this class is unlocked.
/// </summary>
public bool Exists => this.Level != 0;

/// <summary>
/// Value indicating if this class is unlocked.
/// </summary>
public bool IsUnlocked => this.Exists;

/// <summary>
/// The string representation of this object.
/// </summary>
/// <returns>Name (Level)</returns>
public override string ToString() => $"{this.Name} ({this.Level})";
}
124 changes: 124 additions & 0 deletions NetStone/Model/Parseables/Character/ClassJob/ClassJobEureka.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
using System.Linq;
using HtmlAgilityPack;
using NetStone.Definitions.Model.Character;

namespace NetStone.Model.Parseables.Character.ClassJob;

/// <summary>
/// Entry for Eureka Field Operation of a character
/// </summary>
public class ClassJobEureka : LodestoneParseable, IOptionalParseable<ClassJobEureka>
{
private readonly ClassJobEurekaDefinition definition;

/// <summary>
/// Constructs a new class entry
/// </summary>
/// <param name="rootNode">Root node of this entry</param>
/// <param name="definition">Parser definition</param>
public ClassJobEureka(HtmlNode rootNode, ClassJobEurekaDefinition definition) : base(rootNode)
{
this.definition = definition;
}

/// <summary>
/// The name of this class and job combo.
/// </summary>
public string Name => ParseTooltip(this.definition.Name);

/// <summary>
/// Value indicating whether this class has its job unlocked.
/// </summary>
public bool IsJobUnlocked => this.Name.Contains("/");

/// <summary>
/// The level this class or job is at.
/// </summary>
public int Level
{
get
{
var level = Parse(this.definition.Level);
return level == "-" ? 0 : int.Parse(level);
}
}

private string ExpString => ParseInnerText(this.definition.Exp);

private long? expCurrentVal;

/// <summary>
/// The amount of current achieved EXP on this level.
/// </summary>
public long ExpCurrent
{
get
{
if (!this.expCurrentVal.HasValue)
ParseExp();

return this.expCurrentVal!.Value;
}
}

private long? expMaxVal;

/// <summary>
/// The amount of EXP to be reached to gain the next level.
/// </summary>
public long ExpMax
{
get
{
if (!this.expCurrentVal.HasValue)
ParseExp();

return this.expMaxVal!.Value;
}
}

/// <summary>
/// The outstanding amount of EXP to go to the next level.
/// </summary>
public long ExpToGo => this.ExpMax - this.ExpCurrent;

private void ParseExp()
{
if (!this.Exists)
{
this.expCurrentVal = 0;
this.expMaxVal = 0;

return;
}

var expVals = this.ExpString.Split(" / ").Select(x => x.Replace(",", string.Empty)).ToArray();

if (expVals[0] == "--")
{
this.expCurrentVal = 0;
this.expMaxVal = 0;

return;
}

this.expCurrentVal = long.Parse(expVals[0]);
this.expMaxVal = long.Parse(expVals[1]);
}

/// <summary>
/// Value indicating if this class is unlocked.
/// </summary>
public bool Exists => this.Level != 0;

/// <summary>
/// Value indicating if this class is unlocked.
/// </summary>
public bool IsUnlocked => this.Exists;

/// <summary>
/// The string representation of this object.
/// </summary>
/// <returns>Name (Level)</returns>
public override string ToString() => $"{this.Name} ({this.Level})";
}

0 comments on commit 1cb0f26

Please sign in to comment.