Esempio n. 1
0
 async def roll_soak(self, ctx: gb.GreedyContext, parsed: dict) -> str:
     if RollArg.MULTI in parsed or RollArg.SPLIT in parsed or RollArg.ADD in parsed or parsed[
             RollArg.ROLLTYPE] != RollType.NORMALE:
         raise gb.GreedyCommandError(
             "string_error_roll_invalid_param_combination")
     lid = ctx.getLID()
     diff = parsed[RollArg.DIFF] if RollArg.DIFF in parsed else 6
     character = self.bot.dbm.getActiveChar(ctx)
     pool = self.bot.dbm.getTrait_LangSafe(character['id'], 'costituzione',
                                           lid)['cur_value']
     try:
         pool += self.bot.dbm.getTrait_LangSafe(character['id'],
                                                'robustezza',
                                                lid)['cur_value']
     except ghostDB.DBException:
         pass
     return self.rollAndFormatVTM(ctx,
                                  pool,
                                  10,
                                  diff,
                                  RollStatusSoak(self.bot.languageProvider,
                                                 lid),
                                  0,
                                  False,
                                  statistics=RollArg.STATS in parsed)
Esempio n. 2
0
 async def roll_reflexes(self, ctx: gb.GreedyContext, parsed: dict) -> str:
     if RollArg.MULTI in parsed or RollArg.SPLIT in parsed or parsed[
             RollArg.
             ROLLTYPE] != RollType.NORMALE or RollArg.DIFF in parsed:
         raise gb.GreedyCommandError(
             "string_error_roll_invalid_param_combination")
     lid = ctx.getLID()
     add = parsed[RollArg.ADD] if RollArg.ADD in parsed else 0
     character = self.bot.dbm.getActiveChar(ctx)
     volonta = self.bot.dbm.getTrait_LangSafe(character['id'], 'volonta',
                                              lid)  #['cur_value']
     prontezza = self.bot.dbm.getTrait_LangSafe(character['id'],
                                                'prontezza',
                                                lid)  #['cur_value']
     diff = 10 - prontezza['cur_value']
     response = f'{volonta["traitName"]}: {volonta["cur_value"]}, {prontezza["traitName"]}: {prontezza["cur_value"]} -> {volonta["cur_value"]}d{10} {self.bot.getStringForUser(ctx, "string_diff")} ({diff} = {10}-{prontezza["cur_value"]})\n'
     response += self.rollAndFormatVTM(ctx,
                                       volonta['cur_value'],
                                       10,
                                       diff,
                                       RollStatusReflexes(
                                           self.bot.languageProvider, lid),
                                       add,
                                       statistics=RollArg.STATS in parsed)
     return response
Esempio n. 3
0
 async def roll_initiative(self, ctx: gb.GreedyContext,
                           parsed: dict) -> str:
     if RollArg.MULTI in parsed or RollArg.SPLIT in parsed or parsed[
             RollArg.
             ROLLTYPE] != RollType.NORMALE or RollArg.DIFF in parsed:
         raise gb.GreedyCommandError(
             "string_error_roll_invalid_param_combination")
     lid = ctx.getLID()
     add = parsed[RollArg.ADD] if RollArg.ADD in parsed else 0
     raw_roll = random.randint(1, 10)
     bonuses_log = []
     bonus = add
     if add:
         bonuses_log.append(
             self.bot.getStringForUser(ctx, "string_bonus_X", add))
     try:
         character = self.bot.dbm.getActiveChar(ctx)
         for traitid in ['prontezza', 'destrezza',
                         'velocità']:  # TODO dehardcode?
             try:
                 val = self.bot.dbm.getTrait_LangSafe(
                     character['id'], traitid, lid)
                 bonus += val["cur_value"]
                 bonuses_log.append(
                     f'{val["traitName"]}: {val["cur_value"]}')
             except ghostDB.DBException:
                 pass
     except ghostDB.DBException:
         bonuses_log.append(
             self.bot.getStringForUser(ctx, "string_comment_no_pc"))
     details = ""
     if len(bonuses_log):
         details = ", ".join(bonuses_log)
     final_val = raw_roll + bonus
     return f'{self.bot.getStringForUser(ctx, "string_initiative")}: **{final_val}**\n{self.bot.getStringForUser(ctx, "string_roll")}: [{raw_roll}] + {bonus if bonus else 0} ({details})'
Esempio n. 4
0
 async def lang(self,
                ctx: gb.GreedyContext,
                language: gc.LanguageConverter = None):
     issuer = ctx.message.author.id
     if not language:
         await self.bot.atSendLang(ctx, "string_your_lang_is", ctx.getLID())
     else:
         langId = language['langId']
         _ = ctx.getUserInfo()
         self.bot.dbm.db.update("People",
                                where='userid  = $userid',
                                vars=dict(userid=issuer),
                                langId=langId)
         ctx._loadUserInfo(
         )  # we need to reload the language id for the user
         lid = language['langId']
         await self.bot.atSendLang(ctx, "string_lang_updated_to", lid)
Esempio n. 5
0
 async def rmt(self, ctx: gb.GreedyContext, character: gc.CharacterConverter, trait: gc.TraitConverter):
     issuer = str(ctx.message.author.id)
     chartrait = self.bot.dbm.getTrait_LangSafe(character['id'], trait['id'], ctx.getLID())
     ttype = self.bot.dbm.db.select('TraitType', where='id=$id', vars=dict(id=trait['traittype']))[0]
     
     updated_rows = self.bot.dbm.db.delete("CharacterTrait", where='trait = $trait and playerchar = $pc', vars=dict(trait=trait['id'], pc=character['id']))
     if ttype['textbased']:
         self.bot.dbm.log(issuer, character['id'], trait['id'], ghostDB.LogType.DELETE, "", chartrait['text_value'], ctx.message.content)
     else:
         self.bot.dbm.log(issuer, character['id'], trait['id'], ghostDB.LogType.DELETE, "", f"{chartrait['cur_value']}/{chartrait['max_value']}", ctx.message.content)
     if updated_rows > 0:
         await self.bot.atSend(ctx, f"Rimosso {trait['name']} da {character['fullname']} ({updated_rows})")
     else:
         await self.bot.atSend(ctx, f"Nessun tratto rimosso")
Esempio n. 6
0
 async def modt(self, ctx: gb.GreedyContext, character: gc.CharacterConverter, trait: gc.TraitConverter, value, *args):
     issuer = str(ctx.message.author.id)
     
     chartrait = self.bot.dbm.getTrait_LangSafe(character['id'], trait['id'], ctx.getLID())
             
     ttype = self.bot.dbm.db.select('TraitType', where='id=$id', vars=dict(id=trait['traittype']))[0]
     val = None
     if ttype['textbased']:
         val = " ".join([value]+list(args))
         self.bot.dbm.db.update("CharacterTrait", where='trait = $trait and playerchar = $pc', vars=dict(trait=trait['id'], pc=character['id']), text_value = val)
         self.bot.dbm.log(issuer, character['id'], trait['id'], ghostDB.LogType.TEXT_VALUE, val, chartrait['text_value'], ctx.message.content)
     else:
         val = int(value)
         self.bot.dbm.db.update("CharacterTrait", where='trait = $trait and playerchar = $pc', vars=dict(trait=trait['id'], pc=character['id']), cur_value = val, max_value = val)
         self.bot.dbm.log(issuer, character['id'], trait['id'], ghostDB.LogType.MAX_VALUE, val, chartrait['max_value'], ctx.message.content)
         self.bot.dbm.log(issuer, character['id'], trait['id'], ghostDB.LogType.CUR_VALUE, val, chartrait['cur_value'], ctx.message.content)
     
     await self.bot.atSend(ctx, f"{character['fullname']} ora ha {trait['name']} {val}")
Esempio n. 7
0
 async def addt(self, ctx: gb.GreedyContext, character: gc.CharacterConverter, trait: gc.TraitConverter, value, *args):
     issuer = str(ctx.message.author.id)
     
     try:
         lid = ctx.getLID()
         ptrait = self.bot.dbm.getTrait_LangSafe(character['id'], trait['id'], lid)
         raise gb.BotException(f"{character['fullname']} ha già il tratto {ptrait['name']} ")
     except ghostDB.DBException:
         pass
     
     ttype = self.bot.dbm.db.select('TraitType', where='id=$id', vars=dict(id=trait['traittype']))[0]
     val = None
     if ttype['textbased']:
         val = " ".join([value]+list(args))
         self.bot.dbm.db.insert("CharacterTrait", trait=trait['id'], playerchar=character['id'], cur_value = 0, max_value = 0, text_value = val, pimp_max = 0)
         self.bot.dbm.log(issuer, character['id'], trait['id'], ghostDB.LogType.TEXT_VALUE, val, '', ctx.message.content)
     else:
         val = int(value)
         pimp = 6 if trait['traittype'] in ['fisico', 'sociale', 'mentale'] else 0
         self.bot.dbm.db.insert("CharacterTrait", trait=trait['id'], playerchar=character['id'], cur_value = val, max_value = val, text_value = "", pimp_max = pimp)
         self.bot.dbm.log(issuer, character['id'], trait['id'], ghostDB.LogType.MAX_VALUE, val, '', ctx.message.content)
     
     await self.bot.atSend(ctx, f"{character['fullname']} ora ha {trait['name']} {val}")
Esempio n. 8
0
    async def search_trait(self, ctx: gb.GreedyContext, *args):
        if len(args) == 0:
            await self.bot.atSendLang("string_error_no_searchterm")
            return

        searchstring = "%" + (" ".join(args)) + "%"
        lower_version = searchstring.lower()
        traits = self.bot.dbm.db.select(
            "LangTrait",
            where=
            "langId=$langid and (traitId like $search_lower or traitShort like $search_lower or traitName like $search_string)",
            vars=dict(search_lower=lower_version,
                      search_string=searchstring,
                      langid=ctx.getLID()))

        if not len(traits):
            await self.bot.atSendLang("string_msg_no_match")
            return

        response = self.bot.getStringForUser(ctx,
                                             "string_msg_found_traits") + ":\n"
        for trait in traits:
            response += f"\n {trait['traitShort']} ({trait['traitId']}): {trait['traitName']}"
        await self.bot.atSend(ctx, response)
Esempio n. 9
0
    async def pc_interact(self, ctx: gb.GreedyContext, pc: object,
                          can_edit: bool, *args_tuple) -> str:
        lid = ctx.getLID()

        args = list(args_tuple)

        response = ''
        if len(args) == 0:
            parsed = list(
                urllib.parse.urlparse(self.bot.config['Website']
                                      ['website_url']))  # load website url
            parsed[4] = urllib.parse.urlencode({'character':
                                                pc['id']})  # fill query
            unparsed = urllib.parse.urlunparse(tuple(parsed))  # recreate url
            return f"Personaggio: {pc['fullname']}\nScheda: {unparsed}"

        # detach stuff like ["exp+1"] to ["exp", "+1"]" or ["exp-", "1"] to ["exp", "-", "1"] in args
        for op in ["+", "-", "="]:
            idx = args[0].find(op)
            if idx > 0:
                args = [args[0][:idx]] + [args[0][idx:]] + args[1:]
                break

        trait_id = args[0].lower()
        if len(args) == 1:
            trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
            return self.getFormattedTrait(ctx, trait)

        # qui siamo sicuri che c'è un'operazione (o spazzatura)
        if not can_edit:
            return f'A sessione spenta puoi solo consultare le tue statistiche'

        param = "".join(args[1:])  # squish
        operazione = None
        if param in reset_aliases:
            operazione = "r"
        else:
            operazione = param[0]
            if not operazione in ["+", "-", "="]:
                return f'Operazione "{operazione}" non supportata'

        trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
        #trait = dbm.getTrait(pc['id'], trait_id)
        if trait['pimp_max'] == 0 and trait['trackertype'] == 0:
            raise gb.BotException(
                f"Non puoi modificare il valore corrente di {trait['traitName']}"
            )
        if trait['trackertype'] != 2:
            n = None
            if operazione != "r":
                n = param[1:]
                if not (n.isdigit()):
                    return f'"{n}" non è un intero >= 0'

            if operazione == "r":
                if trait['trackertype'] == 1 or trait['trackertype'] == 0:
                    n = trait['max_value'] - trait['cur_value']
                elif trait['trackertype'] == 3:
                    n = -trait['cur_value']
                else:
                    raise gb.BotException(
                        f"Tracker {trait['trackertype']} non supportato")
            elif operazione == "=":
                n = int(param[1:]) - trait['cur_value']  # tricks
            else:
                n = int(param)
            new_val = trait['cur_value'] + n
            max_val = max(trait['max_value'], trait['pimp_max'])
            if new_val < 0:
                raise gb.BotException(
                    f'Non hai abbastanza {trait["traitName"].lower()}!')
            elif new_val > max_val and trait['trackertype'] != 3:
                raise gb.BotException(
                    f"Non puoi avere {new_val} {trait['traitName'].lower()}. Valore massimo: {max_val}"
                )
            #
            u = self.bot.dbm.db.update(
                'CharacterTrait',
                where='trait = $trait and playerchar = $pc',
                vars=dict(trait=trait['id'], pc=pc['id']),
                cur_value=new_val)
            self.bot.dbm.log(ctx.message.author.id, pc['id'], trait['trait'],
                             ghostDB.LogType.CUR_VALUE, new_val,
                             trait['cur_value'], ctx.message.content)
            if u == 1:
                trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
                return self.getFormattedTrait(ctx, trait)
            elif u == 0:
                trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
                return self.getFormattedTrait(ctx, trait)
            else:
                return f'Qualcosa è andato storto, righe aggiornate:  {u}'

        # salute
        response = ''
        n = param[
            1:-1]  # 1st char is the operation, last char is the damaage type
        if n == '':
            n = 1
        elif n.isdigit():
            n = int(n)
        elif operazione == "=" or operazione == "r":
            pass
        else:
            raise gb.BotException(f'"{n}" non è un parametro valido!')
        dmgtype = param[-1].lower()
        new_health = trait['text_value']
        if (not dmgtype in damage_types) and operazione != "r":
            raise gb.BotException(f'"{dmgtype}" non è un tipo di danno valido')
        if operazione == "r":
            new_health = ""

            u = self.bot.dbm.db.update(
                'CharacterTrait',
                where='trait = $trait and playerchar = $pc',
                vars=dict(trait=trait['id'], pc=pc['id']),
                text_value=new_health,
                cur_value=trait['max_value'])
            self.bot.dbm.log(ctx.message.author.id, pc['id'], trait['trait'],
                             ghostDB.LogType.CUR_VALUE, new_health,
                             trait['text_value'], ctx.message.content)
            if u != 1:
                raise gb.BotException(
                    f'Qualcosa è andato storto, righe aggiornate: {u}')
            trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
            response = self.getFormattedTrait(ctx, trait)
        elif operazione == "+":
            rip = False
            for i in range(
                    n):  # applico i danni uno alla volta perchè sono un nabbo
                if dmgtype == "c" and new_health.endswith(
                        "c"):  # non rischio di cambiare la lunghezza
                    new_health = new_health[:-1] + "l"
                else:
                    if len(new_health) < trait[
                            'max_value']:  # non ho già raggiunto il massimo
                        if dmgtype == "c":
                            new_health += "c"
                        elif dmgtype == "a":
                            new_health = "a" + new_health
                        else:
                            la = new_health.rfind("a") + 1
                            new_health = new_health[:la] + "l" + new_health[la:]
                    else:  # oh no
                        convert = False
                        if dmgtype == "c":
                            if trait['cur_value'] > 0:  # trick per salvarsi mezzo aggravato
                                trait['cur_value'] = 0
                            else:
                                convert = True
                                trait['cur_value'] = trait['max_value']
                        elif dmgtype == 'l':
                            convert = True
                        else:
                            rip = True

                        if convert:
                            fl = new_health.find('l')
                            if fl >= 0:
                                new_health = new_health[:fl] + 'a' + new_health[
                                    fl + 1:]
                            else:
                                rip = True
                        if rip:
                            break
            if new_health.count("a") == trait['max_value']:
                rip = True

            u = self.bot.dbm.db.update(
                'CharacterTrait',
                where='trait = $trait and playerchar = $pc',
                vars=dict(trait=trait['id'], pc=pc['id']),
                text_value=new_health,
                cur_value=trait['cur_value'])
            self.bot.dbm.log(ctx.message.author.id, pc['id'], trait['trait'],
                             ghostDB.LogType.CUR_VALUE, new_health,
                             trait['text_value'], ctx.message.content)
            if u != 1 and not rip:
                raise gb.BotException(
                    f'Qualcosa è andato storto, righe aggiornate: {u}')
            trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
            response = self.getFormattedTrait(ctx, trait)
            if rip:
                response += "\n\n RIP"
        elif operazione == "-":
            if dmgtype == "a":
                if new_health.count(dmgtype) < n:
                    raise gb.BotException("Non hai tutti quei danni aggravati")
                else:
                    new_health = new_health[n:]
            elif dmgtype == "l":
                if new_health.count(dmgtype) < n:
                    raise gb.BotException("Non hai tutti quei danni letali")
                else:
                    fl = new_health.find(dmgtype)
                    new_health = new_health[:fl] + new_health[fl + n:]
            else:  # dio can
                if ((int(trait['cur_value']) == 0) + new_health.count(dmgtype)
                        + new_health.count("l") * 2) < n:
                    raise gb.BotException(
                        "Non hai tutti quei danni contundenti")
                for i in range(n):
                    if trait['cur_value'] == 0:
                        trait['cur_value'] = trait[
                            'max_value']  # togli il mezzo aggravato
                    else:
                        if new_health[-1] == 'c':
                            new_health = new_health[:-1]
                        elif new_health[-1] == 'l':
                            new_health = new_health[:-1] + 'c'
                        else:
                            raise gb.BotException(
                                "Non hai tutti quei danni contundenti"
                            )  # non dovrebbe mai succedere
            u = self.bot.dbm.db.update(
                'CharacterTrait',
                where='trait = $trait and playerchar = $pc',
                vars=dict(trait=trait['id'], pc=pc['id']),
                text_value=new_health,
                cur_value=trait['cur_value'])
            self.bot.dbm.log(ctx.message.author.id, pc['id'], trait['trait'],
                             ghostDB.LogType.CUR_VALUE, new_health,
                             trait['text_value'], ctx.message.content)
            if u != 1:
                raise gb.BotException(
                    f'Qualcosa è andato storto, righe aggiornate: {u}')
            trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
            response = self.getFormattedTrait(ctx, trait)
        else:  # =
            full = param[1:]
            counts = list(map(lambda x: full.count(x), damage_types))
            if sum(counts) != len(full):
                raise gb.BotException(f'"{full}" non è un parametro valido!')
            new_health = "".join(
                list(map(lambda x: x[0] * x[1],
                         zip(damage_types,
                             counts))))  # siamo generosi e riordiniamo l'input

            u = self.bot.dbm.db.update(
                'CharacterTrait',
                where='trait = $trait and playerchar = $pc',
                vars=dict(trait=trait['id'], pc=pc['id']),
                text_value=new_health,
                cur_value=1)
            self.bot.dbm.log(ctx.message.author.id, pc['id'], trait['trait'],
                             ghostDB.LogType.CUR_VALUE, new_health,
                             trait['text_value'], ctx.message.content)
            if u != 1:
                raise gb.BotException(
                    f'Qualcosa è andato storto, righe aggiornate: {u}')
            trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
            response = self.getFormattedTrait(ctx, trait)

        return response
Esempio n. 10
0
 def getFormattedTrait(self, ctx: gb.GreedyContext, trait):
     traitFormatterClass = self._getTraitFormatterClass(trait)
     formatter = traitFormatterClass(ctx.getLID(),
                                     self.bot.languageProvider)
     return formatter.format(trait)
Esempio n. 11
0
    async def updt(self, ctx: gb.GreedyContext, old_traitid: gc.GreedyShortIdConverter, new_traitid: gc.GreedyShortIdConverter, traittype: gc.TraitTypeConverter, tracktype: gc.TrackerTypeConverter, std: gc.NoYesConverter, *args):    
        if len(args) == 0:
            await self.bot.atSend(ctx, newTrait_description)
            return
        
        istrait, old_trait = self.bot.dbm.validators.getValidateTrait( old_traitid).validate()
        if not istrait:
            raise gb.BotException(f"Il tratto {old_traitid} non esiste!")
        
        istrait, new_trait = self.bot.dbm.validators.getValidateTrait(new_traitid).validate()
        if istrait and (old_traitid!=new_traitid):
            raise gb.BotException(f"Il tratto {new_traitid} esiste già!")

        traittypeid = traittype['id']

        traitname = " ".join(list(args))
        
        response = f'Il tratto {traitname} è stato aggiornato'
        t = self.bot.dbm.db.transaction()
        try:
            self.bot.dbm.db.update("Trait", where= 'id = $oldid' , vars=dict(oldid = old_traitid), id = new_traitid, name = traitname, traittype = traittypeid, trackertype = tracktype, standard = std, ordering = 1.0)
            # now we update the language description, but only of the current language
            self.bot.dbm.db.update("LangTrait", where= 'traitId = $traitid and langId = $lid' , vars=dict(traitid=new_traitid, lid = ctx.getLID()), traitName = traitname)
            if std and not old_trait['standard']:
                self.bot.dbm.db.query(query_addTraitToPCs_safe, vars = dict(traitid=new_traitid))
                response +=  f'\nIl nuovo talento standard {traitname} è stato assegnato ai personaggi!'
            elif not std and old_trait['standard']:
                self.bot.dbm.db.query("""
    delete from CharacterTrait
    where trait = $traitid and max_value = 0 and cur_value = 0 and text_value = '';
    """, vars = dict(traitid=new_traitid))
                response += f'\nIl talento {traitname} è stato rimosso dai personaggi che non avevano pallini'
        except:
            t.rollback()
            raise
        else:
            t.commit()

        await self.bot.atSend(ctx, response)
Esempio n. 12
0
    async def roll_dice(self, ctx: gb.GreedyContext, parsed: dict) -> str:
        lid = ctx.getLID()
        ndice = 0
        if RollArg.PERMANENTE in parsed:
            ndice = parsed[RollArg.DADI_PERMANENTI]
        else:
            ndice = parsed[RollArg.DADI]

        if not RollArg.NFACES in parsed:
            raise gb.GreedyCommandError("string_error_no_faces")
        nfaces = parsed[RollArg.NFACES]

        character = parsed[RollArg.CHARACTER]  # might be None

        # modifico il numero di dadi

        if RollArg.PENALITA in parsed:
            if not character:
                character = self.bot.dbm.getActiveChar(ctx)
            health = self.bot.dbm.getTrait_LangSafe(character['id'], 'salute',
                                                    lid)
            penalty, _ = utils.parseHealth(health)
            ndice += penalty[0]

        max_dice = int(self.bot.config['BotOptions']['max_dice'])
        if ndice > max_dice:
            raise gb.GreedyCommandError("string_error_toomany_dice",
                                        (max_dice, ))
        if ndice <= 0:
            raise gb.GreedyCommandError("string_error_toofew_dice", (ndice, ))

        # check n° di mosse per le multiple
        if RollArg.MULTI in parsed:
            multi = parsed[RollArg.MULTI]
            max_moves = int(
                ((ndice + 1) / 2) - 0.1
            )  # (ndice+1)/2 è il numero di mosse in cui si rompe, non il massimo. togliendo 0.1 e arrotondando per difetto copro sia il caso intero che il caso con .5
            if max_moves == 1:
                raise gb.GreedyCommandError(
                    "string_error_not_enough_dice_multi")
            elif multi > max_moves:
                raise gb.GreedyCommandError(
                    "string_error_not_enough_dice_multi_MAX_REQUESTED",
                    (max_moves, ndice))

        # decido cosa fare

        add = parsed[RollArg.ADD] if RollArg.ADD in parsed else 0

        # simple roll
        if not (RollArg.MULTI in parsed) and not (
                RollArg.DIFF in parsed) and not (RollArg.SPLIT in parsed) and (
                    parsed[RollArg.ROLLTYPE] == RollType.NORMALE
                    or parsed[RollArg.ROLLTYPE] == RollType.SOMMA):
            raw_roll = list(
                map(lambda x: random.randint(1, nfaces), range(ndice)))
            if add != 0 or parsed[RollArg.ROLLTYPE] == RollType.SOMMA:
                roll_sum = sum(raw_roll) + add
                return f'{repr(raw_roll)} {"+" if add >= 0 else "" }{add} = **{roll_sum}**'
            else:
                return repr(raw_roll)

        if nfaces != 10:
            raise gb.GreedyCommandError('string_error_not_d10')
        # past this point, we are in d10 territory

        stats = RollArg.STATS in parsed
        response = ''

        if RollArg.MULTI in parsed:
            multi = parsed[RollArg.MULTI]
            split = []
            if RollArg.SPLIT in parsed:
                split = parsed[RollArg.SPLIT]
            if parsed[RollArg.ROLLTYPE] == RollType.NORMALE:
                response = ""
                if not RollArg.DIFF in parsed:
                    raise gb.GreedyCommandError("string_error_missing_diff")
                for i in range(multi):
                    parziale = ''
                    ndadi = ndice - i - multi
                    split_diffs = findSplit(i, split)
                    if len(split_diffs):
                        pools = [(ndadi - ndadi // 2), ndadi // 2]
                        for j in range(len(pools)):
                            parziale += f'\n{self.bot.getStringForUser(ctx,  "string_roll")} {j+1}: ' + self.rollAndFormatVTM(
                                ctx,
                                pools[j],
                                nfaces,
                                split_diffs[j],
                                RollStatusNormal(self.bot.languageProvider,
                                                 lid, parsed[RollArg.MINSUCC]),
                                statistics=stats)
                    else:
                        parziale = self.rollAndFormatVTM(
                            ctx,
                            ndadi,
                            nfaces,
                            parsed[RollArg.DIFF],
                            RollStatusNormal(self.bot.languageProvider, lid,
                                             parsed[RollArg.MINSUCC]),
                            statistics=stats,
                            minsucc=parsed[RollArg.MINSUCC])
                    response += f'\n{self.bot.getStringForUser(ctx,  "string_action")} {i+1}: ' + parziale  # line break all'inizio tanto c'è il @mention
            else:
                raise gb.GreedyCommandError(
                    "string_error_roll_invalid_param_combination")
        else:  # 1 tiro solo
            if RollArg.SPLIT in parsed:
                split = parsed[RollArg.SPLIT]
                if parsed[RollArg.ROLLTYPE] == RollType.NORMALE:
                    pools = [(ndice - ndice // 2), ndice // 2]
                    response = ''
                    for i in range(len(pools)):
                        parziale = self.rollAndFormatVTM(
                            ctx,
                            pools[i],
                            nfaces,
                            split[0][i + 1],
                            RollStatusNormal(self.bot.languageProvider, lid,
                                             parsed[RollArg.MINSUCC]),
                            statistics=stats)
                        response += f'\n{self.bot.getStringForUser(ctx, "string_roll")} {i+1}: ' + parziale
                else:
                    raise gb.GreedyCommandError(
                        "string_error_roll_invalid_param_combination")
            else:
                if parsed[
                        RollArg.ROLLTYPE] == RollType.NORMALE:  # tiro normale
                    if not RollArg.DIFF in parsed:
                        raise gb.GreedyCommandError(
                            "string_error_missing_diff")
                    response = self.rollAndFormatVTM(
                        ctx,
                        ndice,
                        nfaces,
                        parsed[RollArg.DIFF],
                        RollStatusNormal(self.bot.languageProvider, lid,
                                         parsed[RollArg.MINSUCC]),
                        add,
                        statistics=stats,
                        minsucc=parsed[RollArg.MINSUCC])
                elif parsed[RollArg.ROLLTYPE] == RollType.DANNI:
                    diff = parsed[
                        RollArg.DIFF] if RollArg.DIFF in parsed else 6
                    response = self.rollAndFormatVTM(
                        ctx,
                        ndice,
                        nfaces,
                        diff,
                        RollStatusDMG(self.bot.languageProvider, lid),
                        add,
                        False,
                        statistics=stats)
                elif parsed[RollArg.ROLLTYPE] == RollType.PROGRESSI:
                    diff = parsed[
                        RollArg.DIFF] if RollArg.DIFF in parsed else 6
                    response = self.rollAndFormatVTM(
                        ctx,
                        ndice,
                        nfaces,
                        diff,
                        RollStatusProgress(self.bot.languageProvider, lid),
                        add,
                        False,
                        True,
                        statistics=stats)
                else:
                    raise gb.GreedyCommandError(
                        "string_error_unknown_rolltype", (RollArg.ROLLTYPE, ))
        return response
Esempio n. 13
0
    def parseDiceExpression_Mixed(self,
                                  ctx: gb.GreedyContext,
                                  what: str,
                                  firstNegative: bool = False,
                                  character=None) -> DiceExprParsed:
        lid = ctx.getLID()

        saw_trait = False
        saw_notd10 = False

        faces = 0
        n = 0
        n_perm = 0
        n_extrasucc = 0

        split_add_list = what.split(
            ADD_CMD
        )  # split on "+", so each of the results STARTS with something to add
        for i in range(0, len(split_add_list)):
            split_add = split_add_list[i]
            split_sub_list = split_add.split(
                SUB_CMD
            )  # split on "-", so the first element will be an addition (unless firstNegative is true and i == 0), and everything else is a subtraction

            for j in range(0, len(split_sub_list)):
                term = split_sub_list[j]
                n_term = 0
                n_term_perm = 0
                n_term_extra = 0
                new_faces = 0
                try:  # either a xdy expr
                    parsed_expr = self.parseDiceExpression_Dice(term)
                    n_term = parsed_expr.n_dice
                    n_term_perm = parsed_expr.n_dice_permanent
                    new_faces = parsed_expr.n_faces
                    saw_notd10 = saw_notd10 or (new_faces != 10)
                except gb.GreedyCommandError as e:  # or a trait
                    try:
                        if not character:
                            character = self.bot.dbm.getActiveChar(
                                ctx)  # can raise
                        temp = self.bot.dbm.getTrait_LangSafe(
                            character['id'], term, lid)
                        n_term = temp['cur_value']
                        n_term_perm = temp['max_value']
                        saw_trait = True
                        new_faces = 10
                    except ghostDB.DBException as edb:
                        try:
                            _, n_term_extra = self.validateNumber(
                                ctx, [term], 0)
                        except ValueError as ve:
                            raise lng.LangSupportErrorGroup(
                                "MultiError", [
                                    gb.GreedyCommandError(
                                        "string_error_notsure_whatroll"), e,
                                    edb,
                                    gb.GreedyCommandError(f'{ve}')
                                ])

                if new_faces:
                    if faces and (
                            faces != new_faces
                    ):  # we do not support mixing different face numbers for now
                        raise gb.GreedyCommandError("string_error_face_mixing")
                    faces = new_faces

                if saw_trait and saw_notd10:  # forced10 = false only lets through non d10 expressions that DO NOT use traits
                    raise gb.GreedyCommandError("string_error_not_d10")

                if j > 0 or (i == 0 and firstNegative):
                    n -= n_term
                    n_perm -= n_term_perm
                    n_extrasucc -= n_term_extra
                else:
                    n += n_term
                    n_perm += n_term_perm
                    n_extrasucc += n_term_extra

        # is it good that if the espression is just flat numbers we can parse it?
        # for example ".roll 3d10 7" will parse the same as ".roll 3d10 +7"

        return DiceExprParsed(n, n_perm, n_extrasucc, faces, character)
Esempio n. 14
0
 async def on_command_error(self, ctx: gb.GreedyContext, error: Exception):
     lid = ctx.getLID()
     error = getattr(error, 'original', error)
     #ignored = (commands.CommandNotFound, )
     #if isinstance(error, ignored):
     #    print(error)
     if isinstance(error, commands.CommandNotFound):
         try:
             msgsplit = ctx.message.content.split(" ")
             msgsplit[0] = msgsplit[0][1:]  # toglie prefisso
             charid = msgsplit[0]
             ic, _ = self.bot.dbm.validators.getValidateCharacter(
                 charid).validate()
             if ic:
                 pgmanage_cog: cogPCmgmt.GreedyGhostCog_PCmgmt = self.bot.get_cog(
                     cogPCmgmt.GreedyGhostCog_PCmgmt.__name__)
                 if pgmanage_cog is not None:
                     await ctx.invoke(
                         pgmanage_cog.bot.get_command('pgmanage'),
                         *msgsplit)
                 else:
                     await self.bot.atSendLang(
                         ctx,
                         "string_error_wat")  # TODO error cog not loaded
             else:
                 await self.bot.atSendLang(ctx, "string_error_wat")
             return
         except Exception as e:
             error = e
     if isinstance(error, gb.BotException):
         await self.bot.atSend(ctx, f'{error}')
     elif isinstance(error, lng.LangSupportErrorGroup):
         await self.bot.atSend(ctx, self.bot.formatException(ctx, error))
     elif isinstance(error, lng.LangSupportException):
         await self.bot.atSend(
             ctx, self.bot.languageProvider.formatException(lid, error))
     elif isinstance(error, gb.GreedyCommandError):
         await self.bot.atSend(
             ctx, self.bot.languageProvider.formatException(lid, error))
     elif isinstance(error, commands.MissingRequiredArgument):
         await ctx.send_help(ctx.command)
     elif isinstance(error, lng.LangException):
         await self.bot.atSend(ctx, f'{error}')
     else:
         if isinstance(error, MySQLdb.OperationalError):
             if error.args[0] == 2006:
                 await self.bot.atSendLang(
                     ctx, "string_error_database_noanswer")
                 self.bot.dbm.reconnect()
             else:
                 await self.bot.atSendLang(ctx,
                                           "string_error_database_generic")
         elif isinstance(error, MySQLdb.IntegrityError):
             await self.bot.atSendLang(
                 ctx, "string_error_database_dataviolation")
         else:
             await self.bot.atSendLang(ctx,
                                       "string_error_unhandled_exception")
         #print("debug user:"******"string_error_details", ctx.message.content, type(error),
             error)
         # figure out where to send the error
         if debug_userid and debug_userid != '':
             debug_user = await self.bot.fetch_user(int(debug_userid))
         if debug_user != '':
             await debug_user.send(error_details)
         else:
             print(error_details)  # TODO logs