diff --git a/LoLMasteryManager/ChampionGG.vb b/LoLMasteryManager/ChampionGG.vb
index b71d702..72c8b9f 100644
--- a/LoLMasteryManager/ChampionGG.vb
+++ b/LoLMasteryManager/ChampionGG.vb
@@ -3,6 +3,7 @@ Imports System.Net
Imports System.Net.Http
Imports HtmlAgilityPack
Imports Newtonsoft.Json
+Imports Newtonsoft.Json.Linq
Module ChampionGG
@@ -419,19 +420,63 @@ Module ChampionGG
With oMastery
.ID = oRiotMastery.ID
.Name = oRiotMastery.Name
- .Tree = oRiotMastery.Tree
+ .Tree = GetTree(sJson, oRiotMastery.ID)
End With
Return oMastery
Catch ex As Exception
-
Throw
End Try
End Function
+ Private Function GetTree(ByVal json As String, ByVal masteryId As Integer) As String
+
+ Dim jobj = JObject.Parse(json)
+
+ Dim ferocityMasteryIds As List(Of Integer) = ParseMasteryTree("Ferocity", jobj)
+ Dim cunningMasteryIds As List(Of Integer) = ParseMasteryTree("Cunning", jobj)
+ Dim resolveMasteryIds As List(Of Integer) = ParseMasteryTree("Resolve", jobj)
+
+ If ferocityMasteryIds.Contains(masteryId) Then
+ Return "Ferocity"
+ End If
+
+ If cunningMasteryIds.Contains(masteryId) Then
+ Return "Cunning"
+ End If
+
+ If resolveMasteryIds.Contains(masteryId) Then
+ Return "Resolve"
+ End If
+
+ Throw New IndexOutOfRangeException
+
+ End Function
+
+ Private Function ParseMasteryTree(ByVal tree As String, ByVal jobj As JObject) As List(Of Integer)
+
+ Dim myMasteryIds As List(Of Integer) = New List(Of Integer)()
+
+ Dim myMasteryJson = jobj("tree")(tree)
+ Dim myMasteryGroupJson = myMasteryJson.Children()
+ For Each grp In myMasteryGroupJson
+
+ For Each leafMastery In grp.Children(Of JObject)
+
+ Dim masteryIdStr = leafMastery("masteryId").ToString()
+ Dim masteryIdInt = Int32.Parse(masteryIdStr)
+ myMasteryIds.Add(masteryIdInt)
+
+ Next
+ Next
+
+ Return myMasteryIds
+
+ End Function
+
'''
''' Extracts the number of assigned mastery ranks from the given node.
'''
diff --git a/LoLMasteryManager/Coordinates.json b/LoLMasteryManager/Coordinates.json
index d6186ba..ea056fe 100644
--- a/LoLMasteryManager/Coordinates.json
+++ b/LoLMasteryManager/Coordinates.json
@@ -3,8 +3,9 @@
"mastery_coordinates_menu": {
"6111": "387, 267",
"6114": "521, 267",
- "6121": "422, 339",
- "6122": "489, 339",
+ "6121": "388, 339",
+ "6122": "455, 339",
+ "6123": "522, 339",
"6131": "388, 410",
"6134": "522, 410",
"6141": "422, 481",
@@ -45,8 +46,9 @@
"mastery_coordinates_champion_select": {
"6111": "397, 186",
"6114": "531, 186",
- "6121": "432, 258",
- "6122": "499, 258",
+ "6121": "398, 258",
+ "6122": "465, 258",
+ "6123": "532, 258",
"6131": "398, 329",
"6134": "532, 329",
"6141": "432, 400",
@@ -84,4 +86,4 @@
"6362": "740, 542",
"6363": "807, 542"
}
-}
+}
\ No newline at end of file
diff --git a/LoLMasteryManager/Json Utilities/Coordinates.json b/LoLMasteryManager/Json Utilities/Coordinates.json
new file mode 100644
index 0000000..ea056fe
--- /dev/null
+++ b/LoLMasteryManager/Json Utilities/Coordinates.json
@@ -0,0 +1,89 @@
+{
+ "reference_client_size": "1280, 800",
+ "mastery_coordinates_menu": {
+ "6111": "387, 267",
+ "6114": "521, 267",
+ "6121": "388, 339",
+ "6122": "455, 339",
+ "6123": "522, 339",
+ "6131": "388, 410",
+ "6134": "522, 410",
+ "6141": "422, 481",
+ "6142": "489, 481",
+ "6151": "388, 552",
+ "6154": "522, 552",
+ "6161": "388, 623",
+ "6162": "455, 623",
+ "6164": "522, 623",
+ "6211": "937, 267",
+ "6212": "1071, 267",
+ "6221": "972, 339",
+ "6223": "1039, 339",
+ "6231": "938, 410",
+ "6232": "1072, 410",
+ "6241": "972, 481",
+ "6242": "1039, 481",
+ "6251": "938, 552",
+ "6252": "1072, 552",
+ "6261": "938, 623",
+ "6262": "1005, 623",
+ "6263": "1072, 623",
+ "6311": "662, 267",
+ "6312": "796, 267",
+ "6321": "663, 339",
+ "6322": "730, 339",
+ "6323": "797, 339",
+ "6331": "663, 410",
+ "6332": "797, 410",
+ "6342": "697, 481",
+ "6343": "764, 481",
+ "6351": "663, 552",
+ "6352": "797, 552",
+ "6361": "663, 623",
+ "6362": "730, 623",
+ "6363": "797, 623"
+ },
+ "mastery_coordinates_champion_select": {
+ "6111": "397, 186",
+ "6114": "531, 186",
+ "6121": "398, 258",
+ "6122": "465, 258",
+ "6123": "532, 258",
+ "6131": "398, 329",
+ "6134": "532, 329",
+ "6141": "432, 400",
+ "6142": "499, 400",
+ "6151": "398, 471",
+ "6154": "532, 471",
+ "6161": "398, 542",
+ "6162": "465, 542",
+ "6164": "532, 542",
+ "6211": "947, 186",
+ "6212": "1081, 186",
+ "6221": "982, 258",
+ "6223": "1049, 258",
+ "6231": "948, 329",
+ "6232": "1082, 329",
+ "6241": "982, 400",
+ "6242": "1049, 400",
+ "6251": "948, 471",
+ "6252": "1082, 471",
+ "6261": "948, 542",
+ "6262": "1015, 542",
+ "6263": "1082, 542",
+ "6311": "672, 186",
+ "6312": "806, 186",
+ "6321": "673, 258",
+ "6322": "740, 258",
+ "6323": "807, 258",
+ "6331": "673, 329",
+ "6332": "807, 329",
+ "6342": "707, 400",
+ "6343": "774, 400",
+ "6351": "673, 471",
+ "6352": "807, 471",
+ "6361": "673, 542",
+ "6362": "740, 542",
+ "6363": "807, 542"
+ }
+}
\ No newline at end of file
diff --git a/LoLMasteryManager/Json Utilities/CoordinatesGenerator.linq b/LoLMasteryManager/Json Utilities/CoordinatesGenerator.linq
new file mode 100644
index 0000000..749aadc
--- /dev/null
+++ b/LoLMasteryManager/Json Utilities/CoordinatesGenerator.linq
@@ -0,0 +1,243 @@
+
+ <RuntimeDirectory>\System.Drawing.dll
+ <RuntimeDirectory>\System.Runtime.InteropServices.dll
+ Newtonsoft.Json
+ RestSharp
+ Newtonsoft.Json
+ Newtonsoft.Json.Linq
+ RestSharp
+ System.Drawing
+ System.Drawing.Imaging
+ System.Runtime.InteropServices
+
+
+/*
+This file will re-build the coordinates.json file for you based on the 2 bmp images you provide. Take 2
+screenshots of the lol app, one on the mastery editing page and one in the champ select mastery editing
+page. Trim them down to 1280x800 file size (the default size of the app), then use a single pixel pencil
+tool with the color Green (red:0 green:255 blue:0, 00FF00) and mark a dot in the upper left corner of every
+mastery (they don't have to be perfectly on the corner, just close). Save as a bmp and then run this script
+to re-generate the coordinates.json file.
+
+The Url to download the masteries will change with each new version and must be updated - see "LOL Static Data" https://developer.riotgames.com/docs/static-data
+*/
+
+//Using single green pixels as the identifier of the upper left corner of each button
+const string hexColor = "00FF00";
+const byte markedR = 0;
+const byte markedG = 255;
+const byte markedB = 0;
+string markedImagePath = Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), "mastery_coordinates_0_255_0_00FF00.bmp");
+string markedImagePathInChampSelect = Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), "mastery_champ_select_coordinates_0_255_0_00FF00.bmp");
+string coordinatesJsonFilePath = Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), "Coordinates.json");
+
+const string lolCdnDomain = "http://ddragon.leagueoflegends.com";
+const string masteriesUrl = "cdn/6.8.1/data/en_US/mastery.json";
+
+void Main()
+{
+ var coordinatesJson = new CoordinatesJsonSchema
+ {
+ reference_client_size = "1280, 800",
+ mastery_coordinates_menu = GetMasteryCoordsByImage(markedImagePath),
+ mastery_coordinates_champion_select = GetMasteryCoordsByImage(markedImagePathInChampSelect),
+ };
+
+ var formattedJson = JsonConvert.SerializeObject(coordinatesJson, Newtonsoft.Json.Formatting.Indented);
+
+ File.WriteAllText(coordinatesJsonFilePath, formattedJson);
+}
+
+Dictionary GetMasteryCoordsByImage(string imagePath)
+{
+ var layout = GetOfficialMasteryLayout();
+
+ var coords = GetMarkedCoordinates(imagePath);
+
+ if (layout.Count() != coords.Count()){
+ throw new Exception("mismatched masteries count");
+ }
+
+ PopulateCoordinates("Ferocity", layout, coords);
+ PopulateCoordinates("Cunning", layout, coords);
+ PopulateCoordinates("Resolve", layout, coords);
+
+ var coordinatesJsonSchema = layout.OrderBy(x => x.MasteryId).ToDictionary(x => x.MasteryId.ToString(), x => x.Coords);
+
+ return coordinatesJsonSchema;
+}
+
+
+class CoordinatesJsonSchema
+{
+ public string reference_client_size{get;set;}
+ public Dictionary mastery_coordinates_menu{get;set;}
+ public Dictionary mastery_coordinates_champion_select{get;set;}
+}
+
+// Define other methods and classes here
+class Coordinate
+{
+ public int x { get; set; }
+ public int y { get; set; }
+ public bool IsAssigned { get; set; }
+ public int? RowNumber{get;set;}
+}
+
+List GetMarkedCoordinates(string imagePath)
+{
+ var bmp = new Bitmap(imagePath);
+
+ // Lock the bitmap's bits.
+ var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ var bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
+
+ // Get the address of the first line.
+ IntPtr ptr = bmpData.Scan0;
+
+ // Declare an array to hold the bytes of the bitmap.
+ int bytes = bmpData.Stride * bmp.Height;
+ byte[] rgbValues = new byte[bytes];
+ byte[] r = new byte[bytes / 3];
+ byte[] g = new byte[bytes / 3];
+ byte[] b = new byte[bytes / 3];
+
+ // Copy the RGB values into the array.
+ Marshal.Copy(ptr, rgbValues, 0, bytes);
+
+ int count = 0;
+ int stride = bmpData.Stride;
+
+ for (int column = 0; column < bmpData.Height; column++)
+ {
+ for (int row = 0; row < bmpData.Width; row++)
+ {
+ b[count] = (byte)(rgbValues[(column * stride) + (row * 3)]);
+ g[count] = (byte)(rgbValues[(column * stride) + (row * 3) + 1]);
+ r[count++] = (byte)(rgbValues[(column * stride) + (row * 3) + 2]);
+ }
+ }
+
+ var coords = new List();
+
+ for (var i = 0; i < r.Length; i ++)
+ {
+ //1280x800
+ if (r[i] == markedR && g[i] == markedG && b[i] == markedB)
+ {
+ var x = i % 1280;
+ var y = i / 1280;
+ coords.Add(new Coordinate
+ {
+ x = x,
+ y = y,
+ });
+ }
+ }
+
+ AnalyzeCoords(coords);
+
+ return coords;
+}
+
+JObject masteriesjobj;
+
+List GetOfficialMasteryLayout()
+{
+ var client = new RestClient(lolCdnDomain);
+ var request = new RestRequest(masteriesUrl, Method.GET);
+ var response = client.Execute(request);
+
+ masteriesjobj = JObject.Parse(response.Content);
+
+ var masteryLayout = new List();
+
+
+ masteryLayout.AddRange(GetOfficialMasteryLayoutTree(masteriesjobj, "Ferocity"));
+ masteryLayout.AddRange(GetOfficialMasteryLayoutTree(masteriesjobj, "Cunning"));
+ masteryLayout.AddRange(GetOfficialMasteryLayoutTree(masteriesjobj, "Resolve"));
+
+
+ return masteryLayout;
+}
+
+List GetOfficialMasteryLayoutTree(JObject masteriesObj, string tree)
+{
+ var masteryLayout = new List();
+
+ var ferocityBranch = masteriesObj["tree"][tree];
+
+ var rowNum = 0;
+ foreach (var row in ferocityBranch)
+ {
+ var colNum = 0;
+ var columns = row.Children();
+ foreach (var col in columns)
+ {
+ var masteryId = Int32.Parse(col["masteryId"].ToString());
+
+ masteryLayout.Add(new MasteryLayout
+ {
+ Tree = tree,
+ MasteryId = masteryId,
+ Row = rowNum,
+ Column = colNum,
+ });
+
+ colNum++;
+ }
+
+ rowNum++;
+ }
+
+ return masteryLayout;
+}
+
+public class MasteryLayout
+{
+ public string Tree {get;set;}
+ public int Row {get;set;}
+ public int Column{get;set;}
+ public int MasteryId{get;set;}
+ public string Coords{get;set;}
+}
+
+void PopulateCoordinates(string tree, List layout, List coords){
+ var ferocityLayout = layout.Where(x => x.Tree == tree);
+
+ for (var row = 0; row <= ferocityLayout.Max(x => x.Row); row++) {
+ var cols = ferocityLayout.Where(x => x.Row == row);
+ for(var col = 0; col <= cols.Max(x => x.Column); col++) {
+
+ var cell = cols.SingleOrDefault (x => x.Column == col);
+ if (cell == null) continue;
+
+ //Get left most unassiged coord for this row
+ var coord = coords.Where(x => x.IsAssigned == false && x.RowNumber == cell.Row).OrderBy(c => c.x).First();
+
+ cell.Coords = string.Format("{0}, {1}", coord.x, coord.y);
+ coord.IsAssigned = true;
+ }
+ }
+}
+
+void AnalyzeCoords(List coords)
+{
+ //Get row numbers (0-5)
+ int minY;
+
+ const int yTolerance = 15;
+ var rowNumber = 0;
+
+ while(coords.Any(x => x.RowNumber == null))
+ {
+ minY = coords.Where(c => c.RowNumber == null).Min(c => c.y);
+
+ var thisRow = coords.Where(c => c.RowNumber == null && c.y < (minY + yTolerance));
+ foreach (var r in thisRow){
+ r.RowNumber = rowNumber;
+ }
+
+ rowNumber++;
+ }
+}
\ No newline at end of file
diff --git a/LoLMasteryManager/Json Utilities/DownloadMasteryJson.linq b/LoLMasteryManager/Json Utilities/DownloadMasteryJson.linq
new file mode 100644
index 0000000..79f805e
--- /dev/null
+++ b/LoLMasteryManager/Json Utilities/DownloadMasteryJson.linq
@@ -0,0 +1,27 @@
+
+ Newtonsoft.Json
+ RestSharp
+ Newtonsoft.Json
+ Newtonsoft.Json.Linq
+ RestSharp
+
+
+/*
+This will download the latest version of the masteries.json file. Useful if the mastery file is updated by riot
+
+The Url to download the masteries will change with each new version and must be updated - see "LOL Static Data" https://developer.riotgames.com/docs/static-data
+*/
+const string lolCdnDomain = "http://ddragon.leagueoflegends.com";
+const string masteriesUrl = "cdn/6.8.1/data/en_US/mastery.json";
+string masteryJsonFilePath = Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), "Masteries.json");
+
+void Main()
+{
+ var client = new RestClient(lolCdnDomain);
+ var request = new RestRequest(masteriesUrl, Method.GET);
+ var response = client.Execute(request);
+
+ var jObject = JObject.Parse(response.Content);
+
+ File.WriteAllText(masteryJsonFilePath, jObject.ToString());
+}
\ No newline at end of file
diff --git a/LoLMasteryManager/Json Utilities/Masteries.json b/LoLMasteryManager/Json Utilities/Masteries.json
new file mode 100644
index 0000000..5d79e82
--- /dev/null
+++ b/LoLMasteryManager/Json Utilities/Masteries.json
@@ -0,0 +1,1033 @@
+{
+ "type": "mastery",
+ "version": "6.8.1",
+ "tree": {
+ "Ferocity": [
+ [
+ {
+ "masteryId": "6111",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6114",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6121",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6122",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6123",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6131",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6134",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6141",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6142",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6151",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6154",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6161",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6162",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6164",
+ "prereq": "0"
+ }
+ ]
+ ],
+ "Cunning": [
+ [
+ {
+ "masteryId": "6311",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6312",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6321",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6322",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6323",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6331",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6332",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6342",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6343",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6351",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6352",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6361",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6362",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6363",
+ "prereq": "0"
+ }
+ ]
+ ],
+ "Resolve": [
+ [
+ {
+ "masteryId": "6211",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6212",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6221",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6223",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6231",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6232",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6241",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6242",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6251",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6252",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6261",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6262",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6263",
+ "prereq": "0"
+ }
+ ]
+ ]
+ },
+ "data": {
+ "6111": {
+ "id": 6111,
+ "name": "Fury",
+ "description": [
+ "+0.8% Attack Speed",
+ "+1.6% Attack Speed",
+ "+2.4% Attack Speed",
+ "+3.2% Attack Speed",
+ "+4% Attack Speed"
+ ],
+ "image": {
+ "full": "6111.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 144,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6114": {
+ "id": 6114,
+ "name": "Sorcery",
+ "description": [
+ "+0.4% increased Ability damage",
+ "+0.8% increased Ability damage",
+ "+1.2% increased Ability damage",
+ "+1.6% increased Ability damage",
+ "+2.0% increased Ability damage"
+ ],
+ "image": {
+ "full": "6114.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 192,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6121": {
+ "id": 6121,
+ "name": "Double Edged Sword",
+ "description": [
+ "Melee: Deal 3% additional damage, take 1.5% additional damage.
Ranged: Deal and take 2% additional damage"
+ ],
+ "image": {
+ "full": "6121.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 240,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6122": {
+ "id": 6122,
+ "name": "Feast",
+ "description": [
+ "Killing a unit restores 20 Health (30 second cooldown)"
+ ],
+ "image": {
+ "full": "6122.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 288,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6123": {
+ "id": 6123,
+ "name": "Expose Weakness",
+ "description": [
+ "Damaging enemy champions causes them to take 3% more damage from your allies"
+ ],
+ "image": {
+ "full": "6123.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 336,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6131": {
+ "id": 6131,
+ "name": "Vampirism",
+ "description": [
+ "+0.4% Lifesteal and Spell Vamp",
+ "+0.8% Lifesteal and Spell Vamp",
+ "+1.2% Lifesteal and Spell Vamp",
+ "+1.6% Lifesteal and Spell Vamp",
+ "+2.0% Lifesteal and Spell Vamp"
+ ],
+ "image": {
+ "full": "6131.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 336,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6134": {
+ "id": 6134,
+ "name": "Natural Talent",
+ "description": [
+ "+2 Attack Damage and 3 Ability Power at level 18 (0.11 Attack Damage and 0.16 Ability Power per level)",
+ "+4 Attack Damage and 6 Ability Power at level 18 (0.22 Attack Damage and 0.32 Ability Power per level)",
+ "+6 Attack Damage and 9 Ability Power at level 18 (0.33 Attack Damage and 0.5 Ability Power per level)",
+ "+8 Attack Damage and 12 Ability Power at level 18 (0.44 Attack Damage and 0.66 Ability Power per level)",
+ "+10 Attack Damage and 15 Ability Power at level 18 (0.55 Attack Damage and 0.83 Ability Power per level)"
+ ],
+ "image": {
+ "full": "6134.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 384,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6141": {
+ "id": 6141,
+ "name": "Bounty Hunter",
+ "description": [
+ "Deal 1% increased damage for each unique enemy champion you have killed"
+ ],
+ "image": {
+ "full": "6141.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 432,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6142": {
+ "id": 6142,
+ "name": "Oppressor",
+ "description": [
+ "Deal 2.5% increased damage to targets with impaired movement (slow, stun, root, taunt, etc.)"
+ ],
+ "image": {
+ "full": "6142.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 0,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6151": {
+ "id": 6151,
+ "name": "Battering Blows",
+ "description": [
+ "+1.4% Armor Penetration",
+ "+2.8% Armor Penetration",
+ "+4.2% Armor Penetration",
+ "+5.6% Armor Penetration",
+ "+7% Armor Penetration"
+ ],
+ "image": {
+ "full": "6151.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 48,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6154": {
+ "id": 6154,
+ "name": "Piercing Thoughts",
+ "description": [
+ "+1.4% Magic Penetration",
+ "+2.8% Magic Penetration",
+ "+4.2% Magic Penetration",
+ "+5.6% Magic Penetration",
+ "+7% Magic Penetration"
+ ],
+ "image": {
+ "full": "6154.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 96,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6161": {
+ "id": 6161,
+ "name": "Warlord's Bloodlust",
+ "description": [
+ "Gain increasingly more Life Steal based on your missing health against champions (up to 20%). Against minions gain 50% benefit (25% for ranged champions)."
+ ],
+ "image": {
+ "full": "6161.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 144,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6162": {
+ "id": 6162,
+ "name": "Fervor of Battle",
+ "description": [
+ "You generate stacks of Fervor by hitting enemy champions with attacks and abilities. Your basic attacks deal 1-14 bonus physical damage (based on your level) to enemy champions for each of your stacks of Fervor (max 8 stacks).
Damaging enemy champions with an attack generates 1 stack of Fervor (2 for melee champions) and damaging enemy champions with an ability generates 2 stacks of Fervor (2 second cooldown). Stacks of Fervor last 6 seconds."
+ ],
+ "image": {
+ "full": "6162.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 192,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6164": {
+ "id": 6164,
+ "name": "Deathfire Touch",
+ "description": [
+ "Your damaging abilities cause enemy champions to take additional magic damage equal to 8 + 60% of your Bonus Attack Damage and 25% of your Ability Power, over 4 seconds.
Deathfire Touch has reduced effectiveness when applied by area of effect and damage over time abilities.
- Area of Effect: 2 second duration.
- Damage over time: 1 second duration."
+ ],
+ "image": {
+ "full": "6164.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 240,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6311": {
+ "id": 6311,
+ "name": "Wanderer",
+ "description": [
+ "+0.6% Movement Speed out of combat",
+ "+1.2% Movement Speed out of combat",
+ "+1.8% Movement Speed out of combat",
+ "+2.4% Movement Speed out of combat",
+ "+3% Movement Speed out of combat"
+ ],
+ "image": {
+ "full": "6311.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 0,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6312": {
+ "id": 6312,
+ "name": "Savagery",
+ "description": [
+ "Single target attacks and spells deal 1 bonus damage to minions and monsters",
+ "Single target attacks and spells deal 2 bonus damage to minions and monsters",
+ "Single target attacks and spells deal 3 bonus damage to minions and monsters",
+ "Single target attacks and spells deal 4 bonus damage to minions and monsters",
+ "Single target attacks and spells deal 5 bonus damage to minions and monsters"
+ ],
+ "image": {
+ "full": "6312.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 48,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6321": {
+ "id": 6321,
+ "name": "Runic Affinity",
+ "description": [
+ "Buffs from neutral monsters last 15% longer"
+ ],
+ "image": {
+ "full": "6321.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 96,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6322": {
+ "id": 6322,
+ "name": "Secret Stash",
+ "description": [
+ "Your Potions and Elixirs last 10% longer.
Your Health Potions are replaced with Biscuits that restore 15 Health and Mana instantly on use"
+ ],
+ "image": {
+ "full": "6322.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 144,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6323": {
+ "id": 6323,
+ "name": "Assassin",
+ "description": [
+ "Deal 2% increased damage to champions when no allied champions are nearby"
+ ],
+ "image": {
+ "full": "6323.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 288,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6331": {
+ "id": 6331,
+ "name": "Merciless",
+ "description": [
+ "Deal 1% increased damage to champions below 40% Health",
+ "Deal 2% increased damage to champions below 40% Health",
+ "Deal 3% increased damage to champions below 40% Health",
+ "Deal 4% increased damage to champions below 40% Health",
+ "Deal 5% increased damage to champions below 40% Health"
+ ],
+ "image": {
+ "full": "6331.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 192,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6332": {
+ "id": 6332,
+ "name": "Meditation",
+ "description": [
+ "Regenerate 0.3% of your missing Mana every 5 seconds",
+ "Regenerate 0.6% of your missing Mana every 5 seconds",
+ "Regenerate 0.9% of your missing Mana every 5 seconds",
+ "Regenerate 1.2% of your missing Mana every 5 seconds",
+ "Regenerate 1.5% of your missing Mana every 5 seconds"
+ ],
+ "image": {
+ "full": "6332.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 240,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6342": {
+ "id": 6342,
+ "name": "Bandit",
+ "description": [
+ "Gain 1 gold for each nearby minion killed by an ally.
Gain 3 gold (10 if melee) when hitting an enemy champion with a basic attack (5 second cooldown)"
+ ],
+ "image": {
+ "full": "6342.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 288,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6343": {
+ "id": 6343,
+ "name": "Dangerous Game",
+ "description": [
+ "Champion kills and assists restore 5% of your missing Health and Mana"
+ ],
+ "image": {
+ "full": "6343.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 336,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6351": {
+ "id": 6351,
+ "name": "Precision",
+ "description": [
+ "Gain 0.6 + 0.06 per level Magic Penetration and Armor Penetration",
+ "Gain 1.2 + 0.12 per level Magic Penetration and Armor Penetration",
+ "Gain 1.8 + 0.18 per level Magic Penetration and Armor Penetration",
+ "Gain 2.4 + 0.24 per level Magic Penetration and Armor Penetration",
+ "Gain 3 + 0.3 per level Magic Penetration and Armor Penetration"
+ ],
+ "image": {
+ "full": "6351.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 384,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6352": {
+ "id": 6352,
+ "name": "Intelligence",
+ "description": [
+ "Your Cooldown Reduction cap is increased to 41% and you gain 1% Cooldown Reduction",
+ "Your Cooldown Reduction cap is increased to 42% and you gain 2% Cooldown Reduction",
+ "Your Cooldown Reduction cap is increased to 43% and you gain 3% Cooldown Reduction",
+ "Your Cooldown Reduction cap is increased to 44% and you gain 4% Cooldown Reduction",
+ "Your Cooldown Reduction cap is increased to 45% and you gain 5% Cooldown Reduction"
+ ],
+ "image": {
+ "full": "6352.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 432,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6361": {
+ "id": 6361,
+ "name": "Stormraider's Surge",
+ "description": [
+ "Dealing 30% of a champion's max Health within 2.5 seconds grants you 40% Movement Speed and 75% Slow Resistance for 3 seconds (10 second cooldown)."
+ ],
+ "image": {
+ "full": "6361.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 0,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6362": {
+ "id": 6362,
+ "name": "Thunderlord's Decree",
+ "description": [
+ "Your 3rd attack or damaging spell against the same enemy champion calls down a lightning strike, dealing magic damage in the area.
Damage: 10 per level, plus 30% of your Bonus Attack Damage, and 10% of your Ability Power (25-15 second cooldown, based on level)."
+ ],
+ "image": {
+ "full": "6362.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 48,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6363": {
+ "id": 6363,
+ "name": "Windspeaker's Blessing",
+ "description": [
+ "Your heals and shields are 10% stronger. Additionally, your shields and heals on other allies increase their armor by 5-22 (based on level) and their magic resistance by half that amount for 3 seconds."
+ ],
+ "image": {
+ "full": "6363.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 96,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6211": {
+ "id": 6211,
+ "name": "Recovery",
+ "description": [
+ "+0.4 Health per 5 seconds",
+ "+0.8 Health per 5 seconds",
+ "+1.2 Health per 5 seconds",
+ "+1.6 Health per 5 seconds",
+ "+2.0 Health per 5 seconds"
+ ],
+ "image": {
+ "full": "6211.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 336,
+ "y": 240,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6212": {
+ "id": 6212,
+ "name": "Unyielding",
+ "description": [
+ "+1% Bonus Armor and Magic Resist",
+ "+2% Bonus Armor and Magic Resist",
+ "+3% Bonus Armor and Magic Resist",
+ "+4% Bonus Armor and Magic Resist",
+ "+5% Bonus Armor and Magic Resist"
+ ],
+ "image": {
+ "full": "6212.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 384,
+ "y": 240,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6221": {
+ "id": 6221,
+ "name": "Explorer",
+ "description": [
+ "+15 Movement Speed in Brush and River"
+ ],
+ "image": {
+ "full": "6221.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 432,
+ "y": 240,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6223": {
+ "id": 6223,
+ "name": "Tough Skin",
+ "description": [
+ "You take 2 less damage from champion and neutral monster basic attacks"
+ ],
+ "image": {
+ "full": "6223.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 0,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6231": {
+ "id": 6231,
+ "name": "Runic Armor",
+ "description": [
+ "Shields, healing, regeneration, and lifesteal on you are 1.6% stronger",
+ "Shields, healing, regeneration, and lifesteal on you are 3.2% stronger",
+ "Shields, healing, regeneration, and lifesteal on you are 4.8% stronger",
+ "Shields, healing, regeneration, and lifesteal on you are 6.4% stronger",
+ "Shields, healing, regeneration, and lifesteal on you are 8% stronger"
+ ],
+ "image": {
+ "full": "6231.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 48,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6232": {
+ "id": 6232,
+ "name": "Veteran's Scars",
+ "description": [
+ "+9 Health",
+ "+18 Health",
+ "+27 Health",
+ "+36 Health",
+ "+45 Health"
+ ],
+ "image": {
+ "full": "6232.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 96,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6241": {
+ "id": 6241,
+ "name": "Insight",
+ "description": [
+ "Reduces the cooldown of Summoner Spells by 15%"
+ ],
+ "image": {
+ "full": "6241.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 144,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6242": {
+ "id": 6242,
+ "name": "Perseverance",
+ "description": [
+ "+50% Base Health Regen, increased to +200% when below 25% Health"
+ ],
+ "image": {
+ "full": "6242.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 192,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6251": {
+ "id": 6251,
+ "name": "Swiftness",
+ "description": [
+ "+3% Tenacity and Slow Resist",
+ "+6% Tenacity and Slow Resist",
+ "+9% Tenacity and Slow Resist",
+ "+12% Tenacity and Slow Resist",
+ "+15% Tenacity and Slow Resist"
+ ],
+ "image": {
+ "full": "6251.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 240,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6252": {
+ "id": 6252,
+ "name": "Legendary Guardian",
+ "description": [
+ "+0.6 Armor and Magic Resist for each nearby enemy champion",
+ "+1.2 Armor and Magic Resist for each nearby enemy champion",
+ "+1.8 Armor and Magic Resist for each nearby enemy champion",
+ "+2.4 Armor and Magic Resist for each nearby enemy champion",
+ "+3 Armor and Magic Resist for each nearby enemy champion"
+ ],
+ "image": {
+ "full": "6252.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 288,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6261": {
+ "id": 6261,
+ "name": "Grasp of the Undying",
+ "description": [
+ "Every 4 seconds in combat, your next attack against an enemy champion steals life equal to 2.5% of your max Health (halved for ranged champions, deals magic damage)"
+ ],
+ "image": {
+ "full": "6261.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 336,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6262": {
+ "id": 6262,
+ "name": "Strength of the Ages",
+ "description": [
+ "Siege minions and large monsters that you or nearby allied champions kill grant 20 and 10 permanent Health, respectively (300 max). After reaching the max bonus, these kills instead restore 6% of your Maximum Health."
+ ],
+ "image": {
+ "full": "6262.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 384,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6263": {
+ "id": 6263,
+ "name": "Bond of Stone",
+ "description": [
+ "+4% Damage Reduction. 6% of the damage from enemy champions taken by the nearest allied champion is dealt to you instead. Damage is not redirected if you are below 5% of your maximum health."
+ ],
+ "image": {
+ "full": "6263.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 432,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/LoLMasteryManager/Json Utilities/ValidateCoordinatesJson.linq b/LoLMasteryManager/Json Utilities/ValidateCoordinatesJson.linq
new file mode 100644
index 0000000..fe12198
--- /dev/null
+++ b/LoLMasteryManager/Json Utilities/ValidateCoordinatesJson.linq
@@ -0,0 +1,127 @@
+
+ Newtonsoft.Json
+ RestSharp
+ Newtonsoft.Json
+ Newtonsoft.Json.Linq
+ RestSharp
+
+
+/*
+Utility for validating the current mastery.json file and coordinates file look correct. Only needed if you need debugging help
+
+The Url to download the masteries will change with each new version and must be updated - see "LOL Static Data" https://developer.riotgames.com/docs/static-data
+*/
+
+const bool inChampionSelect = true;
+const string champSelectMode = inChampionSelect ? "mastery_coordinates_champion_select" : "mastery_coordinates_menu";
+
+const string lolCdnDomain = "http://ddragon.leagueoflegends.com";
+const string masteriesUrl = "cdn/6.8.1/data/en_US/mastery.json";
+string lolMasteryImagePath = "http://ddragon.leagueoflegends.com/cdn/6.8.1/img/mastery/{0}.png";
+string coordinatesJsonFilePath = Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), "Coordinates.json");
+
+
+void Main()
+{
+ champSelectMode.Dump("Mastery Mode");
+
+ var officialMasteryIds = GetOfficialMasteryIds();
+ var coordinateMasteryIds = GetCoordinateMasteryIds();
+
+ var missingMasteries = officialMasteryIds.Except(coordinateMasteryIds);
+ var surplusMasteries = coordinateMasteryIds.Except(officialMasteryIds);
+
+ missingMasteries.Dump("missingMasteries");
+ surplusMasteries.Dump("surplusMasteries");
+
+// ShowMasteryDetails(6111);
+// ShowMasteryDetails(6123);
+
+ var ferocityMasteryIds = ParseMasteryTree(masteriesjobj, "Ferocity");
+ var cunningMasteryIds = ParseMasteryTree(masteriesjobj, "Cunning");
+ var resolveMasteryIds = ParseMasteryTree(masteriesjobj, "Resolve");
+
+ foreach (var mast in ferocityMasteryIds.Union(cunningMasteryIds).Union(resolveMasteryIds))
+ {
+ ShowMasteryDetails(mast);
+ }
+}
+
+// Define other methods and classes here
+JObject masteriesjobj;
+
+List GetOfficialMasteryIds()
+{
+
+ var client = new RestClient(lolCdnDomain);
+ var request = new RestRequest(masteriesUrl, Method.GET);
+ var response = client.Execute(request);
+
+ masteriesjobj = JObject.Parse(response.Content);
+
+ var masteryIds = new List();
+
+ var masteriesElements = masteriesjobj["data"].Children();
+
+ foreach(var prop in masteriesElements){
+ masteryIds.Add(Int32.Parse(prop.Name));
+ }
+
+ return masteryIds;
+}
+
+JObject coordinatesjobj;
+List GetCoordinateMasteryIds()
+{
+ coordinatesjobj = JObject.Parse(File.ReadAllText(coordinatesJsonFilePath));
+
+ var masteryCoords = coordinatesjobj[champSelectMode].Children();
+
+ var masteryIds = new List();
+
+ foreach (var mcoord in masteryCoords)
+ {
+ masteryIds.Add(Int32.Parse(mcoord.Name));
+ }
+
+ return masteryIds;
+}
+
+void ShowMasteryDetails(int masteryId)
+{
+ var masteryName = masteriesjobj["data"][masteryId.ToString()]["name"].ToString();
+
+ var masteryTree = string.Empty;
+ var ferocityMasteryIds = ParseMasteryTree(masteriesjobj, "Ferocity");
+ if (ferocityMasteryIds.Contains(masteryId)){masteryTree = "Ferocity";}
+
+ var cunningMasteryIds = ParseMasteryTree(masteriesjobj, "Cunning");
+ if (cunningMasteryIds.Contains(masteryId)){masteryTree = "Cunning";}
+
+ var resolveMasteryIds = ParseMasteryTree(masteriesjobj, "Resolve");
+ if (resolveMasteryIds.Contains(masteryId)){masteryTree = "FeroResolvecity";}
+
+ var masteryImage = Util.Image(string.Format(lolMasteryImagePath, masteryId));
+
+ var masteryCoordinates = coordinatesjobj[champSelectMode][masteryId.ToString()].ToString();
+
+ masteryImage.Dump(masteryId + " " + masteryName + " - " + masteryTree + ": " + masteryCoordinates);
+}
+
+List ParseMasteryTree(JObject jObject, string tree)
+{
+ var myMasteryIds = new List();
+ var myMasteryJson = jObject["tree"][tree];
+ var myMasteryGroupJson = myMasteryJson.Children();
+ foreach (var grp in myMasteryGroupJson)
+ {
+ foreach (var leafMastery in grp.Children())
+ {
+ var masteryIdStr = leafMastery["masteryId"].ToString();
+ var masteryId = Int32.Parse(masteryIdStr);
+ myMasteryIds.Add(masteryId);
+ }
+ }
+
+ return myMasteryIds;
+}
\ No newline at end of file
diff --git a/LoLMasteryManager/Json Utilities/mastery_champ_select_coordinates_0_255_0_00FF00.bmp b/LoLMasteryManager/Json Utilities/mastery_champ_select_coordinates_0_255_0_00FF00.bmp
new file mode 100644
index 0000000..919fc2c
Binary files /dev/null and b/LoLMasteryManager/Json Utilities/mastery_champ_select_coordinates_0_255_0_00FF00.bmp differ
diff --git a/LoLMasteryManager/Json Utilities/mastery_coordinates_0_255_0_00FF00.bmp b/LoLMasteryManager/Json Utilities/mastery_coordinates_0_255_0_00FF00.bmp
new file mode 100644
index 0000000..b586bdf
Binary files /dev/null and b/LoLMasteryManager/Json Utilities/mastery_coordinates_0_255_0_00FF00.bmp differ
diff --git a/LoLMasteryManager/Masteries.json b/LoLMasteryManager/Masteries.json
index a487354..5d79e82 100644
--- a/LoLMasteryManager/Masteries.json
+++ b/LoLMasteryManager/Masteries.json
@@ -1,7 +1,227 @@
-{
+{
+ "type": "mastery",
+ "version": "6.8.1",
+ "tree": {
+ "Ferocity": [
+ [
+ {
+ "masteryId": "6111",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6114",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6121",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6122",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6123",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6131",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6134",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6141",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6142",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6151",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6154",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6161",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6162",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6164",
+ "prereq": "0"
+ }
+ ]
+ ],
+ "Cunning": [
+ [
+ {
+ "masteryId": "6311",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6312",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6321",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6322",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6323",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6331",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6332",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6342",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6343",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6351",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6352",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6361",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6362",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6363",
+ "prereq": "0"
+ }
+ ]
+ ],
+ "Resolve": [
+ [
+ {
+ "masteryId": "6211",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6212",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6221",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6223",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6231",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6232",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6241",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6242",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6251",
+ "prereq": "0"
+ },
+ null,
+ {
+ "masteryId": "6252",
+ "prereq": "0"
+ }
+ ],
+ [
+ {
+ "masteryId": "6261",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6262",
+ "prereq": "0"
+ },
+ {
+ "masteryId": "6263",
+ "prereq": "0"
+ }
+ ]
+ ]
+ },
"data": {
"6111": {
"id": 6111,
+ "name": "Fury",
"description": [
"+0.8% Attack Speed",
"+1.6% Attack Speed",
@@ -9,35 +229,97 @@
"+3.2% Attack Speed",
"+4% Attack Speed"
],
- "name": "Fury",
- "masteryTree": "Ferocity"
+ "image": {
+ "full": "6111.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 144,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
},
"6114": {
"id": 6114,
+ "name": "Sorcery",
"description": [
- "+0.4% increased Ability and Spell damage",
- "+0.8% increased Ability and Spell damage",
- "+1.2% increased Ability and Spell damage",
- "+1.6% increased Ability and Spell damage",
- "+2.0% increased Ability and Spell damage"
+ "+0.4% increased Ability damage",
+ "+0.8% increased Ability damage",
+ "+1.2% increased Ability damage",
+ "+1.6% increased Ability damage",
+ "+2.0% increased Ability damage"
],
- "name": "Sorcery",
- "masteryTree": "Ferocity"
+ "image": {
+ "full": "6114.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 192,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
},
"6121": {
"id": 6121,
- "description": [ "Melee - Deal an additional 3% damage, take an additional 1.5% damage.
Ranged - Deal and take an additional 2% damage." ],
"name": "Double Edged Sword",
- "masteryTree": "Ferocity"
+ "description": [
+ "Melee: Deal 3% additional damage, take 1.5% additional damage.
Ranged: Deal and take 2% additional damage"
+ ],
+ "image": {
+ "full": "6121.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 240,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6122": {
"id": 6122,
- "description": [ "Killing a unit restores 20 Health (20 second cooldown)." ],
"name": "Feast",
- "masteryTree": "Ferocity"
+ "description": [
+ "Killing a unit restores 20 Health (30 second cooldown)"
+ ],
+ "image": {
+ "full": "6122.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 288,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6123": {
+ "id": 6123,
+ "name": "Expose Weakness",
+ "description": [
+ "Damaging enemy champions causes them to take 3% more damage from your allies"
+ ],
+ "image": {
+ "full": "6123.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 336,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6131": {
"id": 6131,
+ "name": "Vampirism",
"description": [
"+0.4% Lifesteal and Spell Vamp",
"+0.8% Lifesteal and Spell Vamp",
@@ -45,35 +327,79 @@
"+1.6% Lifesteal and Spell Vamp",
"+2.0% Lifesteal and Spell Vamp"
],
- "name": "Vampirism",
- "masteryTree": "Ferocity"
+ "image": {
+ "full": "6131.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 336,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
},
"6134": {
"id": 6134,
+ "name": "Natural Talent",
"description": [
- "+2 Attack Damage and 3 Ability Power at level 18 (.11 Attack Damage and .16 Ability Power per level)",
- "+4 Attack Damage and 6 Ability Power at level 18 (.22 Attack Damage and .32 Ability Power per level)",
- "+6 Attack Damage and 9 Ability Power at level 18 (.33 Attack Damage and .5 Ability Power per level)",
- "+8 Attack Damage and 12 Ability Power at level 18 (.44 Attack Damage and .66 Ability Power per level)",
- "+10 Attack Damage and 15 Ability Power at level 18 (.55 Attack Damage and .83 Ability Power per level)"
+ "+2 Attack Damage and 3 Ability Power at level 18 (0.11 Attack Damage and 0.16 Ability Power per level)",
+ "+4 Attack Damage and 6 Ability Power at level 18 (0.22 Attack Damage and 0.32 Ability Power per level)",
+ "+6 Attack Damage and 9 Ability Power at level 18 (0.33 Attack Damage and 0.5 Ability Power per level)",
+ "+8 Attack Damage and 12 Ability Power at level 18 (0.44 Attack Damage and 0.66 Ability Power per level)",
+ "+10 Attack Damage and 15 Ability Power at level 18 (0.55 Attack Damage and 0.83 Ability Power per level)"
],
- "name": "Natural Talent",
- "masteryTree": "Ferocity"
+ "image": {
+ "full": "6134.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 384,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
},
"6141": {
"id": 6141,
- "description": [ "You deal 1% increased damage for each unique enemy champion you kill." ],
"name": "Bounty Hunter",
- "masteryTree": "Ferocity"
+ "description": [
+ "Deal 1% increased damage for each unique enemy champion you have killed"
+ ],
+ "image": {
+ "full": "6141.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 432,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6142": {
"id": 6142,
- "description": [ "You deal 2.5% increased damage to targets with impaired movement (slow, stun, snare, taunt, etc.)." ],
"name": "Oppressor",
- "masteryTree": "Ferocity"
+ "description": [
+ "Deal 2.5% increased damage to targets with impaired movement (slow, stun, root, taunt, etc.)"
+ ],
+ "image": {
+ "full": "6142.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 0,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6151": {
"id": 6151,
+ "name": "Battering Blows",
"description": [
"+1.4% Armor Penetration",
"+2.8% Armor Penetration",
@@ -81,11 +407,21 @@
"+5.6% Armor Penetration",
"+7% Armor Penetration"
],
- "name": "Battering Blows",
- "masteryTree": "Ferocity"
+ "image": {
+ "full": "6151.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 48,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
},
"6154": {
"id": 6154,
+ "name": "Piercing Thoughts",
"description": [
"+1.4% Magic Penetration",
"+2.8% Magic Penetration",
@@ -93,101 +429,511 @@
"+5.6% Magic Penetration",
"+7% Magic Penetration"
],
- "name": "Piercing Thoughts",
- "masteryTree": "Ferocity"
+ "image": {
+ "full": "6154.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 96,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
},
"6161": {
"id": 6161,
- "description": [ "Critical strikes heal for 15% of the damage dealt and grant you 20% attack speed for 4 seconds (2 second cooldown)." ],
"name": "Warlord's Bloodlust",
- "masteryTree": "Ferocity"
+ "description": [
+ "Gain increasingly more Life Steal based on your missing health against champions (up to 20%). Against minions gain 50% benefit (25% for ranged champions)."
+ ],
+ "image": {
+ "full": "6161.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 144,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6162": {
"id": 6162,
- "description": [ "Your basic attacks and spells grant you a stack of Fervor for 5 seconds (max 10 stacks). Each stack of Fervor adds 1-8 bonus physical damage to your basic attacks against champions, based on your level." ],
"name": "Fervor of Battle",
- "masteryTree": "Ferocity"
+ "description": [
+ "You generate stacks of Fervor by hitting enemy champions with attacks and abilities. Your basic attacks deal 1-14 bonus physical damage (based on your level) to enemy champions for each of your stacks of Fervor (max 8 stacks).
Damaging enemy champions with an attack generates 1 stack of Fervor (2 for melee champions) and damaging enemy champions with an ability generates 2 stacks of Fervor (2 second cooldown). Stacks of Fervor last 6 seconds."
+ ],
+ "image": {
+ "full": "6162.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 192,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6164": {
"id": 6164,
- "description": [ "Your damaging abilities cause enemy champions to take 6 + 50% of your Bonus Attack Damage and 20% of your Ability Power in Magic damage over 3 seconds (Area of effect and damage over time abilities apply half of this damage over 1.5 seconds instead)." ],
"name": "Deathfire Touch",
- "masteryTree": "Ferocity"
+ "description": [
+ "Your damaging abilities cause enemy champions to take additional magic damage equal to 8 + 60% of your Bonus Attack Damage and 25% of your Ability Power, over 4 seconds.
Deathfire Touch has reduced effectiveness when applied by area of effect and damage over time abilities.
- Area of Effect: 2 second duration.
- Damage over time: 1 second duration."
+ ],
+ "image": {
+ "full": "6164.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 240,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6311": {
+ "id": 6311,
+ "name": "Wanderer",
+ "description": [
+ "+0.6% Movement Speed out of combat",
+ "+1.2% Movement Speed out of combat",
+ "+1.8% Movement Speed out of combat",
+ "+2.4% Movement Speed out of combat",
+ "+3% Movement Speed out of combat"
+ ],
+ "image": {
+ "full": "6311.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 0,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6312": {
+ "id": 6312,
+ "name": "Savagery",
+ "description": [
+ "Single target attacks and spells deal 1 bonus damage to minions and monsters",
+ "Single target attacks and spells deal 2 bonus damage to minions and monsters",
+ "Single target attacks and spells deal 3 bonus damage to minions and monsters",
+ "Single target attacks and spells deal 4 bonus damage to minions and monsters",
+ "Single target attacks and spells deal 5 bonus damage to minions and monsters"
+ ],
+ "image": {
+ "full": "6312.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 48,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6321": {
+ "id": 6321,
+ "name": "Runic Affinity",
+ "description": [
+ "Buffs from neutral monsters last 15% longer"
+ ],
+ "image": {
+ "full": "6321.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 96,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6322": {
+ "id": 6322,
+ "name": "Secret Stash",
+ "description": [
+ "Your Potions and Elixirs last 10% longer.
Your Health Potions are replaced with Biscuits that restore 15 Health and Mana instantly on use"
+ ],
+ "image": {
+ "full": "6322.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 144,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6323": {
+ "id": 6323,
+ "name": "Assassin",
+ "description": [
+ "Deal 2% increased damage to champions when no allied champions are nearby"
+ ],
+ "image": {
+ "full": "6323.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 288,
+ "y": 432,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6331": {
+ "id": 6331,
+ "name": "Merciless",
+ "description": [
+ "Deal 1% increased damage to champions below 40% Health",
+ "Deal 2% increased damage to champions below 40% Health",
+ "Deal 3% increased damage to champions below 40% Health",
+ "Deal 4% increased damage to champions below 40% Health",
+ "Deal 5% increased damage to champions below 40% Health"
+ ],
+ "image": {
+ "full": "6331.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 192,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6332": {
+ "id": 6332,
+ "name": "Meditation",
+ "description": [
+ "Regenerate 0.3% of your missing Mana every 5 seconds",
+ "Regenerate 0.6% of your missing Mana every 5 seconds",
+ "Regenerate 0.9% of your missing Mana every 5 seconds",
+ "Regenerate 1.2% of your missing Mana every 5 seconds",
+ "Regenerate 1.5% of your missing Mana every 5 seconds"
+ ],
+ "image": {
+ "full": "6332.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 240,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6342": {
+ "id": 6342,
+ "name": "Bandit",
+ "description": [
+ "Gain 1 gold for each nearby minion killed by an ally.
Gain 3 gold (10 if melee) when hitting an enemy champion with a basic attack (5 second cooldown)"
+ ],
+ "image": {
+ "full": "6342.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 288,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6343": {
+ "id": 6343,
+ "name": "Dangerous Game",
+ "description": [
+ "Champion kills and assists restore 5% of your missing Health and Mana"
+ ],
+ "image": {
+ "full": "6343.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 336,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6351": {
+ "id": 6351,
+ "name": "Precision",
+ "description": [
+ "Gain 0.6 + 0.06 per level Magic Penetration and Armor Penetration",
+ "Gain 1.2 + 0.12 per level Magic Penetration and Armor Penetration",
+ "Gain 1.8 + 0.18 per level Magic Penetration and Armor Penetration",
+ "Gain 2.4 + 0.24 per level Magic Penetration and Armor Penetration",
+ "Gain 3 + 0.3 per level Magic Penetration and Armor Penetration"
+ ],
+ "image": {
+ "full": "6351.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 384,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6352": {
+ "id": 6352,
+ "name": "Intelligence",
+ "description": [
+ "Your Cooldown Reduction cap is increased to 41% and you gain 1% Cooldown Reduction",
+ "Your Cooldown Reduction cap is increased to 42% and you gain 2% Cooldown Reduction",
+ "Your Cooldown Reduction cap is increased to 43% and you gain 3% Cooldown Reduction",
+ "Your Cooldown Reduction cap is increased to 44% and you gain 4% Cooldown Reduction",
+ "Your Cooldown Reduction cap is increased to 45% and you gain 5% Cooldown Reduction"
+ ],
+ "image": {
+ "full": "6352.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 432,
+ "y": 336,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
+ },
+ "6361": {
+ "id": 6361,
+ "name": "Stormraider's Surge",
+ "description": [
+ "Dealing 30% of a champion's max Health within 2.5 seconds grants you 40% Movement Speed and 75% Slow Resistance for 3 seconds (10 second cooldown)."
+ ],
+ "image": {
+ "full": "6361.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 0,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6362": {
+ "id": 6362,
+ "name": "Thunderlord's Decree",
+ "description": [
+ "Your 3rd attack or damaging spell against the same enemy champion calls down a lightning strike, dealing magic damage in the area.
Damage: 10 per level, plus 30% of your Bonus Attack Damage, and 10% of your Ability Power (25-15 second cooldown, based on level)."
+ ],
+ "image": {
+ "full": "6362.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 48,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
+ },
+ "6363": {
+ "id": 6363,
+ "name": "Windspeaker's Blessing",
+ "description": [
+ "Your heals and shields are 10% stronger. Additionally, your shields and heals on other allies increase their armor by 5-22 (based on level) and their magic resistance by half that amount for 3 seconds."
+ ],
+ "image": {
+ "full": "6363.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 96,
+ "y": 384,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6211": {
"id": 6211,
+ "name": "Recovery",
"description": [
- "+0.4 Health Regen per 5 seconds",
- "+0.8 Health Regen per 5 seconds",
- "+1.2 Health Regen per 5 seconds",
- "+1.6 Health Regen per 5 seconds",
- "+2.0 Health Regen per 5 seconds"
+ "+0.4 Health per 5 seconds",
+ "+0.8 Health per 5 seconds",
+ "+1.2 Health per 5 seconds",
+ "+1.6 Health per 5 seconds",
+ "+2.0 Health per 5 seconds"
],
- "name": "Recovery",
- "masteryTree": "Resolve"
+ "image": {
+ "full": "6211.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 336,
+ "y": 240,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
},
"6212": {
"id": 6212,
+ "name": "Unyielding",
"description": [
- "+1.2% Bonus Armor and Magic Resist",
- "+2.4% Bonus Armor and Magic Resist",
- "+3.6% Bonus Armor and Magic Resist",
- "+4.8% Bonus Armor and Magic Resist",
- "+6% Bonus Armor and Magic Resist"
+ "+1% Bonus Armor and Magic Resist",
+ "+2% Bonus Armor and Magic Resist",
+ "+3% Bonus Armor and Magic Resist",
+ "+4% Bonus Armor and Magic Resist",
+ "+5% Bonus Armor and Magic Resist"
],
- "name": "Unyielding",
- "masteryTree": "Resolve"
+ "image": {
+ "full": "6212.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 384,
+ "y": 240,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
},
"6221": {
"id": 6221,
- "description": [ "+12 Movement Speed in Brush and River" ],
"name": "Explorer",
- "masteryTree": "Resolve"
+ "description": [
+ "+15 Movement Speed in Brush and River"
+ ],
+ "image": {
+ "full": "6221.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 432,
+ "y": 240,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6223": {
"id": 6223,
- "description": [ "You take 2 less damage from Champion and Monster basic attacks." ],
"name": "Tough Skin",
- "masteryTree": "Resolve"
+ "description": [
+ "You take 2 less damage from champion and neutral monster basic attacks"
+ ],
+ "image": {
+ "full": "6223.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 0,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6231": {
"id": 6231,
+ "name": "Runic Armor",
"description": [
- "+1.6% bonus to all shields and healing on you (includes lifesteal and regeneration).",
- "+3.2% bonus to all shields and healing on you (includes lifesteal and regeneration)",
- "+4.8% bonus to all shields and healing on you (includes lifesteal and regeneration)",
- "+6.4% bonus to all shields and healing on you (includes lifesteal and regeneration)",
- "+8% bonus to all shields and healing on you (includes lifesteal and regeneration)"
+ "Shields, healing, regeneration, and lifesteal on you are 1.6% stronger",
+ "Shields, healing, regeneration, and lifesteal on you are 3.2% stronger",
+ "Shields, healing, regeneration, and lifesteal on you are 4.8% stronger",
+ "Shields, healing, regeneration, and lifesteal on you are 6.4% stronger",
+ "Shields, healing, regeneration, and lifesteal on you are 8% stronger"
],
- "name": "Runic Armor",
- "masteryTree": "Resolve"
+ "image": {
+ "full": "6231.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 48,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
},
"6232": {
"id": 6232,
+ "name": "Veteran's Scars",
"description": [
- "+0.8% Total Health",
- "+1.6% Total Health",
- "+2.4% Total Health",
- "+3.2% Total Health",
- "+4% Total Health"
+ "+9 Health",
+ "+18 Health",
+ "+27 Health",
+ "+36 Health",
+ "+45 Health"
],
- "name": "Veteran's Scars",
- "masteryTree": "Resolve"
+ "image": {
+ "full": "6232.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 96,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
},
"6241": {
"id": 6241,
- "description": [ "Your summoner spells have 15% reduced cooldown." ],
"name": "Insight",
- "masteryTree": "Resolve"
+ "description": [
+ "Reduces the cooldown of Summoner Spells by 15%"
+ ],
+ "image": {
+ "full": "6241.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 144,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6242": {
"id": 6242,
- "description": [ "+50% Health Regen, increased to +200% when below 20% Health" ],
"name": "Perseverance",
- "masteryTree": "Resolve"
+ "description": [
+ "+50% Base Health Regen, increased to +200% when below 25% Health"
+ ],
+ "image": {
+ "full": "6242.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 192,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6251": {
"id": 6251,
+ "name": "Swiftness",
"description": [
"+3% Tenacity and Slow Resist",
"+6% Tenacity and Slow Resist",
@@ -195,11 +941,21 @@
"+12% Tenacity and Slow Resist",
"+15% Tenacity and Slow Resist"
],
- "name": "Swiftness",
- "masteryTree": "Resolve"
+ "image": {
+ "full": "6251.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 240,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
},
"6252": {
"id": 6252,
+ "name": "Legendary Guardian",
"description": [
"+0.6 Armor and Magic Resist for each nearby enemy champion",
"+1.2 Armor and Magic Resist for each nearby enemy champion",
@@ -207,148 +963,71 @@
"+2.4 Armor and Magic Resist for each nearby enemy champion",
"+3 Armor and Magic Resist for each nearby enemy champion"
],
- "name": "Legendary Guardian",
- "masteryTree": "Resolve"
+ "image": {
+ "full": "6252.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 288,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 5,
+ "prereq": "0"
},
"6261": {
"id": 6261,
- "description": [ "Every 4 seconds in combat your next attack against an enemy champion steals life equal to 3% of your max Health (halved for ranged champions)." ],
"name": "Grasp of the Undying",
- "masteryTree": "Resolve"
+ "description": [
+ "Every 4 seconds in combat, your next attack against an enemy champion steals life equal to 2.5% of your max Health (halved for ranged champions, deals magic damage)"
+ ],
+ "image": {
+ "full": "6261.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 336,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6262": {
"id": 6262,
- "description": [ "Large monsters and siege minions that you or nearby allies kill grant you 20 and 10 permanent Health respectively (300 max). After reaching the max bonus further siege minion kills restore 100 Health." ],
"name": "Strength of the Ages",
- "masteryTree": "Resolve"
+ "description": [
+ "Siege minions and large monsters that you or nearby allied champions kill grant 20 and 10 permanent Health, respectively (300 max). After reaching the max bonus, these kills instead restore 6% of your Maximum Health."
+ ],
+ "image": {
+ "full": "6262.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 384,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
},
"6263": {
"id": 6263,
- "description": [ "+4% Damage Reduction. While near an ally this bonus is doubled and 8% of the damage they would take from champions is dealt to you instead (cannot reduce you below 15% Health)." ],
"name": "Bond of Stone",
- "masteryTree": "Resolve"
- },
- "6311": {
- "id": 6311,
- "description": [
- "+0.6% Movement Speed out of Combat",
- "+1.2% Movement Speed out of Combat",
- "+1.8% Movement Speed out of Combat",
- "+2.4% Movement Speed out of Combat",
- "+3% Movement Speed out of Combat"
- ],
- "name": "Wanderer",
- "masteryTree": "Cunning"
- },
- "6312": {
- "id": 6312,
"description": [
- "Basic attacks and single target spells deal 1 bonus damage to minions and monsters.",
- "Basic attacks and single target spells deal 2 bonus damage to minions and monsters.",
- "Basic attacks and single target spells deal 3 bonus damage to minions and monsters.",
- "Basic attacks and single target spells deal 4 bonus damage to minions and monsters.",
- "Basic attacks and single target spells deal 5 bonus damage to minions and monsters."
+ "+4% Damage Reduction. 6% of the damage from enemy champions taken by the nearest allied champion is dealt to you instead. Damage is not redirected if you are below 5% of your maximum health."
],
- "name": "Savagery",
- "masteryTree": "Cunning"
- },
- "6321": {
- "id": 6321,
- "description": [ "Buffs granted by jungle monsters last 15% longer, including Epic Monsters." ],
- "name": "Runic Affinity",
- "masteryTree": "Cunning"
- },
- "6322": {
- "id": 6322,
- "description": [ "Your potions, flasks, and elixirs last 10% longer. Additionally, your potions are replaced with biscuits that restore 20 Health and 10 Mana instantly upon consumption." ],
- "name": "Secret Stash",
- "masteryTree": "Cunning"
- },
- "6323": {
- "id": 6323,
- "description": [ "Deal 1.5% increased damage when no allied champions are nearby" ],
- "name": "Assassin",
- "masteryTree": "Cunning"
- },
- "6331": {
- "id": 6331,
- "description": [
- "Deal 1% increased damage to champions below 40% Health.",
- "Deal 2% increased damage to champions below 40% Health.",
- "Deal 3% increased damage to champions below 40% Health.",
- "Deal 4% increased damage to champions below 40% Health.",
- "Deal 5% increased damage to champions below 40% Health."
- ],
- "name": "Merciless",
- "masteryTree": "Cunning"
- },
- "6332": {
- "id": 6332,
- "description": [
- "Once every 5 seconds, regenerate 0.3% of your missing Mana.",
- "Once every 5 seconds, regenerate 0.6% of your missing Mana.",
- "Once every 5 seconds, regenerate 0.9% of your missing Mana.",
- "Once every 5 seconds, regenerate 1.2% of your missing Mana.",
- "Once every 5 seconds, regenerate 1.5% of your missing Mana."
- ],
- "name": "Meditation",
- "masteryTree": "Cunning"
- },
- "6342": {
- "id": 6342,
- "description": [ "Gain 1 gold for each nearby minions killed by allied champions. Gain an additional 3 gold (or 10 if you're melee) when hitting an enemy champion with an attack or spell (Cannot occur more than once every 5 seconds)." ],
- "name": "Bandit",
- "masteryTree": "Cunning"
- },
- "6343": {
- "id": 6343,
- "description": [ "Champion kills and assists restore 5% of your missing Health and Mana." ],
- "name": "Dangerous Game",
- "masteryTree": "Cunning"
- },
- "6351": {
- "id": 6351,
- "description": [
- "Gain 0.6 + 0.06 per level Armor and Magic Penetration.",
- "Gain 1.2 + 0.12 per level Armor and Magic Penetration.",
- "Gain 1.8 + 0.18 per level Armor and Magic Penetration.",
- "Gain 2.4 + 0.24 per level Armor and Magic Penetration.",
- "Gain 3 + 0.3 per level Armor and Magic Penetration."
- ],
- "name": "Precision",
- "masteryTree": "Cunning"
- },
- "6352": {
- "id": 6352,
- "description": [
- "Your Cooldown Reduction cap is increased by 1%, gain 1% Cooldown Reduction.",
- "Your Cooldown Reduction cap is increased by 2%, gain 2% Cooldown Reduction.",
- "Your Cooldown Reduction cap is increased by 3%, gain 3% Cooldown Reduction.",
- "Your Cooldown Reduction cap is increased by 4%, gain 4% Cooldown Reduction.",
- "Your Cooldown Reduction cap is increased by 5%, gain 5% Cooldown Reduction."
- ],
- "name": "Intelligence",
- "masteryTree": "Cunning"
- },
- "6361": {
- "id": 6361,
- "description": [ "Dealing 30% of a champion's max Health within 2 seconds grants you 35% Movement Speed for 3 seconds (10 second cooldown)." ],
- "name": "Stormraider's Surge",
- "masteryTree": "Cunning"
- },
- "6362": {
- "id": 6362,
- "description": [ "Your 3rd attack or spell on an enemy champion shocks the area around them, dealing 10 damage per level plus 20% of your Bonus Attack Damage and 10% of your Ability Power as Magic damage to enemies in the area (30 second cooldown)." ],
- "name": "Thunderlord's Decree",
- "masteryTree": "Cunning"
- },
- "6363": {
- "id": 6363,
- "description": [ "Your heals and shields are 10% stronger. Additionally, your shields and heals increase your target's resistances by 15% for 3 seconds when used on an ally other than yourself." ],
- "name": "Windspeaker's Blessing",
- "masteryTree": "Cunning"
+ "image": {
+ "full": "6263.png",
+ "sprite": "mastery0.png",
+ "group": "gray_mastery",
+ "x": 432,
+ "y": 288,
+ "w": 48,
+ "h": 48
+ },
+ "ranks": 1,
+ "prereq": "0"
}
- },
- "type": "mastery",
- "version": "5.22.3"
-}
+ }
+}
\ No newline at end of file
diff --git a/LoLMasteryManager/MasteryAssigner.vb b/LoLMasteryManager/MasteryAssigner.vb
index 7439856..696caa3 100644
--- a/LoLMasteryManager/MasteryAssigner.vb
+++ b/LoLMasteryManager/MasteryAssigner.vb
@@ -6,6 +6,8 @@ Public Class MasteryAssigner
Private _MasteryCoordinatesListFile As MasteryCoordinatesFile
Private _Mode As Modes = Modes.ChampionSelect
+ Private Const SleepTime As Integer = 100 '100 Works well for production, 250 for testing
+
Public Sub New(ByVal masteryCoordinatesPath As String)
Dim sJson As String
@@ -82,11 +84,11 @@ Public Class MasteryAssigner
Mouse.Move(oPosition)
- Threading.Thread.Sleep(100)
+ Threading.Thread.Sleep(SleepTime)
Mouse.LeftClick()
- Threading.Thread.Sleep(100)
+ Threading.Thread.Sleep(SleepTime)
Catch ex As Exception
@@ -110,11 +112,11 @@ Public Class MasteryAssigner
Mouse.Move(oPosition)
- Threading.Thread.Sleep(100)
+ Threading.Thread.Sleep(SleepTime)
Mouse.LeftClick()
- Threading.Thread.Sleep(100)
+ Threading.Thread.Sleep(SleepTime)
Catch ex As Exception
@@ -138,11 +140,11 @@ Public Class MasteryAssigner
Mouse.Move(oPosition)
- Threading.Thread.Sleep(100)
+ Threading.Thread.Sleep(SleepTime)
Mouse.LeftClick()
- Threading.Thread.Sleep(100)
+ Threading.Thread.Sleep(SleepTime)
Catch ex As Exception
@@ -200,7 +202,7 @@ Public Class MasteryAssigner
Mouse.Move(oMasteryPosition)
' Sleep the thread to ensure the mouse has time to move
- Threading.Thread.Sleep(100)
+ Threading.Thread.Sleep(SleepTime)
' If the mastery has all of the points for that row
If mastery.Ranks = 5 Then
@@ -209,7 +211,7 @@ Public Class MasteryAssigner
Mouse.LeftClick()
' Sleep the thread to ensure the click has time to complete
- Threading.Thread.Sleep(100)
+ Threading.Thread.Sleep(SleepTime)
Else ' Points shared between both masteries on the row
@@ -220,7 +222,7 @@ Public Class MasteryAssigner
Mouse.LeftClick()
' Sleep the thread to ensure the click has time to complete
- Threading.Thread.Sleep(100)
+ Threading.Thread.Sleep(SleepTime)
Next iRank ' Loop through the mastery ranks
diff --git a/LoLMasteryManager/MasteryManager.vb b/LoLMasteryManager/MasteryManager.vb
index 78e7191..850fb31 100644
--- a/LoLMasteryManager/MasteryManager.vb
+++ b/LoLMasteryManager/MasteryManager.vb
@@ -39,6 +39,8 @@ Public Class MasteryManager
Private _Champions As New List(Of Champion)
Private _MasteryPages As New List(Of MasteryPage)
+ Private Const SleepTime As Integer = 100 '100 Works well for production, 250 for testing
+
Public Property PatchNumber As String
Public Sub New()
@@ -101,7 +103,7 @@ Public Class MasteryManager
While _LoadingWindow Is Nothing OrElse Not _LoadingWindow.IsHandleCreated
- Thread.Sleep(100)
+ Thread.Sleep(SleepTime)
End While
diff --git a/LoLMasteryManager/Models/Riot.vb b/LoLMasteryManager/Models/Riot.vb
index 10c8574..da4a00b 100644
--- a/LoLMasteryManager/Models/Riot.vb
+++ b/LoLMasteryManager/Models/Riot.vb
@@ -77,9 +77,6 @@ Public Class RiotMastery
Public ID As Integer
-
- Public Tree As String
-
Public Name As String