Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Al Bhed Translator script
- * Generates mysterious languages, then allows players to gradually learn them over time. Inspired by the Al Bhed language system in Final Fantasy X.
- * Usage (single language):
- * !generate Generates a new secret language cipher.
- * !say "Hello" Says "Hello" in the secret language.
- * !learn Increase language knowledge by 1. Knowledge goes from 0 to 26, each point translating one letter.
- * !learn 10 Set language knowledge to 10.
- *
- * Usage (multiple languages):
- * !generate Elvish Generates a new language cipher for Elvish.
- * !say Elvish "Hello" Says "Hello" in Elvish.
- * !learn Elvish Increases language knowledge for Elvish by 1.
- * !learn Elvish 10 Sets Elvish language knowledge to 10.
- *
- * Created by Quinn Gordon
- */
- on('ready', () => {
- // Config:
- const config = {
- enabled: true, // Set to false to disable script
- multipleLanguages: true, // Track multiple languages
- enforceVowels: true, // Ensures the langugae has vowels in the same places as original text
- learnedColor: 'orange', // Color of known letters
- letters: 'abcdefghijklmnopqrstuvwxyz',
- consonants: 'bcdfghjklmnpqrstvwxz',
- vowels: 'aeiouy'
- }
- on('chat:message', function(msg) {
- if(msg.type == 'api' && msg.content.indexOf('!generate') == 0
- && playerIsGM(msg.playerid)) {
- if(!config.enabled) return;
- let language = 'common';
- if(config.multipleLanguages) {
- let args = msg.content.split(/\s+/);
- if(args.length > 1) {
- language = args[1].toLowerCase();
- }
- }
- state.cipher[language] = {};
- // Generate random-order character list
- let baseList = '';
- let charlist = '';
- if(config.enforceVowels) {
- let shuffledVowels = shuffle(config.vowels);
- let shuffledConsonants = shuffle(config.consonants);
- baseList = config.vowels + config.consonants;
- charList = shuffledVowels + shuffledConsonants;
- } else {
- charList = shuffle(letters);
- }
- // Generate a learning order
- let learningOrder = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26];
- for(let i = 25; i > 0; i--) {
- let j = Math.floor(Math.random() * (i + 1));
- let tmp = learningOrder[i];
- learningOrder[i] = learningOrder[j];
- learningOrder[j] = tmp;
- }
- // Generate the Cipher
- for(let i = 0; i < 26; i++) {
- state.cipher[language][baseList[i]] = {
- char: charList[i],
- order: learningOrder[i]
- };
- }
- // Reset language knowledge
- if(!state.knowledge) state.knowledge = {};
- state.knowledge[language] = 0;
- if(config.multipleLanguages) {
- const displayLanguage = language.substring(0, 1).toUpperCase() + language.substring(1);
- sendChat('Translator', `/w gm New cipher generated for language ${displayLanguage}.`);
- } else {
- sendChat('Translator', '/w gm New cipher generated.');
- }
- }
- });
- // Say a message in the encoded language.
- on('chat:message', function(msg) {
- if(msg.type == 'api' && msg.content.indexOf('!say') == 0) {
- if(!config.enabled) return;
- if(!state.cipher) return;
- let language = 'common';
- let input = '';
- let displayInput = '';
- let args = msg.content.split(/\s+/);
- if(config.multipleLanguages) {
- if(args.length > 1) {
- language = args[1].toLowerCase();
- }
- input = args.slice(2).join(' ');
- } else {
- input = args.slice(1).join(' ');
- }
- if(!language) language = 'common';
- const knowledge = state.knowledge[language];
- let output = '';
- let properNoun = false;
- for(let i = 0; i < input.length; i++) {
- // If a word starts with !, don't translate it
- if(i > 0) {
- log(`${input[i]} | ${input[i-1].match(/[^a-zA-Z0-9]/g)}`);
- }
- if(input[i] == '!' &&
- (i == 0 ||
- input[i-1].match(/[^a-zA-Z0-9]/g))) {
- properNoun = true;
- continue;
- }
- if(properNoun) {
- if(input[i].match(/[^a-zA-Z0-9]/g)) {
- properNoun = false;
- }
- }
- let lowerCase = input[i].toLowerCase() == input[i];
- let inputLetter = input[i].toLowerCase();
- let outputLetter = '';
- let c = state.cipher[language][inputLetter];
- if(c == null) {
- outputLetter = input[i];
- } else {
- if(c.order <= knowledge || properNoun) {
- outputLetter = `<span style="color:${config.learnedColor}">${input[i]}</span>`;
- } else {
- outputLetter = c.char;
- }
- }
- outputLetter = lowerCase ? outputLetter.toLowerCase() : outputLetter.toUpperCase();
- output += outputLetter;
- displayInput += lowerCase ? inputLetter.toLowerCase() : inputLetter.toUpperCase();
- }
- if(config.multipleLanguages) {
- const displayLanguage = language.substring(0, 1).toUpperCase() + language.substring(1);
- sendChat(msg.who, `[${displayLanguage}] ${output}`);
- } else {
- sendChat(msg.who, output);
- }
- sendChat(msg.who, `/w gm ${displayInput}`);
- }
- });
- // Say a message in the encoded language.
- on('chat:message', function(msg) {
- if(!config.enabled) return;
- if(msg.type == 'api' && msg.content.indexOf('!learn') == 0) {
- log(state.knowledge);
- if(!state.cipher) {
- return;
- }
- if(!state.knowledge) state.knowledge = {};
- let args = msg.content.split(/\s+/);
- let language = 'common';
- if(config.multipleLanguages) {
- if(args.length > 1) {
- language = args[1].toLowerCase();
- }
- }
- let newKnowledge = state.knowledge[language] + 1;
- if(args.length > 1) {
- let input = parseInt(args[1]);
- if (input == input) {
- newKnowledge = input;
- } else if(args.length > 2) {
- input = parseInt(args[2]);
- if (input == input) {
- newKnowledge = input;
- }
- }
- }
- state.knowledge[language] = newKnowledge;
- if(config.multipleLanguages) {
- const displayLanguage = language.substring(0, 1).toUpperCase() + language.substring(1);
- sendChat('Translator', `/w gm Knowledge set to ${state.knowledge[language]} for language ${displayLanguage}.`);
- } else {
- sendChat('Translator', `/w gm Knowledge set to ${state.knowledge[language]}.`);
- }
- }
- });
- // Input: A string of characters
- // Output: The same string in random order
- function shuffle(input) {
- if(input.length < 2) return input;
- let a = input.split("");
- let b = [];
- let count = 0;
- // Not using the Fisher–Yates shuffle because it can land a letter in the same spot it used to be, and we never want that
- while(a.length > 0) {
- let id = Math.floor(Math.random() * a.length);
- while(id == count) {
- id = Math.floor(Math.random() * a.length);
- }
- b.push(a[id]);
- a.splice(id, 1);
- count++;
- }
- return b.join("");
- }
- });
Advertisement
Add Comment
Please, Sign In to add comment