import chalk from 'chalk' //import inquirer from 'inquirer' import prompts from 'prompts' import { selectRandom } from '../ao-lib/util.js' import { greenChalk, theAO, theMenu, headerStyle } from './styles.js' // Different sets of messages that can be randomly selected from const welcomeMessages = [ `You turn a corner and are suddenly back in the halls of ${theAO}.`, `You make the sign of ${theAO} and are whisked away on a gust of divine wind.`, `You take a closer look at the folder you are in and realize it is a room.`, `You draw an alchemical symbol and open a doorway into ${theAO}. You step through.`, `"Ah, there you are again!" The old man greets you as you step through the portal.`, `A line of doge-masked worshippers glide by. By the time you exit the trance, you are in ${theAO}. Doge bless.`, `You spraypaint an ${greenChalk.bold('A')} superimposed on an ${greenChalk.bold('O')} and step through the portal.`, `You receive a phone call. You answer it. You are in ${theAO}.`, `You dab fiercely, and when you raise your head, you are in ${theAO}.`, `A ship arrives and takes you out to sea. The ship sinks and you somehow wash up safely in ${theAO}.`, `You are reading in the Library when you find a strange book. Whatever you read next in the book is ${theAO}.`, `You plant a magic seed and it grows into a great tree. Climbing up into its branches, you know ${theAO} is here.`, `In the late afternoon, a warm sunbeam highlights motes of dust over your book. These motes are ${theAO}.`, `A black cat crosses your path. Most people wouldn't notice, but you know you have entered the AO.`, `Dipping your brush in ink, you draw a perfect circle. This is ${theAO}.`, `You are offered a choice between two pills. However, you have secretly built up an immunity to both pills, and trick your opponent into taking one. Inconceviably, you are in ${theAO}.`, `A young man with spiky hair and glowing skin appears before you in a halo of light. He guides you to ${theAO}.`, `Looking for a shortcut, you worm your way through through the hedges, and, after struggling through the brush, emerge into a sunny estate garden. You've found the AO.`, `You find a small animal burrow dug-out near the riverside. Crawling in, you find a network of caves that lead to ${theAO}.`, `You receive a handwritten letter in the mail, which reads, in fine calligraphy:, "Dear —, You are in ${theAO}."`, `An unexpected calm settles over you. The ${greenChalk.bold('AO')} is here: Here is ${theAO}.`, `You plant a seed, and from that one seed grow many trees. The forest and the tradition of tree-planting are ${theAO}.` ] const menuMessages = [ `You see ${theMenu}:`, `A page of aged paper wafts into your hand. On it is written ${theMenu}:`, `A minstrel walks by playing a haunting melody, and in its harmonies you hear the refrain of ${theMenu}:`, `You pick up an apple from a nearby table and take a bite. You suddenly recall the words of ${theMenu}:`, `With a screeching sound, a page containing ${theMenu} slowly emerges, line-by-line, from a dot-matrix printer:`, `In the shadows cast in the cavernous space, you see the forms of ${theMenu}:`, `With a low hum, standing waves appear on the reflecting pool at your feet. Impossibly, they spell out ${theMenu}:`, `You see a box of candies labeled 'Eat Me'. Why not? you think. You find ${theMenu} printed on the wrapper:`, `You see an ornate bottle labeled 'Drink Me'. Why not? you think. You take a sip and shrink to the size of a doormouse. Now you can read ${theMenu} scratched into the wainscoating:`, `Cretaceous jungle plants tower overhead, overgrown from the safari room. The ancient fractals of the branches prefigure the structure of ${theMenu}:`, ] const exclamationMessages = [ 'Woah there!', 'Shiver me timbers!', 'iNtErEsTiNg!', 'Turing\'s ghost!', 'Frack!', 'Frell!', 'Good grief!', 'With great power comes great responsibility.', ] const rogerMessages = [ 'You\'ve got it.', 'Aye-aye, captain!', 'The AO provides.', 'Roger.', 'Yokai.' ] const farewellMessages = [ 'Goodbye!', 'Goodbye! Goodbye! Goodbye...!', 'The AO will always be with you.', 'Please return soon; the AO needs your virtue.', 'The AO will await your return.', 'Doge bless.', 'Please remember the AO throughout your day as a ward against evil.', 'Remember your PrioriTEA™.', 'Know thyself.', 'With great power comes great responsibility.', 'The AO is a state of mind.', 'Go for the low-hanging fruit.', ] // Prints a random RPG-style welcome message to contextualize the AO experience and the main menu export async function welcome() { const randomWelcomeMessage = selectRandom(welcomeMessages) const randomMenuMessage = selectRandom(menuMessages) const welcomeMessage = (' ' + randomWelcomeMessage + ' ' + randomMenuMessage).wordWrap(process.stdout.columns - 2) // todo: line breaks would be more accurate if there were a function to count the length of a string minus the formatting codes (regex) // right now the invisible formatting characters are counted so lines are wrapped early console.log('\n' + welcomeMessage) } // Returns a random exclamatory remark export function exclaim() { return selectRandom(exclamationMessages) } // Returns a random obedient/affirmative remark denoting that a command was executed export function roger() { return selectRandom(rogerMessages) } // Returns a random farewell message export function farewell() { console.log(chalk.yellow.bold(selectRandom(farewellMessages))) } // Asks the given yes or no answer returns true or false for their response export async function yesOrNo(prompt = 'Yes or no?', defaultAnswer = true) { const answer = await prompts({ type: 'confirm', name: 'value', message: prompt, initial: defaultAnswer }) return answer.value || 'ESC' } // Ask the user the given question and returns their textual response export async function askQuestionText(prompt = 'Please enter a string:', promptOptions = {}) { let options = { type: 'text', name: 'value', message: prompt } Object.assign(options, promptOptions) const answer = await prompts(options) return answer.value || false } export async function promptMenu(choices, prompt = 'Please choose:', hint = '(Use arrow keys)', defaultValue = null, warningMessage = null, numbered = false) { if(prompt !== 'Please choose:') { prompt = `\n${headerStyle(prompt)}` } if(numbered) { const prependNumber = (num, str) => num + '. ' + str for(let i = 0; i < choices.length; i++) { if(typeof choices[i] === 'string') { choices[i] = prependNumber(i + 1, choices[i]) } else if(typeof choices[i].title === 'string') { if(!choices[i].value) { choices[i].value = choices[i].title } choices[i].title = prependNumber(i + 1, choices[i].title) } } } console.log() const answer = await prompts({ type: 'select', name: 'value', message: prompt, choices: choices, hint: hint, initial: defaultValue, warn: warningMessage }) if(answer && Object.keys(answer).length === 0 && Object.getPrototypeOf(answer) === Object.prototype) { return false } if(typeof answer.value === 'string') { return answer.value } if(!isNaN(answer.value) && (answer.value < 0 || answer.value > choices.length) || answer.value === false) { return false } else if(isNaN(answer.value)) { return answer.value } const chosenOption = choices[answer.value].value || choices[answer.value].title if(!chosenOption) { return choices[answer.value] } return chosenOption }