From 14d40726b121f64879df1c1bdf3e7d6327cea432 Mon Sep 17 00:00:00 2001 From: Daniel Odendahl Jr Date: Tue, 17 Oct 2017 20:43:59 +0000 Subject: [PATCH] Hunger Games, Anagram --- assets/json/hunger-games.json | 1241 ++++++++++++++++++++++ commands/games/akinator.js | 12 +- commands/games/battle.js | 8 +- commands/games/emoji-emoji-revolution.js | 8 +- commands/games/gunfight.js | 9 +- commands/games/hunger-games.js | 117 ++ commands/games/tic-tac-toe.js | 8 +- commands/moderation/ban.js | 8 +- commands/moderation/hackban.js | 8 +- commands/moderation/kick.js | 8 +- commands/moderation/softban.js | 8 +- commands/moderation/unban.js | 8 +- commands/text-edit/anagram.js | 39 + package.json | 2 +- util/Util.js | 8 + 15 files changed, 1437 insertions(+), 55 deletions(-) create mode 100644 assets/json/hunger-games.json create mode 100644 commands/games/hunger-games.js create mode 100644 commands/text-edit/anagram.js diff --git a/assets/json/hunger-games.json b/assets/json/hunger-games.json new file mode 100644 index 00000000..805d40c2 --- /dev/null +++ b/assets/json/hunger-games.json @@ -0,0 +1,1241 @@ +{ + "day": [ + { + "text": "(Player1) goes hunting.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) injures themself.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) explores the arena.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) scares (Player2) off.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) diverts (Player2)'s attention and runs away.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) stalks (Player2).", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) fishes.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) camouflauges themself in the bushes.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) steals from (Player2) while they aren't looking.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) makes a wooden spear.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) discovers a cave.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) attacks (Player2), but they manage to escape.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) chases (Player2).", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) runs away from (Player2).", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) collects fruit from a tree.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) receives a hatchet from an unknown sponsor.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) receives clean water from an unknown sponsor.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) receives medical supplies from an unknown sponsor.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) receives fresh food from an unknown sponsor.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) searches for a water source.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) defeats (Player2) in a fight, but spares their life.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) and (Player2) work together for the day.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) begs for (Player2) to kill them. They refuse, keeping (Player1) alive.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) tries to sleep through the entire day.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1), (Player2), (Player3), and (Player4) raid (Player5)'s camp while they are hunting.", + "tributes": 5, + "deaths": [] + }, + { + "text": "(Player1) constructs a shack.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) overhears (Player2) and (Player3) talking in the distance.", + "tributes": 3, + "deaths": [] + }, + { + "text": "(Player1) practices their archery.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) thinks about home.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) is pricked by thorns while picking berries.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) tries to spear fish with a trident.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) searches for firewood.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) and (Player2) split up to search for resources.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) picks flowers.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) tends to (Player2)'s wounds.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) sees smoke rising in the distance, but decides not to investigate.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) sprains their ankle while running away from (Player2).", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) makes a slingshot.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) travels to higher ground.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) discovers a river.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) hunts for other tributes.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) and (Player2) hunt for other tributes.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1), (Player2), and (Player3) hunt for other tributes.", + "tributes": 3, + "deaths": [] + }, + { + "text": "(Player1), (Player2), (Player3), and (Player4) hunt for other tributes.", + "tributes": 4, + "deaths": [] + }, + { + "text": "(Player1), (Player2), (Player3), (Player4), and (Player5) hunt for other tributes.", + "tributes": 5, + "deaths": [] + }, + { + "text": "(Player1) receives an explosive from an unknown sponsor.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) questions their sanity.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) forces (Player2) to eat pant.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) catches (Player2) off guard and kills them.", + "tributes": 2, + "deaths": [1] + }, + { + "text": "(Player1) throws a knife into (Player2)'s head.", + "tributes": 2, + "deaths": [1] + }, + { + "text": "(Player1) begs for (Player2) to kill them. They reluctantly oblige, killing (Player1).", + "tributes": 2, + "deaths": [1] + }, + { + "text": "(Player1) and (Player2) work together to drown (Player3).", + "tributes": 3, + "deaths": [2] + }, + { + "text": "(Player1) strangles (Player2) after engaging in a fist fight.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) shoots an arrow into (Player2)'s head.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) bleeds out due to untreated injuries.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) cannot handle the circumstances and commits suicide.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) bashes (Player2)'s head against a rock several times.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) unknowingly eats toxic berries.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) silently snaps (Player2)'s neck.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) taints (Player2)'s food, killing them.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) decapitates (Player2) with a sword.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) dies from an infection.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) spears (Player2) in the abdomen.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) sets (Player2) on fire with a molotov.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) falls into a pit and dies.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) stabs (Player2) while their back is turned.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) severely injures (Player2), but puts them out of their misery.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) severely injures (Player2) and leaves them to die.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) bashes (Player2)'s head in with a mace.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) attempts to climb a tree, but falls to their death.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) pushes (Player2) off a cliff during a knife fight.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) throws a knife into (Player2)'s chest.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1)'s trap kills (Player2).", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) kills (Player2) while they are resting.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) is unable to convince (Player2) to not kill them.", + "tributes": 2, + "deaths": [1] + }, + { + "text": "(Player1) convinces (Player2) to not kill them, only to kill them instead.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) falls into a frozen lake and drowns.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1), (Player2), and (Player3) start fighting, but (Player2) runs away as (Player1) kills (Player3).", + "tributes": 3, + "deaths": [3] + }, + { + "text": "(Player1) kills (Player2) with their own weapon.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) overpowers (Player2), killing them.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) sets an explosive off, killing (Player2).", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) sets an explosive off, killing (Player2), and (Player3).", + "tributes": 3, + "deaths": [2, 3] + }, + { + "text": "(Player1) sets an explosive off, killing (Player2), (Player3), and (Player4).", + "tributes": 4, + "deaths": [2, 3, 4] + }, + { + "text": "(Player1) sets an explosive off, killing (Player2), (Player3), (Player4) and (Player5).", + "tributes": 5, + "deaths": [2, 3, 4, 5] + }, + { + "text": "(Player1) kills (Player2) as they try to run.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) and (Player2) threaten a double suicide. It fails and they die.", + "tributes": 2, + "deaths": [1, 2] + }, + { + "text": "(Player1), (Player2), (Player3), and (Player4) form a suicide pact, killing themselves.", + "tributes": 4, + "deaths": [1, 2, 3, 4] + }, + { + "text": "(Player1) dies from hypothermia.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) dies from hunger.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) dies from thirst.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) kills (Player2) with a hatchet.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) and (Player2) fight (Player3) and (Player4). (Player1) and (Player2) survive.", + "tributes": 4, + "deaths": [3, 4] + }, + { + "text": "(Player1) and (Player2) fight (Player3) and (Player4). (Player3) and (Player4) survive.", + "tributes": 4, + "deaths": [1, 2] + }, + { + "text": "(Player1) dies trying to escape the arena.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) dies of dysentery.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) accidently detonates a land mine while trying to arm it.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) attacks (Player2), but (Player3) protects them, killing (Player1).", + "tributes": 3, + "deaths": [1] + }, + { + "text": "(Player1) ambushes (Player2) and kills them.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) accidently steps on a landmine.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) severely slices (Player2) with a sword.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) strangles (Player2) with a rope.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) kills (Player2) for their supplies.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) shoots an arrow at (Player2), but misses and kills (Player3) instead.", + "tributes": 3, + "deaths": [3] + }, + { + "text": "(Player1) shoots a poisonous blow dart into (Player2)'s neck, slowly killing them.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1), (Player2), and (Player3) successfully ambush and kill (Player4), (Player5), and (Player6).", + "tributes": 6, + "deaths": [4, 5, 6] + }, + { + "text": "(Player1), (Player2), and (Player3) unsuccessfully ambush (Player4), (Player5), and (Player6), who kill them instead.", + "tributes": 6, + "deaths": [1, 2, 3] + }, + { + "text": "(Player1) stabs (Player2) with a tree branch.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) forces (Player2) to kill (Player3) or (Player4). They decide to kill (Player3).", + "tributes": 4, + "deaths": [3] + }, + { + "text": "(Player1) forces (Player2) to kill (Player3) or (Player4). They decide to kill (Player4).", + "tributes": 4, + "deaths": [4] + }, + { + "text": "(Player1) forces (Player2) to kill (Player3) or (Player4). They refuse to kill, so (Player1) kills them instead.", + "tributes": 4, + "deaths": [2] + }, + { + "text": "(Player1) poisons (Player2)'s drink, but mistakes it for their own and dies.", + "tributes": 2, + "deaths": [1] + }, + { + "text": "(Player1) poisons (Player2)'s drink. They drink it and die.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) stabs (Player2) in the back with a trident.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) attempts to climb a tree, but falls on (Player2), killing them both.", + "tributes": 2, + "deaths": [1, 2] + }, + { + "text": "(Player1), (Player2), and (Player3) get into a fight. (Player1) triumphantly kills them both.", + "tributes": 3, + "deaths": [2, 3] + }, + { + "text": "(Player1), (Player2), and (Player3) get into a fight. (Player2) triumphantly kills them both.", + "tributes": 3, + "deaths": [1, 3] + }, + { + "text": "(Player1), (Player2), and (Player3) get into a fight. (Player3) triumphantly kills them both.", + "tributes": 3, + "deaths": [1, 2] + }, + { + "text": "(Player1) kills (Player2) with a sickle.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1), (Player2), (Player3), (Player4), and (Player5) track down and kill (Player6).", + "tributes": 6, + "deaths": [6] + }, + { + "text": "(Player1), (Player2), (Player3), and (Player4) track down and kill (Player5).", + "tributes": 5, + "deaths": [5] + }, + { + "text": "(Player1), (Player2), and (Player3) track down and kill (Player4).", + "tributes": 4, + "deaths": [4] + }, + { + "text": "(Player1) and (Player2) track down and kill (Player3).", + "tributes": 3, + "deaths": [3] + }, + { + "text": "(Player1) tracks down and kills (Player2).", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) repeatedly stabs (Player2) to death with sais.", + "tributes": 2, + "deaths": [2] + } + ], + "night": [ + { + "text": "(Player1) starts a fire.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) sets up camp for the night.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) loses sight of where they are.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) climbs a tree to rest.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) goes to sleep.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) and (Player2) tell stories about themselves to each other.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1), (Player2), (Player3), and (Player4) sleep in shifts.", + "tributes": 4, + "deaths": [] + }, + { + "text": "(Player1), (Player2), and (Player3) sleep in shifts.", + "tributes": 3, + "deaths": [] + }, + { + "text": "(Player1) and (Player2) sleep in shifts.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) tends to their wounds.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) sees a fire, but stays hidden.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) screams for help.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) stays awake all night.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) passes out from exhaustion.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) cooks their food before putting their fire out.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) and (Player2) run into each other and decide to truce for the night.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) fends (Player2), (Player3), and (Player4) away from their fire.", + "tributes": 4, + "deaths": [] + }, + { + "text": "(Player1), (Player2), and (Player3) discuss the games and what might happen in the morning.", + "tributes": 3, + "deaths": [] + }, + { + "text": "(Player1) cries themself to sleep.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) tries to treat their infection.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) and (Player2) talk about the tributes still alive.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) is awoken by nightmares.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) and (Player2) huddle for warmth.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) thinks about winning.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1), (Player2), (Player3), and (Player4) tell each other ghost stories to lighten the mood.", + "tributes": 4, + "deaths": [] + }, + { + "text": "(Player1) looks at the night sky.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) defeats (Player2) in a fight, but spares their life.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) begs for (Player2) to kill them. They refuse, keeping (Player1) alive.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) destroys (Player2)'s supplies while they are asleep.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1), (Player2), (Player3), (Player4), and (Player5) sleep in shifts.", + "tributes": 5, + "deaths": [] + }, + { + "text": "(Player1) lets (Player2) into their shelter.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) receives a hatchet from an unknown sponsor.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) receives clean water from an unknown sponsor.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) receives medical supplies from an unknown sponsor.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) receives fresh food from an unknown sponsor.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) tries to sing themself to sleep.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) attempts to start a fire, but is unsuccessful.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) thinks about home.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) tends to (Player2)'s wounds.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) quietly hums.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1), (Player2), and (Player3) cheerfully sing songs together.", + "tributes": 3, + "deaths": [] + }, + { + "text": "(Player1) is unable to start a fire and sleeps without warmth.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) and (Player2) hold hands.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) convinces (Player2) to snuggle with them.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) receives an explosive from an unknown sponsor.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) questions their sanity.", + "tributes": 1, + "deaths": [] + }, + { + "text": "(Player1) forces (Player2) to eat pant.", + "tributes": 2, + "deaths": [] + }, + { + "text": "(Player1) catches (Player2) off guard and kills them.", + "tributes": 2, + "deaths": [1] + }, + { + "text": "(Player1) throws a knife into (Player2)'s head.", + "tributes": 2, + "deaths": [1] + }, + { + "text": "(Player1) begs for (Player2) to kill them. They reluctantly oblige, killing (Player1).", + "tributes": 2, + "deaths": [1] + }, + { + "text": "(Player1) and (Player2) work together to drown (Player3).", + "tributes": 3, + "deaths": [2] + }, + { + "text": "(Player1) strangles (Player2) after engaging in a fist fight.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) shoots an arrow into (Player2)'s head.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) bleeds out due to untreated injuries.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) cannot handle the circumstances and commits suicide.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) bashes (Player2)'s head against a rock several times.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) unknowingly eats toxic berries.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) silently snaps (Player2)'s neck.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) taints (Player2)'s food, killing them.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) decapitates (Player2) with a sword.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) dies from an infection.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) spears (Player2) in the abdomen.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) sets (Player2) on fire with a molotov.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) falls into a pit and dies.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) stabs (Player2) while their back is turned.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) severely injures (Player2), but puts them out of their misery.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) severely injures (Player2) and leaves them to die.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) bashes (Player2)'s head in with a mace.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) attempts to climb a tree, but falls to their death.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) pushes (Player2) off a cliff during a knife fight.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) throws a knife into (Player2)'s chest.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1)'s trap kills (Player2).", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) kills (Player2) while they are sleeping.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) is unable to convince (Player2) to not kill them.", + "tributes": 2, + "deaths": [1] + }, + { + "text": "(Player1) convinces (Player2) to not kill them, only to kill them instead.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) falls into a frozen lake and drowns.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1), (Player2), and (Player3) start fighting, but (Player2) runs away as (Player1) kills (Player3).", + "tributes": 3, + "deaths": [3] + }, + { + "text": "(Player1) kills (Player2) with their own weapon.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) overpowers (Player2), killing them.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) sets an explosive off, killing (Player2).", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) sets an explosive off, killing (Player2), and (Player3).", + "tributes": 3, + "deaths": [2, 3] + }, + { + "text": "(Player1) sets an explosive off, killing (Player2), (Player3), and (Player4).", + "tributes": 4, + "deaths": [2, 3, 4] + }, + { + "text": "(Player1) sets an explosive off, killing (Player2), (Player3), (Player4) and (Player5).", + "tributes": 5, + "deaths": [2, 3, 4, 5] + }, + { + "text": "(Player1) kills (Player2) as they try to run.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) and (Player2) threaten a double suicide. It fails and they die.", + "tributes": 2, + "deaths": [1, 2] + }, + { + "text": "(Player1), (Player2), (Player3), and (Player4) form a suicide pact, killing themselves.", + "tributes": 4, + "deaths": [1, 2, 3, 4] + }, + { + "text": "(Player1) dies from hypothermia.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) dies from hunger.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) dies from thirst.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) kills (Player2) with a hatchet.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) and (Player2) fight (Player3) and (Player4). (Player1) and (Player2) survive.", + "tributes": 4, + "deaths": [3, 4] + }, + { + "text": "(Player1) and (Player2) fight (Player3) and (Player4). (Player3) and (Player4) survive.", + "tributes": 4, + "deaths": [1, 2] + }, + { + "text": "(Player1) dies trying to escape the arena.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) dies of dysentery.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) accidently detonates a land mine while trying to arm it.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) attacks (Player2), but (Player3) protects them, killing (Player1).", + "tributes": 3, + "deaths": [1] + }, + { + "text": "(Player1) ambushes (Player2) and kills them.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) accidently steps on a landmine.", + "tributes": 1, + "deaths": [1] + }, + { + "text": "(Player1) severely slices (Player2) with a sword.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) strangles (Player2) with a rope.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) kills (Player2) for their supplies.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) shoots an arrow at (Player2), but misses and kills (Player3) instead.", + "tributes": 3, + "deaths": [3] + }, + { + "text": "(Player1) shoots a poisonous blow dart into (Player2)'s neck, slowly killing them.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1), (Player2), and (Player3) successfully ambush and kill (Player4), (Player5), and (Player6).", + "tributes": 6, + "deaths": [4, 5, 6] + }, + { + "text": "(Player1), (Player2), and (Player3) unsuccessfully ambush (Player4), (Player5), and (Player6), who kill them instead.", + "tributes": 6, + "deaths": [1, 2, 3] + }, + { + "text": "(Player1) stabs (Player2) with a tree branch.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) forces (Player2) to kill (Player3) or (Player4). They decide to kill (Player3).", + "tributes": 4, + "deaths": [3] + }, + { + "text": "(Player1) forces (Player2) to kill (Player3) or (Player4). They decide to kill (Player4).", + "tributes": 4, + "deaths": [4] + }, + { + "text": "(Player1) forces (Player2) to kill (Player3) or (Player4). They refuse to kill, so (Player1) kills them instead.", + "tributes": 4, + "deaths": [2] + }, + { + "text": "(Player1) poisons (Player2)'s drink, but mistakes it for their own and dies.", + "tributes": 2, + "deaths": [1] + }, + { + "text": "(Player1) poisons (Player2)'s drink. They drink it and die.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) stabs (Player2) in the back with a trident.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) attempts to climb a tree, but falls on (Player2), killing them both.", + "tributes": 2, + "deaths": [1, 2] + }, + { + "text": "(Player1), (Player2), and (Player3) get into a fight. (Player1) triumphantly kills them both.", + "tributes": 3, + "deaths": [2, 3] + }, + { + "text": "(Player1), (Player2), and (Player3) get into a fight. (Player2) triumphantly kills them both.", + "tributes": 3, + "deaths": [1, 3] + }, + { + "text": "(Player1), (Player2), and (Player3) get into a fight. (Player3) triumphantly kills them both.", + "tributes": 3, + "deaths": [1, 2] + }, + { + "text": "(Player1) kills (Player2) with a sickle.", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1), (Player2), (Player3), (Player4), and (Player5) track down and kill (Player6).", + "tributes": 6, + "deaths": [6] + }, + { + "text": "(Player1), (Player2), (Player3), and (Player4) track down and kill (Player5).", + "tributes": 5, + "deaths": [5] + }, + { + "text": "(Player1), (Player2), and (Player3) track down and kill (Player4).", + "tributes": 4, + "deaths": [4] + }, + { + "text": "(Player1) and (Player2) track down and kill (Player3).", + "tributes": 3, + "deaths": [3] + }, + { + "text": "(Player1) tracks down and kills (Player2).", + "tributes": 2, + "deaths": [2] + }, + { + "text": "(Player1) repeatedly stabs (Player2) to death with sais.", + "tributes": 2, + "deaths": [2] + } + ] +} diff --git a/commands/games/akinator.js b/commands/games/akinator.js index 46fa4cfa..1bfaaa7e 100644 --- a/commands/games/akinator.js +++ b/commands/games/akinator.js @@ -2,6 +2,7 @@ const { Command } = require('discord.js-commando'); const { MessageEmbed } = require('discord.js'); const snekfetch = require('snekfetch'); const { stripIndents } = require('common-tags'); +const { verify } = require('../../util/Util'); module.exports = class AkinatorCommand extends Command { constructor(client) { @@ -53,15 +54,10 @@ module.exports = class AkinatorCommand extends Command { `) .setThumbnail(guess.absolute_picture_path); await msg.embed(embed); - const msgs = await msg.channel.awaitMessages(res => res.author.id === msg.author.id, { - max: 1, - time: 30000 - }); + const verification = await verify(msg.channel, msg.author); this.sessions.delete(msg.channel.id); - if (!msgs.size) return msg.say('I guess your silence means I have won.'); - const response = msgs.first().content.toLowerCase(); - if (!['yes', 'no'].includes(response)) return msg.say('I guess I\'m right then!'); - return msg.say(response === 'yes' ? 'Guessed right one more time!' : 'Bravo, you have defeated me.'); + if (!verification) return msg.say('Bravo, you have defeated me.'); + return msg.say('Guessed right one more time! I love playing with you!'); } catch (err) { this.sessions.delete(msg.channel.id); return msg.say(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); diff --git a/commands/games/battle.js b/commands/games/battle.js index 8518fe68..74e69d22 100644 --- a/commands/games/battle.js +++ b/commands/games/battle.js @@ -1,5 +1,6 @@ const { Command } = require('discord.js-commando'); const { stripIndents } = require('common-tags'); +const { verify } = require('../../util/Util'); module.exports = class BattleCommand extends Command { constructor(client) { @@ -30,11 +31,8 @@ module.exports = class BattleCommand extends Command { try { if (!opponent.bot) { await msg.say(`${opponent}, do you accept this challenge?`); - const verify = await msg.channel.awaitMessages(res => res.author.id === opponent.id, { - max: 1, - time: 30000 - }); - if (!verify.size || !['yes', 'y'].includes(verify.first().content.toLowerCase())) { + const verification = await verify(msg.channel, opponent); + if (!verification) { this.fighting.delete(msg.channel.id); return msg.say('Looks like they declined...'); } diff --git a/commands/games/emoji-emoji-revolution.js b/commands/games/emoji-emoji-revolution.js index 2903a150..e47b25f8 100644 --- a/commands/games/emoji-emoji-revolution.js +++ b/commands/games/emoji-emoji-revolution.js @@ -1,5 +1,6 @@ const { Command } = require('discord.js-commando'); const { stripIndents } = require('common-tags'); +const { verify } = require('../../util/Util'); const emojis = ['⬆', '↗', '➡', '↘', '⬇', '↙', '⬅', '↖']; module.exports = class EmojiEmojiRevolutionCommand extends Command { @@ -30,11 +31,8 @@ module.exports = class EmojiEmojiRevolutionCommand extends Command { this.playing.add(msg.channel.id); try { await msg.say(`${opponent}, do you accept this challenge?`); - const verify = await msg.channel.awaitMessages(res => res.author.id === opponent.id, { - max: 1, - time: 30000 - }); - if (!verify.size || !['yes', 'y'].includes(verify.first().content.toLowerCase())) { + const verification = await verify(msg.channel, opponent); + if (!verification) { this.playing.delete(msg.channel.id); return msg.say('Looks like they declined...'); } diff --git a/commands/games/gunfight.js b/commands/games/gunfight.js index 5f8d6161..77d6f0e8 100644 --- a/commands/games/gunfight.js +++ b/commands/games/gunfight.js @@ -1,5 +1,5 @@ const { Command } = require('discord.js-commando'); -const { wait } = require('../../util/Util'); +const { wait, verify } = require('../../util/Util'); const words = ['fire', 'draw', 'shoot', 'bang', 'pull']; module.exports = class GunfightCommand extends Command { @@ -30,11 +30,8 @@ module.exports = class GunfightCommand extends Command { this.fighting.add(msg.channel.id); try { await msg.say(`${opponent}, do you accept this challenge?`); - const verify = await msg.channel.awaitMessages(res => res.author.id === opponent.id, { - max: 1, - time: 30000 - }); - if (!verify.size || !['yes', 'y'].includes(verify.first().content.toLowerCase())) { + const verification = await verify(msg.channel, opponent); + if (!verification) { this.fighting.delete(msg.channel.id); return msg.say('Looks like they declined...'); } diff --git a/commands/games/hunger-games.js b/commands/games/hunger-games.js new file mode 100644 index 00000000..b5ef0ac5 --- /dev/null +++ b/commands/games/hunger-games.js @@ -0,0 +1,117 @@ +const { Command } = require('discord.js-commando'); +const { stripIndents } = require('common-tags'); +const { shuffle, verify } = require('../../util/Util'); +const events = require('../../assets/json/hunger-games'); + +module.exports = class HungerGamesCommand extends Command { + constructor(client) { + super(client, { + name: 'hunger-games', + aliases: ['hunger-games-simulator', 'brantsteele'], + group: 'games', + memberName: 'hunger-games', + description: 'Simulate a Hunger Games match.', + args: [ + { + key: 'tributes', + prompt: 'Who should compete in the games? Up to 24 tributes can participate.', + type: 'string', + infinite: true, + validate: tribute => { + if (tribute.length < 20) return true; + return 'Invalid tribute, please keep each tribute under 20 characters.'; + } + } + ] + }); + + this.playing = new Set(); + } + + async run(msg, { tributes }) { + if (tributes.length < 2) return msg.say(`...${tributes[0]} wins, as they were the only tribute.`); + if (tributes.length > 24) return msg.say('Please do not enter more than 24 tributes.'); + if (new Set(tributes).size !== tributes.length) return msg.say('Please do not enter the same tribute twice.'); + if (this.playing.has(msg.channel.id)) return msg.say('Only one game may be occurring per channel.'); + this.playing.add(msg.channel.id); + try { + let sun = true; + let turn = 0; + const remaining = new Set(shuffle(tributes)); + while (remaining.size > 1) { + if (sun) ++turn; + const sunEvents = sun ? events.day : events.night; + const results = []; + const deaths = []; + this.makeEvents(remaining, sunEvents, deaths, results); + await msg.say(stripIndents` + __**${sun ? 'Day' : 'Night'} ${turn}**__: + ${results.join('\n')} + `); + await msg.say(stripIndents` + **${deaths.length} cannon shot${deaths.length === 1 ? '' : 's'} can be heard in the distance.** + ${deaths.join('\n')} + + _Proceed?_ + `); + const verification = await verify(msg.channel, msg.author, 120000); + if (!verification) { + this.playing.delete(msg.channel.id); + return msg.say('See you next time!'); + } + sun = !sun; + } + this.playing.delete(msg.channel.id); + return msg.say(`And the winner is... ${[...remaining][0]}!`); + } catch (err) { + this.playing.delete(msg.channel.id); + throw err; + } + } + + parseEvent(event, tributes) { + return event + .replace(/\(Player1\)/gi, `**${tributes[0]}**`) + .replace(/\(Player2\)/gi, `**${tributes[1]}**`) + .replace(/\(Player3\)/gi, `**${tributes[2]}**`) + .replace(/\(Player4\)/gi, `**${tributes[3]}**`) + .replace(/\(Player5\)/gi, `**${tributes[4]}**`) + .replace(/\(Player6\)/gi, `**${tributes[5]}**`); + } + + makeEvents(tributes, eventsArr, deaths, results) { + const turn = new Set(tributes); + for (const tribute of tributes) { + if (!turn.has(tribute)) continue; + const valid = eventsArr.filter(event => event.tributes <= turn.size && event.deaths < turn.size); + const event = valid[Math.floor(Math.random() * valid.length)]; + turn.delete(tribute); + if (event.tributes === 1) { + if (event.deaths.length === 1) { + deaths.push(tribute); + tributes.delete(tribute); + } + results.push(this.parseEvent(event.text, [tribute])); + } else { + let deathsLeft = event.deaths.length; + const current = [tribute]; + if (event.deaths.includes(1)) { + --deathsLeft; + deaths.push(tribute); + tributes.delete(tribute); + } + for (let i = 2; i <= event.tributes; i++) { + const tribu = [...turn][Math.floor(Math.random() * turn.size)]; + if (deathsLeft && event.deaths.includes(i)) { + --deathsLeft; + deaths.push(tribu); + tributes.delete(tribu); + } + current.push(tribu); + turn.delete(tribu); + } + results.push(this.parseEvent(event.text, current)); + } + } + } +}; diff --git a/commands/games/tic-tac-toe.js b/commands/games/tic-tac-toe.js index dc275c5a..a8ddadf4 100644 --- a/commands/games/tic-tac-toe.js +++ b/commands/games/tic-tac-toe.js @@ -1,5 +1,6 @@ const { Command } = require('discord.js-commando'); const { stripIndents } = require('common-tags'); +const { verify } = require('../../util/Util'); module.exports = class TicTacToeCommand extends Command { constructor(client) { @@ -27,11 +28,8 @@ module.exports = class TicTacToeCommand extends Command { this.playing.add(msg.channel.id); try { await msg.say(`${opponent}, do you accept this challenge?`); - const verify = await msg.channel.awaitMessages(res => res.author.id === opponent.id, { - max: 1, - time: 30000 - }); - if (!verify.size || !['yes', 'y'].includes(verify.first().content.toLowerCase())) { + const verification = await verify(msg.channel, opponent); + if (!verification) { this.playing.delete(msg.channel.id); return msg.say('Looks like they declined...'); } diff --git a/commands/moderation/ban.js b/commands/moderation/ban.js index eba78cee..fa7cca58 100644 --- a/commands/moderation/ban.js +++ b/commands/moderation/ban.js @@ -1,5 +1,6 @@ const { Command } = require('discord.js-commando'); const { stripIndents } = require('common-tags'); +const { verify } = require('../../util/Util'); module.exports = class BanCommand extends Command { constructor(client) { @@ -39,11 +40,8 @@ module.exports = class BanCommand extends Command { return msg.say('Your roles are too low to ban this member.'); } await msg.say(`Are you sure you want to ban ${member.user.tag} (${member.id})?`); - const msgs = await msg.channel.awaitMessages(res => res.author.id === msg.author.id, { - max: 1, - time: 30000 - }); - if (!msgs.size || !['y', 'yes'].includes(msgs.first().content.toLowerCase())) return msg.say('Aborting.'); + const verification = await verify(msg.channel, msg.author); + if (!verification) return msg.say('Aborting.'); try { await member.send(stripIndents` You were banned from ${msg.guild.name} by ${msg.author.tag}! diff --git a/commands/moderation/hackban.js b/commands/moderation/hackban.js index 7d0cca3a..3e3bfb70 100644 --- a/commands/moderation/hackban.js +++ b/commands/moderation/hackban.js @@ -1,4 +1,5 @@ const { Command } = require('discord.js-commando'); +const { verify } = require('../../util/Util'); module.exports = class HackbanCommand extends Command { constructor(client) { @@ -40,11 +41,8 @@ module.exports = class HackbanCommand extends Command { return msg.say('Could not resolve user.'); } await msg.say(`Are you sure you want to hackban ${user.tag} (${user.id})?`); - const msgs = await msg.channel.awaitMessages(res => res.author.id === msg.author.id, { - max: 1, - time: 30000 - }); - if (!msgs.size || !['y', 'yes'].includes(msgs.first().content.toLowerCase())) return msg.say('Aborting.'); + const verification = await verify(msg.channel, msg.author); + if (!verification) return msg.say('Aborting.'); try { await msg.guild.ban(id, { days: 7, diff --git a/commands/moderation/kick.js b/commands/moderation/kick.js index e33ac2f0..ea544951 100644 --- a/commands/moderation/kick.js +++ b/commands/moderation/kick.js @@ -1,5 +1,6 @@ const { Command } = require('discord.js-commando'); const { stripIndents } = require('common-tags'); +const { verify } = require('../../util/Util'); module.exports = class KickCommand extends Command { constructor(client) { @@ -39,11 +40,8 @@ module.exports = class KickCommand extends Command { return msg.say('Your roles are too low to kick this member.'); } await msg.say(`Are you sure you want to kick ${member.user.tag} (${member.id})?`); - const msgs = await msg.channel.awaitMessages(res => res.author.id === msg.author.id, { - max: 1, - time: 30000 - }); - if (!msgs.size || !['y', 'yes'].includes(msgs.first().content.toLowerCase())) return msg.say('Aborting.'); + const verification = await verify(msg.channel, msg.author); + if (!verification) return msg.say('Aborting.'); try { await member.send(stripIndents` You were kicked from ${msg.guild.name} by ${msg.author.tag}! diff --git a/commands/moderation/softban.js b/commands/moderation/softban.js index 4058223a..3b60fe90 100644 --- a/commands/moderation/softban.js +++ b/commands/moderation/softban.js @@ -1,5 +1,6 @@ const { Command } = require('discord.js-commando'); const { stripIndents } = require('common-tags'); +const { verify } = require('../../util/Util'); module.exports = class SoftbanCommand extends Command { constructor(client) { @@ -39,11 +40,8 @@ module.exports = class SoftbanCommand extends Command { return msg.say('Your roles are too low to softban this member.'); } await msg.say(`Are you sure you want to softban ${member.user.tag} (${member.id})?`); - const msgs = await msg.channel.awaitMessages(res => res.author.id === msg.author.id, { - max: 1, - time: 30000 - }); - if (!msgs.size || !['y', 'yes'].includes(msgs.first().content.toLowerCase())) return msg.say('Aborting.'); + const verification = await verify(msg.channel, msg.author); + if (!verification) return msg.say('Aborting.'); try { await member.send(stripIndents` You were softbanned from ${msg.guild.name} by ${msg.author.tag}! diff --git a/commands/moderation/unban.js b/commands/moderation/unban.js index ff6d58b7..8255d1f2 100644 --- a/commands/moderation/unban.js +++ b/commands/moderation/unban.js @@ -1,4 +1,5 @@ const { Command } = require('discord.js-commando'); +const { verify } = require('../../util/Util'); module.exports = class UnbanCommand extends Command { constructor(client) { @@ -35,11 +36,8 @@ module.exports = class UnbanCommand extends Command { if (!bans.has(id)) return msg.say('This ID is not in the server banlist.'); const member = bans.get(id).user; await msg.say(`Are you sure you want to unban ${member.tag} (${member.id})?`); - const msgs = await msg.channel.awaitMessages(res => res.author.id === msg.author.id, { - max: 1, - time: 30000 - }); - if (!msgs.size || !['y', 'yes'].includes(msgs.first().content.toLowerCase())) return msg.say('Aborting.'); + const verification = await verify(msg.channel, msg.author); + if (!verification) return msg.say('Aborting.'); await msg.guild.unban(member, `${msg.author.tag}: ${reason}`); return msg.say(`Successfully unbanned ${member.tag}.`); } diff --git a/commands/text-edit/anagram.js b/commands/text-edit/anagram.js new file mode 100644 index 00000000..43ad0dc2 --- /dev/null +++ b/commands/text-edit/anagram.js @@ -0,0 +1,39 @@ +const { Command } = require('discord.js-commando'); +const snekfetch = require('snekfetch'); + +module.exports = class AnagramCommand extends Command { + constructor(client) { + super(client, { + name: 'anagram', + group: 'text-edit', + memberName: 'anagram', + description: 'Gets an anagram for a word.', + args: [ + { + key: 'word', + prompt: 'What word would you like to get an anagram for?', + type: 'string', + parse: word => encodeURIComponent(word.toLowerCase()) + }, + { + key: 'strict', + prompt: 'Would you like to get only words that contain all letters?', + type: 'boolean', + default: true + } + ] + }); + } + + async run(msg, { word, strict }) { + try { + const { body } = await snekfetch.get(`http://www.anagramica.com/best/${word}`); + if (!body.best.length) return msg.say('Could not find any results.'); + const words = strict ? body.best.filter(anagram => anagram.length === word.length) : body.best; + return msg.say(words[Math.floor(Math.random() * words.length)]); + } catch (err) { + if (err.status === 500) return msg.say('Could not find any results.'); + return msg.say(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); + } + } +}; diff --git a/package.json b/package.json index 93fd86cd..551f1737 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiaobot", - "version": "47.4.3", + "version": "47.5.0", "description": "Your personal server companion.", "main": "Shard.js", "scripts": { diff --git a/util/Util.js b/util/Util.js index d7af072e..c5bbfcaa 100644 --- a/util/Util.js +++ b/util/Util.js @@ -91,6 +91,14 @@ class Util { ctx.putImageData(data, x, y); return ctx; } + + static async verify(channel, user, time = 30000) { + const verify = await channel.awaitMessages(res => res.author.id === user.id, { + max: 1, + time + }); + return verify.size && ['yes', 'y', 'ye', 'yeah', 'yup'].includes(verify.first().content.toLowerCase()); + } } module.exports = Util;