diff --git a/HKCheckCompletion.js b/HKCheckCompletion.js
index c576a4f..d7360cb 100644
--- a/HKCheckCompletion.js
+++ b/HKCheckCompletion.js
@@ -209,13 +209,13 @@ const HK_DREAMNAIL = {
};
const HK_EQUIPMENT = {
- hasDash: ["Mothwing Cloak", "Greenpath; Dash ability"],
- hasWalljump: ["Mantis Claw", "Mantis Village; Wall Jump ability"],
- hasSuperDash: ["Crystal Heart", "Crystal Peak; Super Dash ability"],
- hasAcidArmour: ["Isma's Tear", "Royal Waterways; Acid Armour ability"],
- hasDoubleJump: ["Monarch Wings", "Ancient Basin; Double Jump ability"],
+ hasDash: ["Mothwing Cloak", "Greenpath: Dash ability"],
+ hasWalljump: ["Mantis Claw", "Mantis Village: Wall Jump ability"],
+ hasSuperDash: ["Crystal Heart", "Crystal Peak: Super Dash ability"],
+ hasDoubleJump: ["Monarch Wings", "Ancient Basin: Double Jump ability"],
+ hasAcidArmour: ["Isma's Tear", "Royal Waterways: Acid Armour ability"],
hasKingsBrand: ["King's Brand", "Kingdom's Edge"],
- hasShadowDash: ["Shade Cloak", "The Abyss; Shadow Dash ability"]
+ hasShadowDash: ["Shade Cloak", "The Abyss: Shadow Dash ability"]
};
const HK_MASKSHARDS = {
@@ -321,7 +321,7 @@ const HK_GODMASTER_DOORS = [
/**
* Checks Hollow Knight game completion by analyzing the save file
- * @param {object} jsonObject Save data in JavaScript Object form
+ * @param {object} jsonObject Decoded save data in JavaScript Object Notation form (JSON)
*/
function HKCheckCompletion(jsonObject) {
@@ -332,7 +332,7 @@ function HKCheckCompletion(jsonObject) {
CheckboxHintsToggle("hide");
CheckboxLocationsToggle("hide");
- // Pre-Cleaning and filling initial data
+ // Pre-Cleaning and filling initial data (h2, id) needed for FillHTML()
PrefillHTML(DIV_ID);
// Shallow Clone const objects (used for destructive functions)
@@ -558,14 +558,14 @@ function CheckPlayTime(divId, playTime) {
* @param {object} playerData Reference/pointer to specific data where to search
*/
function CheckCompletionPercent(divId, playerData) {
-
+
let textFill = "";
CurrentDataFalse();
for (let i in playerData) {
if (i === "completionPercentage") {
if (playerData[i] >= 112) CurrentDataTrue();
-
+
textFill = "Game Completion: " + playerData[i] + " % (out of " + divId.maxPercent + " %)";
document.getElementById(divId.id).innerHTML += divStart + completionSymbol + textFill + divEnd;
}
@@ -656,92 +656,66 @@ function CheckWorldDataTrue(divId, idText, dataObject, worldData) {
* @param {object} worldData object containing HK World Data to look in
*/
function CheckHintsTrue(divId, dataObject, playerData, worldData) {
- let hollowKnightDefeated = false;
for (let i in dataObject) {
- CurrentDataFalse();
-
if (playerData[i] === true) {
if (i === "killedHollowKnight") {
- hollowKnightDefeated = true;
+ // a text to show when player already finished their first playthrough (killed Hollow Knight first time)
+ FillHTML(divId, "", "...a successful Knight who doesn't need hints anymore");
break;
}
- CurrentDataTrue();
continue;
} else if (i === "fireballLevel") {
if (playerData[i] >= 1) {
- CurrentDataTrue();
continue;
} else {
- CurrentDataFalse();
FillHTML(divId, dataObject[i][0], dataObject[i][1]);
break;
}
} else if (i === "Crossroads_04") {
+ let GruzMotherDefeated = false;
+
for (let k = 0, length = worldData.length; k < length; k++) {
if (worldData[k].id === "Battle Scene" && worldData[k].sceneName === "Crossroads_04" && worldData[k].activated === true) {
- CurrentDataTrue();
+ GruzMotherDefeated = true;
break;
}
}
- if (completionSymbol === SYMBOL_FALSE) {
+ if (GruzMotherDefeated) {
+ continue; // next dataObject (i)
+ } else {
FillHTML(divId, dataObject[i][0], dataObject[i][1]);
+ break;
}
} else if (i === "dungDefenderOrHornet2") {
- for (let k in playerData) {
- if (k === "defeatedDungDefender" && playerData[k] === true) {
- CurrentDataTrue();
- break;
- } else if (k === "hornetOutskirtsDefeated" && playerData[k] === true) {
- CurrentDataTrue();
- break;
- } else if ((k === "defeatedDungDefender" && playerData[k] === false) &&
- (k === "hornetOutskirtsDefeated" && playerData[k] === false)) {
- CurrentDataFalse();
+ if (playerData.defeatedDungDefender === true) {
+ continue;
+ } else if (playerData.hornetOutskirtsDefeated === true) {
+ continue;
+ } else { // if no Dung Defender or Hornet 2
+ FillHTML(divId, dataObject[i][0], dataObject[i][1]);
+ break;
+ }
+ } else if (i === "ismaTearOrShadeCloak") {
+ if (playerData.hasAcidArmour === true) {
+ continue;
+ } else if (playerData.hasKingsBrand === true) {
+ if (playerData.hasShadowDash === true) {
+ continue;
+ } else { // if Kings Brand but no Shade Cloak
FillHTML(divId, dataObject[i][0], dataObject[i][1]);
break;
}
+ } else { // if no Isma's Tear or Kings Brand
+ FillHTML(divId, dataObject[i][0], dataObject[i][1]);
+ break;
}
- } else if (i === "ismaTearOrShadeCloak") {
- for (let k in playerData) {
- if (k === "hasAcidArmour") {
- if (playerData[k] === true) {
- CurrentDataTrue();
- break;
- }
- } else if (k === "hasKingsBrand") {
- if (playerData[k] === true) {
- for (let l in playerData) {
- if (l === "hasShadowDash") {
- if (playerData[l] === true) {
- CurrentDataTrue();
- break;
- } else {
- CurrentDataFalse();
- FillHTML(divId, dataObject[i][0], dataObject[i][1]);
- break;
- }
- }
- }
- } else {
- CurrentDataFalse();
- FillHTML(divId, dataObject[i][0], dataObject[i][1]);
- break;
- }
- }
- }
- } else {
- CurrentDataFalse();
+ } else { // if anything from the hints list is not done
FillHTML(divId, dataObject[i][0], dataObject[i][1]);
break;
}
} // end: for (let i in dataObject)
-
- // prevents showing hints when player already has seen the credits
- if (hollowKnightDefeated) {
- FillHTML(divId, "", "...a successful Knight who doesn't need hints anymore");
- }
-}
+} // function CheckHintsTrue()
/**
* Pre-Cleans HTML. Reads contents inside text area and parses it to a JavaScript object. If not empty, runs HKCheckCompletion() to check data.
diff --git a/favicon.png b/favicon.png
new file mode 100644
index 0000000..6ebf7d6
Binary files /dev/null and b/favicon.png differ
diff --git a/index.html b/index.html
index 307024e..e5b6ccf 100644
--- a/index.html
+++ b/index.html
@@ -4,21 +4,21 @@
-
+
-
Hollow Knight Completion Check Tool
+ Hollow Knight: Analyze Save Completion
-
+
-
+
@@ -28,12 +28,11 @@
- Calculate all % in all categories from save data
- Single Pale Ore locations? (required for completion)
- Single Keys/Pass locations? (required for completion)
- - CheckHintsTrue optimize algorithm
-->
-
Hollow Knight Completion % Check
+
Hollow Knight Analyze Save Completion
Check what you have left for completion. Hints for first playthrough.
Use bloodorca's amazing [ Online Hollow Knight Save Editor ] to decode your save file.
diff --git a/loadJson.js b/loadJson.js
index 468482c..c348dbb 100644
--- a/loadJson.js
+++ b/loadJson.js
@@ -44,7 +44,7 @@ function loadJSON(filename, callback) {
xobj.send(null);
}
-loadJSON("save/" + fileName[5],
+loadJSON("save/" + fileName[9],
function JSONparse(response) {
// Parse JSON string into object
jsonObj = JSON.parse(response);
diff --git a/style.css b/style.css
index 0f1fa37..7e793d9 100644
--- a/style.css
+++ b/style.css
@@ -31,6 +31,7 @@ body {
}
b {
font-weight: 500;
+ color: #1e406c;
}
strong {
font-weight: 700;
@@ -40,7 +41,8 @@ strong {
margin: 0 auto;
}
h1 {
- font-size: 1.9rem;
+ font-size: 1.7rem;
+ color: #1e406c;
margin: 0.6rem 0;
}
#h1-title {
@@ -82,7 +84,7 @@ h1 {
}
h2 {
margin: 0.6rem 0;
- color: #737373;
+ color: #6f7583;
}
p {
margin-top: 0.6rem;
@@ -110,12 +112,13 @@ p {
a,
a:active,
a:visited {
- color: black;
+ color: #1e406c;
font-weight: 700;
text-decoration: none;
}
a:hover {
- text-decoration: underline;
+ color: #529dff;
+ text-decoration: none;
}
.icon-cancel {
color: #f03a17;
@@ -194,6 +197,12 @@ input[type="radio"]
background-color: #1e406c;
background-color: var(--rt-main);
}
+/* When the checkbox is checked change background color on hover */
+.radio-label:hover input:checked ~ .radiomark,
+.checkbox-label:hover input:checked ~ .checkmark
+{
+ background-color: #285188;
+}
/* Create the checkmark/indicator (hidden when not checked) */
.radiomark:after,
.checkmark:after