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

View file

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

View file

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

View file

@ -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",
"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
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
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", "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:
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}!"
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()
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))