From 6de7fd0d2d47676949d02e84b5436db1121a1e92 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 21 Dec 2018 23:30:25 +1100 Subject: [PATCH] add tutorial --- client/src/tutorial.js | 134 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 client/src/tutorial.js diff --git a/client/src/tutorial.js b/client/src/tutorial.js new file mode 100644 index 00000000..35a84402 --- /dev/null +++ b/client/src/tutorial.js @@ -0,0 +1,134 @@ +const toast = require('izitoast'); + +const OK_BUTTON = ''; +const NO_MORE_BUTTON = ''; + +function noMore(instance, thisToast) { + window.localStorage.set('tutorial', false); + return instance.hide({ transitionOut: 'fadeOut' }, thisToast); +} + +const WELCOME_MESSAGE = ` +Welcome to cryps.gg +Enter a username and password and press register to sign up, +or just press DEMO to quick start. +`; + +const HOMEPAGE_MESSAGE = ` +This homepage shows your cryps, joinable online games, PVE options and your items.\n +If you have no cryps yet, press SPAWN and give your cryp a name to create one. +Once you have made a cryp, click on them to visit their stat page and teach them some SKILLS. +The stat page also has descriptions of each skill and their effects. +cryps have 3 basic stats: stamina, physical damage and magic damage. +Toggle whether a cryp is selected for your team by clicking the coloured stripes next to the cryp or press 1,2,3. +Once you have a team ready press the New PVE Game button to start playing. +`; + +const SKILL_PHASE_MESSAGE = ` +A cryps battle has three main phases. This first phase is called the SKILL PHASE. +Your cryps are positioned on the left, your opponent's are on the right. +In the centre are your cryps' SKILLS, grayed out SKILLS are currently ON COOLDOWN. +A skill's cooldown reduces on every turn that cryp does not use a skill with a cooldown. +For the moment, drag ATTACK onto the opponent team to have your cryps attack them with physical damage. +`; + +const TARGET_PHASE_MESSAGE = ` +This phase is the TARGET PHASE. +In cryps you do not directly attack your opponent's cryps, you attack the opponent as a team +and you and your opponent choose which cryp is the TARGET of each ability. +Drag the incoming ATTACKS from the right hand side onto your own cryps. +It's wise to spread the damage around! +`; + +const RESOLUTION_PHASE_MESSAGE = ` +Finally we come to the RESOLUTION PHASE. +This phase happens automatically, every skill is RESOLVED in order of its SPEED. +This is important because attacks only RESOVLE while their caster is still able to use the skill, +a fast skill that does a small amount of damage may KO an opponent cryp, causing any SKILLS +they have used to no longer RESOLVE! +Another example of this is the skill STUN. STUN causes an opponent cryp to be unable to use any +abilities for TWO TURNS (including the turn it resolves on). +Try it now! +`; + +const FINISH_PHASE_MESSAGE = ` +gg! The game has now concluded, if you were the winner you have been awarded with a STAT REROLL ITEM. +You can use this to reroll a stat on a cryp which may be lacking. +A good metric is that if a stat is more than 1/2 of its STAMINA that's a good roll. +Now that you have learned the basics, press BACKSPACE to return to the main menu +and experiment with some combinations of SKILLS or replace the ones your cryps know in the STAT PAGE. +glhf! +`; + +const STEPS = [ + 'init', + 'welcome', + 'homepage', + 'skillPhase', + 'targetPhase', + 'resolutionPhase', + 'finishPhase', + 'none', +]; + +function showTutorial(message, step, nextStep) { + const existing = document.querySelector(`#${step}`); // Selector of your toast + + if (existing) return false; + + toast.info({ + id: step, + theme: 'dark', + color: 'black', + timeout: false, + drag: false, + title: 'TUTORIAL', + position: 'bottomCenter', + maxWidth: window.innerWidth / 2, + close: false, + buttons: [ + [NO_MORE_BUTTON, noMore], + [OK_BUTTON, (instance, thisToast) => { + const thisStep = STEPS.indexOf(step); + const storageStep = STEPS.indexOf(window.localStorage.getItem('tutorial')); + if (thisStep >= storageStep) { + window.localStorage.setItem('tutorial', nextStep); + } + + return instance.hide({ transitionOut: 'fadeOut' }, thisToast); + }], + ], + message, + }); + + return true; +} + +function tutorial() { + function show(step) { + const currentStage = window.localStorage.getItem('tutorial'); + if (currentStage === false) { + return false; + } + + const thisStep = STEPS.indexOf(step); + const storageStep = STEPS.indexOf(window.localStorage.getItem('tutorial')); + + if (thisStep < storageStep) return false; + + if (step === 'welcome') return showTutorial(WELCOME_MESSAGE, 'welcome', 'homepage'); + if (step === 'homepage') return showTutorial(HOMEPAGE_MESSAGE, 'homepage', 'skillPhase'); + if (step === 'skillPhase') return showTutorial(SKILL_PHASE_MESSAGE, 'skillPhase', 'targetPhase'); + if (step === 'targetPhase') return showTutorial(TARGET_PHASE_MESSAGE, 'targetPhase', 'resolutionPhase'); + if (step === 'resolutionPhase') return showTutorial(RESOLUTION_PHASE_MESSAGE, 'resolutionPhase', 'finishPhase'); + if (step === 'finishPhase') return showTutorial(FINISH_PHASE_MESSAGE, 'finishPhase', 'none'); + + return true; + } + + if (window.localStorage.getItem('tutorial') !== 'none') window.localStorage.setItem('tutorial', 'init'); + + return show; +} + +module.exports = tutorial;