diff --git a/README.md b/README.md index ccf50e22..088897ac 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ in the appropriate channel's topic to use it. ## Commands -Total: 398 +Total: 399 ### Utility: @@ -375,6 +375,7 @@ Total: 398 * **fishy:** Go fishing. * **google-feud:** Attempt to determine the top suggestions for a Google search. * **hangman:** Prevent a man from being hanged by guessing a word as fast as you can. +* **horse-race:** Bet on the fastest horse in a 6-horse race. * **hunger-games:** Simulate a Hunger Games match with up to 24 tributes. * **lottery:** Attempt to win the lottery with 6 numbers. * **mad-libs:** Choose words that fill in the blanks to create a crazy story! @@ -640,6 +641,8 @@ here. * hollywood-star ([Hollywood Star Font](https://alexeystar.com/hollywood-star-font/)) - [Alpha Vantage](https://www.alphavantage.co/) * stocks (API) +- [Ambition](https://ambition.com/) + * horse-race ([Image](https://help.ambition.com/hc/en-us/articles/360005048011-How-do-I-set-up-a-Leaderboard-Slide-)) - [Andrew Tyler](https://www.dafont.com/andrew-tyler.d2526) * achievement ([Minecraftia Font](https://www.dafont.com/minecraftia.font)) - [AniList](https://anilist.co/) @@ -740,6 +743,8 @@ here. * flickr ([API](https://www.flickr.com/services/api/)) - [Foreign exchange rates API](https://exchangeratesapi.io/) * currency (API) +- [Free SVG](https://freesvg.org/) + * horse-race ([Image](https://freesvg.org/race-horse)) - [freeiconspng.com](https://www.freeiconspng.com/) * hat ([Birthday Hat Image](https://www.freeiconspng.com/img/43917)) - [Frinkiac](https://frinkiac.com/) @@ -811,6 +816,7 @@ here. - [Humble Bundle](https://www.humblebundle.com/) * humble-bundle ([API](https://www.humblebundle.com/developer)) - [Iconian Fonts](https://www.fontspace.com/iconian-fonts) + * horse-race ([Paladins Font](https://www.fontspace.com/paladins-font-f32777)) * rip ([Coffin Stone Font](https://www.fontspace.com/coffin-stone-font-f40998)) - [iCrawl](https://github.com/iCrawl) * butt ([Code, Concept](https://github.com/iCrawl/Tohru/blob/master/src/commands/fun/butts.js)) @@ -1077,6 +1083,8 @@ here. * sora-selfie ([Original "Kingdom Hearts" Game](https://www.kingdomhearts.com/home/us/)) - [Stack Exchange](https://stackexchange.com/) * stack-overflow ([API](https://api.stackexchange.com/docs)) +- [Stadium Talk](https://www.stadiumtalk.com/) + * horse-race ([Horse Name Data](https://www.stadiumtalk.com/s/best-racehorse-names-be7b8ad6b49a42df)) - [Star Wars](https://www.starwars.com/) * lando (Original Movie) - [Steam](https://store.steampowered.com/) diff --git a/assets/fonts/Paladins-nl8P.otf b/assets/fonts/Paladins-nl8P.otf new file mode 100644 index 00000000..544628c8 Binary files /dev/null and b/assets/fonts/Paladins-nl8P.otf differ diff --git a/assets/images/horse-race/horse.png b/assets/images/horse-race/horse.png new file mode 100644 index 00000000..65ac6995 Binary files /dev/null and b/assets/images/horse-race/horse.png differ diff --git a/assets/images/horse-race/leaderboard.png b/assets/images/horse-race/leaderboard.png new file mode 100644 index 00000000..4e1fd953 Binary files /dev/null and b/assets/images/horse-race/leaderboard.png differ diff --git a/assets/json/horse-race.json b/assets/json/horse-race.json new file mode 100644 index 00000000..d72f2a02 --- /dev/null +++ b/assets/json/horse-race.json @@ -0,0 +1,182 @@ +[ + { + "name": "Johnny Lightning", + "minTime": 80 + }, + { + "name": "Superbee", + "minTime": 157 + }, + { + "name": "Arrrrr", + "minTime": 115 + }, + { + "name": "Covfefe", + "minTime": 141 + }, + { + "name": "Donald Trump", + "minTime": 160 + }, + { + "name": "Doremifasolatido", + "minTime": 110 + }, + { + "name": "Clydesdale Earnhardt Jr.", + "minTime": 115 + }, + { + "name": "Sea Biscuit", + "minTime": 143 + }, + { + "name": "Big John", + "minTime": 144 + }, + { + "name": "Burgoo King", + "minTime": 145 + }, + { + "name": "Small John", + "minTime": 154 + }, + { + "name": "Vinny", + "minTime": 148 + }, + { + "name": "Michael", + "minTime": 105 + }, + { + "name": "I am a Donkey", + "minTime": 101 + }, + { + "name": "Rainbow Dash", + "minTime": 85 + }, + { + "name": "Twilight Sparkle", + "minTime": 137 + }, + { + "name": "Pinkie Pie", + "minTime": 121 + }, + { + "name": "Applejack", + "minTime": 105 + }, + { + "name": "Rarity", + "minTime": 139 + }, + { + "name": "Fluttershy", + "minTime": 86 + }, + { + "name": "Trixie", + "minTime": 95 + }, + { + "name": "Vert Wheeler", + "minTime": 122 + }, + { + "name": "Invite Xiao", + "minTime": 87 + }, + { + "name": "Mystery", + "minTime": 145 + }, + { + "name": "Dr. Fager", + "minTime": 114 + }, + { + "name": "Fiftyshadesofhay", + "minTime": 160 + }, + { + "name": "Dr. Pepper", + "minTime": 96 + }, + { + "name": "First Dude", + "minTime": 144 + }, + { + "name": "Flat Drunk", + "minTime": 85 + }, + { + "name": "Flat Fleet Feet", + "minTime": 100 + }, + { + "name": "Santa's Little Helper", + "minTime": 165 + }, + { + "name": "Whirlwind", + "minTime": 110 + }, + { + "name": "Harass", + "minTime": 141 + }, + { + "name": "Hoof Hearted", + "minTime": 152 + }, + { + "name": "I'll Have Another", + "minTime": 114 + }, + { + "name": "John Henry", + "minTime": 115 + }, + { + "name": "Notacatbutallama", + "minTime": 154 + }, + { + "name": "Larry the Cucumber", + "minTime": 155 + }, + { + "name": "Bob the Tomato", + "minTime": 89 + }, + { + "name": "Onoitsmymothernlaw", + "minTime": 116 + }, + { + "name": "Panty Raid", + "minTime": 123 + }, + { + "name": "Yakahickamickadola", + "minTime": 158 + }, + { + "name": "Last Place", + "minTime": 165 + }, + { + "name": "Luke Horsewalker", + "minTime": 108 + }, + { + "name": "Willy", + "minTime": 152 + } +] diff --git a/commands/edit-image/apple-engraving.js b/commands/edit-image/apple-engraving.js index 34e7d690..c8b89d76 100644 --- a/commands/edit-image/apple-engraving.js +++ b/commands/edit-image/apple-engraving.js @@ -44,7 +44,7 @@ module.exports = class AppleEngravingCommand extends Command { s: 2, f: 'font1' }); - return msg.channel.send({ files: [{ attachment: body, name: 'apple-engraving.jpg' }] }); + return msg.say({ files: [{ attachment: body, name: 'apple-engraving.jpg' }] }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/edit-image/newspaper.js b/commands/edit-image/newspaper.js index 27ff74c9..746ad1e9 100644 --- a/commands/edit-image/newspaper.js +++ b/commands/edit-image/newspaper.js @@ -41,7 +41,7 @@ module.exports = class NewspaperCommand extends Command { .attach('headline', headline) .attach('text', body); const newspaperURL = text.match(/ `**${i + 1}.** ${horse.name}`).join('\n')} + `); + const filter = res => { + if (res.author.id !== msg.author.id) return false; + const num = Number.parseInt(res.content, 10); + if (!num) return false; + return num > 0 && num <= chosenHorses.length; + }; + const msgs = await msg.channel.awaitMessages(filter, { + max: 1, + time: 30000 + }); + if (!msgs.size) return msg.reply('Sorry, can\'t have a race with no bets!'); + const pick = chosenHorses[Number.parseInt(msgs.first().content, 10) - 1]; + const results = []; + for (const horse of chosenHorses) { + results.push({ + name: horse.name, + time: randomRange(horse.minTime, horse.minTime + 15) + Math.random() + }); + } + results = results.sort((a, b) => b.time - a.time); + const leaderboard = await this.generateLeaderboard(chosenHorses, results); + const win = results[0].name === pick.name; + return msg.reply(win ? `Nice job! Your horse won!` : 'Better luck next time!', { files: [leaderboard] }); + } + + async generateLeaderboard(horses, results) { + const lb = await loadImage(path.join(__dirname, '..', '..', 'assets', 'images', 'horse-race', 'leaderboard.png')); + const horseImg = await loadImage(path.join(__dirname, '..', '..', 'assets', 'images', 'horse-race', 'horse.png')); + const canvas = createCanvas(lb.width, lb.height); + const ctx = canvas.getContext('2d'); + ctx.drawImage(base, 0, 0); + ctx.font = '34px Paladins'; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + for (let i = 0; i < horses.length; i++) { + const horse = horses[i]; + const result = results.find(result => horse.name === result.name).time; + drawImageWithTint(ctx, horseImg, horse.color, 37 * i, 114, 49, 49); + ctx.fillText(this.formatTime(result), 138 * i, 755); + ctx.fillText(horse.name, 138 * 1, 251); + } + return { attachment: canvas.toBuffer(), name: 'leaderboard.png' }; + } + + formatTime(time) { + const min = Math.floor(time / 60); + const sec = Math.floor(time - (min * 60)); + const ms = time - sec - (min * 60); + return `${min}:${sec}.${ms.toFixed(4).slice(2)}`; + } +}; diff --git a/commands/random-img/light-novel-cover.js b/commands/random-img/light-novel-cover.js index e4808df7..65b89a38 100644 --- a/commands/random-img/light-novel-cover.js +++ b/commands/random-img/light-novel-cover.js @@ -26,7 +26,7 @@ module.exports = class LightNovelCoverCommand extends Command { const { text } = await request.get('https://salty-salty-studios.com/shiz/lncovers.php'); const $ = cheerio.load(text); const cover = $('img').first(); - return msg.channel.send(cover.attr('alt'), { + return msg.say(cover.attr('alt'), { files: [`https://salty-salty-studios.com/shiz/${cover.attr('src')}`] }); } catch (err) { diff --git a/commands/random-res/roll.js b/commands/random-res/roll.js index 30c69d0d..dc8b7a9c 100644 --- a/commands/random-res/roll.js +++ b/commands/random-res/roll.js @@ -34,8 +34,8 @@ module.exports = class RollCommand extends Command { run(msg, { maxValue, minValue }) { let result; - if (!minValue) result = Math.floor(Math.random() * maxValue) + 1; - else result = randomRange(minValue, maxValue); + if (minValue) result = randomRange(minValue, maxValue); + else result = Math.floor(Math.random() * maxValue) + 1; return msg.say(`You rolled a ${formatNumber(result)}.`); } }; diff --git a/commands/readme/generate-commands.js b/commands/readme/generate-commands.js index c403d2a0..0a92ff5e 100644 --- a/commands/readme/generate-commands.js +++ b/commands/readme/generate-commands.js @@ -32,6 +32,6 @@ module.exports = class GenerateCommandsCommand extends Command { }).join('\n')}`; }); const text = `Total: ${this.client.registry.commands.size}\n${list.join('\n')}`; - return msg.channel.send({ files: [{ attachment: Buffer.from(text), name: 'commands.txt' }] }); + return msg.say({ files: [{ attachment: Buffer.from(text), name: 'commands.txt' }] }); } }; diff --git a/commands/readme/generate-credit.js b/commands/readme/generate-credit.js index 4ac513ae..19a0a49b 100644 --- a/commands/readme/generate-credit.js +++ b/commands/readme/generate-credit.js @@ -47,6 +47,6 @@ module.exports = class GenerateCreditCommand extends Command { if (!cmd.reasonURL) return ` * ${cmd.name} (${cmd.reason})`; return ` * ${cmd.name} (${embedURL(cmd.reason, cmd.reasonURL || '', false)})`; }).join('\n')}`); - return msg.channel.send({ files: [{ attachment: Buffer.from(mapped.join('\n')), name: 'credit.txt' }] }); + return msg.say({ files: [{ attachment: Buffer.from(mapped.join('\n')), name: 'credit.txt' }] }); } }; diff --git a/commands/readme/generate-process-env.js b/commands/readme/generate-process-env.js index 27365ec3..5a027dc8 100644 --- a/commands/readme/generate-process-env.js +++ b/commands/readme/generate-process-env.js @@ -24,6 +24,6 @@ module.exports = class GenerateProcessEnvCommand extends Command { line = line.replace('=', ''); return `${line}="${process.env[line] || ''}"`; }).join('\n'); - return msg.channel.send({ files: [{ attachment: Buffer.from(list), name: 'process.env.txt' }] }); + return msg.say({ files: [{ attachment: Buffer.from(list), name: 'process.env.txt' }] }); } }; diff --git a/package.json b/package.json index 33f7f9da..46d78972 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "113.12.2", + "version": "113.13.0", "description": "Your personal server companion.", "main": "Xiao.js", "scripts": {