wip stage loader integration

This commit is contained in:
Matteias Collet 2020-06-28 00:05:33 +02:00
parent b7bea697be
commit a1a4777162
4 changed files with 408 additions and 76 deletions

View file

@ -0,0 +1,59 @@
<template>
<div :class="
disabled
? 'button-wrapper disabled'
: 'button-wrapper'
">
<button @click="onClick">{{ label }}</button>
</div>
</template>
<script>
import CodeFormatter from "./scripts/codeFormatter";
export default {
props: {
disabled: { type: Boolean },
onClick: { type: Function },
label: { type: String }
}
};
</script>
<style scoped>
.button-wrapper {
position: relative;
display: block;
max-width: 400px;
min-width: 180px;
margin: 0 auto;
text-align: center;
}
.button-wrapper.disabled button {
background-color: rgb(165, 165, 165);
cursor: not-allowed;
}
button {
border: none;
outline: none;
background-color: #2eb9e2;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border-radius: 0;
margin: 0;
display: block;
width: 100%;
padding: 6px 15px;
font-size: 14px;
color: white;
font-weight: bold;
cursor: pointer;
}
button:hover {
background-color: #3fc1e9;
}
</style>

View file

@ -1,23 +1,16 @@
<template> <template>
<div <ButtonComponent label="Download" :onClick="onClick" :disabled="!codes || codes.length === 0" />
:class="
!codes || codes.length === 0
? 'download-wrapper disabled'
: 'download-wrapper'
"
>
<button @click="onClick">Download</button>
</div>
</template> </template>
<script> <script>
import ButtonComponent from "./ButtonComponent";
import CodeFormatter from "./scripts/codeFormatter"; import CodeFormatter from "./scripts/codeFormatter";
export default { export default {
props: { props: {
codes: { type: Array }, codes: { type: Array },
format: { type: String }, format: { type: String },
versionIdentifier: { type: String }, versionIdentifier: { type: String }
}, },
methods: { methods: {
onClick() { onClick() {
@ -40,45 +33,9 @@ export default {
); );
break; break;
} }
}, }
}, }
}; };
</script> </script>
<style scoped>
.download-wrapper {
position: relative;
display: block;
max-width: 400px;
min-width: 180px;
margin: 0 auto;
text-align: center;
}
.download-wrapper.disabled button {
background-color: rgb(165, 165, 165);
cursor: not-allowed;
}
button {
border: none;
outline: none;
background-color: #2eb9e2;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border-radius: 0;
margin: 0;
display: block;
width: 100%;
padding: 6px 15px;
font-size: 14px;
color: white;
font-weight: bold;
cursor: pointer;
}
button:hover {
background-color: #3fc1e9;
}
</style>

View file

@ -12,6 +12,10 @@
<span>Download Format:</span> <span>Download Format:</span>
<FormatSelect :onChange="onFormatChanged" /> <FormatSelect :onChange="onFormatChanged" />
</div> </div>
<div>
<span>Use Stage Loader:</span>
<SelectComponent :options="useStageLoaderOptions" :onChange="onStageLoaderChanged" />
</div>
<div> <div>
<span>Download:</span> <span>Download:</span>
<DownloadButton <DownloadButton
@ -30,6 +34,10 @@
:onInspect="inspect" :onInspect="inspect"
/> />
</div> </div>
<div v-if="codes && codes.length > 0 && useStageLoader">
<h3>Stage Loader</h3>
<StageLoader />
</div>
<div v-if="codes && codes.length > 0" class="help"> <div v-if="codes && codes.length > 0" class="help">
<h3>Help</h3> <h3>Help</h3>
@ -43,10 +51,14 @@
This is a cheatfile generator for Super Mario Sunshine speedrun This is a cheatfile generator for Super Mario Sunshine speedrun
practice. If this is your first time using the generator we highly practice. If this is your first time using the generator we highly
recommend to check out the recommend to check out the
<a href="/guide.html" target="_blank">guide</a> first. Visit the <a
<a href="/guide.html#troubleshooting" target="_blank" href="/guide.html"
>the troubleshooting section</a target="_blank"
> >guide</a> first. Visit the
<a
href="/guide.html#troubleshooting"
target="_blank"
>the troubleshooting section</a>
if you encounter any issues. if you encounter any issues.
</p> </p>
<div> <div>
@ -54,41 +66,42 @@
<ul> <ul>
<li> <li>
Discord: Discord:
<a href="https://discord.gg/9dGJWEc" target="_blank" <a
>https://discord.gg/9dGJWEc</a href="https://discord.gg/9dGJWEc"
> target="_blank"
>https://discord.gg/9dGJWEc</a>
</li> </li>
<li> <li>
Speedrun.com: Speedrun.com:
<a href="https://speedrun.com/sms" target="_blank" <a
>https://speedrun.com/sms</a href="https://speedrun.com/sms"
> target="_blank"
>https://speedrun.com/sms</a>
</li> </li>
<li> <li>
Twitter: Twitter:
<a href="https://twitter.com/SMSCommunity" target="_blank" <a
>https://twitter.com/SMSCommunity</a href="https://twitter.com/SMSCommunity"
> target="_blank"
>https://twitter.com/SMSCommunity</a>
</li> </li>
<li> <li>
Twitch: Twitch:
<a <a
href="https://www.twitch.tv/SunshineCommunity" href="https://www.twitch.tv/SunshineCommunity"
target="_blank" target="_blank"
>https://www.twitch.tv/SunshineCommunity</a >https://www.twitch.tv/SunshineCommunity</a>
>
</li> </li>
</ul> </ul>
</div> </div>
<div> <div>
<p> <p>
The generator is brought to you by The generator is brought to you by
<a href="https://twitter.com/psychonauter" target="_blank" <a
>Psychonauter</a href="https://twitter.com/psychonauter"
>, target="_blank"
<a href="https://twitter.com/Qbe_Root" target="_blank" >Psychonauter</a>,
>Noki Doki</a <a href="https://twitter.com/Qbe_Root" target="_blank">Noki Doki</a>
>
and and
<a href="https://twitter.com/srlMilk" target="_blank">Milk</a>. <a href="https://twitter.com/srlMilk" target="_blank">Milk</a>.
</p> </p>
@ -103,6 +116,8 @@
// Components // Components
import VersionSelect from "./VersionSelect"; import VersionSelect from "./VersionSelect";
import FormatSelect from "./FormatSelect"; import FormatSelect from "./FormatSelect";
import SelectComponent from "./SelectComponent";
import StageLoader from "./StageLoader";
import CodeInfo from "./CodeInfo"; import CodeInfo from "./CodeInfo";
import CodeList from "./CodeList"; import CodeList from "./CodeList";
import DownloadButton from "./DownloadButton"; import DownloadButton from "./DownloadButton";
@ -119,17 +134,17 @@ import axios from "axios";
export default { export default {
mounted() { mounted() {
Promise.all( Promise.all(
gameVersions.map(async (v) => ({ gameVersions.map(async v => ({
identifier: v.identifier, identifier: v.identifier,
cheats: parseXml((await axios.get(`/codes/${v.identifier}.xml`)).data), cheats: parseXml((await axios.get(`/codes/${v.identifier}.xml`)).data),
fastCodes: (await axios.get(`/codes/fast/${v.identifier}.json`)).data, fastCodes: (await axios.get(`/codes/fast/${v.identifier}.json`)).data
})) }))
) )
.then((codes) => { .then(codes => {
localStorage.setItem("codes", JSON.stringify(codes)); localStorage.setItem("codes", JSON.stringify(codes));
this.isLoading = false; this.isLoading = false;
}) })
.catch((err) => { .catch(err => {
if (localStorage.getItem("codes") != null) this.isLoading = false; if (localStorage.getItem("codes") != null) this.isLoading = false;
}); });
}, },
@ -141,6 +156,11 @@ export default {
inspectingCode: null, inspectingCode: null,
selectedVersion: null, selectedVersion: null,
selectedFormat: null, selectedFormat: null,
useStageLoader: false,
useStageLoaderOptions: [
{ value: false, label: "No" },
{ value: true, label: "Yes" }
]
}; };
}, },
methods: { methods: {
@ -148,19 +168,22 @@ export default {
this.selectedVersion = e; this.selectedVersion = e;
this.selectedCheats = []; this.selectedCheats = [];
const storedCodes = JSON.parse(localStorage.getItem("codes")); const storedCodes = JSON.parse(localStorage.getItem("codes"));
this.codes = storedCodes.find((c) => c.identifier === e).cheats; this.codes = storedCodes.find(c => c.identifier === e).cheats;
this.inspectingCode = null; this.inspectingCode = null;
}, },
onFormatChanged(e) { onFormatChanged(e) {
this.selectedFormat = e; this.selectedFormat = e;
}, },
onStageLoaderChanged(e) {
this.useStageLoader = e;
},
onCheatSelectionChanged(e) { onCheatSelectionChanged(e) {
this.selectedCheats = e; this.selectedCheats = e;
}, },
inspect(code) { inspect(code) {
this.inspectingCode = code; this.inspectingCode = code;
}, }
}, }
}; };
</script> </script>
<style scoped> <style scoped>

View file

@ -0,0 +1,293 @@
<template>
<div>
<div class="config">
<span>Remove Dialogue:</span>
<SelectComponent :options="removeDialogueOptions" :onChange="onRemoveDialogueChanged" />
</div>
<div class="config">
<span>Skippable FMVs:</span>
<SelectComponent :options="skippableFMVsOptions" :onChange="onSkippableFMVsChanged" />
</div>
<div class="config">
<span>Level Order:</span>
<SelectComponent :options="levelOrderOptions" :onChange="onLevelOrderChanged" />
</div>
<div class="config">
<span>Post Game:</span>
<SelectComponent :options="postGameOptions" :onChange="onPostGameSelectionChanged" />
</div>
<div>
<ul id="route_levels">
<li draggable="false">
<div class="route_drag">&#8801;</div>
<select>
<option value="0F00" selected disabled>Select a level</option>
<optgroup label="Delfino Plaza">
<option value="01FF">Plaza - Current</option>
<option value="0100">Plaza - Bianco unlock</option>
<option value="0101">Plaza - Peach chase</option>
<option value="0105">Plaza - Ricco/Gelato unlocks</option>
<option value="0106">Plaza - Peaceful</option>
<option value="0107">Plaza - Pinna unlock</option>
<option value="0108">Plaza - Yoshi/nozzles unlocks</option>
<option value="0109">Plaza - Flooded</option>
<option value="0102">Plaza - Post-Corona</option>
</optgroup>
<optgroup label="Delfino Plaza sublevels">
<option value="0000">Airstrip</option>
<option value="1400">Airstrip (red coins)</option>
<option value="1500">Slide</option>
<option value="1600">Pachinko</option>
<option value="1700">Grass pipe</option>
<option value="1800">Lily Pad Ride</option>
<option value="1D00">Jail secret</option>
</optgroup>
<optgroup label="Bianco Hills">
<option value="0200">Bianco 1</option>
<option value="0201">Bianco 2</option>
<option value="0202">Bianco 3</option>
<option value="0203">Bianco 4</option>
<option value="0204">Bianco 5</option>
<option value="0205">Bianco 6</option>
<option value="0206">Bianco 7</option>
<option value="0207">Bianco 8</option>
</optgroup>
<optgroup label="Ricco Harbor">
<option value="0300">Ricco 1</option>
<option value="0301">Ricco 2</option>
<option value="0302">Ricco 3</option>
<option value="0303">Ricco 4</option>
<option value="0304">Ricco 5</option>
<option value="0305">Ricco 6</option>
<option value="0306">Ricco 7</option>
<option value="0307">Ricco 8</option>
</optgroup>
<optgroup label="Gelato Beach">
<option value="0400">Gelato 1</option>
<option value="0401">Gelato 2</option>
<option value="0402">Gelato 3</option>
<option value="0403">Gelato 4</option>
<option value="0404">Gelato 5</option>
<option value="0405">Gelato 6</option>
<option value="0406">Gelato 7</option>
<option value="0407">Gelato 8</option>
</optgroup>
<optgroup label="Pinna Park">
<option value="0500">Pinna 1</option>
<option value="0501">Pinna 2</option>
<option value="0502">Pinna 3</option>
<option value="0503">Pinna 4</option>
<option value="0504">Pinna 5</option>
<option value="0505">Pinna 6</option>
<option value="0506">Pinna 7</option>
<option value="0507">Pinna 8</option>
</optgroup>
<optgroup label="Sirena Beach">
<option value="0600">Sirena 1</option>
<option value="0601">Sirena 2</option>
<option value="0602">Sirena 3</option>
<option value="0603">Sirena 4</option>
<option value="0604">Sirena 5</option>
<option value="0605">Sirena 6</option>
<option value="0606">Sirena 7</option>
<option value="0607">Sirena 8</option>
</optgroup>
<optgroup label="Noki Bay">
<option value="0900">Noki 1</option>
<option value="0901">Noki 2</option>
<option value="0902">Noki 3</option>
<option value="0903">Noki 4</option>
<option value="0904">Noki 5</option>
<option value="0905">Noki 6</option>
<option value="0906">Noki 7</option>
<option value="0907">Noki 8</option>
</optgroup>
<optgroup label="Pianta Village">
<option value="0800">Pianta 1</option>
<option value="0801">Pianta 2</option>
<option value="0802">Pianta 3</option>
<option value="0803">Pianta 4</option>
<option value="0804">Pianta 5</option>
<option value="0805">Pianta 6</option>
<option value="0806">Pianta 7</option>
<option value="0807">Pianta 8</option>
</optgroup>
<optgroup label="Secret areas">
<option value="2F00">Bianco 3 secret</option>
<option value="2E00">Bianco 6 secret</option>
<option value="3000">Ricco 4 secret</option>
<option value="2000">Gelato 1 secret</option>
<option value="3200">Pinna 2 secret</option>
<option value="2900">Pinna 6 secret</option>
<option value="3300">Sirena 2 secret</option>
<option value="2800">Sirena 4 secret</option>
<option value="1F00">Noki 6 secret</option>
<option value="2A00">Pianta 5 secret</option>
</optgroup>
<optgroup label="Sublevels">
<option value="3700">Petey Piranha fight (Bianco 2)</option>
<option value="3B00">Gooper Blooper fight (Ricco 1)</option>
<option value="1E00">Race course (Ricco 2)</option>
<option value="2100">Sand bird (Gelato 4)</option>
<option value="3A01">Mecha-Bowser fight (Pinna 1)</option>
<option value="3A00">Rollercoaster (Pinna 8)</option>
<option value="0E00">Casino Delfino (Sirena 4)</option>
<option value="0E01">Casino Delfino (Sirena 5)</option>
<option value="3800">King Boo fight (Sirena 5)</option>
<option value="2C00">Bottle (Noki 3)</option>
<option value="3900">Deep Sea of Mare (Noki 4)</option>
<option value="1000">Deep Sea of Mare (Noki 8)</option>
</optgroup>
<optgroup label="Miscellaneous">
<option value="02FF">Bianco episode selection</option>
<option value="03FF">Ricco episode selection</option>
<option value="04FF">Gelato episode selection</option>
<option value="05FF">Pinna episode selection</option>
<option value="06FF">Sirena episode selection</option>
<option value="09FF">Noki episode selection</option>
<option value="08FF">Pianta episode selection</option>
</optgroup>
</select>
<button type="button" class="route_remove">&#215;</button>
</li>
</ul>
</div>
<div class="config row">
<div class="config">
<ButtonComponent label="Clear List" :onClick="onClearList" />
</div>
<div>
<button id="route_clear" type="button">Clear List</button>
</div>
<div>
<select id="route_presets">
<option value selected>Load a preset</option>
<optgroup label="Full-game categories, minimal plaza">
<option
value="020002020203020404000406080008010802080308040805080605000501050205030502050603000301030203030304030503060205020606000601060206030604060506060900090109020903090409050906;3400"
>Fast Any% usual route</option>
<option
value="020002020203020404000406080008010802080308040805080605000501050205030502050602050206060006010602060306040605060609000901090209030904090509060300030103020303030403050306;3400"
>Fast Any% Ricco late</option>
<option
value="020002020203020408000801080208030804080508060500050105020503050405050506030003010302030303040305030602050206060006010602060306040605060609000901090209030904090509060400040104020403040404050406;3400"
>Fast Any% No Major Skips</option>
<option
value="02000201020202030800080108020803080408050806080705000501050205030504050505060507030003010302030303040305030603070204020502060207060006010602060306040605060606070900090109020903090409050906090704000401040204030404040304050406;3400"
>Fast 58 Shines / All Episodes</option>
<option
value="02000201020202020800080108020803080408040804080508060807080705000501050105020503050405040505050505060507030003010301030203030303030403050305030603070203020402050205020502060207060006010601060206030603060306040605060606070900090109010901090209030904090509050906090704000400040004010402040304050404040304020406;3400"
>Fast 79 Shines / All Level Shines</option>
<option
value="020002020203020404000406080008010802080308040805080605000501050105020503050405050506030003010302030303040305030602050206060006010602060306040605060609000901090209030904090509060102160001021400010201021D00010201020102010201020102010204060405040404030402040204010400040015000207020502070205020003020307030303010507050705051700060706030603060109070905090109010807080708040804;3400"
>Fast 96 Shines / All Shines, No Blues</option>
</optgroup>
<optgroup label="Full-game categories">
<option
value="00000100020002020105020302040105040004060106080008010802080308040805080601070108050005010502050305020506010803000301030203030304030503060108020502060108060006010602060306040605060601080900090109020903090409050906;0109"
>Any% usual route</option>
<option
value="00000100020002020105020302040105080008010802080308040805080601070108050005010502050305040505050601080300030103020303030403050306010802050206010806000601060206030604060506060108090009010902090309040905090601080400040104020403040404050406;0109"
>Any% No Major Skips</option>
<option
value="0000010002000201010502020203010508000801080208030804080508060807010701080500050105020503050405050506050701080300030103020303030403050306030701080204020502060207010806000601060206030604060506060607010809000901090209030904090509060907010804000401040204030404040304050406;0109"
>58 Shines / All Episodes</option>
<option
value="0000010002000201010502020202010508000801080208030804080408040805080608070807010701080500050105010502050305040504050505050506050701080300030103010302030303030304030503050306030701080203020402050205020502060207010806000601060106020603060306030604060506060607010809000901090109010902090309040905090509060907010804000400040004010402040304050404040304020406;0109"
>79 Shines / All Level Shines</option>
<option
value="0000010002000202010502030204010504000406010608000801080208030804080508060107010805000501050105020503050405050506010803000301030203030304030503060108020502060108010806000601060206030604060506060108090009010902090309040905090601FF0102010201020102010201020102010201020102010201020102010204060405040404030402040204010400040001020102020702050207020502000102030203070303030101020507050705050102010206070603060306010102090709050901090101020807080708040804;0102"
>96 Shines / All Shines, No Blues</option>
<option
value="0000010002000202010502030204010504000406010608000801080208030804080508060107010805000501050105020503050405050506010803000301030203030304030503060108020502060108010806000601060206030604060506060108090009010902090309040905090601FF01020102010201020102010201020102010201020102010201020404040304020405040004000401040204050102010202000207020702070207010209010905090509070102080408040807080701020505050705070102010206010603060606070102010203010303030703070102;0102"
>120 Shines / All Shines, All Blues</option>
</optgroup>
<optgroup label="Individual Worlds">
<option value="020002020203020402050206">Bianco Hills</option>
<option value="0300030103020303030403050306">Ricco Harbor</option>
<option value="0400040104020403040404050406">Gelato Beach</option>
<option value="050005010502050305020506">Pinna Park</option>
<option value="0600060106020603060406050606">Sirena Beach</option>
<option value="0900090109020903090409050906">Noki Bay</option>
<option value="0800080108020803080408050806">Pianta Village</option>
</optgroup>
<optgroup label="All Shines IWs">
<option value="02000201020202020203020402050205020502060207">Bianco Hills</option>
<option value="03000301030103020303030303040305030503060307">Ricco Harbor</option>
<option value="04000406040404060401040504000400040204020403">Gelato Beach</option>
<option value="05000501050105020503050405040505050505060507">Pinna Park</option>
<option value="06000601060106020603060306030604060506060607">Sirena Beach</option>
<option value="09000901090109020903090409050905090609060907">Noki Bay</option>
<option value="08000801080208030804080408040805080608070807">Pianta Village</option>
</optgroup>
</select>
</div>
</div>
</div>
</template>
<script>
import SelectComponent from "./SelectComponent";
import ButtonComponent from "./ButtonComponent";
export default {
data() {
return {
removeDialogueOptions: [
{ value: "yes", label: "Always" },
{ value: "pv5", label: "Not in Pinna 5" },
{ value: "no", label: "Don't include" }
],
skippableFMVsOptions: [
{ value: "yes", label: "Always" },
{ value: "pp", label: "Not in Pinna" },
{ value: "no", label: "Don't include" }
],
levelOrderOptions: [
{ value: "list", label: "As specified" },
{ value: "shuffle", label: "Random, no duplicates" },
{ value: "random", label: "Fully random" }
],
postGameOptions: [
{ value: "0F00", label: "Return to title screen" },
{ value: "0109", label: "Load the flooded plaza" },
{ value: "3400", label: "Load post-Corona plaza" },
{ value: "3C00", label: "Load the Bowser fight" }
],
removeDialogSelection: null,
skippableFMVsSelection: null,
levelOrderSelection: null,
postGameSelection: null
};
},
methods: {
onRemoveDialogueChanged(e) {
this.removeDialogSelection = e;
},
onSkippableFMVsChanged(e) {
this.skippableFMVsSelection = e;
},
onLevelOrderChanged(e) {
this.levelOrderSelection = e;
},
onPostGameSelectionChanged(e) {
this.postGameSelection = e;
},
onClearList() {
return;
}
}
};
</script>
<style scoped>
.config span {
display: block;
margin-bottom: 10px;
padding-left: 2px;
}
.config select {
width: 100%;
}
</style>