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)
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
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})'
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)
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")
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}")
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}")
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)
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
def getFormattedTrait(self, ctx: gb.GreedyContext, trait): traitFormatterClass = self._getTraitFormatterClass(trait) formatter = traitFormatterClass(ctx.getLID(), self.bot.languageProvider) return formatter.format(trait)
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)
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
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)
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