async def spellbook_add(self, ctx, *, spell_name): """Adds a spell to the spellbook override. If character is live, will add to sheet as well.""" result = searchSpell(spell_name) if result is None: return await self.bot.say('Spell not found.') strict = result[1] results = result[0] if strict: result = results else: if len(results) == 1: result = results[0] else: result = await get_selection(ctx, [(r, r) for r in results]) if result is None: return await self.bot.say( 'Selection timed out or was cancelled.') spell = getSpell(result) character = await Character.from_ctx(ctx) if character.live: try: await DicecloudClient.getInstance().sync_add_spell( character, dicecloud_parse(spell)) except MeteorClient.MeteorClientException: return await self.bot.say( "Error: Failed to connect to Dicecloud. The site may be down." ) character.add_known_spell(spell) await character.commit(ctx) live = "Spell added to Dicecloud!" if character.live else '' await self.bot.say( f"{spell['name']} added to known spell list!\n{live}")
async def spell(self, ctx, *, name: str): """Looks up a spell.""" try: guild_id = ctx.message.server.id pm = self.settings.get(guild_id, {}).get("pm_result", False) srd = self.settings.get(guild_id, {}).get("srd", False) except: pm = False srd = False self.bot.db.incr('spells_looked_up_life') result = await search_and_select(ctx, c.spells, name, lambda e: e['name'], return_key=True, srd=srd) result = getSpell(result) spellDesc = [] embed = EmbedWithAuthor(ctx) color = embed.colour spell = copy.copy(result) def parseschool(school): if school == "A": return "abjuration" if school == "EV": return "evocation" if school == "EN": return "enchantment" if school == "I": return "illusion" if school == "D": return "divination" if school == "N": return "necromancy" if school == "T": return "transmutation" if school == "C": return "conjuration" return school def parsespelllevel(level): if level == "0": return "cantrip" if level == "2": return level + "nd level" if level == "3": return level + "rd level" if level == "1": return level + "st level" return level + "th level" spell['school'] = parseschool(spell.get('school')) spell['ritual'] = spell.get('ritual', 'no').lower() embed.title = spell['name'] if spell.get("source") == "UAMystic": embed.description = "*{level} Mystic Talent. ({classes})*".format( **spell) else: spell['level'] = parsespelllevel(spell['level']) embed.description = "*{level} {school}. ({classes})*".format( **spell) embed.add_field(name="Casting Time", value=spell['time']) embed.add_field(name="Range", value=spell['range']) embed.add_field(name="Components", value=spell['components']) embed.add_field(name="Duration", value=spell['duration']) embed.add_field(name="Ritual", value=spell['ritual']) if isinstance(spell['text'], list): for a in spell["text"]: if a is '': continue spellDesc.append( a.replace("At Higher Levels: ", "**At Higher Levels:** "). replace( "This spell can be found in the Elemental Evil Player's Companion", "")) else: spellDesc.append(spell['text'].replace( "At Higher Levels: ", "**At Higher Levels:** " ).replace( "This spell can be found in the Elemental Evil Player's Companion", "")) text = '\n'.join(spellDesc) if "**At Higher Levels:** " in text: text, higher_levels = text.split("**At Higher Levels:** ", 1) elif "At Higher Levels" in text: text, higher_levels = text.split("At Higher Levels", 1) text = text.strip('*\n') higher_levels = higher_levels.strip('* \n.:') else: higher_levels = None if not spell['srd'] and srd: text = "No description available." higher_levels = '' if len(text) > 1020: pieces = [text[:1020]] + [ text[i:i + 2040] for i in range(1020, len(text), 2040) ] else: pieces = [text] embed.add_field(name="Description", value=pieces[0]) embed_queue = [embed] if len(pieces) > 1: for piece in pieces[1:]: temp_embed = discord.Embed() temp_embed.colour = color temp_embed.description = piece embed_queue.append(temp_embed) if higher_levels: embed_queue[-1].add_field(name="At Higher Levels", value=higher_levels) for embed in embed_queue: if pm: await self.bot.send_message(ctx.message.author, embed=embed) else: await self.bot.say(embed=embed)
async def _old_cast(self, ctx, spell_name, args): spell = getSpell(spell_name) self.bot.rdb.incr('spells_looked_up_life') if spell is None: return await self.bot.say("Spell not found.", delete_after=15) if spell.get('source') == "UAMystic": return await self.bot.say("Mystic talents are not supported.") char = await Character.from_ctx(ctx) args = await scripting.parse_snippets(args, ctx) args = await char.parse_cvars(args, ctx) args = shlex.split(args) args = argparse(args) can_cast = True spell_level = int(spell.get('level', 0)) cast_level = args.last('l', spell_level, int) if not spell_level <= cast_level <= 9: return await self.bot.say("Invalid spell level.") # make sure we can cast it if not char.get_remaining_slots( cast_level) > 0 and spell_name in char.get_spell_list(): can_cast = False if args.last('i', type_=bool): can_cast = True if not can_cast: embed = EmbedWithCharacter(char) embed.title = "Cannot cast spell!" embed.description = "Not enough spell slots remaining, or spell not in known spell list!\n" \ "Use `!game longrest` to restore all spell slots, or pass `-i` to ignore restrictions." if cast_level > 0: embed.add_field(name="Spell Slots", value=char.get_remaining_slots_str(cast_level)) return await self.bot.say(embed=embed) if len(args) == 0: rolls = spell.get('roll', None) if isinstance(rolls, list): rolls = '\n'.join(rolls) \ .replace('SPELL', str(char.get_spell_ab() - char.get_prof_bonus())) \ .replace('PROF', str(char.get_prof_bonus())) rolls = rolls.split('\n') out = "**{} casts {}:** ".format( char.get_name(), spell['name']) + '\n'.join( roll(r, inline=True).skeleton for r in rolls) elif rolls is not None: rolls = rolls \ .replace('SPELL', str(char.get_spell_ab() - char.get_prof_bonus())) \ .replace('PROF', str(char.get_prof_bonus())) out = "**{} casts {}:** ".format( char.get_name(), spell['name']) + roll( rolls, inline=True).skeleton else: out = "**{} casts {}!** ".format(char.get_name(), spell['name']) else: rolls = args.get('r') roll_results = "" for r in rolls: res = roll(r, inline=True) if res.total is not None: roll_results += res.result + '\n' else: roll_results += "**Effect:** " + r out = "**{} casts {}:**\n".format(char.get_name(), spell['name']) + roll_results if not args.last('i', type_=bool): char.use_slot(cast_level) if cast_level > 0: out += f"\n**Remaining Spell Slots**: {char.get_remaining_slots_str(cast_level)}" out = "Spell not supported by new cast, falling back to old cast.\n" + out await char.commit(ctx) # make sure we save changes await self.bot.say(out) spell_cmd = self.bot.get_command('spell') if spell_cmd is None: return await self.bot.say("Lookup cog not loaded.") await ctx.invoke(spell_cmd, name=spell['name'])