mirror of
https://github.com/brandons209/Red-bot-Cogs.git
synced 2024-05-19 11:52:55 +12:00
add trick or treat cog
This commit is contained in:
parent
24a8601053
commit
9da4fbb312
5
trickortreat/__init__.py
Normal file
5
trickortreat/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from .trickortreat import TrickorTreat
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.add_cog(TrickorTreat(bot))
|
17
trickortreat/info.json
Normal file
17
trickortreat/info.json
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
"author": [
|
||||||
|
"Brandons209"
|
||||||
|
],
|
||||||
|
"bot_version": [
|
||||||
|
3,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"description": "Trick or treat! Sometimes you get some credits, sometimes you get tricked and lose them!",
|
||||||
|
"hidden": false,
|
||||||
|
"install_msg": "Thank you for using this cog! Please make sure to setup the cog using [p]totset",
|
||||||
|
"requirements": [],
|
||||||
|
"short": "Provides a fun way to get currency during spooktober.",
|
||||||
|
"tags": [
|
||||||
|
"brandons209",
|
||||||
|
"Halloween"
|
||||||
|
]
|
315
trickortreat/trickortreat.py
Normal file
315
trickortreat/trickortreat.py
Normal file
|
@ -0,0 +1,315 @@
|
||||||
|
from redbot.core.utils.chat_formatting import *
|
||||||
|
from redbot.core import Config, checks, commands, bank
|
||||||
|
from redbot.core.utils.predicates import MessagePredicate
|
||||||
|
import discord
|
||||||
|
import asyncio
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
from .utils import parse_timedelta, display_time
|
||||||
|
|
||||||
|
MAX_MSG_LEN = 1900
|
||||||
|
|
||||||
|
|
||||||
|
class TrickorTreat(commands.Cog):
|
||||||
|
"""
|
||||||
|
Modified payday command to give you some treats, or sometimes a trick!
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
self.config = Config.get_conf(self, identifier=5894564654561635, force_registration=True)
|
||||||
|
default_guild = {
|
||||||
|
"treat_msgs": [
|
||||||
|
"Aurelia likes your costume!",
|
||||||
|
"A house is giving out your favorite candy!",
|
||||||
|
'You win the "best costume" competition!',
|
||||||
|
"Your Halloween party is a massive hit!",
|
||||||
|
"Your front lawn is the spookiest in the whole neighborhood!",
|
||||||
|
"You and your friends have a Halloween movie marathon!",
|
||||||
|
"You managed to repulse a vampire with garlic!",
|
||||||
|
"You got invited to the biggest Halloween party!",
|
||||||
|
"Your crush said they liked your costume!",
|
||||||
|
"You enter a graveyard filled with dancing skeletons. Time to party!",
|
||||||
|
"A little ghost noticed your ghost costume and wants to be your friend!",
|
||||||
|
"You notice someone disguised as one of your favorite characters! You approach them and they let you take a picture with them!",
|
||||||
|
"A house is giving out FULL SIZED CHOCOLATE BARS! Best night ever!",
|
||||||
|
"You got to scare someone really good with your costume!",
|
||||||
|
"After an awesome night out, you fill your tummy with delicious candy! All is good.",
|
||||||
|
],
|
||||||
|
"trick_msgs": [
|
||||||
|
"A hole tears in your candy bag and you lose a bunch of candies before you fix it!",
|
||||||
|
"You're wearing the same costume as someone else! Someone’s gonna have to change.",
|
||||||
|
"It starts raining and your spooky getup is ruined! Oh no!",
|
||||||
|
"This house is only giving out... CANDY CORN! THE HORROR! THE HORROR!",
|
||||||
|
"All the Halloween candy at the store is sold out!",
|
||||||
|
"You got lost in a cemetery where the dead is rising! Ruuuuuun!",
|
||||||
|
"Your ghost costume made a real ghost angry and he started to haunt you!",
|
||||||
|
"A witch turns you into a frog!",
|
||||||
|
"A vampire attacks you because you forgot your garlic necklace at home. Uh-oh!",
|
||||||
|
"A black cat crosses your path and you trip, dropping a bunch of candies!",
|
||||||
|
"You wandered in the woods and got lost when you suddenly see what looks like a very tall and slender man in the distance.",
|
||||||
|
"You slipped in a puddle and dropped candies in a sewer opening where you hear some laughing. Suddenly a red balloon appears from inside.",
|
||||||
|
"You and your friends go to a lake, when suddenly something.. or someone is coming out of it, holding a machete.",
|
||||||
|
"As you walk with your friends, you suddenly hear the sound of a chainsaw revving up from behind you. It’s rapidly getting closer.",
|
||||||
|
"You got sick and had to miss trick or treating! :(",
|
||||||
|
],
|
||||||
|
"treat_amount": 500,
|
||||||
|
"treat_chance": 0.4,
|
||||||
|
"pay_delay": 1200,
|
||||||
|
}
|
||||||
|
|
||||||
|
default_member = {"last_pay": 0}
|
||||||
|
|
||||||
|
self.config.register_guild(**default_guild)
|
||||||
|
self.config.register_member(**default_member)
|
||||||
|
|
||||||
|
@commands.group()
|
||||||
|
@commands.guild_only()
|
||||||
|
@checks.admin()
|
||||||
|
async def totset(self, ctx):
|
||||||
|
"""
|
||||||
|
Manage your tricks and treats!
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@totset.command()
|
||||||
|
async def amount(self, ctx, amount: int):
|
||||||
|
"""
|
||||||
|
Set the amount of currency to give on a treat
|
||||||
|
"""
|
||||||
|
if amount <= 0:
|
||||||
|
await ctx.send(error("Please use an amount greater than 0."))
|
||||||
|
return
|
||||||
|
await self.config.guild(ctx.guild).treat_amount.set(amount)
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
@totset.command()
|
||||||
|
async def chance(self, ctx, chance: float):
|
||||||
|
"""
|
||||||
|
Set the chance for a treat to occur
|
||||||
|
|
||||||
|
Chance should be between 0 and 1.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if chance <= 0 or chance > 1:
|
||||||
|
await ctx.send(error("Please use a chance amount between 0 and 1."))
|
||||||
|
return
|
||||||
|
|
||||||
|
await self.config.guild(ctx.guild).treat_chance.set(chance)
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
@totset.command()
|
||||||
|
async def delay(self, ctx, *, delay: str):
|
||||||
|
"""
|
||||||
|
Set delay between trick or treats.
|
||||||
|
|
||||||
|
Delay can be an interval like:
|
||||||
|
|
||||||
|
15 minutes
|
||||||
|
30 seconds
|
||||||
|
5 minutes 30 seconds
|
||||||
|
10m30s
|
||||||
|
|
||||||
|
4 hours
|
||||||
|
4h30m
|
||||||
|
"""
|
||||||
|
|
||||||
|
delta = parse_timedelta(delay)
|
||||||
|
|
||||||
|
if not delta:
|
||||||
|
await ctx.send(error("Unrecognized delay, try again."))
|
||||||
|
return
|
||||||
|
|
||||||
|
await self.config.guild(ctx.guild).pay_delay.set(delta.total_seconds())
|
||||||
|
|
||||||
|
await ctx.send(f"Delay set to {display_time(delta.total_seconds())}")
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
@totset.group(name="treatmsg")
|
||||||
|
async def treatmsg(self, ctx):
|
||||||
|
"""
|
||||||
|
Manage messages sent for getting a treat.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@treatmsg.command(name="add")
|
||||||
|
async def treatmsg_add(self, ctx, *, msg: str):
|
||||||
|
"""
|
||||||
|
Add a new possible message sent for a treat
|
||||||
|
"""
|
||||||
|
|
||||||
|
async with self.config.guild(ctx.guild).treat_msgs() as treat_msgs:
|
||||||
|
treat_msgs.append(msg)
|
||||||
|
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
@treatmsg.command(name="del")
|
||||||
|
async def treatmsg_del(self, ctx):
|
||||||
|
"""
|
||||||
|
Delete one of the treat messages
|
||||||
|
"""
|
||||||
|
|
||||||
|
async with self.config.guild(ctx.guild).treat_msgs() as treat_msgs:
|
||||||
|
if not treat_msgs:
|
||||||
|
await ctx.send(warning("No messages defined!"))
|
||||||
|
return
|
||||||
|
msg = "\n".join(f"{i+1}. {m}" for i, m in enumerate(treat_msgs))
|
||||||
|
|
||||||
|
for page in pagify(msg):
|
||||||
|
await ctx.send(box(page))
|
||||||
|
|
||||||
|
await ctx.send("Choose the number of the message to delete.")
|
||||||
|
pred = MessagePredicate.valid_int()
|
||||||
|
|
||||||
|
try:
|
||||||
|
await self.bot.wait_for("message", check=pred, timeout=30)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await ctx.send("Took too long.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if pred.result < 1 or pred.result > len(treat_msgs):
|
||||||
|
await ctx.send(error("Please choose one of the messages."))
|
||||||
|
return
|
||||||
|
|
||||||
|
del treat_msgs[pred.result - 1]
|
||||||
|
|
||||||
|
await ctx.send("Deleted message.")
|
||||||
|
|
||||||
|
@treatmsg.command(name="list")
|
||||||
|
async def treatmsg_list(self, ctx):
|
||||||
|
"""
|
||||||
|
List all treat messages
|
||||||
|
"""
|
||||||
|
|
||||||
|
async with self.config.guild(ctx.guild).treat_msgs() as treat_msgs:
|
||||||
|
if not treat_msgs:
|
||||||
|
await ctx.send(warning("No messages defined!"))
|
||||||
|
return
|
||||||
|
|
||||||
|
msg = "\n".join(f"{i+1}. {m}" for i, m in enumerate(treat_msgs))
|
||||||
|
|
||||||
|
for page in pagify(msg):
|
||||||
|
await ctx.send(box(page))
|
||||||
|
|
||||||
|
@totset.group(name="trickmsg")
|
||||||
|
async def trickmsg(self, ctx):
|
||||||
|
"""
|
||||||
|
Manage messages sent for getting a trick.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@trickmsg.command(name="add")
|
||||||
|
async def trickmsg_add(self, ctx, *, msg: str):
|
||||||
|
"""
|
||||||
|
Add a new possible message sent for a trick
|
||||||
|
"""
|
||||||
|
|
||||||
|
async with self.config.guild(ctx.guild).trick_msgs() as trick_msgs:
|
||||||
|
trick_msgs.append(msg)
|
||||||
|
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
@trickmsg.command(name="del")
|
||||||
|
async def trickmsg_del(self, ctx):
|
||||||
|
"""
|
||||||
|
Delete one of the trick messages
|
||||||
|
"""
|
||||||
|
|
||||||
|
async with self.config.guild(ctx.guild).trick_msgs() as trick_msgs:
|
||||||
|
if not trick_msgs:
|
||||||
|
await ctx.send(warning("No messages defined!"))
|
||||||
|
return
|
||||||
|
msg = "\n".join(f"{i+1}. {m}" for i, m in enumerate(trick_msgs))
|
||||||
|
|
||||||
|
for page in pagify(msg):
|
||||||
|
await ctx.send(box(page))
|
||||||
|
|
||||||
|
await ctx.send("Choose the number of the message to delete.")
|
||||||
|
pred = MessagePredicate.valid_int()
|
||||||
|
|
||||||
|
try:
|
||||||
|
await self.bot.wait_for("message", check=pred, timeout=30)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await ctx.send("Took too long.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if pred.result < 1 or pred.result > len(trick_msgs):
|
||||||
|
await ctx.send(error("Please choose one of the messages."))
|
||||||
|
return
|
||||||
|
|
||||||
|
del trick_msgs[pred.result - 1]
|
||||||
|
|
||||||
|
await ctx.send("Deleted message.")
|
||||||
|
|
||||||
|
@trickmsg.command(name="list")
|
||||||
|
async def trickmsg_list(self, ctx):
|
||||||
|
"""
|
||||||
|
List all trick messages
|
||||||
|
"""
|
||||||
|
|
||||||
|
async with self.config.guild(ctx.guild).trick_msgs() as trick_msgs:
|
||||||
|
if not trick_msgs:
|
||||||
|
await ctx.send(warning("No messages defined!"))
|
||||||
|
return
|
||||||
|
|
||||||
|
msg = "\n".join(f"{i+1}. {m}" for i, m in enumerate(trick_msgs))
|
||||||
|
|
||||||
|
for page in pagify(msg):
|
||||||
|
await ctx.send(box(page))
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
@commands.guild_only()
|
||||||
|
async def trickortreat(self, ctx):
|
||||||
|
"""
|
||||||
|
Get a treat, or maybe a sneaky trick!
|
||||||
|
"""
|
||||||
|
guild = ctx.guild
|
||||||
|
delay = await self.config.guild(guild).pay_delay()
|
||||||
|
last_pay = await self.config.member(ctx.author).last_pay()
|
||||||
|
next_pay = last_pay + delay
|
||||||
|
if time.time() < next_pay:
|
||||||
|
await ctx.send(
|
||||||
|
f"Too soon {ctx.author.mention}, gotta find another house! The next house is {display_time(next_pay - time.time())} away."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
currency_name = await bank.get_currency_name(guild)
|
||||||
|
amount = await self.config.guild(guild).treat_amount()
|
||||||
|
chance = await self.config.guild(guild).treat_chance()
|
||||||
|
|
||||||
|
if random.random() < chance:
|
||||||
|
# treat!
|
||||||
|
msg = random.choice(await self.config.guild(guild).treat_msgs())
|
||||||
|
if len(msg) < MAX_MSG_LEN:
|
||||||
|
await ctx.send(f"**{msg}**\n\nYou got {amount} {currency_name} {ctx.author.mention}!")
|
||||||
|
else:
|
||||||
|
await ctx.send(f"{random.choice(treat_msgs)}")
|
||||||
|
await ctx.send(f"You got {amount} {currency_name} {ctx.author.mention}!")
|
||||||
|
|
||||||
|
try:
|
||||||
|
await bank.deposit_credits(ctx.author, amount)
|
||||||
|
except errors.BalanceTooHigh as exc:
|
||||||
|
await bank.set_balance(author, exc.max_balance)
|
||||||
|
await ctx.send(
|
||||||
|
_(
|
||||||
|
"You've reached the maximum amount of {currency}! "
|
||||||
|
"Please spend some more \N{GRIMACING FACE}\n\n"
|
||||||
|
"You currently have {new_balance} {currency}."
|
||||||
|
).format(currency=currency_name, new_balance=humanize_number(exc.max_balance))
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# trick!
|
||||||
|
msg = random.choice(await self.config.guild(guild).trick_msgs())
|
||||||
|
if len(msg) < MAX_MSG_LEN:
|
||||||
|
await ctx.send(f"**{msg}**\n\nYou lost {amount} {currency_name} {ctx.author.mention}!")
|
||||||
|
else:
|
||||||
|
await ctx.send(f"{random.choice(treat_msgs)}")
|
||||||
|
await ctx.send(f"You lost {amount} {currency_name} {ctx.author.mention}!")
|
||||||
|
|
||||||
|
bal = await bank.get_balance(ctx.author)
|
||||||
|
if bal < amount:
|
||||||
|
await bank.withdraw_credits(ctx.author, bal)
|
||||||
|
else:
|
||||||
|
await bank.withdraw_credits(ctx.author, amount)
|
||||||
|
|
||||||
|
await self.config.member(ctx.author).last_pay.set(time.time())
|
46
trickortreat/utils.py
Normal file
46
trickortreat/utils.py
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import pytz
|
||||||
|
from typing import Optional
|
||||||
|
from datetime import timedelta
|
||||||
|
import re
|
||||||
|
|
||||||
|
TIME_RE_STRING = r"\s?".join(
|
||||||
|
[
|
||||||
|
r"((?P<weeks>\d+?)\s?(weeks?|w))?",
|
||||||
|
r"((?P<days>\d+?)\s?(days?|d))?",
|
||||||
|
r"((?P<hours>\d+?)\s?(hours?|hrs|hr?))?",
|
||||||
|
r"((?P<minutes>\d+?)\s?(minutes?|mins?|m(?!o)))?", # prevent matching "months"
|
||||||
|
r"((?P<seconds>\d+?)\s?(seconds?|secs?|s))?",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
TIME_RE = re.compile(TIME_RE_STRING, re.I)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_timedelta(argument: str) -> Optional[timedelta]:
|
||||||
|
matches = TIME_RE.match(argument)
|
||||||
|
if matches:
|
||||||
|
params = {k: int(v) for k, v in matches.groupdict().items() if v}
|
||||||
|
if params:
|
||||||
|
return timedelta(**params)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def display_time(seconds, granularity=2) -> str:
|
||||||
|
intervals = ( # Source: http://stackoverflow.com/a/24542445
|
||||||
|
("weeks", 604800), # 60 * 60 * 24 * 7
|
||||||
|
("days", 86400), # 60 * 60 * 24
|
||||||
|
("hours", 3600), # 60 * 60
|
||||||
|
("minutes", 60),
|
||||||
|
("seconds", 1),
|
||||||
|
)
|
||||||
|
|
||||||
|
result = []
|
||||||
|
|
||||||
|
for name, count in intervals:
|
||||||
|
value = int(seconds // count)
|
||||||
|
if value:
|
||||||
|
seconds -= value * count
|
||||||
|
if value == 1:
|
||||||
|
name = name.rstrip("s")
|
||||||
|
result.append("{} {}".format(value, name))
|
||||||
|
return ", ".join(result[:granularity])
|
Loading…
Reference in a new issue