From b02812f3022d807e3cced6dd21288e8cd8b2e124 Mon Sep 17 00:00:00 2001 From: DigiDuncan Date: Tue, 7 Nov 2023 15:19:14 -0500 Subject: [PATCH] add quake command --- sizebot/cogs/quake.py | 53 +++++++++++++++++++++++++++++++++++++++++ sizebot/lib/quake.py | 55 +++++++++++++++++++++++++++++++++++++++++++ sizebot/main.py | 1 + 3 files changed, 109 insertions(+) create mode 100644 sizebot/cogs/quake.py create mode 100644 sizebot/lib/quake.py diff --git a/sizebot/cogs/quake.py b/sizebot/cogs/quake.py new file mode 100644 index 00000000..0589e7c5 --- /dev/null +++ b/sizebot/cogs/quake.py @@ -0,0 +1,53 @@ +from decimal import Decimal +import typing +from discord import Embed +import discord +from discord.ext import commands + +from sizebot.lib.constants import colors +from sizebot.lib.fakeplayer import FakePlayer +from sizebot.lib.quake import joules_to_mag, mag_to_name, mag_to_radius, step_joules +from sizebot.lib.units import SV +from sizebot.lib.userdb import load_or_fake + +EARTH_RAD = 10_018_570 + +class QuakeCog(commands.Cog): + """Quake commands.""" + + def __init__(self, bot): + self.bot = bot + + @commands.command(aliases = ["quake"], + usage = "[user/height]", + category = "stats") + async def earthquake(self, ctx, user: typing.Union[discord.Member, FakePlayer, SV] = None): + """See what quakes would be caused by your steps.""" + if user is None: + user = ctx.author + userdata = load_or_fake(user) + joules = step_joules(userdata) + mag = joules_to_mag(joules) + e_type = mag_to_name(mag).title() + rad = mag_to_radius(mag) + print_mag = max(mag, Decimal(0.0)) + if rad < EARTH_RAD: + print_rad = f"{rad:,.1mu}" + else: + e_rad = rad / EARTH_RAD + print_rad = f"{e_rad:,.2} 🌎" + e = Embed( + title=f"Earthquake generated by {userdata.nickname} stepping", + description=f"{userdata.nickname} is {userdata.height:,.3mu} tall, and weighs {userdata.weight:,.3mu}.", + color=colors.cyan + ) + e.add_field(name = "Magnitude", value = f"{print_mag:,.1}") + e.add_field(name = "Joules", value = f"{joules:,.0}") + e.add_field(name = "Earthquake Type", value = e_type) + e.add_field(name = "Radius", value = print_rad) + + await ctx.send(embed = e) + + +async def setup(bot): + await bot.add_cog(QuakeCog(bot)) diff --git a/sizebot/lib/quake.py b/sizebot/lib/quake.py new file mode 100644 index 00000000..05bc9e57 --- /dev/null +++ b/sizebot/lib/quake.py @@ -0,0 +1,55 @@ +import math + +from sizebot.lib.digidecimal import Decimal +from sizebot.lib.userdb import User +from sizebot.lib.units import SV + +G = 9.81 +STOMP_G = 11.5 + +STEP_FACTOR = 0.07 +STOMP_FACTOR = 0.5 +JUMP_FACTOR = 0.43 + +def joules_to_mag(joules: float) -> Decimal: + # This might not be super accurate. + return Decimal(2/3) * Decimal(math.log10(joules)) - Decimal(3.2) + +def mag_to_radius(mag: float) -> SV: + return SV(Decimal(math.exp(Decimal(mag) / Decimal(1.01) - Decimal(0.13))) * 1000) + +def mag_to_name(mag: float) -> str: + if mag < 1: + return "no" + elif mag < 3: + return "unnoticeable" + elif mag < 4: + return "minor" + elif mag < 5: + return "light" + elif mag < 6: + return "moderate" + elif mag < 7: + return "strong" + elif mag < 8: + return "major" + elif mag < 9: + return "great" + elif mag < 10: + return "extreme" + elif mag < 22: + return "apocalyptic" + else: + return "earth-ending" + +def scale_to_joules(user: User, g: float, factor: float) -> int: + return math.floor((user.weight * Decimal(0.4536)) / 2 * Decimal(g) * (Decimal(factor) * user.scale)) + +def step_joules(user: User) -> int: + return scale_to_joules(user, G, STEP_FACTOR) + +def stomp_joules(user: User) -> int: + return scale_to_joules(user, STOMP_G, STOMP_FACTOR) + +def jump_joules(user: User) -> int: + return scale_to_joules(user, G, JUMP_FACTOR) diff --git a/sizebot/main.py b/sizebot/main.py index 3013c902..87decd88 100644 --- a/sizebot/main.py +++ b/sizebot/main.py @@ -52,6 +52,7 @@ "objects", "pokemon", "profile", + "quake", # "rainbow", "register", "roll",