Files
Gwendolyn/gwendolyn_old/funcs/lookup/lookup_funcs.py
2024-10-28 13:05:06 +01:00

222 lines
7.9 KiB
Python

import math
import json
import discord
from gwendolyn_old.utils import cap
STATS = [
"strength",
"dexterity",
"constitution",
"intelligence",
"wisdom",
"charisma"
]
def mod(statistic):
"""Calculates D&D modifier."""
modifier = math.floor((statistic-10)/2)
if modifier >= 0:
modifier = "+"+str(modifier)
return modifier
class LookupFuncs():
def __init__(self, bot):
self.bot = bot
self.saves = [
"strength_save",
"dexterity_save",
"constitution_save",
"intelligence_save",
"wisdom_save",
"charisma_save"
]
self.abilities = [
"acrobatics",
"animal_handling",
"arcana",
"athletics",
"deception",
"history",
"insight",
"intimidation",
"investigation",
"medicine",
"nature",
"perception",
"performance",
"persuasion",
"religion",
"sleight_of_hand",
"stealth",
"survival"
]
def _format_monster(self, monster):
# Looks at the information about the monster and
# returns that information in separate variables,
# allowing Gwendolyn to know where to separate
# the messages
types = monster["type"]
if monster["subtype"] != "":
types += " ("+monster["subtype"]+")"
stats = []
for stat in STATS:
value = monster[stat]
stats.append(f"**{cap(stat[:3])}:** {value} ({mod(value)})")
stats = "\t".join(stats[:3]) + "\n" + "\t".join(stats[3:])
saving_throws = []
for save in self.saves:
if save in monster:
value = monster[save]
if monster[save] >= 0:
saving_throws.append(f"{cap(save[:3])} +{value}")
else:
saving_throws.append(f"{cap(save[:3])} {value}")
if saving_throws:
saving_throws = f"\n**Saving Throws:** {', '.join(saving_throws)}"
else:
saving_throws = ""
skills = []
for skill in self.abilities:
if skill in monster:
skill_name = cap(skill.replace("_"," "))
if monster[skill] >= 0:
skills.append(f"{skill_name} +{monster[skill]}")
else:
skills.append(f"{skill_name} {monster[skill]}")
if skills:
skills = f"\n**Skills:** {', '.join(skills)}"
else:
skills = ""
vulnerabilities = monster["damage_vulnerabilities"]
if vulnerabilities != "":
vulnerabilities = "\n**Damage Vulnerabilities** "+vulnerabilities
resistances = monster["damage_resistances"]
if resistances != "":
resistances = "\n**Damage Resistances** "+resistances
immunities = monster["damage_immunities"]
if immunities != "":
immunities = "\n**Damage Immunities** "+immunities
c_immunities = monster["condition_immunities"]
if c_immunities != "":
c_immunities = "\n**Condition Immunities** "+c_immunities
special_abilities = ""
if "special_abilities" in monster:
for ability in monster["special_abilities"]:
special_abilities += "\n\n***"+ability["name"]+".*** "+ability["desc"]
act = ""
if "actions" in monster:
for action in monster["actions"]:
act += "\n\n***"+action["name"]+".*** "+action["desc"]
react = ""
if "reactions" in monster:
for reaction in monster["reactions"]:
react += "\n\n***"+reaction["name"]+".*** "+reaction["desc"]
legendaryActions = ""
if "legendary_actions" in monster:
for action in monster["legendary_actions"]:
legendaryActions += "\n\n***"+action["name"]+".*** "+action["desc"]
hit_dice = monster["hit_dice"]
dice_amount = int(monster["hit_dice"].replace("d"," ").split()[0])
con_mod = math.floor((monster['constitution']-10)/2)
if con_mod < 0:
hit_dice += f" - {abs(con_mod) * dice_amount}"
elif con_mod > 0:
hit_dice += (f" + {con_mod * dice_amount}")
new_part = "\n--------------------"
monster_type = f"*{monster['size']} {types}, {monster['alignment']}*"
basic_info = "\n**Armor Class** "+str(monster["armor_class"])+"\n**Hit Points** "+str(monster["hit_points"])+" ("+hit_dice+")\n**Speed **"+monster["speed"]+new_part+"\n"
info = (monster_type+new_part+basic_info+stats+new_part+saving_throws+skills+vulnerabilities+resistances+immunities+c_immunities+"\n**Senses** "+monster["senses"]+"\n**Languages** "+monster["languages"]+"\n**Challenge** "+monster["challenge_rating"])
monster_info = [(info, monster['name']),
(special_abilities, "Special Abilities"),
(act, "Actions"),
(react, "Reactions"),
(legendaryActions, "Legendary Actions")]
self.bot.log("Returning monster information")
return monster_info
# Looks up a monster
async def monster_func(self, ctx, query):
query = cap(query)
self.bot.log("Looking up "+query)
# 1-letter monsters don't exist
if len(query) < 2:
self.bot.log("Monster name too short")
await ctx.send("I don't know that monster...")
return
# Opens "monsters.json"
monster_file_path = "gwendolyn/resources/lookup/monsters.json"
with open(monster_file_path,"r", encoding="utf-8") as file_pointer:
data = json.load(file_pointer)
for monster in data:
if "name" in monster and str(query) == monster["name"]:
self.bot.log("Found it!")
monster_info = self._format_monster(monster)
# Sends the received information. Separates into separate messages if
# there is too much text
await ctx.send(f"Result for \"{query}\"")
for text, title in monster_info:
if text != "":
if len(text) < 2000:
em = discord.Embed(title = title, description = text, colour=0xDEADBF)
await ctx.channel.send(embed = em)
else:
index = text[:2000].rfind(".")+1
em1 = discord.Embed(title = title, description = text[:index], colour=0xDEADBF)
await ctx.channel.send(embed = em1)
em2 = discord.Embed(title = "", description = text[index+1:], colour=0xDEADBF)
await ctx.channel.send(embed = em2)
break
else:
self.bot.log("Monster not in database")
await ctx.send("I don't know that monster...")
# Looks up a spell
async def spell_func(self, ctx, query):
query = cap(query)
self.bot.log("Looking up "+query)
# Opens "spells.json"
data = json.load(open('gwendolyn/resources/lookup/spells.json', encoding = "utf8"))
if query in data:
self.bot.log("Returning spell information")
send_message = (f"***{query}***\n*{data[query]['level']} level {data[query]['school']}\nCasting Time: {data[query]['casting_time']}\nRange:{data[query]['range']}\nComponents:{data[query]['components']}\nDuration:{data[query]['duration']}*\n \n{data[query]['description']}")
else:
self.bot.log("I don't know that spell")
send_message = "I don't think that's a spell"
if len(send_message) > 2000:
await ctx.send(send_message[:2000])
await ctx.send(send_message[2000:])
else:
await ctx.send(send_message)