async def setsystem(self, ctx, newsys): """Set measurement system.""" newsys = newsys.lower() systemmap = AliasMap({ "m": ("b", "e", "metric", "british", "europe", "european"), "u": ("i", "c", "a", "us", "imperial", "customary", "american") }) if newsys not in systemmap: await ctx.send( f"Please enter `{ctx.prefix}{ctx.invoked_with} {ctx.command.usage}`." ) return newsys = systemmap[newsys] userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.unitsystem = newsys completed_registration = userdata.complete_step("setsystem") userdb.save(userdata) await ctx.send( f"{userdata.nickname}'s system is now set to {userdata.unitsystem}." ) await proportions.nickUpdate(ctx.author) await showNextStep(ctx, userdata, completed=completed_registration)
async def on_message(m): # non-guild messages if not isinstance(m.author, discord.Member): return try: userdata = userdb.load(m.guild.id, m.author.id) except UserNotFoundException: return try: guilddata = guilddb.load(m.guild.id) except GuildNotFoundException: return if guilddata.low_limit: if userdata.height < guilddata.low_limit: userdata.height = guilddata.low_limit userdb.save(userdata) if guilddata.high_limit: if userdata.height > guilddata.high_limit: userdata.height = guilddata.high_limit userdb.save(userdata) if userdata.display: await proportions.nickUpdate(m.author)
async def setgender(self, ctx, gender): """Set gender.""" guild = ctx.guild user = ctx.author gendermap = { "m": "m", "male": "m", "man": "m", "boy": "m", "f": "f", "female": "f", "woman": "f", "girl": "f", "none": None, None: None } try: gender = gendermap[gender] except KeyError: raise errors.ArgumentException userdata = userdb.load(guild.id, user.id) userdata.gender = gender userdb.save(userdata) if userdata.display: await proportions.nickUpdate(user) logger.info( f"User {user.id} ({user.display_name}) set their gender to {userdata.gender}." ) await ctx.send( f"<@{user.id}>'s gender is now set to {userdata.gender}.")
async def setgender(self, ctx, gender): """Set gender.""" guild = ctx.guild user = ctx.author gendermap = AliasMap({ "m": ("male", "man", "boy"), "f": ("female", "woman", "girl"), None: ("none", "x", "nb") }) try: gender = gendermap[gender.lower()] except KeyError: raise errors.ArgumentException userdata = userdb.load(guild.id, user.id, allow_unreg=True) userdata.gender = gender userdb.save(userdata) if userdata.display: await proportions.nickUpdate(user) await ctx.send( f"{userdata.nickname}'s gender is now set to {userdata.gender}.") await showNextStep(ctx, userdata)
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) # 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.") for arg in [arg1, arg2]: if isinstance(arg, SV): userdata.baseheight = arg if isinstance(arg, WV): userdata.baseweight = arg userdb.save(userdata) logger.info( f"User {ctx.author.id} ({ctx.author.display_name}) changed their base height and weight to {userdata.baseheight:,.3mu} and {userdata.baseweight:,.3mu}." ) await ctx.send( f"{ctx.author.display_name} changed their base height and weight to {userdata.baseheight:,.3mu} and {userdata.baseweight:,.3mu}" )
async def setdescription(self, ctx, *, desc): """Set your profile description. Accepts slightly more markdown than usual, see https://leovoel.github.io/embed-visualizer/""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.description = desc userdb.save(userdata) await ctx.send("Profile description set.")
async def change(self, ctx, *, string: Union[LimitedRate, ParseableRate, Diff]): """Either change or slow-change your height. Can be used in essentially the three following ways: `&change <amount>` `&change <amount>/<time>` `&change <amount>/<time> until <size/time>` Examples: `&change +1ft` `&change *2` `&change 50ft/day` `&change -1in/min until 1ft` `&change -1mm/sec for 1hr` """ guildid = ctx.guild.id userid = ctx.author.id if isinstance(string, Diff): style = string.changetype amount = string.amount userdata = userdb.load(guildid, userid) if style == "add": userdata.height += amount elif style == "multiply": userdata.height *= amount elif style == "power": userdata = userdata**amount else: raise ChangeMethodInvalidException await proportions.nickUpdate(ctx.author) userdb.save(userdata) await ctx.send( f"User <@{userid}> is now {userdata.height:m} ({userdata.height:u}) tall." ) elif isinstance(string, ParseableRate) or isinstance( string, LimitedRate): addPerSec, mulPerSec, stopSV, stopTV = Rate.parse(string.original) userdata = userdb.load( guildid, userid ) # Load this data but don't use it as an ad-hoc user test. changes.start(userid, guildid, addPerSec=addPerSec, mulPerSec=mulPerSec, stopSV=stopSV, stopTV=stopTV) await ctx.send( f"{ctx.author.display_name} has begun slow-changing at a rate of `{string.original}`." )
async def resettail(self, ctx): """Remove custom tail length.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.taillength = None userdb.save(userdata) await ctx.send(f"{userdata.nickname}'s tail length is now cleared.") await showNextStep(ctx, userdata)
async def resetear(self, ctx): """Remove custom ear height.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.earheight = None userdb.save(userdata) await ctx.send(f"{userdata.nickname}'s ear height is now cleared.") await showNextStep(ctx, userdata)
async def resetrun(self, ctx): """Remove custom run speed.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.runperhour = None userdb.save(userdata) await ctx.send(f"{userdata.nickname}'s run speed is now cleared.") await showNextStep(ctx, userdata)
async def resetfoot(self, ctx): """Remove custom foot length.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.footlength = None userdb.save(userdata) await ctx.send(f"{userdata.nickname}'s foot length is now default.") await showNextStep(ctx, userdata)
def changeUser(guildid, userid, changestyle, amount): changestyle = changestyle.lower() if changestyle in ["add", "+", "a", "plus"]: changestyle = "add" if changestyle in ["subtract", "sub", "-", "minus"]: changestyle = "subtract" if changestyle in ["power", "exp", "pow", "exponent", "^", "**"]: changestyle = "power" if changestyle in ["multiply", "mult", "m", "x", "times", "*"]: changestyle = "multiply" if changestyle in ["divide", "d", "/", "div"]: changestyle = "divide" if changestyle in ["percent", "per", "perc", "%"]: changestyle = "percent" if changestyle not in [ "add", "subtract", "multiply", "divide", "power", "percent" ]: raise errors.ChangeMethodInvalidException(changestyle) amountSV = None amountVal = None newamount = None if changestyle in ["add", "subtract"]: amountSV = SV.parse(amount) elif changestyle in ["multiply", "divide", "power"]: amountVal = Decimal(amount) if amountVal == 1: raise errors.ValueIsOneException if amountVal == 0: raise errors.ValueIsZeroException elif changestyle in ["percent"]: amountVal = Decimal(amount) if amountVal == 0: raise errors.ValueIsZeroException userdata = userdb.load(guildid, userid) if changestyle == "add": newamount = userdata.height + amountSV elif changestyle == "subtract": newamount = userdata.height - amountSV elif changestyle == "multiply": newamount = userdata.height * amountVal elif changestyle == "divide": newamount = userdata.height / amountVal elif changestyle == "power": userdata = userdata**amountVal elif changestyle == "percent": newamount = userdata.height * (amountVal / 100) if changestyle != "power": userdata.height = newamount userdb.save(userdata)
async def resetstepscale(self, ctx): """Clear your step-scale amount, for use with `&step`.""" guildid = ctx.guild.id userid = ctx.author.id userdata = userdb.load(guildid, userid) userdata.currentscalestep = None userdb.save(userdata) await ctx.send(f"{userdata.nickname}'s scale per step is now cleared.")
async def on_message(m): """Is this user active?""" if m.author.bot: return try: userdata = userdb.load(m.guild.id, m.author.id) except errors.UserNotFoundException: return userdata.lastactive = arrow.now() userdb.save(userdata)
def upgradeusers(): print(f"Looking for user files in {userdb.userdbpath}") filepaths = list(userdb.userdbpath.glob("*.txt")) print(f"Found {len(filepaths)} users") for filepath in filepaths: id = filepath.stem print(f"Loading legacy user file for {id}") userdata = loadLegacy(id) print(f"Saving new user file for {id}") userdb.save(userdata)
async def resettail(self, ctx): """Remove custom tail length.""" userdata = userdb.load(ctx.guild.id, ctx.author.id) userdata.taillength = None userdb.save(userdata) logger.info( f"User {ctx.author.id} ({ctx.author.display_name}) removed their custom tail length." ) await ctx.send(f"<@{ctx.author.id}>'s tail length is now cleared.")
async def resetfoot(self, ctx): """Remove custom foot length.""" userdata = userdb.load(ctx.guild.id, ctx.author.id) userdata.footlength = None userdb.save(userdata) logger.info( f"User {ctx.author.id} ({ctx.author.display_name}) removed their custom foot length." ) await ctx.send(f"<@{ctx.author.id}>'s foot length is now default.")
async def setbaserun(self, ctx, *, newrun: ParseableRate): """Set a custom run speed.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.runperhour = newrun userdb.save(userdata) await ctx.send( f"{userdata.nickname}'s run is now {userdata.runperhour:mu}.") await showNextStep(ctx, userdata)
async def resetheight(self, ctx): """Reset height/size.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.height = userdata.baseheight userdb.save(userdata) await ctx.send(f"{ctx.author.display_name} reset their size.") await proportions.nickUpdate(ctx.author) await showNextStep(ctx, userdata)
async def resetspecies(self, ctx): """Remove species.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.species = None userdb.save(userdata) await ctx.send(f"{userdata.nickname}'s species is now cleared.") await proportions.nickUpdate(ctx.author) await showNextStep(ctx, userdata)
async def togglefur(self, ctx): """Switch between the word "hair" and "fur" for your stats.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.furtoggle = not userdata.furtoggle userdb.save(userdata) await ctx.send( f"The hair of {userdata.nickname} is now called {userdata.hairname.lower()}." ) await showNextStep(ctx, userdata)
async def togglepaw(self, ctx): """Switch between the word "foot" and "paw" for your stats.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.pawtoggle = not userdata.pawtoggle userdb.save(userdata) await ctx.send( f"The end of {userdata.nickname}'s legs are now called a {userdata.footname.lower()}." ) await showNextStep(ctx, userdata)
async def setbaseear(self, ctx, *, newear): """Set a custom ear height.""" newearsv = SV.parse(newear) userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.earheight = newearsv userdb.save(userdata) await ctx.send( f"{userdata.nickname}'s ear is now {userdata.earheight:mu} long.") await showNextStep(ctx, userdata)
async def setbasestrength(self, ctx, *, newstrength: WV): """Set a custom lift/carry strength.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.liftstrength = newstrength userdb.save(userdata) await ctx.send( f"{userdata.nickname}'s strength is now {userdata.liftstrength:mu}." ) await showNextStep(ctx, userdata)
async def setspecies(self, ctx, *, newtag): """Change species.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.species = newtag userdb.save(userdata) await ctx.send( f"{userdata.nickname}'s species is now a {userdata.species}.") await proportions.nickUpdate(ctx.author) await showNextStep(ctx, userdata)
async def setinf(self, ctx): """Change height to infinity.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.height = SV("infinity") completed_registration = userdata.complete_step("setheight") userdb.save(userdata) await ctx.send(f"{userdata.nickname} is now infinitely tall.") await proportions.nickUpdate(ctx.author) await showNextStep(ctx, userdata, completed=completed_registration)
async def set0(self, ctx): """Change height to a zero.""" userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True) userdata.height = 0 completed_registration = userdata.complete_step("setheight") userdb.save(userdata) await ctx.send(f"{userdata.nickname} is now nothing.") await proportions.nickUpdate(ctx.author) await showNextStep(ctx, userdata, completed=completed_registration)
async def step(self, ctx, steps=None): """Step a certain number of times, scaling by the amount set in `&setscalestep`. Scales you the amount that you would change depending on the scale factor you have set in `&setstepscale`. Can take a number, e.g.: `&step 20` """ guildid = ctx.guild.id userid = ctx.author.id userdata = userdb.load(guildid, userid) stats = proportions.PersonStats(userdata) if steps is None: steps = 1 steps = tryInt(steps) if steps == "car": await ctx.send("Cronch.") logger.log(EGG, f"{ctx.author.display_name} stepped on a car.") return if not isinstance(steps, int): await ctx.send(f"`{steps}` is not a number.") return if steps <= 0: await ctx.send("You... stand... still.") return if userdata.currentscalestep is None: await ctx.send( f"You do not have a stepscale set. Please use `{conf.prefix}setstepscale <amount>` to do so." ) return if userdata.currentscalestep.changetype == "add": userdata.height += (userdata.currentscalestep.amount * steps) elif userdata.currentscalestep.changetype == "multiply": userdata.height *= (userdata.currentscalestep.amount**steps) else: raise ChangeMethodInvalidException( "This change type is not yet supported for scale-walking.") dist_travelled = get_dist(stats.walksteplength, userdata.currentscalestep, (steps + 1)) await ctx.send( f"You walked {dist_travelled:,.3mu} in {steps} {'step' if steps == 1 else 'steps'}." ) userdb.save(userdata)
async def scalewalk(self, ctx, change: Diff, dist: SV, flag=None): """Walk a certain distance, scaling by an amount each step you take. Accepts addition or subtraction of a certain height, or multiplication/division of a factor. Examples: `&scalewalk 2x 50m `&scalewalk -1mm 20ft""" guildid = ctx.guild.id userid = ctx.author.id userdata = userdb.load(guildid, userid) stats = proportions.PersonStats(userdata) stepcount, final_inc, final_ratio = get_steps(stats.walksteplength, change, dist) finalheight = SV(userdata.height / final_ratio) symbol = "" if change.changetype == "add": symbol = "+" if change.changetype == "multiply": symbol = "x" amountstring = "" if change.changetype == "add": amountstring = f"{symbol}{change.amount:,.3mu}" if change.changetype == "multiply": amountstring = f"{symbol}{change.amount:,.3}" if flag is None: e = discord.Embed( title= f"If {userdata.nickname} walked {dist:,.3mu}, scaling {amountstring} each step...", description= f"They would now be **{finalheight:,.3mu}** tall after **{stepcount}** steps." ) await ctx.send(embed=e) elif flag == "apply": userdata.height = finalheight userdb.save(userdata) e = discord.Embed( title= f"{userdata.nickname} walked {dist:,.3mu}, scaling {amountstring} each step...", description= f"They are now **{finalheight:,.3mu}** tall after **{stepcount}** steps." ) await ctx.send(embed=e) else: raise DigiContextException(f"Invalid flag {flag}.")
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)