mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-27 13:34:28 +00:00
Cast v3.0
This commit is contained in:
parent
35ba344f2c
commit
d8fdd0565d
4 changed files with 128 additions and 95 deletions
24
strings.py
24
strings.py
|
@ -8,7 +8,9 @@ class SafeDict(dict):
|
||||||
return key
|
return key
|
||||||
|
|
||||||
|
|
||||||
def safely_format_string(string: str, words: typing.Dict[str, str], ignore_escaping=False) -> str:
|
def safely_format_string(string: str, words: typing.Dict[str, str] = None, ignore_escaping=False) -> str:
|
||||||
|
if words is None:
|
||||||
|
words = {}
|
||||||
if ignore_escaping:
|
if ignore_escaping:
|
||||||
escaped = words
|
escaped = words
|
||||||
else:
|
else:
|
||||||
|
@ -47,6 +49,12 @@ class BRIDGE:
|
||||||
INACTIVE_BRIDGE = "⚠ Il collegamento tra Telegram e Discord non è attivo al momento."
|
INACTIVE_BRIDGE = "⚠ Il collegamento tra Telegram e Discord non è attivo al momento."
|
||||||
|
|
||||||
|
|
||||||
|
# Random spellslinging
|
||||||
|
class CAST:
|
||||||
|
class ERRORS:
|
||||||
|
NOT_YET_AVAILABLE = "⚠ Il nuovo cast non è ancora disponibile! Per un'anteprima sulle nuove funzioni, usa <code>/spell</code>."
|
||||||
|
|
||||||
|
|
||||||
# Ciao Ruozi!
|
# Ciao Ruozi!
|
||||||
class CIAORUOZI:
|
class CIAORUOZI:
|
||||||
THE_LEGEND_HIMSELF = "👋 Ciao me!"
|
THE_LEGEND_HIMSELF = "👋 Ciao me!"
|
||||||
|
@ -200,10 +208,22 @@ class SHIP:
|
||||||
RESULT = "💕 {one} + {two} = <b>{result}</b>"
|
RESULT = "💕 {one} + {two} = <b>{result}</b>"
|
||||||
|
|
||||||
class ERRORS:
|
class ERRORS:
|
||||||
INVALID_SYNTAX = "⚠ Non hai specificato correttamente i due nomi!\nSintassi corretta: <code>/ship (nome) (nome)</code>"
|
INVALID_SYNTAX = "⚠ Non hai specificato correttamente i due nomi!\nSintassi: <code>/ship (nome) (nome)</code>"
|
||||||
INVALID_NAMES = "⚠ I nomi specificati non sono validi.\nRiprova con dei nomi diversi!"
|
INVALID_NAMES = "⚠ I nomi specificati non sono validi.\nRiprova con dei nomi diversi!"
|
||||||
|
|
||||||
|
|
||||||
|
# Get information about a spell
|
||||||
|
class SPELL:
|
||||||
|
HEADER = "🔍 La magia <b>{name}</b> ha le seguenti proprietà (v{version}):\n"
|
||||||
|
ACCURACY = "Precisione - <b>{accuracy}%</b>\n"
|
||||||
|
DAMAGE = "Danni - <b>{number}d{type}{constant}</b>\n"
|
||||||
|
TYPE = "Tipo - <b>{type}</b>\n"
|
||||||
|
REPEAT = "Multiattacco - <b>×{repeat}</b>\n"
|
||||||
|
|
||||||
|
class ERRORS:
|
||||||
|
INVALID_SYNTAX = "⚠ Non hai specificato la magia di cui vuoi conoscere i dettagli!\nSintassi: <code>/spell (nome)</code>"
|
||||||
|
|
||||||
|
|
||||||
# Secondo me, è colpa delle stringhe.
|
# Secondo me, è colpa delle stringhe.
|
||||||
SMECDS = "🤔 Secondo me, è colpa {ds}."
|
SMECDS = "🤔 Secondo me, è colpa {ds}."
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ def command(func: "function"):
|
||||||
# noinspection PyBroadException
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
reply_msg(bot, main_group_id, strings.TELEGRAM.ERRORS.CRITICAL_ERROR,
|
reply_msg(bot, main_group_id, strings.TELEGRAM.ERRORS.CRITICAL_ERROR,
|
||||||
exc_info=sys.exc_info())
|
exc_info=repr(sys.exc_info()))
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.error(f"Double critical error: {sys.exc_info()}")
|
logger.error(f"Double critical error: {sys.exc_info()}")
|
||||||
sentry.user_context({
|
sentry.user_context({
|
||||||
|
@ -173,21 +173,8 @@ def cmd_cv(bot: telegram.Bot, update: telegram.Update):
|
||||||
|
|
||||||
|
|
||||||
@command
|
@command
|
||||||
@database_access
|
def cmd_cast(bot: telegram.Bot, update: telegram.Update):
|
||||||
def cmd_cast(bot: telegram.Bot, update: telegram.Update, session: db.Session):
|
reply(bot, update, strings.CAST.ERRORS.NOT_YET_AVAILABLE)
|
||||||
try:
|
|
||||||
spell: str = update.message.text.split(" ", 1)[1]
|
|
||||||
except IndexError:
|
|
||||||
bot.send_message(update.message.chat.id, "⚠️ Non hai specificato nessun incantesimo!\n"
|
|
||||||
"Sintassi corretta: `/cast <nome_incantesimo>`", parse_mode="Markdown")
|
|
||||||
return
|
|
||||||
# Find a target for the spell
|
|
||||||
target = random.sample(session.query(db.Telegram).all(), 1)[0]
|
|
||||||
# END
|
|
||||||
bot.send_message(update.message.chat.id, cast(spell_name=spell,
|
|
||||||
target_name=target.username if target.username is not None
|
|
||||||
else target.first_name, platform="telegram"),
|
|
||||||
parse_mode="HTML")
|
|
||||||
|
|
||||||
|
|
||||||
@command
|
@command
|
||||||
|
@ -732,7 +719,6 @@ def cmd_dndmarkov(bot: telegram.Bot, update: telegram.Update):
|
||||||
reply(bot, update, sentence)
|
reply(bot, update, sentence)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def exec_roll(roll) -> str:
|
def exec_roll(roll) -> str:
|
||||||
result = int(roll.evaluate())
|
result = int(roll.evaluate())
|
||||||
string = ""
|
string = ""
|
||||||
|
@ -772,6 +758,17 @@ def cmd_start(bot: telegram.Bot, update: telegram.Update):
|
||||||
reply(bot, update, strings.TELEGRAM.BOT_STARTED)
|
reply(bot, update, strings.TELEGRAM.BOT_STARTED)
|
||||||
|
|
||||||
|
|
||||||
|
@command
|
||||||
|
def cmd_spell(bot: telegram.Bot, update: telegram.Update):
|
||||||
|
try:
|
||||||
|
input: str = update.message.text.split(" ", 1)[1]
|
||||||
|
except IndexError:
|
||||||
|
reply(bot, update, strings.SPELL.ERRORS.INVALID_SYNTAX)
|
||||||
|
return
|
||||||
|
spell = cast.Spell(input)
|
||||||
|
reply(bot, update, spell.stringify())
|
||||||
|
|
||||||
|
|
||||||
def process(arg_discord_connection):
|
def process(arg_discord_connection):
|
||||||
if arg_discord_connection is not None:
|
if arg_discord_connection is not None:
|
||||||
global discord_connection
|
global discord_connection
|
||||||
|
@ -806,6 +803,7 @@ def process(arg_discord_connection):
|
||||||
u.dispatcher.add_handler(CommandHandler("search", cmd_search))
|
u.dispatcher.add_handler(CommandHandler("search", cmd_search))
|
||||||
u.dispatcher.add_handler(CommandHandler("regex", cmd_regex))
|
u.dispatcher.add_handler(CommandHandler("regex", cmd_regex))
|
||||||
u.dispatcher.add_handler(CommandHandler("start", cmd_start))
|
u.dispatcher.add_handler(CommandHandler("start", cmd_start))
|
||||||
|
u.dispatcher.add_handler(CommandHandler("spell", cmd_spell))
|
||||||
u.dispatcher.add_handler(CallbackQueryHandler(on_callback_query))
|
u.dispatcher.add_handler(CallbackQueryHandler(on_callback_query))
|
||||||
logger.info("Handlers registered.")
|
logger.info("Handlers registered.")
|
||||||
u.start_polling()
|
u.start_polling()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from .dirty import Dirty, DirtyDelta
|
from .dirty import Dirty, DirtyDelta
|
||||||
from .mmstatus import MatchmakingStatus
|
from .mmstatus import MatchmakingStatus
|
||||||
from .cast import cast
|
from .cast import Spell, Hit, Cast
|
||||||
from .stagismo import smecds
|
from .stagismo import smecds
|
||||||
|
|
||||||
__all__ = ["Dirty", "DirtyDelta", "MatchmakingStatus", "cast", "smecds"]
|
__all__ = ["Dirty", "DirtyDelta", "MatchmakingStatus", "Spell", "Hit", "Cast", "smecds"]
|
||||||
|
|
163
utils/cast.py
163
utils/cast.py
|
@ -1,79 +1,94 @@
|
||||||
import random
|
import random
|
||||||
import math
|
import math
|
||||||
import db
|
import typing
|
||||||
|
import strings
|
||||||
|
s = strings.safely_format_string
|
||||||
|
|
||||||
|
|
||||||
def cast(spell_name: str, target_name: str, platform: str) -> str:
|
class Spell:
|
||||||
spell = spell_name.capitalize()
|
version = "3.0"
|
||||||
# Seed the rng with the spell name
|
|
||||||
# so that spells always deal the same damage
|
dice_type_distribution = ([4] * 1) +\
|
||||||
random.seed(spell)
|
([6] * 6) +\
|
||||||
dmg_dice = random.randrange(1, 11)
|
([8] * 24) +\
|
||||||
dmg_max = random.sample([4, 6, 8, 10, 12, 20, 100], 1)[0]
|
([10] * 38) +\
|
||||||
dmg_mod = random.randrange(math.floor(-dmg_max / 5), math.ceil(dmg_max / 5) + 1)
|
([12] * 24) +\
|
||||||
dmg_type = random.sample(["da fuoco", "da freddo", "elettrici", "sonici", "necrotici", "magici",
|
([20] * 6) +\
|
||||||
"da acido", "divini", "nucleari", "psichici", "fisici", "puri", "da taglio",
|
([100] * 1)
|
||||||
"da perforazione", "da impatto", "da caduta", "gelato", "onnipotenti", "oscuri",
|
|
||||||
"di luce", "da velocità", "da cactus", "meta", "dannosi", "da radiazione",
|
all_damage_types = ["da fuoco", "da freddo", "elettrici", "sonici", "necrotici", "magici",
|
||||||
"tuamammici", "da maledizione", "pesanti", "leggeri", "immaginari", "da laser",
|
"da acido", "divini", "nucleari", "psichici", "fisici", "puri", "da taglio",
|
||||||
"da neutrini", "galattici", "cerebrali", "ritardati", "ritardanti"], 1)[0]
|
"da perforazione", "da impatto", "da caduta", "gelato", "onnipotenti", "oscuri",
|
||||||
# Reseed the rng with a random value
|
"di luce", "da velocità", "da cactus", "meta", "dannosi", "da radiazione",
|
||||||
# so that the dice roll always deals a different damage
|
"tuamammici", "da maledizione", "pesanti", "leggeri", "immaginari", "da laser",
|
||||||
random.seed()
|
"da neutrini", "galattici", "cerebrali", "ritardati", "ritardanti", "morali", "materiali",
|
||||||
total = dmg_mod
|
"energetici", "esplosivi"]
|
||||||
# Check for a critical hit
|
|
||||||
crit = 1
|
repeat_distribution = ([1] * 8) +\
|
||||||
while True:
|
([2] * 1) +\
|
||||||
crit_die = random.randrange(1, 21)
|
([3] * 1)
|
||||||
if crit_die == 20:
|
|
||||||
crit *= 2
|
damage_types_distribution = ([1] * 6) + \
|
||||||
|
([2] * 3) + \
|
||||||
|
([3] * 1)
|
||||||
|
|
||||||
|
def __init__(self, name: str):
|
||||||
|
seed = name.capitalize()
|
||||||
|
random.seed(seed)
|
||||||
|
# Spell data
|
||||||
|
self.name = seed
|
||||||
|
self.dice_number = random.randrange(1, 21)
|
||||||
|
self.dice_type = random.sample(self.dice_type_distribution, 1)[0]
|
||||||
|
self.constant = random.randrange(math.floor(-self.dice_type / 4), math.ceil(self.dice_type / 4) + 1)
|
||||||
|
self.miss_chance = random.randrange(80, 101)
|
||||||
|
self.repeat = random.sample(self.repeat_distribution, 1)[0]
|
||||||
|
self.damage_types_qty = random.sample(self.damage_types_distribution, 1)[0]
|
||||||
|
self.damage_types = random.sample(self.all_damage_types, self.damage_types_qty)
|
||||||
|
|
||||||
|
def stringify(self) -> str:
|
||||||
|
string = s(strings.SPELL.HEADER, words={"name": self.name, "version": self.version})
|
||||||
|
string += s(strings.SPELL.ACCURACY, words={"accuracy": str(self.miss_chance)})
|
||||||
|
if self.constant > 0:
|
||||||
|
constant = "+" + str(self.constant)
|
||||||
|
elif self.constant == 0:
|
||||||
|
constant = ""
|
||||||
else:
|
else:
|
||||||
break
|
constant = str(self.constant)
|
||||||
for dice in range(0, dmg_dice):
|
string += s(strings.SPELL.DAMAGE,
|
||||||
total += random.randrange(1, dmg_max + 1)
|
words={"number": str(self.dice_number),
|
||||||
if crit > 1:
|
"type": str(self.dice_type),
|
||||||
if platform == "telegram":
|
"constant": constant})
|
||||||
crit_msg = f"<b>CRITICO ×{crit}{'!' * crit}</b>\n"
|
for dmg_type in self.damage_types:
|
||||||
elif platform == "discord":
|
string += s(strings.SPELL.TYPE, words={"type": dmg_type})
|
||||||
crit_msg = f"**CRITICO ×{crit}{'!' * crit}**\n"
|
if self.repeat > 1:
|
||||||
total *= crit
|
string += s(strings.SPELL.REPEAT, words={"repeat": str(self.repeat)})
|
||||||
else:
|
return string
|
||||||
crit_msg = ""
|
|
||||||
if platform == "telegram":
|
|
||||||
if dmg_dice == 10 and dmg_max == 100 and dmg_mod == 20:
|
class Hit:
|
||||||
return f"❇️‼️ Ho lanciato <b>{spell}</b> su " \
|
def __init__(self, spell: Spell):
|
||||||
f"<i>{target_name}</i>.\n" \
|
random.seed()
|
||||||
f"Una grande luce illumina il cielo, seguita poco dopo da un fungo di fumo nel luogo" \
|
self.hit_roll = random.randrange(0, 101)
|
||||||
f" in cui si trovava <i>{target_name}</i>.\n" \
|
self.damage = 0
|
||||||
f"Il fungo si espande a velocità smodata, finchè il fumo non ricopre la Terra intera e le tenebre" \
|
self.crit_multiplier = 1
|
||||||
f" cadono su di essa.\n" \
|
self.damage_type = random.sample(spell.damage_types, 1)[0]
|
||||||
f"Dopo qualche minuto, la temperatura ambiente raggiunge gli 0 °C, e continua a diminuire.\n" \
|
if self.hit_roll > spell.miss_chance:
|
||||||
f"L'Apocalisse Nucleare è giunta, e tutto per polverizzare <i>{target_name}</i>" \
|
return
|
||||||
f" con <b>{spell}</b>.\n" \
|
for _ in range(spell.dice_number):
|
||||||
f"<i>{target_name}</i> subisce 10d100+20=<b>9999</b> danni apocalittici!"
|
self.damage += random.randrange(1, spell.dice_type + 1)
|
||||||
return f"❇️ Ho lanciato <b>{spell}</b> su " \
|
self.damage += spell.constant
|
||||||
f"<i>{target_name}</i>.\n" \
|
if self.damage < 0:
|
||||||
f"{crit_msg}" \
|
self.damage = 0
|
||||||
f"<i>{target_name}</i> subisce {dmg_dice}d{dmg_max}" \
|
while random.randrange(1, 21) == 20:
|
||||||
f"{'+' if dmg_mod > 0 else ''}{str(dmg_mod) if dmg_mod != 0 else ''}" \
|
self.crit_multiplier *= 2
|
||||||
f"{'×' + str(crit) if crit > 1 else ''}" \
|
|
||||||
f"=<b>{total if total > 0 else 0}</b> danni {dmg_type}!"
|
def damage(self):
|
||||||
elif platform == "discord":
|
return self.damage * self.crit_multiplier
|
||||||
if dmg_dice == 10 and dmg_max == 100 and dmg_mod == 20:
|
|
||||||
return f"❇️‼️ Ho lanciato **{spell}** su " \
|
|
||||||
f"_{target_name}_.\n" \
|
class Cast:
|
||||||
f"Una grande luce illumina il cielo, seguita poco dopo da un fungo di fumo nel luogo" \
|
def __init__(self, spell: Spell):
|
||||||
f" in cui si trovava _{target_name}_.\n" \
|
self.hits = []
|
||||||
f"Il fungo si espande a velocità smodata, finchè il fumo non ricopre la Terra intera e le tenebre" \
|
for _ in spell.repeat:
|
||||||
f" cadono su di essa.\n" \
|
self.hits.append(Hit(spell))
|
||||||
f"Dopo qualche minuto, la temperatura ambiente raggiunge gli 0 °C, e continua a diminuire.\n" \
|
|
||||||
f"L'Apocalisse Nucleare è giunta, e tutto per polverizzare _{target_name}_" \
|
|
||||||
f" con **{spell}**.\n" \
|
|
||||||
f"_{target_name}_ subisce 10d100+20=**9999** danni apocalittici!"
|
|
||||||
return f"❇️ Ho lanciato **{spell}** su " \
|
|
||||||
f"_{target_name}_.\n" \
|
|
||||||
f"{crit_msg}" \
|
|
||||||
f"_{target_name}_ subisce {dmg_dice}d{dmg_max}" \
|
|
||||||
f"{'+' if dmg_mod > 0 else ''}{str(dmg_mod) if dmg_mod != 0 else ''}" \
|
|
||||||
f"{'×' + str(crit) if crit > 1 else ''}" \
|
|
||||||
f"=**{total if total > 0 else 0}** danni {dmg_type}!"
|
|
||||||
|
|
Loading…
Reference in a new issue