├── img ├── favicon.ico ├── favicon-152.png └── pinned-tab-icon.svg ├── README.md ├── License.md ├── js ├── jquery.highlight.js └── main.js ├── css └── main.css └── index.html /img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZKjellberg/sekiro-cheat-sheet/HEAD/img/favicon.ico -------------------------------------------------------------------------------- /img/favicon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZKjellberg/sekiro-cheat-sheet/HEAD/img/favicon-152.png -------------------------------------------------------------------------------- /img/pinned-tab-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sekiro Cheat Sheet 2 | 3 | To view the cheat sheet [click here](https://zkjellberg.github.io/sekiro-cheat-sheet) 4 | 5 | ## Contribution Guide 6 | 7 | If you are interested in contributing to this guide, I welcome Pull Requests on GitHub. 8 | 9 | **NOTE: This guide is currently in its early phases and will be evolving quickly.** 10 | 11 | For some background on how the guide code is written, here is a sample item on the checklist: 12 | 13 | ```html 14 |
  • Continue left until you can enter a room with a Large Soul of a Nameless Soldier and a Raw Gem
  • 15 | ``` 16 | 17 | The **data-id** is a unique ID used to store the user's progress. For example, ***playthrough_13_20*** is the 20th task in zone 13. New data-ids must be used in ascending order, but you can place the new entries anywhere within a zone. 18 | 19 | The **class="f_gem f_misc"** field is used for the filtering system. This task provides the user with a gem and a consumable, so we use **f_gem** and **f_misc**. This is a feature from the Dark Souls guide and will be revamped as the walkthrough is built. -------------------------------------------------------------------------------- /License.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Zachary Kjellberg 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /js/jquery.highlight.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Highlight plugin 3 | * 4 | * Based on highlight v3 by Johann Burkard 5 | * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html 6 | * 7 | * Code a little bit refactored and cleaned (in my humble opinion). 8 | * Most important changes: 9 | * - has an option to highlight only entire words (wordsOnly - false by default), 10 | * - has an option to be case sensitive (caseSensitive - false by default) 11 | * - highlight element tag and class names can be specified in options 12 | * 13 | * Usage: 14 | * // wrap every occurrance of text 'lorem' in content 15 | * // with (default options) 16 | * $('#content').highlight('lorem'); 17 | * 18 | * // search for and highlight more terms at once 19 | * // so you can save some time on traversing DOM 20 | * $('#content').highlight(['lorem', 'ipsum']); 21 | * $('#content').highlight('lorem ipsum'); 22 | * 23 | * // search only for entire word 'lorem' 24 | * $('#content').highlight('lorem', { wordsOnly: true }); 25 | * 26 | * // don't ignore case during search of term 'lorem' 27 | * $('#content').highlight('lorem', { caseSensitive: true }); 28 | * 29 | * // wrap every occurrance of term 'ipsum' in content 30 | * // with 31 | * $('#content').highlight('ipsum', { element: 'em', className: 'important' }); 32 | * 33 | * // remove default highlight 34 | * $('#content').unhighlight(); 35 | * 36 | * // remove custom highlight 37 | * $('#content').unhighlight({ element: 'em', className: 'important' }); 38 | * 39 | * 40 | * Copyright (c) 2009 Bartek Szopka 41 | * 42 | * Licensed under MIT license. 43 | * 44 | */ 45 | 46 | jQuery.extend({ 47 | highlight: function (node, re, nodeName, className) { 48 | if (node.nodeType === 3) { 49 | var match = node.data.match(re); 50 | if (match) { 51 | var highlight = document.createElement(nodeName || 'span'); 52 | highlight.className = className || 'highlight'; 53 | var wordNode = node.splitText(match.index); 54 | wordNode.splitText(match[0].length); 55 | var wordClone = wordNode.cloneNode(true); 56 | highlight.appendChild(wordClone); 57 | wordNode.parentNode.replaceChild(highlight, wordNode); 58 | return 1; //skip added node in parent 59 | } 60 | } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children 61 | !/(script|style)/i.test(node.tagName) && // ignore script and style nodes 62 | !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted 63 | for (var i = 0; i < node.childNodes.length; i++) { 64 | i += jQuery.highlight(node.childNodes[i], re, nodeName, className); 65 | } 66 | } 67 | return 0; 68 | } 69 | }); 70 | 71 | jQuery.fn.unhighlight = function (options) { 72 | var settings = { className: 'highlight', element: 'span' }; 73 | jQuery.extend(settings, options); 74 | 75 | return this.find(settings.element + "." + settings.className).each(function () { 76 | var parent = this.parentNode; 77 | parent.replaceChild(this.firstChild, this); 78 | parent.normalize(); 79 | }).end(); 80 | }; 81 | 82 | jQuery.fn.highlight = function (words, options) { 83 | var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false }; 84 | jQuery.extend(settings, options); 85 | 86 | if (words.constructor === String) { 87 | words = [words]; 88 | } 89 | words = jQuery.grep(words, function(word, i){ 90 | return word != ''; 91 | }); 92 | words = jQuery.map(words, function(word, i) { 93 | return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 94 | }); 95 | if (words.length == 0) { return this; }; 96 | 97 | var flag = settings.caseSensitive ? "" : "i"; 98 | var pattern = "(" + words.join("|") + ")"; 99 | if (settings.wordsOnly) { 100 | pattern = "\\b" + pattern + "\\b"; 101 | } 102 | var re = new RegExp(pattern, flag); 103 | 104 | return this.each(function () { 105 | jQuery.highlight(this, re, settings.element, settings.className); 106 | }); 107 | }; 108 | 109 | -------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | .in_progress, 2 | .done { 3 | color: #C60; 4 | border: 1px solid; 5 | border-radius: 3px; 6 | padding: .1em 0.4em; 7 | font-weight: normal; 8 | margin-left: .2em; 9 | vertical-align: middle; 10 | font-size: 0.9em; 11 | } 12 | .done { color: #009933; } 13 | 14 | @media print { 15 | body { color: #000; } 16 | .navbar, #intro, input[type="checkbox"], .done, .in_progress { display: none; } 17 | a { color: #000; text-decoration: underline; } 18 | a[href]:after { content: none !important; } 19 | .tab-content > .tab-pane, .pill-content > .pill-pane { display: block; } 20 | .tab-pane { page-break-after: always; } 21 | } 22 | 23 | ul { 24 | list-style-type: none; 25 | padding-left: 22px; 26 | } 27 | ul li ul { 28 | padding-top: 0; 29 | } 30 | h3 { 31 | margin-bottom: 0; 32 | } 33 | .checkbox label, 34 | .radio label { 35 | padding-left: 24px; 36 | } 37 | .checkbox input[type=checkbox], 38 | .checkbox-inline input[type=checkbox], 39 | .radio input[type=radio], 40 | .radio-inline input[type=radio] { 41 | margin-left: -24px; 42 | } 43 | 44 | .table_of_contents { 45 | margin-left: 0; 46 | padding: 0; 47 | line-height: 1.8; 48 | } 49 | 50 | .highlight { 51 | background-color: rgb(255, 246, 18); 52 | } 53 | 54 | .hiddenfile { 55 | width: 0px; 56 | height: 0px; 57 | overflow: hidden; 58 | } 59 | 60 | .btn.fadingbutton { 61 | border-bottom-right-radius: 0; 62 | border-bottom-left-radius: 0; 63 | border-bottom: 0; 64 | position: fixed; 65 | display: none; 66 | z-index: 1; 67 | bottom: 0; 68 | /* The "Paper" bootstrap theme modifies the transition properties; 69 | reset them to the default value to prevent ruining the fadeIn() */ 70 | -webkit-transition: all 0s ease 0s; 71 | -o-transition: all 0s ease 0s; 72 | transition: all 0s ease 0s; 73 | } 74 | .fadingbutton.back-to-top { 75 | border-top-right-radius: 0; 76 | border-right: 0; 77 | right: 0; 78 | } 79 | .fadingbutton.togglehide { 80 | border-top-left-radius: 0; 81 | border-left: 0; 82 | left: 0; 83 | } 84 | 85 | .btn-collapse { 86 | padding: 4px 10px 1px; 87 | margin-right: 10px; 88 | vertical-align: top; 89 | } 90 | 91 | .btn:focus, .btn.active:focus { 92 | outline: none; 93 | outline: 0; 94 | } 95 | 96 | /* Icon when the collapsible content is shown */ 97 | .btn-collapse:after { 98 | font-family: 'Glyphicons Halflings'; 99 | content:"\e082"; 100 | } 101 | /* Icon when the collapsible content is hidden */ 102 | .btn-collapse.collapsed:after { 103 | content:"\e081"; 104 | } 105 | 106 | h1 { 107 | margin-top: 0; 108 | margin-bottom: 20px; 109 | } 110 | 111 | body.hide_completed .completed { 112 | display: none !important; 113 | } 114 | 115 | input[type="checkbox"]:checked + .item_content { 116 | text-decoration: line-through; 117 | } 118 | 119 | input[type="checkbox"] ~ .glyphicon-eye-close, 120 | input[type="checkbox"] ~ * > .glyphicon-eye-close, 121 | input[type="checkbox"]:checked ~ .glyphicon-eye-open, 122 | input[type="checkbox"]:checked ~ * > .glyphicon-eye-open { 123 | display: none; 124 | } 125 | input[type="checkbox"] ~ .glyphicon-eye-open, 126 | input[type="checkbox"] ~ * > .glyphicon-eye-open, 127 | input[type="checkbox"]:checked ~ .glyphicon-eye-close, 128 | input[type="checkbox"]:checked ~ * > .glyphicon-eye-close { 129 | display: inline-block; 130 | } 131 | 132 | textarea#profileText { 133 | height: 15em; 134 | resize: vertical; 135 | } 136 | 137 | /* Work around what seems to be a bootstrap bug affecting the hover border on the right side of the add profile button */ 138 | .input-group-btn:last-child>.btn:focus, 139 | .input-group-btn:last-child>.btn:hover { 140 | z-index: 3; 141 | } 142 | 143 | /* Decorators for NG+/NG++ entries */ 144 | .s_ng\+ .item_content:before { 145 | content: "[NG+: "; 146 | } 147 | .s_ng\+\+ .item_content:before { 148 | content: "[NG++: "; 149 | } 150 | .s_ng\+ .item_content:after, 151 | .s_ng\+\+ .item_content:after { 152 | content: "]"; 153 | } 154 | 155 | /* Styling for checklist filter categories and toggles */ 156 | .btn-group.btn-group-vertical > .btn-group:not(:first-child) > .btn-group-vertical { 157 | left: 0; 158 | top: 100%; 159 | display: none; 160 | position: absolute; 161 | } 162 | .btn-group.btn-group-vertical:hover > .btn-group:not(:first-child) > .btn-group-vertical { 163 | display: block; 164 | } 165 | .btn-group.btn-group-vertical > .btn-group:first-child > .btn-group-vertical.open > .btn { 166 | z-index: 1; 167 | } 168 | .btn-group.btn-group-vertical > .btn-group:not(:first-child) > .btn-group-vertical > .btn { 169 | z-index: 3; 170 | text-align: left; 171 | } 172 | .btn-group.btn-group-vertical > .btn-group:not(:first-child) > .btn-group-vertical > .btn:hover { 173 | z-index: 4; 174 | } 175 | .btn-group.btn-group-vertical:not(:last-child) > .btn-group:first-child > .btn-group-vertical > .btn { 176 | border-top-right-radius: 0; 177 | border-bottom-right-radius: 0; 178 | } 179 | .btn-group.btn-group-vertical:not(:first-child) > .btn-group:first-child > .btn-group-vertical > .btn, 180 | .btn-group.btn-group-vertical > .btn-group:not(:first-child) > .btn-group-vertical > .btn:first-child { 181 | border-top-left-radius: 0; 182 | } 183 | .btn-group.btn-group-vertical:not(:first-child) > .btn-group:first-child > .btn-group-vertical > .btn, 184 | .btn-group.btn-group-vertical:first-child:hover > .btn-group:first-child > .btn-group-vertical > .btn { 185 | border-bottom-left-radius: 0; 186 | } 187 | -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | var profilesKey = 'sekiro_profiles'; 2 | 3 | (function($) { 4 | 'use strict'; 5 | 6 | var themes = { 7 | "Standard" : "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css", 8 | "Cosmo" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/cosmo/bootstrap.min.css", 9 | "Cyborg" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/cyborg/bootstrap.min.css", 10 | "Darkly" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/darkly/bootstrap.min.css", 11 | "Flatly" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/flatly/bootstrap.min.css", 12 | "Journal" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/journal/bootstrap.min.css", 13 | "Lumen" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/lumen/bootstrap.min.css", 14 | "Paper" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/paper/bootstrap.min.css", 15 | "Readable" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/readable/bootstrap.min.css", 16 | "Sandstone" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/sandstone/bootstrap.min.css", 17 | "Simplex" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/simplex/bootstrap.min.css", 18 | "Slate" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/slate/bootstrap.min.css", 19 | "Spacelab" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/spacelab/bootstrap.min.css", 20 | "Superhero" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/superhero/bootstrap.min.css", 21 | "United" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/united/bootstrap.min.css", 22 | "Yeti" : "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/yeti/bootstrap.min.css" 23 | }; 24 | 25 | var profiles = $.jStorage.get(profilesKey, {}); 26 | 27 | /// assure default values are set 28 | /// necessary 'cause we're abusing local storage to store JSON data 29 | /// done in a more verbose way to be easier to understand 30 | if (!('current' in profiles)) profiles.current = 'Default Profile'; 31 | if (!(profilesKey in profiles)) profiles[profilesKey] = {}; 32 | initializeProfile(profiles.current); 33 | 34 | jQuery(document).ready(function($) { 35 | // Get the right style going... 36 | themeSetup(buildThemeSelection()); 37 | 38 | $('ul li[data-id]').each(function() { 39 | addCheckbox(this); 40 | }); 41 | 42 | // Open external links in new tab 43 | $("a[href^='http']").attr('target','_blank'); 44 | 45 | populateProfiles(); 46 | 47 | $('.checkbox input[type="checkbox"]').click(function() { 48 | var id = $(this).attr('id'); 49 | var isChecked = profiles[profilesKey][profiles.current].checklistData[id] = $(this).prop('checked'); 50 | if (isChecked === true) { 51 | $('[data-id="'+id+'"] label').addClass('completed'); 52 | } else { 53 | $('[data-id="'+id+'"] label').removeClass('completed'); 54 | } 55 | $.jStorage.set(profilesKey, profiles); 56 | calculateTotals(); 57 | }); 58 | 59 | // Theme callback 60 | $('#themes').change(function(event) { 61 | var stylesheet = $('#themes').val(); 62 | themeSetup(stylesheet); 63 | $.jStorage.set("style", stylesheet); 64 | }); 65 | 66 | $('#profiles').change(function(event) { 67 | profiles.current = $(this).val(); 68 | $.jStorage.set(profilesKey, profiles); 69 | 70 | $('li .checkbox .completed').show(); 71 | 72 | populateChecklists(); 73 | 74 | restoreState(profiles.current); 75 | 76 | calculateTotals(); 77 | }); 78 | 79 | $('#profileAdd').click(function() { 80 | $('#profileModalTitle').html('Add Profile'); 81 | $('#profileModalName').val(''); 82 | $('#profileModalAdd').show(); 83 | $('#profileModalUpdate').hide(); 84 | $('#profileModalDelete').hide(); 85 | $('#profileModal').modal('show'); 86 | }); 87 | 88 | $('#profileEdit').click(function() { 89 | $('#profileModalTitle').html('Edit Profile'); 90 | $('#profileModalName').val(profiles.current); 91 | $('#profileModalAdd').hide(); 92 | $('#profileModalUpdate').show(); 93 | if (canDelete()) { 94 | $('#profileModalDelete').show(); 95 | } else { 96 | $('#profileModalDelete').hide(); 97 | } 98 | $('#profileModal').modal('show'); 99 | }); 100 | 101 | $('#profileModalAdd').click(function(event) { 102 | event.preventDefault(); 103 | var profile = $.trim($('#profileModalName').val()); 104 | if (profile.length > 0) { 105 | initializeProfile(profile); 106 | 107 | profiles.current = profile; 108 | $.jStorage.set(profilesKey, profiles); 109 | populateProfiles(); 110 | populateChecklists(); 111 | restoreState(profiles.current); 112 | } 113 | }); 114 | 115 | $('#profileModalUpdate').click(function(event) { 116 | event.preventDefault(); 117 | var newName = $.trim($('#profileModalName').val()); 118 | if (newName.length > 0 && newName != profiles.current) { 119 | profiles[profilesKey][newName] = profiles[profilesKey][profiles.current]; 120 | delete profiles[profilesKey][profiles.current]; 121 | profiles.current = newName; 122 | $.jStorage.set(profilesKey, profiles); 123 | populateProfiles(); 124 | } 125 | $('#profileModal').modal('hide'); 126 | }); 127 | 128 | $('#profileModalDelete').click(function(event) { 129 | event.preventDefault(); 130 | if (!canDelete()) { 131 | return; 132 | } 133 | if (!confirm('Are you sure?')) { 134 | return; 135 | } 136 | delete profiles[profilesKey][profiles.current]; 137 | profiles.current = getFirstProfile(); 138 | $.jStorage.set(profilesKey, profiles); 139 | populateProfiles(); 140 | populateChecklists(); 141 | restoreState(profiles.current); 142 | $('#profileModal').modal('hide'); 143 | }); 144 | 145 | $('#profileNG\\+').click(function() { 146 | $('#NG\\+Modal').modal('show'); 147 | }); 148 | 149 | $('#NG\\+ModalYes').click(function(event) { 150 | event.preventDefault(); 151 | if (!confirm('Are you sure you wish to begin the next journey?')) { 152 | return; 153 | } 154 | $('[id^="playthrough_"], [id^="crow_"]').filter(':checked').each(function(){ 155 | profiles[profilesKey][profiles.current].checklistData[this.id] = false; 156 | }); 157 | $.each(profiles[profilesKey][profiles.current].hidden_categories, function(f){ 158 | profiles[profilesKey][profiles.current].hidden_categories[f] = false; 159 | }); 160 | if (profiles[profilesKey][profiles.current].journey < 3) { 161 | profiles[profilesKey][profiles.current].journey++; 162 | } 163 | $.jStorage.set(profilesKey, profiles); 164 | populateChecklists(); 165 | restoreState(profiles.current); 166 | $('#NG\\+Modal').modal('hide'); 167 | }); 168 | 169 | $('#profileExport').click(function(){ 170 | var filename = 'profiles.json'; 171 | var text = JSON.stringify(profiles); 172 | if (window.Blob && window.navigator.msSaveBlob) { 173 | // Microsoft browsers (https://docs.microsoft.com/en-us/microsoft-edge/dev-guide/html5/file-api/blob) 174 | var blob = new window.Blob([text]); 175 | window.navigator.msSaveBlob(blob, filename); 176 | } else { 177 | // All other modern browsers 178 | var element = document.createElement('a'); 179 | element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); 180 | element.setAttribute('download', filename); 181 | element.style.display = 'none'; 182 | document.body.appendChild(element); 183 | element.click(); 184 | document.body.removeChild(element); 185 | } 186 | }); 187 | 188 | $('#profileImport').click(function(){ 189 | $('#fileInput').trigger('click'); 190 | }); 191 | /* Will reject if an incorrect file or no file is selected */ 192 | $('input#fileInput').change(function(){ 193 | var fileInput = document.getElementById('fileInput'); 194 | if(!fileInput.files || !fileInput.files[0] || !/\.json$/.test(fileInput.files[0].name)){ 195 | alert("Bad input file. File should end in .json") 196 | return; 197 | } 198 | var fr = new FileReader(); 199 | fr.readAsText(fileInput.files[0]); 200 | fr.onload = dataLoadCallback; 201 | }); 202 | 203 | /* 204 | * Import & Export using textarea instead of files 205 | */ 206 | $('#profileExportText').click(function(){ 207 | document.getElementById("profileText").value = JSON.stringify(profiles); 208 | document.getElementById("profileText").select(); 209 | document.execCommand("copy"); 210 | }); 211 | 212 | $('#profileImportText').click(function(){ 213 | if (!confirm('Are you sure you want to import profile data?')) { 214 | return; 215 | } 216 | try { 217 | var jsonProfileData = JSON.parse(document.getElementById("profileText").value); 218 | profiles = jsonProfileData; 219 | $.jStorage.set(profilesKey, profiles); 220 | populateProfiles(); 221 | populateChecklists(); 222 | $('#profiles').trigger("change"); 223 | location.reload(); 224 | } catch(e) { 225 | alert(e); // error in the above string (in this case, yes)! 226 | } 227 | }); 228 | 229 | $("#toggleHideCompleted").change(function() { 230 | // Store information about the old scroll position 231 | var oldPos = $(window).scrollTop(); 232 | var labels = $('ul>li>div>label:visible:not(.completed)'); 233 | var oldOff = labels.map(function(){return $(this).offset().top}); 234 | 235 | var hidden = !$(this).is(':checked'); 236 | 237 | $('body').toggleClass('hide_completed', !hidden); 238 | 239 | profiles[profilesKey][profiles.current].hide_completed = !hidden; 240 | $.jStorage.set(profilesKey, profiles); 241 | 242 | // Try to find a reasonable new scroll position 243 | for (var a=0; aoldPos) break; 244 | for (var b=0; boldPos+$(window).height()) break; 245 | if (!oldOff.length || $('h2:visible').last().offset().top>oldPos) $('html, body').scrollTop(oldPos); 246 | else if (a==b) $('html, body').scrollTop(Math.round(labels.eq(b).offset().top)-Math.round($(window).height()/2)); 247 | else {var c = Math.round((a+b)/2); $('html, body').scrollTop(oldPos+Math.round(labels.eq(c).offset().top)-Math.round(oldOff[c]));} 248 | }); 249 | 250 | $('[data-ng-toggle]').change(function() { 251 | var journey = $(this).data('ng-toggle'); 252 | 253 | profiles[profilesKey][profiles.current].journey = +journey 254 | $.jStorage.set(profilesKey, profiles); 255 | 256 | toggleFilteredClasses('h_ng\\+'); 257 | toggleFilteredClasses('s_ng\\+'); 258 | toggleFilteredClasses('s_ng\\+\\+'); 259 | 260 | calculateTotals(); 261 | }); 262 | 263 | $('[data-item-toggle]').change(function() { 264 | var type = $(this).data('item-toggle'); 265 | var to_hide = $(this).is(':checked'); 266 | var item_toggles = $(this).closest('.btn-group.btn-group-vertical').find('[data-item-toggle]'); 267 | 268 | profiles[profilesKey][profiles.current].hidden_categories[type] = to_hide; 269 | $.jStorage.set(profilesKey, profiles); 270 | 271 | toggleFilteredClasses(type); 272 | toggleFilteredClasses('f_none'); 273 | 274 | // Mark parent category as hidden if and only if all items in it are hidden 275 | if (to_hide === (item_toggles.length === item_toggles.filter(':checked').length)) { 276 | $(this).closest('.btn-group.btn-group-vertical').find('[data-category-toggle]').not(function(){return this.checked === to_hide}).click(); 277 | } 278 | // Apply partial highlight to the parent category if at least one item in it is hidden 279 | $(this).closest('.btn-group.btn-group-vertical').find('.btn-group-vertical').toggleClass('open', item_toggles.filter(':checked').length > 0); 280 | 281 | calculateTotals(); 282 | }); 283 | 284 | $('[data-category-toggle]').change(function() { 285 | var to_hide = $(this).is(':checked'); 286 | var item_toggles = $(this).closest('.btn-group.btn-group-vertical').find('[data-item-toggle]'); 287 | 288 | // Change all child items to the same state as the category 289 | if (to_hide || (item_toggles.length === item_toggles.filter(':checked').length)) { 290 | item_toggles.not(function(){return this.checked === to_hide}).click(); 291 | } 292 | }); 293 | 294 | calculateTotals(); 295 | 296 | }); 297 | 298 | function initializeProfile(profile_name) { 299 | if (!(profile_name in profiles[profilesKey])) profiles[profilesKey][profile_name] = {}; 300 | if (!('checklistData' in profiles[profilesKey][profile_name])) 301 | profiles[profilesKey][profile_name].checklistData = {}; 302 | if (!('collapsed' in profiles[profilesKey][profile_name])) 303 | profiles[profilesKey][profile_name].collapsed = {}; 304 | if (!('current_tab' in profiles[profilesKey][profile_name])) 305 | profiles[profilesKey][profile_name].current_tab = '#tabPlaythrough'; 306 | if (!('hide_completed' in profiles[profilesKey][profile_name])) 307 | profiles[profilesKey][profile_name].hide_completed = false; 308 | if (!('journey' in profiles[profilesKey][profile_name])) 309 | profiles[profilesKey][profile_name].journey = 1; 310 | if (!('hidden_categories' in profiles[profilesKey][profile_name])) 311 | profiles[profilesKey][profile_name].hidden_categories = { 312 | f_boss: false, 313 | f_npc: false, 314 | f_estus: false, 315 | f_bone: false, 316 | f_tome: false, 317 | f_coal: false, 318 | f_ash: false, 319 | f_gest: false, 320 | f_sorc: false, 321 | f_pyro: false, 322 | f_mirac: false, 323 | f_ring: false, 324 | f_weap: false, 325 | f_arm: false, 326 | f_tit: false, 327 | f_gem: false, 328 | f_cov: false, 329 | f_misc: false 330 | }; 331 | } 332 | 333 | /// restore all saved state, except for the current tab 334 | /// used on page load or when switching profiles 335 | function restoreState(profile_name) { 336 | $('a[href$="_col"]').each(function() { 337 | var value = profiles[profilesKey][profile_name].collapsed[$(this).attr('href')]; 338 | var active = $(this).hasClass('collapsed'); 339 | 340 | // interesting note: this condition is the same as (value ^ active), 341 | // but there's no logical xor in JS as far as I know; also, this is more readable 342 | if ((value && !active) || (!value && active)) { 343 | $($(this).attr('href')).collapse('toggle'); 344 | } 345 | }); 346 | 347 | var $button = $("#toggleHideCompleted"); 348 | var hide_completed_state = profiles[profilesKey][profile_name].hide_completed; 349 | var button_active = $button.is(':checked'); 350 | if ((hide_completed_state && !button_active) || (!hide_completed_state && button_active)) { 351 | $button.click(); 352 | } 353 | 354 | $('[data-ng-toggle="' + profiles[profilesKey][profile_name].journey + '"]').click().change(); 355 | $.each(profiles[profilesKey][profile_name].hidden_categories, function(key, value) { 356 | var $el = $('[data-item-toggle="' + key + '"]'); 357 | var active = $el.is(':checked'); 358 | 359 | if ((value && !active) || (!value && active)) { 360 | $el.click(); 361 | } 362 | }); 363 | } 364 | 365 | // Setup ("bootstrap", haha) styling 366 | function themeSetup(stylesheet) { 367 | if(stylesheet === null || stylesheet === undefined) { // if we didn't get a param, then 368 | stylesheet = $.jStorage.get("style") || "Standard"; // fall back on "light" if cookie not set 369 | } 370 | $("#bootstrap").attr("href", themes[stylesheet]); 371 | } 372 | 373 | function buildThemeSelection() { 374 | var style = $.jStorage.get("style") || "Standard"; 375 | var themeSelect = $("#themes"); 376 | $.each(themes, function(key, value){ 377 | themeSelect.append( 378 | $('').val(key).html(key + " Theme") 379 | ); 380 | }); 381 | themeSelect.val(style); 382 | return style; 383 | } 384 | 385 | function dataLoadCallback(arg){ 386 | var jsonProfileData = JSON.parse(arg.currentTarget.result); 387 | profiles = jsonProfileData; 388 | $.jStorage.set(profilesKey, profiles); 389 | populateProfiles(); 390 | populateChecklists(); 391 | $('#profiles').trigger("change"); 392 | location.reload(); 393 | } 394 | 395 | function populateProfiles() { 396 | $('#profiles').empty(); 397 | $.each(profiles[profilesKey], function(index, value) { 398 | $('#profiles').append($("").attr('value', index).text(index)); 399 | }); 400 | $('#profiles').val(profiles.current); 401 | } 402 | 403 | function populateChecklists() { 404 | $('.checkbox input[type="checkbox"]') 405 | .prop('checked', false) 406 | .closest('label') 407 | .removeClass('completed') 408 | .closest('li').show(); 409 | 410 | $.each(profiles[profilesKey][profiles.current].checklistData, function(index, value) { 411 | $('#' + index) 412 | .prop('checked', value) 413 | .closest('label') 414 | .toggleClass('completed', value); 415 | }); 416 | 417 | calculateTotals(); 418 | } 419 | 420 | function calculateTotals() { 421 | $('[id$="_overall_total"]').each(function(index) { 422 | var type = this.id.match(/(.*)_overall_total/)[1]; 423 | var overallCount = 0, overallChecked = 0; 424 | $('[id^="' + type + '_totals_"]').each(function(index) { 425 | var regex = new RegExp(type + '_totals_(.*)'); 426 | var regexFilter = new RegExp('^playthrough_(.*)'); 427 | var i = parseInt(this.id.match(regex)[1]); 428 | var count = 0, checked = 0; 429 | for (var j = 1; ; j++) { 430 | var checkbox = $('#' + type + '_' + i + '_' + j); 431 | if (checkbox.length === 0) { 432 | break; 433 | } 434 | if (checkbox.is(':hidden') && checkbox.prop('id').match(regexFilter) && canFilter(checkbox.closest('li'))) { 435 | continue; 436 | } 437 | count++; 438 | overallCount++; 439 | if (checkbox.prop('checked')) { 440 | checked++; 441 | overallChecked++; 442 | } 443 | } 444 | if (checked === count) { 445 | this.innerHTML = $('#' + type + '_nav_totals_' + i)[0].innerHTML = 'DONE'; 446 | $(this).removeClass('in_progress').addClass('done'); 447 | $(this).parent('h3').addClass('completed');// Hide heading for completed category 448 | $($('#' + type + '_nav_totals_' + i)[0]).removeClass('in_progress').addClass('done'); 449 | } else { 450 | this.innerHTML = $('#' + type + '_nav_totals_' + i)[0].innerHTML = checked + '/' + count; 451 | $(this).removeClass('done').addClass('in_progress'); 452 | $(this).parent('h3').removeClass('completed');// Show heading for not yet completed category 453 | $($('#' + type + '_nav_totals_' + i)[0]).removeClass('done').addClass('in_progress'); 454 | } 455 | $(this).parent('h3').next('div').children('h4').addClass('completed');// Hide all subheadings... 456 | $(this).parent('h3').next('div').children('ul').children('li').children('div').children('label:not(.completed)').parent('div').parent('li').parent('ul').prev('h4').removeClass('completed');// ... except those where not all entries below the subheading are labeled as completed 457 | }); 458 | if (overallChecked === overallCount) { 459 | this.innerHTML = 'DONE'; 460 | $(this).removeClass('in_progress').addClass('done'); 461 | } else { 462 | this.innerHTML = overallChecked + '/' + overallCount; 463 | $(this).removeClass('done').addClass('in_progress'); 464 | } 465 | // Update textarea for profile export 466 | document.getElementById("profileText").value = JSON.stringify(profiles); 467 | }); 468 | } 469 | 470 | function addCheckbox(el) { 471 | var $el = $(el); 472 | // assuming all content lies on the first line 473 | var content = $el.html().split('\n')[0]; 474 | var sublists = $el.children('ul'); 475 | 476 | content = 477 | '
    ' + 478 | '' + 482 | '
    '; 483 | 484 | $el.html(content).append(sublists); 485 | 486 | if (profiles[profilesKey][profiles.current].checklistData[$el.attr('data-id')] === true) { 487 | $('#' + $el.attr('data-id')).prop('checked', true); 488 | $('label', $el).addClass('completed'); 489 | } 490 | } 491 | 492 | function canDelete() { 493 | var count = 0; 494 | $.each(profiles[profilesKey], function(index, value) { 495 | count++; 496 | }); 497 | return (count > 1); 498 | } 499 | 500 | function getFirstProfile() { 501 | for (var profile in profiles[profilesKey]) { 502 | return profile; 503 | } 504 | } 505 | 506 | function canFilter(entry) { 507 | var classAttr = entry.attr('class'); 508 | if (!classAttr) { 509 | return false; 510 | } 511 | if (classAttr === 'f_none') { 512 | // If some filters are enabled, all entries marked f_none are automatically filtered as well 513 | return Object.values(profiles[profilesKey][profiles.current].hidden_categories).some(function(f){return f}); 514 | } 515 | var classList = classAttr.split(/\s+/); 516 | for (var i = 0; i < classList.length; i++) { 517 | // Hide(h) or show(s) entries based on journey number 518 | if ((classList[i].match(/^h_ng\+*$/) && classList[i].match(/^h_ng(\+*)$/)[1].length < profiles[profilesKey][profiles.current].journey) || 519 | (classList[i].match(/^s_ng\+*$/) && classList[i].match(/^s_ng(\+*)$/)[1].length >= profiles[profilesKey][profiles.current].journey)) { 520 | return true; 521 | } 522 | } 523 | var foundMatch = 0; 524 | for (var i = 0; i < classList.length; i++) { 525 | if (!classList[i].match(/^f_.*/)) { 526 | continue; 527 | } 528 | if(classList[i] in profiles[profilesKey][profiles.current].hidden_categories) { 529 | if(!profiles[profilesKey][profiles.current].hidden_categories[classList[i]]) { 530 | return false; 531 | } 532 | foundMatch = 1; 533 | } 534 | } 535 | if (foundMatch === 0) { 536 | return false; 537 | } 538 | return true; 539 | } 540 | 541 | function toggleFilteredClasses(str) { 542 | $("li." + str).each(function() { 543 | if(canFilter($(this))) { 544 | $(this).css('display', 'none'); 545 | } else { 546 | $(this).css('display', ''); 547 | } 548 | }); 549 | } 550 | 551 | /* 552 | * ---------------------------------- 553 | * Search and highlight functionality 554 | * ---------------------------------- 555 | */ 556 | $(function() { 557 | var jets = [new Jets({ 558 | searchTag: '#playthrough_search', 559 | contentTag: '#playthrough_list ul' 560 | }), new Jets({ 561 | searchTag: '#item_search', 562 | contentTag: '#item_list h4, #item_list ul'// This does not mean that we are searching inside the content of both

    and
      tags 563 | }), new Jets({ 564 | searchTag: '#weapons_search', 565 | contentTag: '#weapons_list h4, #weapons_list ul'// The outcome is that all

      tags are hidden while searching inside
        tags 566 | }), new Jets({ 567 | searchTag: '#armors_search', 568 | contentTag: '#armors_list ul' 569 | })]; 570 | 571 | $('#playthrough_search').keyup(function() { 572 | $('#playthrough_list').unhighlight(); 573 | $('#playthrough_list').highlight($(this).val()); 574 | }); 575 | $('#item_search').keyup(function() { 576 | $('#item_list').unhighlight(); 577 | $('#item_list').highlight($(this).val()); 578 | }); 579 | $('#weapons_search').keyup(function() { 580 | $('#weapons_list').unhighlight(); 581 | $('#weapons_list').highlight($(this).val()); 582 | }); 583 | $('#armors_search').keyup(function() { 584 | $('#armors_list').unhighlight(); 585 | $('#armors_list').highlight($(this).val()); 586 | }); 587 | }); 588 | 589 | /* 590 | * ------------------------- 591 | * Back to top functionality 592 | * ------------------------- 593 | */ 594 | $(function() { 595 | var offset = 220; 596 | var duration = 500; 597 | $(window).scroll(function() { 598 | if ($(this).scrollTop() > offset) { 599 | $('.fadingbutton').fadeIn(duration); 600 | } else { 601 | $('.fadingbutton').fadeOut(duration); 602 | } 603 | }); 604 | 605 | $('.back-to-top').click(function(event) { 606 | event.preventDefault(); 607 | $('html, body').animate({scrollTop: 0}, duration); 608 | return false; 609 | }); 610 | }); 611 | 612 | /* 613 | * ------------------------------------------ 614 | * Restore tabs/hidden sections functionality 615 | * ------------------------------------------ 616 | */ 617 | $(function() { 618 | // reset `Hide completed` button state (otherwise Chrome bugs out) 619 | $('#toggleHideCompleted').attr('checked', false); 620 | 621 | // restore collapsed state on page load 622 | restoreState(profiles.current); 623 | 624 | if (profiles[profilesKey][profiles.current].current_tab) { 625 | $('.nav.navbar-nav li a[href="' + profiles[profilesKey][profiles.current].current_tab + '"]').click(); 626 | } 627 | 628 | // register on click handlers to store state 629 | $('a[href$="_col"]').on('click', function(el) { 630 | var collapsed_key = $(this).attr('href'); 631 | var saved_tab_state = !!profiles[profilesKey][profiles.current].collapsed[collapsed_key]; 632 | 633 | profiles[profilesKey][profiles.current].collapsed[$(this).attr('href')] = !saved_tab_state; 634 | 635 | $.jStorage.set(profilesKey, profiles); 636 | }); 637 | 638 | $('.nav.navbar-nav li a').on('click', function(el) { 639 | profiles[profilesKey][profiles.current].current_tab = $(this).attr('href'); 640 | 641 | $.jStorage.set(profilesKey, profiles); 642 | }); 643 | }); 644 | })( jQuery ); 645 | 646 | // to color the plus symbol in combined item pickups 647 | $(".p").html(' + '); 648 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Sekiro Cheat Sheet 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 46 | 47 |
        48 |
        49 |
        50 |

        Sekiro Cheat Sheet

        51 |

        Contribute to the guide on GitHub

        52 |
        53 |
        54 | 55 |
        56 | 57 |
        58 |
        59 | 70 |
        71 |
        72 | 73 |
        74 | 75 |

        Filter Checklist 76 | 77 | 78 | 79 | 80 | 81 |

        82 |
        83 |
        84 |
        85 |
        86 | 92 |
        93 |
        94 |
        95 |
        96 | 102 | 108 |
        109 |
        110 |
        111 |
        112 |
        113 |
        114 | 120 |
        121 |
        122 |
        123 |
        124 | 130 | 136 | 142 | 148 | 154 |
        155 |
        156 |
        157 |
        158 |
        159 |
        160 | 166 |
        167 |
        168 |
        169 |
        170 | 176 | 182 | 188 | 194 | 200 |
        201 |
        202 |
        203 |
        204 |
        205 |
        206 | 212 |
        213 |
        214 |
        215 |
        216 | 222 | 228 |
        229 |
        230 |
        231 |
        232 |
        233 |
        234 | 240 |
        241 |
        242 |
        243 |
        244 | 250 | 256 |
        257 |
        258 |
        259 |
        260 |
        261 |
        262 | 268 |
        269 |
        270 |
        271 |
        272 | 278 | 284 |
        285 |
        286 |
        287 |
        288 | 289 |

        Playthrough Checklist

        290 | 294 | 295 |
        296 | 297 |
        298 | 299 |
        300 | 301 |

        Ashina Reservoir

        302 |
          303 |
        • Proceed forward, pick up the Ornamental Letter.
        • 304 |
        • Obtain Kusabimaru from Kuro
        • 305 |
        306 | 307 |

        Dilapidated Temple

        308 |
          309 |
        • Talk to the Sculptor
        • 310 |
        • Talk to Emma
        • 311 |
        312 | 313 |
        314 | 315 |
        316 | 317 | 318 |
        319 |

        Achievement Checklists

        320 | 327 | 328 |
        329 | 330 |
        331 | 332 | 348 | 349 |
        350 |

        General Achievements

        351 |
          352 |
        • Revered Blade: Received the "Kusabimaru" from Kuro
        • 353 |
        • Shinobi Prosthetic: Acquired the Shinobi Prosthetic
        • 354 |
        • Resurrection: Returned from the dead using "Resurrection" for the first time
        • 355 |
        • Memorial Mob: Encountered the Memorial Mob
        • 356 |
        • Ashina Traveler: Traveled to all areas of the game
        • 357 |
        • Master of the Arts: Grasped the inner mysteries of any combat style
        • 358 |
        • Lazuline Upgrade: Used Lapis Lazuli to upgrade any tool to its limit
        • 359 |
        • Sekiro: All trophies have been unlocked
        • 360 |
        361 | 362 |

        All Prosthetic Tools: Acquired all Prosthetic Tools

        363 | 375 | 376 |

        Man Without Equal: Defeated all bosses

        377 | 394 | 395 |

        Ending Achievements

        396 | 402 | 403 |

        Master of the Prosthetic: Upgraded all Prosthetic Tools to their limit

        404 |
        405 |

        Loaded Shuriken

        406 |
          407 |
        • Spinning Shuriken
        • 408 |
        • Gouging Top
        • 409 |
        • Phantom Kunai
        • 410 |
        • Sen Throw
        • 411 |
        • Lazulite Shuriken
        • 412 |
        413 |

        Shinobi Firecracker

        414 |
          415 |
        • Spring-load Firecracker
        • 416 |
        • Long Spark
        • 417 |
        • Purple Fume Spark
        • 418 |
        419 |

        Flame Vent

        420 |
          421 |
        • Spring-load Flame Vent
        • 422 |
        • Okinaga's Flame Vent
        • 423 |
        • Lazulite Sacred Flame
        • 424 |
        425 |

        Loaded Axe

        426 |
          427 |
        • Spring-load Axe
        • 428 |
        • Sparking Axe
        • 429 |
        • Lazulite Axe
        • 430 |
        431 |

        Mist Raven

        432 |
          433 |
        • Aged Feather Mist Raven
        • 434 |
        • Great Feather Mist Raven
        • 435 |
        436 |

        Loaded Spear

        437 |
          438 |
        • Loaded Spear Thrust Type
        • 439 |
        • Loaded Spear Cleave Type
        • 440 |
        • Spiral Spear
        • 441 |
        • Leaping Flame
        • 442 |
        443 |

        Sabimaru

        444 |
          445 |
        • Improved Sabimaru
        • 446 |
        • Piercing Sabimaru
        • 447 |
        • Lazulite Sabimaru
        • 448 |
        449 |

        Divine Abduction

        450 |
          451 |
        • Golden Vortex
        • 452 |
        • Double Divine Abduction
        • 453 |
        454 |

        Loaded Umbrella

        455 |
          456 |
        • Loaded Umbrella - Magnet
        • 457 |
        • Phoenix's Lilac Umbrella
        • 458 |
        • Suzaku's Lotus Umbrella
        • 459 |
        460 |

        Finger Whistle

        461 |
          462 |
        • Mountain Echo
        • 463 |
        • Malcontent
        • 464 |
        465 |
        466 | 467 |

        Ultimate Healing Gourd: Fully upgraded the Healing Gourd. See Gourd Seeds

        468 |
          469 |
        • Ashina Outskirts - Drop from General Naomori Kawarada, immediately past the "Outskirts Wall - Gate Path" Sculptor's Idol
        • 470 |
        • Ashina Outskirts - In the building right after the Chained Ogre, just past the "Outskirts Wall - Stairway" Sculptor's Idol
        • 471 |
        • Ashina Outskirts - Bought from the Battlefield Memorial Mob Vendor for 1,000 Sen, located up the steps and to the right from where you fight Gyoubu Oniwa
        • 472 |
        • Ashina Castle - Just before the "Upper Tower - Antechamber" Sculptor's Idol in a chest
        • 473 |
        • Dilapidated Temple - One can be bought from Fujioka the Info Broker for 2,000 Sen, once he arrives
        • 474 |
        • Senpou Temple, Mt. Kongo - In front of the first immortal monk you encounter in the Senpou Temple, in the first building that's filled with crickets
        • 475 |
        • Sunken Valley - From the "Under-shrine Valley" Idol, progress forward and after encountering the fourth rifleman on the path, climb up the wall on the left to find the gourd seed in a small hut
        • 476 |
        • Ashina Depths - In the center of Mibu Village, by the orange glowing tree. It is guarded by multiple enemies
        • 477 |
        • Fountainhead Palace - In a chest in the last room of the palace by the "Palace Grounds" Sculptor's Idol
        • 478 |
        479 | 480 |
        481 | 482 |
        483 | 484 | 485 |
        486 |

        Weapons and Shields Checklists

        487 | 491 | 492 |
        493 | 494 |
        495 | 496 |
        497 |

        Weapons

        498 |
        499 |

        Daggers

        500 | 503 |

        Straight Swords

        504 | 507 |
        508 |
        509 |
        510 | 511 | 512 |
        513 |

        Armor Checklists

        514 | 520 | 521 |
        522 | 523 |
        524 | 525 |
        526 |

        Head

        527 | 530 |

        Chest

        531 | 534 |
        535 |
        536 | 537 | 538 |
        539 |

        Misc

        540 | 544 | 545 |

        Pickle Pee, Pump-a-Rum Crow

        546 |
          547 |
        • Trade
        • 548 |
        • Trade
        • 549 |
        550 | 551 |

        Coin Purses

        552 |
        553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 |
        NameCostValue
        Light Coin Purse110 sen100 sen
        Heavy Coin Purse550 sen500 sen
        Bulging Coin Purse1100 sen1000 sen
        577 |
        578 |
        579 | 580 |
        581 |

        FAQ

        582 | 583 |

        I have feedback, how can I contribute?

        584 |

        You can visit the GitHub repository and report Issues or create a fork and submit a Pull Request.

        585 | 586 |

        Is this a guide?

        587 |

        Nope, not really. This is a set of checklists and information that you can use while playing Dark Souls to make sure you don't miss an item, action, conversation, or boss. If you need playthroughs then you can click on the zone titles to read the wiki walkthrough.

        588 | 589 |

        Do I need to follow the playthrough in this exact order?

        590 |

        Sekiro is not a linear game and has multiple ways of progressing. This guide highlights zones as they become available, so feel free to follow however you please. You can always check things off in a different order.

        591 | 592 |

        Can I use this for multiple characters?

        593 |

        Yup, use the profile selector and buttons in the options tab at the top of the page to setup multiple profiles.

        594 | 595 |

        How does the checklist status get saved?

        596 |

        The checklist is saved to your browser's local storage. Be careful when clearing your browser's cache as it will also destroy your saved progress.

        597 |
        598 | 599 |
        600 |

        Options

        601 | 602 | 603 |
        604 |

        Theme selection:

        605 |
        606 |
        607 | 608 |
        609 |

        Profile management:

        610 |
        611 |
        612 | 613 | 614 | 615 | 616 | 617 | 618 |
        619 |
        620 |
        621 | 622 |
        623 |

        Data import/export:

        624 |
        625 |
        626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 |
        635 |
        636 |
        637 | 638 |
        639 |
        640 |
        641 | 642 | 670 | 671 | 690 | 691 |
        692 | 693 |
        694 | 695 | 696 |
        697 | 698 |
        699 | 700 | Back to Top  701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 716 | 717 | 718 | --------------------------------------------------------------------------------