Skip to content

Commit bb4a2e2

Browse files
committed
shrinkray/growthray
1 parent e38cec8 commit bb4a2e2

2 files changed

Lines changed: 140 additions & 1 deletion

File tree

sizebot/cogs/multiplayer.py

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
from copy import copy
22
import logging
3+
import random
34

45
import discord
56
from discord.ext import commands
67

78
from sizebot.lib import userdb, nickmanager
89
from sizebot.lib.constants import colors, emojis
910
from sizebot.lib.diff import Diff
10-
from sizebot.lib.errors import ChangeMethodInvalidException
11+
from sizebot.lib.errors import ChangeMethodInvalidException, UserNotFoundException
1112
from sizebot.lib.types import BotContext, GuildContext
1213
from sizebot.lib.units import SV, WV, Decimal
14+
from sizebot.lib.utils import map_range
1315

1416
logger = logging.getLogger("sizebot")
1517

@@ -196,6 +198,128 @@ async def setother(self, ctx: GuildContext, other: discord.Member, *, newheight:
196198

197199
await nickmanager.nick_update(other)
198200

201+
@commands.command(
202+
category = "multiplayer",
203+
usage = "<power> [user]"
204+
)
205+
@commands.guild_only()
206+
async def shrinkray(self, ctx: GuildContext, level: int, user: discord.Member | None = None):
207+
"""Zap! Shrink a user with power 1-10."""
208+
if user is None:
209+
user = ctx.author
210+
userdata = userdb.load(user.guild.id, user.id)
211+
212+
if not userdata.allowchangefromothers:
213+
await ctx.send(f"{userdata.nickname} does not allow others to change their size.")
214+
return
215+
216+
if level == 0:
217+
await ctx.send("The shrink ray is off...")
218+
return
219+
if level < 0:
220+
await ctx.send("Did you mean to use the growth ray?")
221+
return
222+
if level > 11:
223+
await ctx.send("Don't overpower the shrink ray!")
224+
return
225+
226+
level_was_11 = level == 11
227+
original_level = level
228+
crit = random.random() < 0.05
229+
230+
randomness = map_range(random.random(), 0, 1, 0.75, 1.25)
231+
level = level + (1 if crit else 0)
232+
level: float = level * randomness
233+
234+
amount = 0.9 ** (level * (1 + (level / 5)))
235+
236+
userdata.height *= amount
237+
238+
await nickmanager.nick_update(user)
239+
userdb.save(userdata)
240+
241+
self_nick = ctx.author.display_name
242+
try:
243+
self_data = userdb.load(ctx.guild.id, ctx.author.id)
244+
self_nick = self_data.nickname
245+
except UserNotFoundException:
246+
pass
247+
248+
outstring = f"{self_nick} cranks the shrink ray to {original_level}..."
249+
if level_was_11:
250+
outstring += "\n-# *Wait, it goes up that high?!*"
251+
if ctx.author.id == user.id:
252+
outstring += "and zaps themselves!"
253+
else:
254+
outstring += f"and zaps {userdata.nickname}!"
255+
if crit:
256+
outstring += f" And it's a critical hit! They are now {userdata.height:mu} tall."
257+
else:
258+
outstring += f" They are now {userdata.height:mu} tall."
259+
260+
await ctx.send(outstring)
261+
262+
@commands.command(
263+
category = "multiplayer",
264+
usage = "<power> [user]"
265+
)
266+
@commands.guild_only()
267+
async def growthray(self, ctx: GuildContext, level: int, user: discord.Member | None = None):
268+
"""Zap! Grow a user with power 1-10."""
269+
if user is None:
270+
user = ctx.author
271+
userdata = userdb.load(user.guild.id, user.id)
272+
273+
if not userdata.allowchangefromothers:
274+
await ctx.send(f"{userdata.nickname} does not allow others to change their size.")
275+
return
276+
277+
if level == 0:
278+
await ctx.send("The growth ray is off...")
279+
return
280+
if level < 0:
281+
await ctx.send("Did you mean to use the shrink ray?")
282+
return
283+
if level > 11:
284+
await ctx.send("Don't overpower the growth ray!")
285+
return
286+
287+
level_was_11 = level == 11
288+
original_level = level
289+
crit = random.random() < 0.05
290+
291+
randomness = map_range(random.random(), 0, 1, 0.75, 1.25)
292+
level = level + (1 if crit else 0)
293+
level: float = level * randomness
294+
295+
amount = 1.1 ** (level * (1 + (level / 5)))
296+
297+
userdata.height *= amount
298+
299+
await nickmanager.nick_update(user)
300+
userdb.save(userdata)
301+
302+
self_nick = ctx.author.display_name
303+
try:
304+
self_data = userdb.load(ctx.guild.id, ctx.author.id)
305+
self_nick = self_data.nickname
306+
except UserNotFoundException:
307+
pass
308+
309+
outstring = f"{self_nick} cranks the growth ray to {original_level}..."
310+
if level_was_11:
311+
outstring += "\n-# *Wait, it goes up that high?!*"
312+
if ctx.author.id == user.id:
313+
outstring += "and zaps themselves!"
314+
else:
315+
outstring += f"and zaps {userdata.nickname}!"
316+
if crit:
317+
outstring += f" And it's a critical hit! They are now {userdata.height:mu} tall."
318+
else:
319+
outstring += f" They are now {userdata.height:mu} tall."
320+
321+
await ctx.send(outstring)
322+
199323
@commands.command(
200324
category = "multiplayer"
201325
)

sizebot/lib/utils.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,3 +371,18 @@ def round_fraction(number: Decimal, denominator: int) -> Decimal:
371371
"""
372372
rounded = round(number * denominator) / denominator
373373
return rounded
374+
375+
376+
def map_range[L](x: L, n1: L, m1: L, n2: L = -1, m2: L = 1) -> L:
377+
"""Scale a value `x` that is currently somewhere between `n1` and `m1` to now be in an
378+
equivalent position between `n2` and `m2`."""
379+
# Make the range start at 0.
380+
old_max = m1 - n1
381+
old_x = x - n1
382+
percentage = old_x / old_max
383+
384+
# Shmoove it over.
385+
new_max = m2 - n2
386+
new_pos = new_max * percentage
387+
ans = new_pos + n2
388+
return ans

0 commit comments

Comments
 (0)