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
|
||||
|
||||
|
||||
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:
|
||||
escaped = words
|
||||
else:
|
||||
|
@ -47,6 +49,12 @@ class BRIDGE:
|
|||
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!
|
||||
class CIAORUOZI:
|
||||
THE_LEGEND_HIMSELF = "👋 Ciao me!"
|
||||
|
@ -200,10 +208,22 @@ class SHIP:
|
|||
RESULT = "💕 {one} + {two} = <b>{result}</b>"
|
||||
|
||||
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!"
|
||||
|
||||
|
||||
# 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.
|
||||
SMECDS = "🤔 Secondo me, è colpa {ds}."
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ def command(func: "function"):
|
|||
# noinspection PyBroadException
|
||||
try:
|
||||
reply_msg(bot, main_group_id, strings.TELEGRAM.ERRORS.CRITICAL_ERROR,
|
||||
exc_info=sys.exc_info())
|
||||
exc_info=repr(sys.exc_info()))
|
||||
except Exception:
|
||||
logger.error(f"Double critical error: {sys.exc_info()}")
|
||||
sentry.user_context({
|
||||
|
@ -173,21 +173,8 @@ def cmd_cv(bot: telegram.Bot, update: telegram.Update):
|
|||
|
||||
|
||||
@command
|
||||
@database_access
|
||||
def cmd_cast(bot: telegram.Bot, update: telegram.Update, session: db.Session):
|
||||
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")
|
||||
def cmd_cast(bot: telegram.Bot, update: telegram.Update):
|
||||
reply(bot, update, strings.CAST.ERRORS.NOT_YET_AVAILABLE)
|
||||
|
||||
|
||||
@command
|
||||
|
@ -732,7 +719,6 @@ def cmd_dndmarkov(bot: telegram.Bot, update: telegram.Update):
|
|||
reply(bot, update, sentence)
|
||||
|
||||
|
||||
|
||||
def exec_roll(roll) -> str:
|
||||
result = int(roll.evaluate())
|
||||
string = ""
|
||||
|
@ -772,6 +758,17 @@ def cmd_start(bot: telegram.Bot, update: telegram.Update):
|
|||
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):
|
||||
if arg_discord_connection is not None:
|
||||
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("regex", cmd_regex))
|
||||
u.dispatcher.add_handler(CommandHandler("start", cmd_start))
|
||||
u.dispatcher.add_handler(CommandHandler("spell", cmd_spell))
|
||||
u.dispatcher.add_handler(CallbackQueryHandler(on_callback_query))
|
||||
logger.info("Handlers registered.")
|
||||
u.start_polling()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from .dirty import Dirty, DirtyDelta
|
||||
from .mmstatus import MatchmakingStatus
|
||||
from .cast import cast
|
||||
from .cast import Spell, Hit, Cast
|
||||
from .stagismo import smecds
|
||||
|
||||
__all__ = ["Dirty", "DirtyDelta", "MatchmakingStatus", "cast", "smecds"]
|
||||
__all__ = ["Dirty", "DirtyDelta", "MatchmakingStatus", "Spell", "Hit", "Cast", "smecds"]
|
||||
|
|
155
utils/cast.py
155
utils/cast.py
|
@ -1,79 +1,94 @@
|
|||
import random
|
||||
import math
|
||||
import db
|
||||
import typing
|
||||
import strings
|
||||
s = strings.safely_format_string
|
||||
|
||||
|
||||
def cast(spell_name: str, target_name: str, platform: str) -> str:
|
||||
spell = spell_name.capitalize()
|
||||
# Seed the rng with the spell name
|
||||
# so that spells always deal the same damage
|
||||
random.seed(spell)
|
||||
dmg_dice = random.randrange(1, 11)
|
||||
dmg_max = random.sample([4, 6, 8, 10, 12, 20, 100], 1)[0]
|
||||
dmg_mod = random.randrange(math.floor(-dmg_max / 5), math.ceil(dmg_max / 5) + 1)
|
||||
dmg_type = random.sample(["da fuoco", "da freddo", "elettrici", "sonici", "necrotici", "magici",
|
||||
class Spell:
|
||||
version = "3.0"
|
||||
|
||||
dice_type_distribution = ([4] * 1) +\
|
||||
([6] * 6) +\
|
||||
([8] * 24) +\
|
||||
([10] * 38) +\
|
||||
([12] * 24) +\
|
||||
([20] * 6) +\
|
||||
([100] * 1)
|
||||
|
||||
all_damage_types = ["da fuoco", "da freddo", "elettrici", "sonici", "necrotici", "magici",
|
||||
"da acido", "divini", "nucleari", "psichici", "fisici", "puri", "da taglio",
|
||||
"da perforazione", "da impatto", "da caduta", "gelato", "onnipotenti", "oscuri",
|
||||
"di luce", "da velocità", "da cactus", "meta", "dannosi", "da radiazione",
|
||||
"tuamammici", "da maledizione", "pesanti", "leggeri", "immaginari", "da laser",
|
||||
"da neutrini", "galattici", "cerebrali", "ritardati", "ritardanti"], 1)[0]
|
||||
# Reseed the rng with a random value
|
||||
# so that the dice roll always deals a different damage
|
||||
"da neutrini", "galattici", "cerebrali", "ritardati", "ritardanti", "morali", "materiali",
|
||||
"energetici", "esplosivi"]
|
||||
|
||||
repeat_distribution = ([1] * 8) +\
|
||||
([2] * 1) +\
|
||||
([3] * 1)
|
||||
|
||||
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:
|
||||
constant = str(self.constant)
|
||||
string += s(strings.SPELL.DAMAGE,
|
||||
words={"number": str(self.dice_number),
|
||||
"type": str(self.dice_type),
|
||||
"constant": constant})
|
||||
for dmg_type in self.damage_types:
|
||||
string += s(strings.SPELL.TYPE, words={"type": dmg_type})
|
||||
if self.repeat > 1:
|
||||
string += s(strings.SPELL.REPEAT, words={"repeat": str(self.repeat)})
|
||||
return string
|
||||
|
||||
|
||||
class Hit:
|
||||
def __init__(self, spell: Spell):
|
||||
random.seed()
|
||||
total = dmg_mod
|
||||
# Check for a critical hit
|
||||
crit = 1
|
||||
while True:
|
||||
crit_die = random.randrange(1, 21)
|
||||
if crit_die == 20:
|
||||
crit *= 2
|
||||
else:
|
||||
break
|
||||
for dice in range(0, dmg_dice):
|
||||
total += random.randrange(1, dmg_max + 1)
|
||||
if crit > 1:
|
||||
if platform == "telegram":
|
||||
crit_msg = f"<b>CRITICO ×{crit}{'!' * crit}</b>\n"
|
||||
elif platform == "discord":
|
||||
crit_msg = f"**CRITICO ×{crit}{'!' * crit}**\n"
|
||||
total *= crit
|
||||
else:
|
||||
crit_msg = ""
|
||||
if platform == "telegram":
|
||||
if dmg_dice == 10 and dmg_max == 100 and dmg_mod == 20:
|
||||
return f"❇️‼️ Ho lanciato <b>{spell}</b> su " \
|
||||
f"<i>{target_name}</i>.\n" \
|
||||
f"Una grande luce illumina il cielo, seguita poco dopo da un fungo di fumo nel luogo" \
|
||||
f" in cui si trovava <i>{target_name}</i>.\n" \
|
||||
f"Il fungo si espande a velocità smodata, finchè il fumo non ricopre la Terra intera e le tenebre" \
|
||||
f" cadono su di essa.\n" \
|
||||
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 <i>{target_name}</i>" \
|
||||
f" con <b>{spell}</b>.\n" \
|
||||
f"<i>{target_name}</i> subisce 10d100+20=<b>9999</b> danni apocalittici!"
|
||||
return f"❇️ Ho lanciato <b>{spell}</b> su " \
|
||||
f"<i>{target_name}</i>.\n" \
|
||||
f"{crit_msg}" \
|
||||
f"<i>{target_name}</i> 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"=<b>{total if total > 0 else 0}</b> danni {dmg_type}!"
|
||||
elif platform == "discord":
|
||||
if dmg_dice == 10 and dmg_max == 100 and dmg_mod == 20:
|
||||
return f"❇️‼️ Ho lanciato **{spell}** su " \
|
||||
f"_{target_name}_.\n" \
|
||||
f"Una grande luce illumina il cielo, seguita poco dopo da un fungo di fumo nel luogo" \
|
||||
f" in cui si trovava _{target_name}_.\n" \
|
||||
f"Il fungo si espande a velocità smodata, finchè il fumo non ricopre la Terra intera e le tenebre" \
|
||||
f" cadono su di essa.\n" \
|
||||
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}!"
|
||||
self.hit_roll = random.randrange(0, 101)
|
||||
self.damage = 0
|
||||
self.crit_multiplier = 1
|
||||
self.damage_type = random.sample(spell.damage_types, 1)[0]
|
||||
if self.hit_roll > spell.miss_chance:
|
||||
return
|
||||
for _ in range(spell.dice_number):
|
||||
self.damage += random.randrange(1, spell.dice_type + 1)
|
||||
self.damage += spell.constant
|
||||
if self.damage < 0:
|
||||
self.damage = 0
|
||||
while random.randrange(1, 21) == 20:
|
||||
self.crit_multiplier *= 2
|
||||
|
||||
def damage(self):
|
||||
return self.damage * self.crit_multiplier
|
||||
|
||||
|
||||
class Cast:
|
||||
def __init__(self, spell: Spell):
|
||||
self.hits = []
|
||||
for _ in spell.repeat:
|
||||
self.hits.append(Hit(spell))
|
||||
|
||||
|
|
Loading…
Reference in a new issue