fixing blackjack and improving lookup
This commit is contained in:
@ -4,22 +4,162 @@ import discord
|
||||
|
||||
from gwendolyn.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"]
|
||||
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"
|
||||
]
|
||||
|
||||
# Calculates D&D stat modifier
|
||||
def modifier(self, statistic):
|
||||
mods = math.floor((statistic-10)/2)
|
||||
if mods >= 0:
|
||||
mods = "+"+str(mods)
|
||||
return(str(mods))
|
||||
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 monsterFunc(self, ctx, query):
|
||||
async def monster_func(self, ctx, query):
|
||||
query = cap(query)
|
||||
self.bot.log("Looking up "+query)
|
||||
|
||||
@ -27,124 +167,41 @@ class LookupFuncs():
|
||||
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:
|
||||
# Opens "monsters.json"
|
||||
data = json.load(open('gwendolyn/resources/lookup/monsters.json', encoding = "utf8"))
|
||||
for monster in data:
|
||||
if "name" in monster and str(query) == monster["name"]:
|
||||
self.bot.log("Found it!")
|
||||
|
||||
# Looks at the information about the monster and returns that information
|
||||
# in separate variables, allowing Gwendolyn to know where to separate
|
||||
# the messages
|
||||
if monster["subtype"] != "":
|
||||
types = (monster["type"]+" ("+monster["subtype"]+")")
|
||||
else:
|
||||
types = monster["type"]
|
||||
con_mod = math.floor((monster["constitution"]-10)/2)
|
||||
hit_dice = monster["hit_dice"]
|
||||
|
||||
stats = ("**Str:** "+str(monster["strength"])+" ("+self.modifier(monster["strength"])+")\t**Dex:** "+str(monster["dexterity"])+" ("+self.modifier(monster["dexterity"])+")\t**Con:** "+str(monster["constitution"])+" ("+self.modifier(monster["constitution"])+")\n**Int: **"+str(monster["intelligence"])+" ("+self.modifier(monster["intelligence"])+")\t**Wis: **"+str(monster["wisdom"])+" ("+self.modifier(monster["wisdom"])+")\t**Cha: **"+str(monster["charisma"])+" ("+self.modifier(monster["charisma"])+")")
|
||||
|
||||
saving_throws = ""
|
||||
for save in self.saves:
|
||||
if save in monster:
|
||||
if monster[save] >= 0:
|
||||
saving_throws += " "+cap(save[:3])+" +"+str(monster[save])+","
|
||||
else:
|
||||
saving_throws += " "+cap(save[:3])+" "+str(monster[save])+","
|
||||
if saving_throws != "":
|
||||
saving_throws = "\n**Saving Throws**"+saving_throws[:-1]
|
||||
|
||||
skills = ""
|
||||
for skill in self.abilities:
|
||||
if skill in monster:
|
||||
if monster[skill] >= 0:
|
||||
skills += " "+cap(skill.replace("_"," "))+" +"+str(monster[skill])+","
|
||||
else:
|
||||
skills += " "+cap(skill.replace("_"," "))+" "+str(monster[skill])+","
|
||||
if skills != "":
|
||||
skills = "\n**Skills**"+skills[:-1]
|
||||
|
||||
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
|
||||
|
||||
specialAbilities = ""
|
||||
if "special_abilities" in monster:
|
||||
for ability in monster["special_abilities"]:
|
||||
specialAbilities += "\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"]
|
||||
|
||||
if con_mod < 0:
|
||||
hit_dice += (" - "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0])*(-1)))
|
||||
if con_mod > 0:
|
||||
hit_dice += (" + "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0])))
|
||||
|
||||
new_part = "\n--------------------"
|
||||
|
||||
monster_type = 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"])
|
||||
|
||||
monsterInfo = [(info, query),
|
||||
(specialAbilities, "Special Abilities"),
|
||||
(act, "Actions"),
|
||||
(react, "Reactions"),
|
||||
(legendaryActions, "Legendary Actions")]
|
||||
|
||||
self.bot.log("Returning monster information")
|
||||
|
||||
# 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 monsterInfo:
|
||||
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...")
|
||||
self.bot.log("Monster not in database")
|
||||
await ctx.send("I don't know that monster...")
|
||||
|
||||
# Looks up a spell
|
||||
async def spellFunc(self, ctx, query):
|
||||
async def spell_func(self, ctx, query):
|
||||
query = cap(query)
|
||||
self.bot.log("Looking up "+query)
|
||||
|
||||
|
Reference in New Issue
Block a user