Merge branch 'master' of github.com:NikolajDanger/Gwendolyn
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,6 +1,10 @@
|
|||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
funcs/__pycache__/
|
funcs/__pycache__/
|
||||||
|
funcs/lookup/__pycache__/
|
||||||
|
funcs/other/__pycache__/
|
||||||
|
funcs/roll/__pycache__/
|
||||||
|
funcs/swfuncs/__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
*$py.class
|
*$py.class
|
||||||
|
|
||||||
@ -143,3 +147,4 @@ cython_debug/
|
|||||||
media
|
media
|
||||||
static
|
static
|
||||||
.vscode/
|
.vscode/
|
||||||
|
token.txt
|
||||||
|
18
Gwendolyn.py
18
Gwendolyn.py
@ -9,7 +9,11 @@ import codecs
|
|||||||
|
|
||||||
import funcs
|
import funcs
|
||||||
|
|
||||||
logging.basicConfig(filename="logfilename.log", level=logging.INFO)
|
logging.basicConfig(filename="gwendolyn.log", level=logging.INFO)
|
||||||
|
|
||||||
|
with open("token.txt","r") as f:
|
||||||
|
token = f.read().replace("\n","")
|
||||||
|
|
||||||
client = discord.Client()
|
client = discord.Client()
|
||||||
|
|
||||||
@client.event
|
@client.event
|
||||||
@ -30,13 +34,16 @@ async def on_message(message):
|
|||||||
localtime = time.asctime( time.localtime(time.time()) )
|
localtime = time.asctime( time.localtime(time.time()) )
|
||||||
print("\n"+localtime+"\n"+message.author.name+" ran !help")
|
print("\n"+localtime+"\n"+message.author.name+" ran !help")
|
||||||
logging.info("\n"+localtime+"\n"+message.author.name+" ran !help")
|
logging.info("\n"+localtime+"\n"+message.author.name+" ran !help")
|
||||||
with codecs.open("help.txt",encoding="utf-8") as f:
|
with codecs.open("resources/help.txt",encoding="utf-8") as f:
|
||||||
text = f.read()
|
text = f.read()
|
||||||
print(text)
|
print(text)
|
||||||
em = discord.Embed(title = "Help", description = text,colour = 0x59f442)
|
em = discord.Embed(title = "Help", description = text,colour = 0x59f442)
|
||||||
await message.channel.send(embed = em)
|
await message.channel.send(embed = em)
|
||||||
|
|
||||||
if message.content.lower().startswith("!hello"):
|
elif message.content.lower().startswith("!stop"):
|
||||||
|
await client.logout()
|
||||||
|
|
||||||
|
elif message.content.lower().startswith("!hello"):
|
||||||
localtime = time.asctime( time.localtime(time.time()) )
|
localtime = time.asctime( time.localtime(time.time()) )
|
||||||
print("\n"+localtime+"\n"+message.author.name+" ran !hello")
|
print("\n"+localtime+"\n"+message.author.name+" ran !hello")
|
||||||
logging.info("\n"+localtime+"\n"+message.author.name+" ran !hello")
|
logging.info("\n"+localtime+"\n"+message.author.name+" ran !hello")
|
||||||
@ -63,6 +70,9 @@ async def on_message(message):
|
|||||||
logging.info("\n"+localtime+"\n"+message.author.name+" ran !monster")
|
logging.info("\n"+localtime+"\n"+message.author.name+" ran !monster")
|
||||||
title, text1, text2, text3, text4, text5 = funcs.monsterFunc(message.content)
|
title, text1, text2, text3, text4, text5 = funcs.monsterFunc(message.content)
|
||||||
em1 = discord.Embed(title = title, description = text1, colour=0xDEADBF)
|
em1 = discord.Embed(title = title, description = text1, colour=0xDEADBF)
|
||||||
|
|
||||||
|
# Sends the received information. Seperates into seperate messages if
|
||||||
|
# there is too much text
|
||||||
await message.channel.send(embed = em1)
|
await message.channel.send(embed = em1)
|
||||||
if text2 != "":
|
if text2 != "":
|
||||||
if len(text2) < 2048:
|
if len(text2) < 2048:
|
||||||
@ -167,5 +177,5 @@ async def on_message(message):
|
|||||||
await message.channel.send(desc)
|
await message.channel.send(desc)
|
||||||
|
|
||||||
|
|
||||||
client.run("MzgwNzI4OTkwMTEwODQyODgx.DO81GQ.rctkEQtieciETXnmsYbwZvvOkaA")
|
client.run(token)
|
||||||
|
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
# Gwendolyn
|
# Gwendolyn
|
||||||
|
|
||||||
Gwendolyn is a discord bot that I made. It does a bunch of stuff.
|
Gwendolyn is a discord bot that I made. It does a bunch of stuff.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
Create a file named "token.txt" that contains your bot token.
|
||||||
|
@ -1 +1,7 @@
|
|||||||
from .gwendolynFuncs import helloFunc, roll_dice, cap, imageFunc, movieFunc, parseChar, parseRoll, spellFunc, monsterFunc, nameGen, tavernGen
|
from .gwendolynFuncs import helloFunc, roll_dice, cap, imageFunc
|
||||||
|
|
||||||
|
from .swfuncs import parseChar, parseRoll
|
||||||
|
|
||||||
|
from .lookup import spellFunc, monsterFunc
|
||||||
|
|
||||||
|
from .other import nameGen, tavernGen, movieFunc
|
@ -7,11 +7,8 @@ import urllib #used by imageFunc
|
|||||||
import imdb #used by movieFunc
|
import imdb #used by movieFunc
|
||||||
|
|
||||||
from .roll import dice
|
from .roll import dice
|
||||||
from .lookup import lookupFuncs
|
|
||||||
from .other import movie, generators
|
|
||||||
from .swfuncs import swchar, swroll
|
|
||||||
|
|
||||||
def roll_dice(author, rollStr: str = "1d20"):
|
def roll_dice(author : str, rollStr : str = "1d20"):
|
||||||
print("Rolling "+str(rollStr))
|
print("Rolling "+str(rollStr))
|
||||||
if rollStr == '0/0': # easter eggs
|
if rollStr == '0/0': # easter eggs
|
||||||
return("What do you expect me to do, destroy the universe?")
|
return("What do you expect me to do, destroy the universe?")
|
||||||
@ -100,50 +97,3 @@ def imageFunc():
|
|||||||
print("Successfully returned an image")
|
print("Successfully returned an image")
|
||||||
print("")
|
print("")
|
||||||
return(image)
|
return(image)
|
||||||
|
|
||||||
def movieFunc():
|
|
||||||
try:
|
|
||||||
print("Creating IMDb object")
|
|
||||||
ia = imdb.IMDb()
|
|
||||||
|
|
||||||
print("Picking a movie")
|
|
||||||
movs = open("funcs/other/movies.txt", "r")
|
|
||||||
movlist = movs.read().split("\n")
|
|
||||||
mov = random.choice(movlist)
|
|
||||||
movs.close()
|
|
||||||
|
|
||||||
print("Searching for "+mov)
|
|
||||||
s_result = ia.search_movie(mov)
|
|
||||||
|
|
||||||
print("Getting the data")
|
|
||||||
movie = s_result[0]
|
|
||||||
ia.update(movie)
|
|
||||||
cast = movie['cast']
|
|
||||||
pcast = ""
|
|
||||||
for x in range(3):
|
|
||||||
if cast[x]:
|
|
||||||
pcast += cast[x]['name']+", "
|
|
||||||
print("Successfully ran !movie")
|
|
||||||
print("")
|
|
||||||
return(movie['title'], movie['plot'][0].split("::")[0], movie['cover url'].replace("150","600").replace("101","404"), pcast[:-2])
|
|
||||||
except:
|
|
||||||
print("Something bad happened...")
|
|
||||||
return("error","","","")
|
|
||||||
|
|
||||||
def parseChar(user : str, cmd : str = ""):
|
|
||||||
return swchar.parseChar(user,cmd)
|
|
||||||
|
|
||||||
def parseRoll(user : str, cmd : str = ""):
|
|
||||||
return swroll.parseRoll(user,cmd)
|
|
||||||
|
|
||||||
def spellFunc(content):
|
|
||||||
return lookupFuncs.spellFunc(content)
|
|
||||||
|
|
||||||
def monsterFunc(content):
|
|
||||||
return lookupFuncs.monsterFunc(content)
|
|
||||||
|
|
||||||
def nameGen():
|
|
||||||
return generators.nameGen()
|
|
||||||
|
|
||||||
def tavernGen():
|
|
||||||
return generators.tavernGen()
|
|
||||||
|
1
funcs/lookup/__init__.py
Normal file
1
funcs/lookup/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from .lookupFuncs import spellFunc, monsterFunc
|
@ -1,10 +1,11 @@
|
|||||||
import math
|
import math
|
||||||
import discord
|
import discord
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
from funcs import gwendolynFuncs as gf
|
from funcs import gwendolynFuncs as gf
|
||||||
|
|
||||||
|
logging.basicConfig(filename="gwendolyn.log", level=logging.INFO)
|
||||||
|
|
||||||
def modifier(statistic):
|
def modifier(statistic):
|
||||||
mods = math.floor((statistic-10)/2)
|
mods = math.floor((statistic-10)/2)
|
||||||
@ -18,15 +19,21 @@ abilities = ["acrobatics","animal_handling","arcana","athletics","deception","hi
|
|||||||
def monsterFunc(content):
|
def monsterFunc(content):
|
||||||
command = gf.cap(content.lower().replace("!monster ",""))
|
command = gf.cap(content.lower().replace("!monster ",""))
|
||||||
print("Looking up "+command)
|
print("Looking up "+command)
|
||||||
|
logging.info("Looking up "+command)
|
||||||
if len(content.lower().split()) < 2:
|
if len(content.lower().split()) < 2:
|
||||||
print("Monster doesn't exist in database")
|
print("Monster doesn't exist in database\n")
|
||||||
print("")
|
logging.info("Monster doesn't exist in database\n")
|
||||||
return("I don't know that monster...","","","","","")
|
return("I don't know that monster...","","","","","")
|
||||||
else:
|
else:
|
||||||
data = json.load(open('funcs/lookup/monsters.json', encoding = "utf8"))
|
data = json.load(open('resources/monsters.json', encoding = "utf8"))
|
||||||
for monster in data:
|
for monster in data:
|
||||||
print("Found it!")
|
|
||||||
if str(command) == monster["name"]:
|
if str(command) == monster["name"]:
|
||||||
|
print("Found it!")
|
||||||
|
logging.info("Found it!")
|
||||||
|
|
||||||
|
# Looks at the information about the monster and returns that information
|
||||||
|
# in seperate variables, allowing Gwendolyn to know where to seperate
|
||||||
|
# the messages
|
||||||
if monster["subtype"] != "":
|
if monster["subtype"] != "":
|
||||||
typs = (monster["type"]+" ("+monster["subtype"]+")")
|
typs = (monster["type"]+" ("+monster["subtype"]+")")
|
||||||
else:
|
else:
|
||||||
@ -96,29 +103,40 @@ def monsterFunc(content):
|
|||||||
hit_dice += (" - "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0])*(-1)))
|
hit_dice += (" - "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0])*(-1)))
|
||||||
if con_mod > 0:
|
if con_mod > 0:
|
||||||
hit_dice += (" + "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0])))
|
hit_dice += (" + "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0])))
|
||||||
|
|
||||||
new_part = "\n--------------------"
|
new_part = "\n--------------------"
|
||||||
|
|
||||||
monster_type = monster["size"]+" "+typs+", "+monster["alignment"]+"*"
|
monster_type = monster["size"]+" "+typs+", "+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"
|
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"
|
||||||
|
|
||||||
text1 = (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"])
|
text1 = (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"])
|
||||||
|
|
||||||
text2 = (spec_ab)
|
text2 = (spec_ab)
|
||||||
text3 = (act)
|
text3 = (act)
|
||||||
text4 = (react)
|
text4 = (react)
|
||||||
text5 = (leg_act)
|
text5 = (leg_act)
|
||||||
|
|
||||||
print("Returning monster information")
|
print("Returning monster information")
|
||||||
print("")
|
logging.info("Returning monster information")
|
||||||
return(str(command),text1,text2,text3,text4,text5)
|
return(str(command),text1,text2,text3,text4,text5)
|
||||||
print("")
|
print("Couldn't find monster")
|
||||||
|
logging.info("Couldn't find monster")
|
||||||
return("I don't know that monster...","","","","","")
|
return("I don't know that monster...","","","","","")
|
||||||
|
|
||||||
def spellFunc(content):
|
def spellFunc(content):
|
||||||
command = gf.cap(content.lower().replace("!spell ",""))
|
command = gf.cap(content.lower().replace("!spell ",""))
|
||||||
print("Looking up "+command)
|
print("Looking up "+command)
|
||||||
data = json.load(open('funcs/lookup/spells.json', encoding = "utf8"))
|
logging.info("Looking up "+command)
|
||||||
|
data = json.load(open('resources/spells.json', encoding = "utf8"))
|
||||||
if str(command) in data:
|
if str(command) in data:
|
||||||
print("Returning spell information")
|
print("Returning spell information")
|
||||||
|
logging.info("Returning spell information")
|
||||||
spell_output = ("***"+str(command)+"***\n*"+str(data[str(command)]["level"])+" level "+str(data[str(command)]["school"])+"\nCasting Time: "+str(data[str(command)]["casting_time"])+"\nRange: "+str(data[str(command)]["range"])+"\nComponents: "+str(data[str(command)]["components"])+"\nDuration: "+str(data[str(command)]["duration"])+"*\n \n"+str(data[str(command)]["description"]))
|
spell_output = ("***"+str(command)+"***\n*"+str(data[str(command)]["level"])+" level "+str(data[str(command)]["school"])+"\nCasting Time: "+str(data[str(command)]["casting_time"])+"\nRange: "+str(data[str(command)]["range"])+"\nComponents: "+str(data[str(command)]["components"])+"\nDuration: "+str(data[str(command)]["duration"])+"*\n \n"+str(data[str(command)]["description"]))
|
||||||
else:
|
else:
|
||||||
print("I don't know that spell")
|
print("I don't know that spell")
|
||||||
|
logging.info("I don't know that spell")
|
||||||
spell_output = "I don't think that's a spell"
|
spell_output = "I don't think that's a spell"
|
||||||
print("Successfully ran !spell")
|
print("Successfully ran !spell")
|
||||||
|
logging.info("Successfully ran !spell")
|
||||||
return(spell_output)
|
return(spell_output)
|
||||||
|
2
funcs/other/__init__.py
Normal file
2
funcs/other/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from .generators import nameGen, tavernGen
|
||||||
|
from .movie import movieFunc
|
@ -1,14 +1,15 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import random
|
import random
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logging.basicConfig(filename="gwendolyn.log", level=logging.INFO)
|
||||||
|
|
||||||
def make_pairs(corpus):
|
def make_pairs(corpus):
|
||||||
for i in range(len(corpus)-1):
|
for i in range(len(corpus)-1):
|
||||||
yield (corpus[i], corpus[i+1])
|
yield (corpus[i], corpus[i+1])
|
||||||
|
|
||||||
def nameGen():
|
def nameGen():
|
||||||
names = open('funcs/other/names.txt', encoding='utf8').read()
|
names = open('resources/names.txt', encoding='utf8').read()
|
||||||
corpus = list(names)
|
corpus = list(names)
|
||||||
|
|
||||||
pairs = make_pairs(corpus)
|
pairs = make_pairs(corpus)
|
||||||
@ -36,13 +37,15 @@ def nameGen():
|
|||||||
if new_letter == "\n":
|
if new_letter == "\n":
|
||||||
done = True
|
done = True
|
||||||
genName = "".join(chain)
|
genName = "".join(chain)
|
||||||
print("Generated "+genName+"\n")
|
print("Generated "+genName)
|
||||||
|
logging.info("Generated "+genName)
|
||||||
return(genName)
|
return(genName)
|
||||||
|
|
||||||
def tavernGen():
|
def tavernGen():
|
||||||
fp = ["The Silver","The Golden","The Staggering","The Laughing","The Prancing","The Gilded","The Running","The Howling","The Slaughtered","The Leering","The Drunken","The Leaping","The Roaring","The Frowning","The Lonely","The Wandering","The Mysterious","The Barking","The Black","The Gleaming","The Tap-Dancing","The Sad","The Sexy","The Artificial","The Groovy","The Merciful","The Confused","The Pouting","The Horny","The Okay","The Friendly","The Hungry","The Handicapped","The Fire-breathing","The One-Eyed","The Psychotic","The Mad","The Evil","The Idiotic"]
|
fp = ["The Silver","The Golden","The Staggering","The Laughing","The Prancing","The Gilded","The Running","The Howling","The Slaughtered","The Leering","The Drunken","The Leaping","The Roaring","The Frowning","The Lonely","The Wandering","The Mysterious","The Barking","The Black","The Gleaming","The Tap-Dancing","The Sad","The Sexy","The Artificial","The Groovy","The Merciful","The Confused","The Pouting","The Horny","The Okay","The Friendly","The Hungry","The Handicapped","The Fire-breathing","The One-Eyed","The Psychotic","The Mad","The Evil","The Idiotic","The Trusty","The Busty"]
|
||||||
sp = ["Eel","Dolphin","Dwarf","Pegasus","Pony","Rose","Stag","Wolf","Lamb","Demon","Goat","Spirit","Horde","Jester","Mountain","Eagle","Satyr","Dog","Spider","Star","Dad","Rat","Jeremy","Mouse","Unicorn","Pearl","Ant","Crab","Penguin","Octopus","Lawyer","Ghost","Toad","Handjob","Immigrant","SJW","Dragon","Bard","Sphinx","Soldier","Salmon","Owlbear","Kite","Frost Giant","'̶̧̗̣̰̞̜̤̦̖͗̈́̏͊͒͜+̴͎̰͓̱̻̝̬̼͕̥͍̪͕̮͙͂͝*̶̲̓̊̏'̷̥̺͈̞͒̆̏͋̀̐̇͆̓͊͠'̷͖̱̟̟͉̝̪̮͕̃͑́̍͆̓̌͒̄͛̇͘̚ͅ!̷̡̻̈́#̸̳̰̿̿̏͐̏̓̌̚̚͠¨̷̟͙̱͎̟̱̅̀͋̇͗͂͋͋̕͘´̴̡̡͎͔̦̜̟̼̠̰̤͋́̀̓́̄́̏͂̀͜.̸̛̭͍̮̜͑̋̀̋̈́̇̆̆̌_̸̡̥̜̞̝̮̑͑̓̓̇͜͜^̴̡̢͕̠̖̤̺̭̮̙͕̼̳̺̼͋̿̏̎̑͑̊̀̅͐̚͝͝","Arsonist"]
|
sp = ["Eel","Dolphin","Dwarf","Pegasus","Pony","Rose","Stag","Wolf","Lamb","Demon","Goat","Spirit","Horde","Jester","Mountain","Eagle","Satyr","Dog","Spider","Star","Dad","Rat","Jeremy","Mouse","Unicorn","Pearl","Ant","Crab","Penguin","Octopus","Lawyer","Ghost","Toad","Handjob","Immigrant","SJW","Dragon","Bard","Sphinx","Soldier","Salmon","Owlbear","Kite","Frost Giant","Arsonist"]
|
||||||
tp = [" Tavern"," Inn","","","","","","","","",""]
|
tp = [" Tavern"," Inn","","","","","","","","",""]
|
||||||
genTav = random.choice(fp)+" "+random.choice(sp)+random.choice(tp)
|
genTav = random.choice(fp)+" "+random.choice(sp)+random.choice(tp)
|
||||||
print("Generated "+genTav+"\n")
|
print("Generated "+genTav)
|
||||||
|
logging.info("Generated "+genTav)
|
||||||
return(genTav)
|
return(genTav)
|
||||||
|
@ -1,28 +1,39 @@
|
|||||||
import imdb
|
import imdb
|
||||||
import random
|
import random
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logging.basicConfig(filename="gwendolyn.log", level=logging.INFO)
|
||||||
|
|
||||||
def movieFunc():
|
def movieFunc():
|
||||||
print("Running !movie")
|
try:
|
||||||
print("Creating IMDb object")
|
print("Creating IMDb object")
|
||||||
ia = imdb.IMDb()
|
logging.info("Creating IMDb object")
|
||||||
|
ia = imdb.IMDb()
|
||||||
|
|
||||||
print("Picking a movie")
|
print("Picking a movie")
|
||||||
movs = open("movies.txt", "r")
|
logging.info("Picking a movie")
|
||||||
movlist = movs.read().split("\n")
|
movs = open("resources/movies.txt", "r")
|
||||||
mov = random.choice(movlist)
|
movlist = movs.read().split("\n")
|
||||||
movs.close()
|
mov = random.choice(movlist)
|
||||||
|
movs.close()
|
||||||
|
|
||||||
print("Searching")
|
print("Searching for "+mov)
|
||||||
s_result = ia.search_movie(mov)
|
logging.info("Searching for "+mov)
|
||||||
|
s_result = ia.search_movie(mov)
|
||||||
|
|
||||||
print("Picking the movie")
|
print("Getting the data")
|
||||||
movie = s_result[0]
|
logging.info("Getting the data")
|
||||||
ia.update(movie)
|
movie = s_result[0]
|
||||||
cast = movie['cast']
|
ia.update(movie)
|
||||||
pcast = ""
|
cast = movie['cast']
|
||||||
for x in range(3):
|
pcast = ""
|
||||||
if cast[x]:
|
for x in range(3):
|
||||||
pcast += cast[x]['name']+", "
|
if cast[x]:
|
||||||
print("Successfully ran !movie")
|
pcast += cast[x]['name']+", "
|
||||||
print("")
|
print("Successfully ran !movie")
|
||||||
return(movie['title'], movie['plot'][0].split("::")[0], movie['cover url'].replace("150","600").replace("101","404"), pcast[:-2])
|
logging.info("Successfully ran !movie")
|
||||||
|
return(movie['title'], movie['plot'][0].split("::")[0], movie['cover url'].replace("150","600").replace("101","404"), pcast[:-2])
|
||||||
|
except:
|
||||||
|
print("Something bad happened...")
|
||||||
|
logging.info("Something bad happened...")
|
||||||
|
return("error","","","")
|
||||||
|
@ -10,7 +10,7 @@ import numexpr
|
|||||||
|
|
||||||
from . import errors
|
from . import errors
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
logging.basicConfig(filename="gwendolyn.log", level=logging.INFO)
|
||||||
|
|
||||||
VALID_OPERATORS = 'k|rr|ro|mi|ma|ra|e|p'
|
VALID_OPERATORS = 'k|rr|ro|mi|ma|ra|e|p'
|
||||||
VALID_OPERATORS_ARRAY = VALID_OPERATORS.split('|')
|
VALID_OPERATORS_ARRAY = VALID_OPERATORS.split('|')
|
||||||
@ -41,10 +41,10 @@ def get_roll_comment(rollStr):
|
|||||||
no_comment = ''
|
no_comment = ''
|
||||||
dice_set = re.split('([-+*/().=])', rollStr)
|
dice_set = re.split('([-+*/().=])', rollStr)
|
||||||
dice_set = [d for d in dice_set if not d in (None, '')]
|
dice_set = [d for d in dice_set if not d in (None, '')]
|
||||||
log.debug("Found dice set: " + str(dice_set))
|
logging.debug("Found dice set: " + str(dice_set))
|
||||||
for index, dice in enumerate(dice_set):
|
for index, dice in enumerate(dice_set):
|
||||||
match = DICE_PATTERN.match(dice)
|
match = DICE_PATTERN.match(dice)
|
||||||
log.debug("Found dice group: " + str(match.groups()))
|
logging.debug("Found dice group: " + str(match.groups()))
|
||||||
no_comment += dice.replace(match.group(5), '')
|
no_comment += dice.replace(match.group(5), '')
|
||||||
if match.group(5):
|
if match.group(5):
|
||||||
comment = match.group(5) + ''.join(dice_set[index + 1:])
|
comment = match.group(5) + ''.join(dice_set[index + 1:])
|
||||||
@ -85,10 +85,10 @@ class Roll(object):
|
|||||||
# parse each, returning a SingleDiceResult
|
# parse each, returning a SingleDiceResult
|
||||||
dice_set = re.split('([-+*/().=])', rollStr)
|
dice_set = re.split('([-+*/().=])', rollStr)
|
||||||
dice_set = [d for d in dice_set if not d in (None, '')]
|
dice_set = [d for d in dice_set if not d in (None, '')]
|
||||||
log.debug("Found dice set: " + str(dice_set))
|
logging.debug("Found dice set: " + str(dice_set))
|
||||||
for index, dice in enumerate(dice_set):
|
for index, dice in enumerate(dice_set):
|
||||||
match = DICE_PATTERN.match(dice)
|
match = DICE_PATTERN.match(dice)
|
||||||
log.debug("Found dice group: " + str(match.groups()))
|
logging.debug("Found dice group: " + str(match.groups()))
|
||||||
# check if it's dice
|
# check if it's dice
|
||||||
if match.group(1):
|
if match.group(1):
|
||||||
roll = self.roll_one(dice.replace(match.group(5), ''), adv)
|
roll = self.roll_one(dice.replace(match.group(5), ''), adv)
|
||||||
@ -157,7 +157,7 @@ class Roll(object):
|
|||||||
skeleton=skeletonReply, raw_dice=self)
|
skeleton=skeletonReply, raw_dice=self)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
if not isinstance(ex, (SyntaxError, KeyError, errors.AvraeException)):
|
if not isinstance(ex, (SyntaxError, KeyError, errors.AvraeException)):
|
||||||
log.error('Error in roll() caused by roll {}:'.format(rollStr))
|
logging.error('Error in roll() caused by roll {}:'.format(rollStr))
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return DiceResult(verbose_result="Invalid input: {}".format(ex))
|
return DiceResult(verbose_result="Invalid input: {}".format(ex))
|
||||||
|
|
||||||
|
2
funcs/swfuncs/__init__.py
Normal file
2
funcs/swfuncs/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from .swchar import parseChar
|
||||||
|
from .swroll import parseRoll
|
@ -1,73 +0,0 @@
|
|||||||
{
|
|
||||||
"Nikolaj": {
|
|
||||||
"Name": "Jared",
|
|
||||||
"Species": "",
|
|
||||||
"Career": "",
|
|
||||||
"Specialization Trees": [],
|
|
||||||
"Soak": 0,
|
|
||||||
"Wound Threshold": 0,
|
|
||||||
"Wounds": 0,
|
|
||||||
"Strain Threshold": 0,
|
|
||||||
"Strain": 0,
|
|
||||||
"Defense, Ranged": 0,
|
|
||||||
"Defense, Melee": 0,
|
|
||||||
"Force Rating": 0,
|
|
||||||
"Characteristics": {
|
|
||||||
"Brawn": 5,
|
|
||||||
"Agility": 0,
|
|
||||||
"Intellect": 0,
|
|
||||||
"Cunning": 0,
|
|
||||||
"Willpower": 0,
|
|
||||||
"Presence": 0
|
|
||||||
},
|
|
||||||
"Skills": {
|
|
||||||
"Astrogation": 0,
|
|
||||||
"Athletics": 0,
|
|
||||||
"Brawl": 1,
|
|
||||||
"Charm": 0,
|
|
||||||
"Coercion": 0,
|
|
||||||
"Computers": 0,
|
|
||||||
"Cool": 0,
|
|
||||||
"Coordination": 0,
|
|
||||||
"Core Worlds": 0,
|
|
||||||
"Discipline": 0,
|
|
||||||
"Gunnery": 0,
|
|
||||||
"Leadership": 0,
|
|
||||||
"Lightsaber": 0,
|
|
||||||
"Lore": 0,
|
|
||||||
"Mechanics": 0,
|
|
||||||
"Medicine": 0,
|
|
||||||
"Melee": 0,
|
|
||||||
"Negotiation": 0,
|
|
||||||
"Outer Rim": 0,
|
|
||||||
"Perception": 0,
|
|
||||||
"Piloting - Planetary": 0,
|
|
||||||
"Piloting - Space": 0,
|
|
||||||
"Ranged - Heavy": 0,
|
|
||||||
"Ranged - Light": 0,
|
|
||||||
"Resilience": 0,
|
|
||||||
"Skullduggery": 0,
|
|
||||||
"Stealth": 0,
|
|
||||||
"Streetwise": 0,
|
|
||||||
"Survival": 0,
|
|
||||||
"Underworld": 0,
|
|
||||||
"Vigilance": 0,
|
|
||||||
"Xenology": 0
|
|
||||||
},
|
|
||||||
"Lightsaber Characteristic": "Brawn",
|
|
||||||
"Obligations": {},
|
|
||||||
"Morality": {
|
|
||||||
"Emotional Weakness": "",
|
|
||||||
"Emotional Strength": "",
|
|
||||||
"Conflict": "",
|
|
||||||
"Morality": ""
|
|
||||||
},
|
|
||||||
"Credits": 0,
|
|
||||||
"Equipment": [],
|
|
||||||
"Armor": "",
|
|
||||||
"Critical Injuries": {},
|
|
||||||
"Weapons": {},
|
|
||||||
"Talents": {},
|
|
||||||
"Force Powers": {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,11 @@
|
|||||||
import json
|
import json
|
||||||
import string
|
import string
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logging.basicConfig(filename="gwendolyn.log", level=logging.INFO)
|
||||||
|
|
||||||
def getName(user : str):
|
def getName(user : str):
|
||||||
with open("funcs/swfuncs/characters.json", "r") as f:
|
with open("resources/swcharacters.json", "r") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if user in data:
|
if user in data:
|
||||||
@ -81,7 +84,7 @@ def characterSheet(character : dict):
|
|||||||
return name, text1+"\n\n"+text2+divider+text3
|
return name, text1+"\n\n"+text2+divider+text3
|
||||||
|
|
||||||
def charData(user : str,cmd : str):
|
def charData(user : str,cmd : str):
|
||||||
with open("funcs/swfuncs/characters.json", "r") as f:
|
with open("resources/swcharacters.json", "r") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
key = string.capwords(cmd.split(" ")[0])
|
key = string.capwords(cmd.split(" ")[0])
|
||||||
@ -107,7 +110,7 @@ def charData(user : str,cmd : str):
|
|||||||
|
|
||||||
if type(lookUpResult) is dict:
|
if type(lookUpResult) is dict:
|
||||||
data[user][key] = lookUpResult
|
data[user][key] = lookUpResult
|
||||||
with open("funcs/swfuncs/characters.json", "w") as f:
|
with open("resources/swcharacters.json", "w") as f:
|
||||||
json.dump(data,f,indent = 4)
|
json.dump(data,f,indent = 4)
|
||||||
return "Changed " + data[user]["Name"] + "'s " + key
|
return "Changed " + data[user]["Name"] + "'s " + key
|
||||||
else:
|
else:
|
||||||
@ -133,7 +136,7 @@ def charData(user : str,cmd : str):
|
|||||||
return "Can't add that"
|
return "Can't add that"
|
||||||
else:
|
else:
|
||||||
data[user][key] = cmd
|
data[user][key] = cmd
|
||||||
with open("funcs/swfuncs/characters.json", "w") as f:
|
with open("resources/swcharacters.json", "w") as f:
|
||||||
json.dump(data,f,indent = 4)
|
json.dump(data,f,indent = 4)
|
||||||
return "Changed " + data[user]["Name"] + "'s " + key +" to " + cmd
|
return "Changed " + data[user]["Name"] + "'s " + key +" to " + cmd
|
||||||
else:
|
else:
|
||||||
@ -142,7 +145,7 @@ def charData(user : str,cmd : str):
|
|||||||
return "You don't have a character. You can make one with !swchar"
|
return "You don't have a character. You can make one with !swchar"
|
||||||
|
|
||||||
def parseChar(user : str, cmd : str):
|
def parseChar(user : str, cmd : str):
|
||||||
with open("funcs/swfuncs/characters.json", "r") as f:
|
with open("resources/swcharacters.json", "r") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if cmd == " ":
|
if cmd == " ":
|
||||||
@ -157,25 +160,30 @@ def parseChar(user : str, cmd : str):
|
|||||||
if user in data:
|
if user in data:
|
||||||
return characterSheet(data[user])
|
return characterSheet(data[user])
|
||||||
else:
|
else:
|
||||||
with open("funcs/swfuncs/templates.json", "r") as f:
|
with open("resources/swtemplates.json", "r") as f:
|
||||||
templates = json.load(f)
|
templates = json.load(f)
|
||||||
newChar = templates["Character"]
|
newChar = templates["Character"]
|
||||||
data[user] = newChar
|
data[user] = newChar
|
||||||
with open("funcs/swfuncs/characters.json", "w") as f:
|
with open("resources/swcharacters.json", "w") as f:
|
||||||
json.dump(data,f,indent = 4)
|
json.dump(data,f,indent = 4)
|
||||||
return "", "Character for " + user + " created"
|
return "", "Character for " + user + " created"
|
||||||
else:
|
else:
|
||||||
|
if cmd == "purge":
|
||||||
|
del data[user]
|
||||||
|
with open("resources/swcharacters.json", "w") as f:
|
||||||
|
json.dump(data,f,indent = 4)
|
||||||
|
return "", "Character for " + user + " deleted"
|
||||||
return "", charData(user,cmd)
|
return "", charData(user,cmd)
|
||||||
|
|
||||||
def lightsaberChar(user : str):
|
def lightsaberChar(user : str):
|
||||||
with open("funcs/swfuncs/characters.json", "r") as f:
|
with open("resources/swcharacters.json", "r") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if user in data:
|
if user in data:
|
||||||
return data[user]["Lightsaber Characteristic"]
|
return data[user]["Lightsaber Characteristic"]
|
||||||
|
|
||||||
def userHasChar(user : str):
|
def userHasChar(user : str):
|
||||||
with open("funcs/swfuncs/characters.json", "r") as f:
|
with open("resources/swcharacters.json", "r") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
return user in data
|
return user in data
|
||||||
|
@ -2,10 +2,11 @@ import random
|
|||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
from . import swchar
|
from . import swchar
|
||||||
|
|
||||||
with open("funcs/swfuncs/skills.json", "r") as f:
|
with open("resources/swskills.json", "r") as f:
|
||||||
skillData = json.load(f)
|
skillData = json.load(f)
|
||||||
|
|
||||||
def roll(abi : int = 1, prof : int = 0, dif : int = 3, cha : int = 0, boo : int = 0, setb : int = 0, force : int = 0):
|
def roll(abi : int = 1, prof : int = 0, dif : int = 3, cha : int = 0, boo : int = 0, setb : int = 0, force : int = 0):
|
||||||
|
30
gwendolynTest.py
Normal file
30
gwendolynTest.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
import funcs
|
||||||
|
|
||||||
|
class testSwChar(unittest.TestCase):
|
||||||
|
def testNewChar(self):
|
||||||
|
text1, result = funcs.parseChar("TestUser","")
|
||||||
|
self.assertEqual(result,"Character for TestUser created")
|
||||||
|
|
||||||
|
def testChangeName(self):
|
||||||
|
text1, result = funcs.parseChar("TestUser","name TestChar")
|
||||||
|
self.assertEqual(result,"Changed TestChar's Name to TestChar")
|
||||||
|
|
||||||
|
def testChangeChar(self):
|
||||||
|
text1, result = funcs.parseChar("TestUser","characteristics brawn 1")
|
||||||
|
self.assertEqual(result,"Changed New Character's Characteristics")
|
||||||
|
|
||||||
|
def testDelChar(self):
|
||||||
|
text1, result = funcs.parseChar("TestUser","purge")
|
||||||
|
self.assertEqual(result,"Character for TestUser deleted")
|
||||||
|
|
||||||
|
|
||||||
|
class testGwendolynFuncs(unittest.TestCase):
|
||||||
|
def testCap(self):
|
||||||
|
self.assertEqual(funcs.cap("planet of the apes"),"Planet of the Apes")
|
||||||
|
self.assertEqual(funcs.cap("the greatest showman"),"The Greatest Showman")
|
||||||
|
self.assertEqual(funcs.cap("i'm the best person!"),"I'm the Best Person!")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
@ -303,13 +303,13 @@ Fantastic Four
|
|||||||
Fantastic Mr Fox
|
Fantastic Mr Fox
|
||||||
Fargo
|
Fargo
|
||||||
The Fast and the Furious
|
The Fast and the Furious
|
||||||
The Fast and the Furious 2 (2 Fast 2 Furious)
|
2 Fast 2 Furious
|
||||||
The Fast and the Furious 3 (Tokyo Drift)
|
The Fast and the Furious Tokyo Drift
|
||||||
The Fast and the Furious 4 (Fast & Furious)
|
Fast & Furious
|
||||||
The Fast and the Furious 5 (Fast Five)
|
Fast Five
|
||||||
The Fast and the Furious 6
|
The Fast and the Furious 6
|
||||||
The Fast and the Furious 7 (Furious 7)
|
Furious 7
|
||||||
The Fast and the Furious 8 (The Fate of the Furious)
|
The Fate of the Furious
|
||||||
Fast and Furious Presents: Hobbs and Shaw
|
Fast and Furious Presents: Hobbs and Shaw
|
||||||
Fast Times of Ridgemont High
|
Fast Times of Ridgemont High
|
||||||
The Fault in Our Stars
|
The Fault in Our Stars
|
144
resources/swcharacters.json
Normal file
144
resources/swcharacters.json
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
{
|
||||||
|
"Nikolaj": {
|
||||||
|
"Name": "Jared",
|
||||||
|
"Species": "",
|
||||||
|
"Career": "",
|
||||||
|
"Specialization Trees": [],
|
||||||
|
"Soak": 0,
|
||||||
|
"Wound Threshold": 0,
|
||||||
|
"Wounds": 0,
|
||||||
|
"Strain Threshold": 0,
|
||||||
|
"Strain": 0,
|
||||||
|
"Defense, Ranged": 0,
|
||||||
|
"Defense, Melee": 0,
|
||||||
|
"Force Rating": 0,
|
||||||
|
"Characteristics": {
|
||||||
|
"Brawn": 5,
|
||||||
|
"Agility": 0,
|
||||||
|
"Intellect": 0,
|
||||||
|
"Cunning": 0,
|
||||||
|
"Willpower": 0,
|
||||||
|
"Presence": 0
|
||||||
|
},
|
||||||
|
"Skills": {
|
||||||
|
"Astrogation": 0,
|
||||||
|
"Athletics": 0,
|
||||||
|
"Brawl": 1,
|
||||||
|
"Charm": 0,
|
||||||
|
"Coercion": 0,
|
||||||
|
"Computers": 0,
|
||||||
|
"Cool": 0,
|
||||||
|
"Coordination": 0,
|
||||||
|
"Core Worlds": 0,
|
||||||
|
"Discipline": 0,
|
||||||
|
"Gunnery": 0,
|
||||||
|
"Leadership": 0,
|
||||||
|
"Lightsaber": 0,
|
||||||
|
"Lore": 0,
|
||||||
|
"Mechanics": 0,
|
||||||
|
"Medicine": 0,
|
||||||
|
"Melee": 0,
|
||||||
|
"Negotiation": 0,
|
||||||
|
"Outer Rim": 0,
|
||||||
|
"Perception": 0,
|
||||||
|
"Piloting - Planetary": 0,
|
||||||
|
"Piloting - Space": 0,
|
||||||
|
"Ranged - Heavy": 0,
|
||||||
|
"Ranged - Light": 0,
|
||||||
|
"Resilience": 0,
|
||||||
|
"Skullduggery": 0,
|
||||||
|
"Stealth": 0,
|
||||||
|
"Streetwise": 0,
|
||||||
|
"Survival": 0,
|
||||||
|
"Underworld": 0,
|
||||||
|
"Vigilance": 0,
|
||||||
|
"Xenology": 0
|
||||||
|
},
|
||||||
|
"Lightsaber Characteristic": "Brawn",
|
||||||
|
"Obligations": {},
|
||||||
|
"Morality": {
|
||||||
|
"Emotional Weakness": "",
|
||||||
|
"Emotional Strength": "",
|
||||||
|
"Conflict": "",
|
||||||
|
"Morality": ""
|
||||||
|
},
|
||||||
|
"Credits": 0,
|
||||||
|
"Equipment": [],
|
||||||
|
"Armor": "",
|
||||||
|
"Critical Injuries": {},
|
||||||
|
"Weapons": {},
|
||||||
|
"Talents": {},
|
||||||
|
"Force Powers": {}
|
||||||
|
},
|
||||||
|
"TestUser": {
|
||||||
|
"Name": "New Character",
|
||||||
|
"Species": "",
|
||||||
|
"Career": "",
|
||||||
|
"Specialization Trees": [],
|
||||||
|
"Soak": 0,
|
||||||
|
"Wound Threshold": 0,
|
||||||
|
"Wounds": 0,
|
||||||
|
"Strain Threshold": 0,
|
||||||
|
"Strain": 0,
|
||||||
|
"Defense, Ranged": 0,
|
||||||
|
"Defense, Melee": 0,
|
||||||
|
"Force Rating": 0,
|
||||||
|
"Characteristics": {
|
||||||
|
"Brawn": 0,
|
||||||
|
"Agility": 0,
|
||||||
|
"Intellect": 0,
|
||||||
|
"Cunning": 0,
|
||||||
|
"Willpower": 0,
|
||||||
|
"Presence": 0
|
||||||
|
},
|
||||||
|
"Skills": {
|
||||||
|
"Astrogation": 0,
|
||||||
|
"Athletics": 0,
|
||||||
|
"Brawl": 0,
|
||||||
|
"Charm": 0,
|
||||||
|
"Coercion": 0,
|
||||||
|
"Computers": 0,
|
||||||
|
"Cool": 0,
|
||||||
|
"Coordination": 0,
|
||||||
|
"Core Worlds": 0,
|
||||||
|
"Discipline": 0,
|
||||||
|
"Gunnery": 0,
|
||||||
|
"Leadership": 0,
|
||||||
|
"Lightsaber": 0,
|
||||||
|
"Lore": 0,
|
||||||
|
"Mechanics": 0,
|
||||||
|
"Medicine": 0,
|
||||||
|
"Melee": 0,
|
||||||
|
"Negotiation": 0,
|
||||||
|
"Outer Rim": 0,
|
||||||
|
"Perception": 0,
|
||||||
|
"Piloting - Planetary": 0,
|
||||||
|
"Piloting - Space": 0,
|
||||||
|
"Ranged - Heavy": 0,
|
||||||
|
"Ranged - Light": 0,
|
||||||
|
"Resilience": 0,
|
||||||
|
"Skullduggery": 0,
|
||||||
|
"Stealth": 0,
|
||||||
|
"Streetwise": 0,
|
||||||
|
"Survival": 0,
|
||||||
|
"Underworld": 0,
|
||||||
|
"Vigilance": 0,
|
||||||
|
"Xenology": 0
|
||||||
|
},
|
||||||
|
"Lightsaber Characteristic": "Brawn",
|
||||||
|
"Obligations": {},
|
||||||
|
"Morality": {
|
||||||
|
"Emotional Weakness": "",
|
||||||
|
"Emotional Strength": "",
|
||||||
|
"Conflict": "",
|
||||||
|
"Morality": ""
|
||||||
|
},
|
||||||
|
"Credits": 0,
|
||||||
|
"Equipment": [],
|
||||||
|
"Armor": "",
|
||||||
|
"Critical Injuries": {},
|
||||||
|
"Weapons": {},
|
||||||
|
"Talents": {},
|
||||||
|
"Force Powers": {}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user