diff --git a/WebHostLib/static/assets/playerSettings.js b/WebHostLib/static/assets/playerSettings.js index c4cbf330..de9f75e5 100644 --- a/WebHostLib/static/assets/playerSettings.js +++ b/WebHostLib/static/assets/playerSettings.js @@ -1,16 +1,35 @@ window.addEventListener('load', () => { - fetchSettingData().then((settingData) => { - createDefaultSettings(settingData); - buildUI(settingData); + Promise.all([fetchSettingData(), fetchSpriteData()]).then((results) => { + // Page setup + createDefaultSettings(results[0]); + buildUI(results[0]); + adjustHeaderWidth(); + + // Event listeners document.getElementById('export-settings').addEventListener('click', () => exportSettings()); document.getElementById('generate-race').addEventListener('click', () => generateGame(true)) document.getElementById('generate-game').addEventListener('click', () => generateGame()); + // Name input field const playerSettings = JSON.parse(localStorage.getItem('playerSettings')); const nameInput = document.getElementById('player-name'); nameInput.addEventListener('keyup', (event) => updateSetting(event)); nameInput.value = playerSettings.name; - }); + + // Sprite options + const spriteData = JSON.parse(results[1]); + const spriteSelect = document.getElementById('sprite'); + Object.keys(spriteData).forEach((sprite) => { + if (sprite.trim().length === 0) { return; } + const option = document.createElement('option'); + option.setAttribute('value', spriteData[sprite]); + if (playerSettings.rom.sprite === sprite) { option.selected = true; } + option.innerText = sprite; + spriteSelect.appendChild(option); + }); + }).catch((error) => { + console.error(error); + }) }); const fetchSettingData = () => new Promise((resolve, reject) => { @@ -40,8 +59,9 @@ const createDefaultSettings = (settingData) => { for (let gameOption of Object.keys(settingData.gameOptions)){ newSettings[gameOption] = settingData.gameOptions[gameOption].defaultValue; } + newSettings.rom = {}; for (let romOption of Object.keys(settingData.romOptions)){ - newSettings[romOption] = settingData.romOptions[romOption].defaultValue; + newSettings.rom[romOption] = settingData.romOptions[romOption].defaultValue; } localStorage.setItem('playerSettings', JSON.stringify(newSettings)); } @@ -65,11 +85,11 @@ const buildUI = (settingData) => { if (index < Object.keys(settingData.romOptions).length / 2) { leftRomOpts[key] = settingData.romOptions[key]; } else { rightRomOpts[key] = settingData.romOptions[key]; } }); - document.getElementById('rom-options-left').appendChild(buildOptionsTable(leftRomOpts)); - document.getElementById('rom-options-right').appendChild(buildOptionsTable(rightRomOpts)); + document.getElementById('rom-options-left').appendChild(buildOptionsTable(leftRomOpts, true)); + document.getElementById('rom-options-right').appendChild(buildOptionsTable(rightRomOpts, true)); }; -const buildOptionsTable = (settings) => { +const buildOptionsTable = (settings, romOpts = false) => { const currentSettings = JSON.parse(localStorage.getItem('playerSettings')); const table = document.createElement('table'); const tbody = document.createElement('tbody'); @@ -89,7 +109,9 @@ const buildOptionsTable = (settings) => { // td Right const tdr = document.createElement('td'); const select = document.createElement('select'); + select.setAttribute('id', setting); select.setAttribute('data-key', setting); + if (romOpts) { select.setAttribute('data-romOpt', '1'); } settings[setting].options.forEach((opt) => { const option = document.createElement('option'); option.setAttribute('value', opt.value); @@ -112,8 +134,13 @@ const buildOptionsTable = (settings) => { const updateSetting = (event) => { const options = JSON.parse(localStorage.getItem('playerSettings')); - options[event.target.getAttribute('data-key')] = isNaN(event.target.value) ? - event.target.value : parseInt(event.target.value, 10); + if (event.target.getAttribute('data-romOpt')) { + options.rom[event.target.getAttribute('data-key')] = isNaN(event.target.value) ? + event.target.value : parseInt(event.target.value, 10); + } else { + options[event.target.getAttribute('data-key')] = isNaN(event.target.value) ? + event.target.value : parseInt(event.target.value, 10); + } localStorage.setItem('playerSettings', JSON.stringify(options)); }; @@ -145,3 +172,17 @@ const generateGame = (raceMode = false) => { window.location.href = response.data.url; }); }; + +const fetchSpriteData = () => new Promise((resolve, reject) => { + const ajax = new XMLHttpRequest(); + ajax.onreadystatechange = () => { + if (ajax.readyState !== 4) { return; } + if (ajax.status !== 200) { + reject('Unable to fetch sprite data.'); + return; + } + resolve(ajax.responseText); + }; + ajax.open('GET', `${window.location.origin}/static/static/spriteData.json`, true); + ajax.send(); +}); diff --git a/WebHostLib/static/static/playerSettings.json b/WebHostLib/static/static/playerSettings.json index 597689c0..4d9d5c2d 100644 --- a/WebHostLib/static/static/playerSettings.json +++ b/WebHostLib/static/static/playerSettings.json @@ -648,6 +648,34 @@ "value": "random" } ] + }, + "sword_palettes": { + "type": "select", + "friendlyName": "Sword Palette", + "description": "Change the colors of the swords, within reason", + "defaultValue": "default", + "options": [ + { + "name": "Vanilla", + "value": "default" + }, + { + "name": "Shuffled", + "value": "random" + } + ] + }, + "sprite": { + "type": "select", + "friendlyName": "Sprite", + "description": "Choose a sprite to play as!", + "defaultValue": "link", + "options": [ + { + "name": "Random", + "value": "random" + } + ] } } } diff --git a/WebHostLib/static/styles/checkResult.css b/WebHostLib/static/styles/checkResult.css index bd5a1f1f..1b22b206 100644 --- a/WebHostLib/static/styles/checkResult.css +++ b/WebHostLib/static/styles/checkResult.css @@ -7,5 +7,12 @@ #check-result{ width: 540px; - text-align: center; +} + +#check-result table{ + text-align: left; +} + +#check-result table th, #check-result table td{ + padding-right: 20px; } diff --git a/WebHostLib/static/styles/globalStyles.css b/WebHostLib/static/styles/globalStyles.css index e077cc52..26b6c48a 100644 --- a/WebHostLib/static/styles/globalStyles.css +++ b/WebHostLib/static/styles/globalStyles.css @@ -24,7 +24,7 @@ button{ font-family: Jost, sans-serif; font-weight: 500; font-size: 0.9rem; - padding: 10px 17px 11px 16px; + padding: 10px 17px 11px 16px; /* top right bottom left */ border-radius: 4px; border-top: 1px solid rgba(0, 0, 0, 0.5); border-left: 1px solid rgba(0, 0, 0, 0.5); @@ -38,6 +38,7 @@ button:active{ border-right: 1px solid rgba(0, 0, 0, 0.5); border-bottom: 1px solid rgba(0, 0, 0, 0.5); padding-right: 16px; + margin-right: 2px; padding-bottom: 10px; margin-bottom: 2px; } diff --git a/WebHostLib/static/styles/playerSettings.css b/WebHostLib/static/styles/playerSettings.css index 7924d88d..b0fc2262 100644 --- a/WebHostLib/static/styles/playerSettings.css +++ b/WebHostLib/static/styles/playerSettings.css @@ -66,6 +66,10 @@ html{ min-width: 150px; } +#player-settings input:not([type]):focus{ + border: 1px solid #ffffff; +} + #player-settings select{ border: 1px solid #000000; padding: 3px; diff --git a/WebHostLib/static/styles/weightedSettings.css b/WebHostLib/static/styles/weightedSettings.css index 45c17fef..303095cb 100644 --- a/WebHostLib/static/styles/weightedSettings.css +++ b/WebHostLib/static/styles/weightedSettings.css @@ -139,9 +139,14 @@ html{ min-width: 150px; } +#weighted-settings input:not([type]):focus{ + border: 1px solid #ffffff; +} + #weighted-settings select{ border: 1px solid #000000; padding: 3px; border-radius: 3px; min-width: 150px; } + diff --git a/WebHostLib/templates/checkResult.html b/WebHostLib/templates/checkResult.html index 13465258..a6e8e0b8 100644 --- a/WebHostLib/templates/checkResult.html +++ b/WebHostLib/templates/checkResult.html @@ -10,9 +10,24 @@ {% include 'header/oceanHeader.html' %}
The results of your requested file check are below.
+File | +Result | +
---|---|
{{ filename }} | +{{ "Valid" if resulttext == True else resulttext }} | +
Choose the options you would like to play with! You may generate a single-player game from this page, or download a settings file you can use to participate in a MultiWorld. If you would like to make your settings extra random, check out the weighted settings - page.
+ page. There, you will find examples of all available sprites as well.