async def setstrength(self, ctx, *, newstrength): """Set your current lift/carry strength.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.liftstrength = WV( WV.parse(newstrength) * (userdata.viewscale**3)) userdb.save(userdata) await ctx.send( f"{userdata.nickname}'s base lift strength is now {userdata.liftstrength:mu} long, " f"or {SV(userdata.liftstrength):mu} currently.") await showNextStep(ctx, userdata)
async def setweight(self, ctx, *, newweight): """Set your current weight.""" userdata = userdb.load(ctx.guild.id, ctx.author.id) userdata.baseweight = WV(WV.parse(newweight) * (userdata.viewscale**3)) userdb.save(userdata) logger.info( f"User {ctx.author.id} ({ctx.author.display_name}) changed their weight to {newweight}." ) await ctx.send( f"<@{ctx.author.id}>'s weight is now {userdata.weight:mu}") await proportions.nickUpdate(ctx.author)
def WV_parse(): s = request.args.get("s") try: val = WV.parse(s) except InvalidSizeValue: abort(404) return json.dumps({"WV": str(val)})
def __init__(self, userdata): self.nickname = userdata.nickname self.tag = userdata.tag self.gender = userdata.gender self.height = userdata.height self.baseheight = userdata.baseheight self.viewscale = userdata.viewscale self.scale = userdata.scale self.formattedscale = userdata.getFormattedScale(verbose=True) self.baseweight = userdata.baseweight self.weight = userdata.weight self.formattedweightscale = userdata.getFormattedScale( scaletype="weight", verbose=True) self.averageheightmult = self.height / defaultheight self.averageweightmult = self.weight / defaultweight if userdata.hairlength is None: self.hairlength = None else: self.hairlength = SV(userdata.hairlength / self.viewscale) if userdata.taillength is None: self.taillength = None else: self.taillength = SV(userdata.taillength / self.viewscale) if userdata.footlength is None: self.footlength = SV(self.height * self.footfactor) else: self.footlength = SV(userdata.footlength / self.viewscale) self.shoesize = formatShoeSize(self.footlength, self.gender == "f") self.footwidth = SV(self.height * self.footwidthfactor) self.toeheight = SV(self.height * self.toeheightfactor) self.shoeprintdepth = SV(self.height * self.toeheightfactor) self.pointerlength = SV(self.height * self.pointerfactor) self.thumbwidth = SV(self.height * self.thumbfactor) self.fingerprintdepth = SV(self.height * self.fingerprintfactor) defaultthreadthickness = SV.parse("1.016mm") self.threadthickness = SV(defaultthreadthickness * self.averageheightmult) self.hairwidth = SV(self.height * self.hairfactor) self.nailthickness = SV(self.height * self.nailthickfactor) self.eyewidth = SV(self.height * self.eyewidthfactor) self.avgheightcomp = SV(defaultheight * self.viewscale) self.avgweightcomp = WV(defaultweight * self.viewscale**3) viewangle = calcViewAngle(self.height, defaultheight) self.avglookangle = abs(viewangle) self.avglookdirection = "up" if viewangle >= 0 else "down" defaultwalkspeed = SV.parse("2.5mi") defaultrunspeed = SV.parse("7.5mi") self.walkperhour = SV(defaultwalkspeed * self.averageheightmult) self.runperhour = SV(defaultrunspeed * self.averageheightmult)
def WV_format(): value = Decimal(request.args.get("value")) system = request.args.get("system") try: val = WV(value) except InvalidSizeValue: abort(404) return json.dumps({"formatted": format(val, system)})
def addToUnits(self): if self.unitlength is not None: SV.addUnit( Unit(factor=self.unitlength, name=self.name, namePlural=self.namePlural, names=self.aliases, symbol=self.symbol)) SV.addSystemUnit("o", SystemUnit(self.name)) if self.weight is not None: WV.addUnit( Unit(factor=self.weight, name=self.name, namePlural=self.namePlural, names=self.aliases, symbol=self.symbol)) WV.addSystemUnit("o", SystemUnit(self.name))
async def setbaseweight(self, ctx, *, newbaseweight: WV): """Change base weight.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) if "setweight" in userdata.registration_steps_remaining: if not (WV.parse("10lb") < newbaseweight < WV.parse("1000lb")): await ctx.send( f"{emojis.warning} **WARNING:** Your base weight should probably be something more human-scale. This makes comparison math work out much nicer. If this was intended, you can ignore this warning, but it is ***highly recommended*** that you have a base weight similar to that of a normal human being." ) userdata.baseweight = newbaseweight completed_registration = userdata.complete_step("setweight") userdb.save(userdata) await ctx.send( f"{userdata.nickname}'s base weight is now {userdata.baseweight:mu}" ) await proportions.nickUpdate(ctx.author) await showNextStep(ctx, userdata, completed=completed_registration)
async def setbaseweight(self, ctx, *, newbaseweight): """Change base weight.""" userdata = userdb.load(ctx.guild.id, ctx.author.id) userdata.baseweight = WV.parse(newbaseweight) userdb.save(userdata) logger.info( f"User {ctx.author.id} ({ctx.author.display_name}) changed their base weight to {newbaseweight}." ) await ctx.send( f"<@{ctx.author.id}>'s base weight is now {userdata.baseweight:mu}" ) await proportions.nickUpdate(ctx.author)
async def setbase(self, ctx, arg1: typing.Union[SV, WV], arg2: typing.Union[SV, WV] = None): """Set your base height and weight.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) # Don't allow a user to enter setbase(SV, SV) or setbase(WV, WV) if (isinstance(arg1, SV) and isinstance(arg2, SV)) or (isinstance(arg1, WV) and isinstance(arg2, WV)): raise errors.UserMessedUpException( "Please do not enter two heights or two weights.") newbaseheight = None newbaseweight = None for arg in [arg1, arg2]: if isinstance(arg, SV): newbaseheight = arg if isinstance(arg, WV): newbaseweight = arg completed_registration = False if newbaseheight is not None: if "setheight" in userdata.registration_steps_remaining: userdata.height = newbaseheight if not (SV.parse("4ft") < newbaseheight < SV.parse("8ft")): await ctx.send( f"{emojis.warning} **WARNING:** Your base height should probably be something more human-scale. This makes comparison math work out much nicer. If this was intended, you can ignore this warning, but it is ***highly recommended*** that you have a base height similar to the size of a normal human being." ) userdata.baseheight = newbaseheight completed_registration = userdata.complete_step( "setheight") or completed_registration if newbaseweight is not None: if "setweight" in userdata.registration_steps_remaining: if not (WV.parse("10lb") < newbaseheight < SV.parse("1000lb")): await ctx.send( f"{emojis.warning} **WARNING:** Your base weight should probably be something more human-scale. This makes comparison math work out much nicer. If this was intended, you can ignore this warning, but it is ***highly recommended*** that you have a base weight similar to that of a normal human being." ) userdata.baseweight = newbaseweight completed_registration = userdata.complete_step( "setweight") or completed_registration userdb.save(userdata) await ctx.send( f"{userdata.nickname} changed their base height and weight to {userdata.baseheight:,.3mu} and {userdata.baseweight:,.3mu}" ) await showNextStep(ctx, userdata, completed=completed_registration)
def __init__(self, name, dimension, aliases=[], symbol=None, height=None, length=None, width=None, diameter=None, depth=None, thickness=None, weight=None): self.name = name self.namePlural = getPlural(name) self.singularNames = aliases + [self.name] self.aliases = aliases + [getPlural(a) for a in aliases] self.article = getIndefiniteArticle(self.name).split(" ")[0] self.symbol = symbol or None self.height = height and SV(height) self.length = length and SV(length) self.width = width and SV(width) self.diameter = diameter and SV(diameter) self.depth = depth and SV(depth) self.thickness = thickness and SV(thickness) self.weight = weight and WV(weight) dimensionmap = { "h": "height", "l": "length", "w": "width", "d": "diameter", "p": "depth", "t": "thickness" } self.unitlength = getattr(self, dimensionmap[dimension])
import json from copy import copy from functools import total_ordering from typing import Literal from sizebot import conf from sizebot.lib import errors from sizebot.lib.units import SV, WV # Defaults defaultheight = SV("1.754") # meters defaultweight = WV("66760") # grams # Map the deprecated user array constants to the new names # TODO: This is used never, I think? # NICK DISP CHEI BHEI BWEI UNIT SPEC DEPRECATED_NAME_MAP = [ "nickname", "display", "height", "baseheight", "baseweight", "unitsystem", "species" ] @total_ordering class User: # __slots__ declares to python what attributes to expect. __slots__ = [ "guildid", "id", "nickname", "_gender", "display", "_height", "_baseheight", "_baseweight", "_footlength", "_hairlength", "_taillength", "_unitsystem", "species" ]
def weight(self): return WV(self.baseweight * (self.scale**3))
def baseweight(self, value): value = WV(value) if value < 0: value = WV(0) self._baseweight = value
from functools import total_ordering import importlib.resources as pkg_resources from typing import Literal import arrow import sizebot.data from sizebot.lib import errors, paths from sizebot.lib.decimal import Decimal from sizebot.lib.diff import Diff, Rate as ParseableRate from sizebot.lib.units import SV, WV from sizebot.lib.utils import isURL, truncate # Defaults defaultheight = SV("1.754") # meters defaultweight = WV("66760") # grams defaultterminalvelocity = SV("63.63") # meters/second falllimit = SV("7.73") # meters/second defaultliftstrength = WV("18143.7") # grams modelJSON = json.loads(pkg_resources.read_text(sizebot.data, "models.json")) @total_ordering class User: # __slots__ declares to python what attributes to expect. __slots__ = [ "guildid", "id", "nickname", "lastactive", "_picture_url", "description", "_gender", "display", "_height", "_baseheight", "_baseweight", "_footlength", "_pawtoggle", "_furtoggle", "_hairlength", "_taillength", "_earheight", "_liftstrength",
def __init__(self, userdata): self.nickname = userdata.nickname self.tag = userdata.tag self.gender = userdata.autogender self.height = userdata.height self.baseheight = userdata.baseheight self.viewscale = userdata.viewscale self.scale = userdata.scale self.formattedscale = userdata.getFormattedScale(verbose=True) self.baseweight = userdata.baseweight self.weight = userdata.weight self.formattedweightscale = userdata.getFormattedScale( scaletype="weight", verbose=True) self.footname = userdata.footname self.hairname = userdata.hairname self.pawtoggle = userdata.pawtoggle self.furtoggle = userdata.furtoggle self.macrovision_model = userdata.macrovision_model self.macrovision_view = userdata.macrovision_view self.averageheightmult = self.height / defaultheight self.averageweightmult = self.weight / defaultweight if userdata.hairlength is None: self.hairlength = None else: self.hairlength = SV(userdata.hairlength / self.viewscale) if userdata.taillength is None: self.taillength = None else: self.taillength = SV(userdata.taillength / self.viewscale) if userdata.earheight is None: self.earheight = None else: self.earheight = SV(userdata.earheight / self.viewscale) if userdata.liftstrength is None: self.liftstrength = WV(defaultliftstrength / (self.viewscale**3)) else: self.liftstrength = WV(userdata.liftstrength / (self.viewscale**3)) if userdata.footlength is None: self.footlength = SV(self.height * self.footfactor) else: self.footlength = SV(userdata.footlength / self.viewscale) self.shoesize = formatShoeSize(self.footlength, self.gender == "f") self.footwidth = SV(self.height * self.footwidthfactor) self.toeheight = SV(self.height * self.toeheightfactor) self.shoeprintdepth = SV(self.height * self.toeheightfactor) self.pointerlength = SV(self.height * self.pointerfactor) self.thumbwidth = SV(self.height * self.thumbfactor) self.fingerprintdepth = SV(self.height * self.fingerprintfactor) self.threadthickness = SV(self.defaultthreadthickness * self.averageheightmult) self.hairwidth = SV( (self.baseheight * self.hairfactor) / self.viewscale) self.nailthickness = SV( (self.baseheight * self.nailthickfactor) / self.viewscale) self.eyewidth = SV(self.height * self.eyewidthfactor) self.avgheightcomp = SV(defaultheight * self.viewscale) self.avgweightcomp = WV(defaultweight * self.viewscale**3) viewangle = calcViewAngle(self.height, defaultheight) self.avglookangle = abs(viewangle) self.avglookdirection = "up" if viewangle >= 0 else "down" if userdata.walkperhour is None: self.walkperhour = SV(self.defaultwalkspeed * self.averageheightmult) else: self.walkperhour = SV(userdata.walkperhour * self.averageheightmult) if userdata.runperhour is None: self.runperhour = SV(self.defaultrunspeed * self.averageheightmult) else: self.runperhour = SV(userdata.runperhour * self.averageheightmult) self.walksteplength = SV(self.walkperhour / self.walkstepsperhour) self.runsteplength = SV(self.runperhour / self.runstepsperhour) self.horizondistance = SV( math.sqrt(math.pow(self.height + 6378137, 2) - 40680631590769)) self.terminalvelocity = SV(defaultterminalvelocity * Decimal(math.sqrt(self.scale))) self.fallproof = self.terminalvelocity < falllimit self.fallproofcheck = emojis.voteyes if self.fallproof else emojis.voteno
def baseweight(self, value): self._baseweight = WV(max(0, WV(value)))
def test_negative_WV_parse(): result = WV.parse("-12kg") assert result == WV("-12000")
async def lookat(self, ctx, *, what: typing.Union[DigiObject, discord.Member, SV, str]): """See what an object looks like to you. Used to see how an object would look at your scale. Examples: `&lookat man` `&look book` `&examine building`""" if isinstance(what, SV): telemetry.SizeViewed(what).save() userdata = getUserdata(ctx.author) if isinstance(what, str): what = what.lower() if isinstance(what, DigiObject): telemetry.ObjectUsed(str(what)).save() la = what.relativestatssentence(userdata) # Easter eggs. if what.name == "photograph": la += "\n\n<https://www.youtube.com/watch?v=BB0DU4DoPP4>" logger.log(EGG, f"{ctx.author.display_name} is jamming to Nickleback.") if what.name == "enderman": la += f"\n\n`{ctx.author.display_name} was slain by an Enderman.`" logger.log(EGG, f"{ctx.author.display_name} was slain by an Enderman.") await ctx.send(la) return elif isinstance(what, discord.Member) or isinstance(what, SV): # TODO: Make this not literally just a compare. (make a sentence) compdata = getUserdata(what) elif isinstance(what, str) and what.lower() in ["person", "man", "average", "average person", "average man", "average human", "human"]: compheight = userdb.defaultheight compdata = getUserdata(compheight, nickname = "an average person") elif isinstance(what, str) and what.lower() in ["chocolate", "stuffed animal", "stuffed beaver", "beaver"]: logger.log(EGG, f"{ctx.author.display_name} found Chocolate!") compdata = getUserdata(SV.parse("11in"), nickname = "Chocolate [Stuffed Beaver]") compdata.baseweight = WV.parse("4.8oz") compdata.footlength = SV.parse("2.75in") compdata.taillength = SV.parse("12cm") elif isinstance(what, str) and what.lower() in ["me", "myself"]: compdata = userdb.load(ctx.guild.id, ctx.author.id) else: # Easter eggs. if what.lower() in ["all those chickens", "chickens"]: await ctx.send("https://www.youtube.com/watch?v=NsLKQTh-Bqo") logger.log(EGG, f"{ctx.author.display_name} looked at all those chickens.") return if what.lower() == "that horse": await ctx.send("https://www.youtube.com/watch?v=Uz4bW2yOLXA") logger.log(EGG, f"{ctx.author.display_name} looked at that horse (it may in fact be a moth.)") return if what.lower() == "my horse": await ctx.send("https://www.youtube.com/watch?v=o7cCJqya7wc") logger.log(EGG, f"{ctx.author.display_name} looked at my horse (my horse is amazing.)") return if what.lower() == "cake": await ctx.send("The cake is a lie.") logger.log(EGG, f"{ctx.author.display_name} realized the cake was lie.") return if what.lower() == "snout": await ctx.send("https://www.youtube.com/watch?v=k2mFvwDTTt0") logger.log(EGG, f"{ctx.author.display_name} took a closer look at that snout.") return await ctx.send( f"Sorry, I don't know what `{what}` is.\n" f"If this is an object or alias you'd like added to SizeBot, " f"use `{ctx.prefix}suggestobject` to suggest it " f"(see `{ctx.prefix}help suggestobject` for instructions on doing that.)" ) telemetry.UnknownObject(str(what)).save() return stats = proportions.PersonComparison(userdata, compdata) embedtosend = await stats.toEmbed(requesterID = ctx.message.author.id) await ctx.send(embed = embedtosend)