1
Fork 0
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:
Steffo 2019-02-15 19:42:02 +01:00
parent 35ba344f2c
commit d8fdd0565d
4 changed files with 128 additions and 95 deletions

View file

@ -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}."

View file

@ -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()

View file

@ -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"]

View file

@ -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) +\
([100] * 1)
all_damage_types = ["da fuoco", "da freddo", "elettrici", "sonici", "necrotici", "magici",
"da acido", "divini", "nucleari", "psichici", "fisici", "puri", "da taglio", "da acido", "divini", "nucleari", "psichici", "fisici", "puri", "da taglio",
"da perforazione", "da impatto", "da caduta", "gelato", "onnipotenti", "oscuri", "da perforazione", "da impatto", "da caduta", "gelato", "onnipotenti", "oscuri",
"di luce", "da velocità", "da cactus", "meta", "dannosi", "da radiazione", "di luce", "da velocità", "da cactus", "meta", "dannosi", "da radiazione",
"tuamammici", "da maledizione", "pesanti", "leggeri", "immaginari", "da laser", "tuamammici", "da maledizione", "pesanti", "leggeri", "immaginari", "da laser",
"da neutrini", "galattici", "cerebrali", "ritardati", "ritardanti"], 1)[0] "da neutrini", "galattici", "cerebrali", "ritardati", "ritardanti", "morali", "materiali",
# Reseed the rng with a random value "energetici", "esplosivi"]
# so that the dice roll always deals a different damage
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() random.seed()
total = dmg_mod self.hit_roll = random.randrange(0, 101)
# Check for a critical hit self.damage = 0
crit = 1 self.crit_multiplier = 1
while True: self.damage_type = random.sample(spell.damage_types, 1)[0]
crit_die = random.randrange(1, 21) if self.hit_roll > spell.miss_chance:
if crit_die == 20: return
crit *= 2 for _ in range(spell.dice_number):
else: self.damage += random.randrange(1, spell.dice_type + 1)
break self.damage += spell.constant
for dice in range(0, dmg_dice): if self.damage < 0:
total += random.randrange(1, dmg_max + 1) self.damage = 0
if crit > 1: while random.randrange(1, 21) == 20:
if platform == "telegram": self.crit_multiplier *= 2
crit_msg = f"<b>CRITICO ×{crit}{'!' * crit}</b>\n"
elif platform == "discord": def damage(self):
crit_msg = f"**CRITICO ×{crit}{'!' * crit}**\n" return self.damage * self.crit_multiplier
total *= crit
else:
crit_msg = "" class Cast:
if platform == "telegram": def __init__(self, spell: Spell):
if dmg_dice == 10 and dmg_max == 100 and dmg_mod == 20: self.hits = []
return f"❇️‼️ Ho lanciato <b>{spell}</b> su " \ for _ in spell.repeat:
f"<i>{target_name}</i>.\n" \ self.hits.append(Hit(spell))
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}!"