This commit is contained in:
jona605a
2020-08-06 17:22:33 +02:00
42 changed files with 1239 additions and 1842 deletions

2
.gitignore vendored
View File

@ -153,12 +153,14 @@ token.txt
resources/starWars/swcharacters.json
resources/games/games.json
resources/games/hexGames.json
resources/games/monopolyGames.json
resources/games/blackjackCards/
resources/games/hilo/
resources/starWars/destinyPoints.txt
resources/games/blackjackTables/
resources/games/oldImages/
resources/games/4InARowBoards/
resources/games/monopolyBoards/
resources/lookup/monsters.json
resources/lookup/spells.json
resources/movies.txt

View File

@ -1,587 +1,11 @@
# -*- coding: utf-8 -*-
import discord, os
import discord
import asyncio
#import pickle
import codecs
import string
import json
import random
#import math
import os
from discord.ext import commands
from funcs import helloFunc, cap, imageFunc, logThis, findWikiPage, makeFiles, emojiToNumber, fiarReactionTest, deleteGame, stopServer, checkBalance, giveMoney, triviaCountPoints, triviaStart, triviaAnswer, blackjackShuffle, blackjackStart, blackjackPlayerDrawHand, blackjackContinue, blackjackFinish, blackjackHit, blackjackStand, blackjackDouble, blackjackSplit, parseFourInARow, fourInARowAI, spellFunc, monsterFunc, nameGen, tavernGen, movieFunc, roll_dice, parseChar, parseRoll, critRoll, parseDestiny, parseHex, addToDict
from gameLoops import fiar, blackjackLoop, runHex
from funcs import logThis, makeFiles
commandPrefix = "!"
# Blackjack shuffle variables
blackjackMinCards = 50
blackjackDecks = 4
# Variable for reacting to messages
meanWords = ["stupid", "bitch", "fuck", "dumb", "idiot"]
async def parseCommands(message,content):
# Sends the contents of a help file, as specified by the message.
if content.startswith("help"):
try:
if content == "help" or content == "help ":
try:
with codecs.open("resources/help/help.txt",encoding="utf-8") as f:
text = f.read()
em = discord.Embed(title = "Help", description = text,colour = 0x59f442)
await message.channel.send(embed = em)
except:
logThis("Couldn't find help.txt (error code 101)",str(message.channel))
await message.channel.send("Couldn't find help.txt (error code 101)")
else:
command = content.replace(" ","-")
logThis("Looking for "+command+".txt",str(message.channel))
try:
with codecs.open("resources/help/"+command+".txt",encoding="utf-8") as f:
text = f.read()
em = discord.Embed(title = command.replace("help-","").capitalize(), description = text,colour = 0x59f442)
await message.channel.send(embed = em)
except:
logThis("Couldn't find help for that command (error code 102)",str(message.channel))
await message.channel.send("Couldn't find help for that command (error code 102)")
except:
logThis("Something fucked up (error code 100)",str(message.channel))
await message.channel.send("Something fucked up (error code 100)")
# Logs whatever you write in the message
elif content.startswith("log "):
logThis(content.replace("log ",""),str(message.channel))
# Stops the bot
elif content.startswith("stop"):
try:
if "#"+str(message.author.id) in ["#266269899859427329", "#380732645602230272"]:
await message.channel.send("Logging out...")
stopServer()
await client.logout()
else:
logThis(message.author.display_name+" tried to run stop me! (error code 201)",str(message.channel))
await message.channel.send("I don't think I will, "+message.author.display_name+" (error code 201)")
except:
logThis("Something fucked up (error code 200)",str(message.channel))
await message.channel.send("Something fucked up (error code 200)")
# Does a hello with the helloFunc function from funcs/gwendolynpy
elif content.startswith("hello"):
try:
await message.channel.send(helloFunc(message.author.display_name))
except:
logThis("Something fucked up (error code 310)",str(message.channel))
await message.channel.send("Something fucked up (error code 310)")
# Rolls dice with the roll_dice function from funcs/roll/dice.py
elif content.startswith("roll"):
try:
if content == "roll" or content == "roll ":
await message.channel.send(roll_dice(message.author.display_name))
else:
await message.channel.send(roll_dice(message.author.display_name, content.replace("roll","")))
except:
logThis("Something fucked up (error code 400)",str(message.channel))
await message.channel.send("Something fucked up (error code 400)")
# Looks up a spell with the spellFunc function from funcs/lookup/lookuppy
elif content.startswith("spell "):
try:
spell = spellFunc(cap(content.replace("spell","")))
if len(spell) > 2000:
await message.channel.send(spell[:2000])
await message.channel.send(spell[2000:])
else:
await message.channel.send(spell)
except:
logThis("Something fucked up (error code 500)",str(message.channel))
await message.channel.send("Something fucked up (error code 500)")
# Looks up a monster with the monsterFuncs() from funcs/lookup/lookuppy
elif content.startswith("monster "):
try:
title, text1, text2, text3, text4, text5 = monsterFunc(cap(content.replace("monster","")))
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)
if text2 != "":
if len(text2) < 2048:
em2 = discord.Embed(title = "Special Abilities", description = text2, colour=0xDEADBF)
await message.channel.send(embed = em2)
else:
em2 = discord.Embed(title = "Special Abilities", description = text2[:2048], colour=0xDEADBF)
await message.channel.send(embed = em2)
em2_2 = discord.Embed(title = "", description = text2[2048:], colour=0xDEADBF)
await message.channel.send(embed = em2_2)
if text3 != "":
if len(text3) < 2048:
em3 = discord.Embed(title = "Actions", description = text3, colour=0xDEADBF)
await message.channel.send(embed = em3)
else:
em3 = discord.Embed(title = "Actions", description = text3[:2048], colour=0xDEADBF)
await message.channel.send(embed = em3)
em3_2 = discord.Embed(title = "", description = text3[2048:], colour=0xDEADBF)
await message.channel.send(embed = em3_2)
if text4 != "":
if len(text4) < 2048:
em4 = discord.Embed(title = "Reactions", description = text4, colour=0xDEADBF)
await message.channel.send(embed = em4)
else:
em4 = discord.Embed(title = "Reactions", description = text4[:2048], colour=0xDEADBF)
await message.channel.send(embed = em4)
em4_2 = discord.Embed(title = "", description = text4[2048:], colour=0xDEADBF)
await message.channel.send(embed = em4_2)
if text5 != "":
if len(text5) < 2048:
em5 = discord.Embed(title = "Legendary Actions", description = text5, colour=0xDEADBF)
await message.channel.send(embed = em5)
else:
em5 = discord.Embed(title = "Legendary Actions", description = text5[:2048], colour=0xDEADBF)
await message.channel.send(embed = em5)
em5_2 = discord.Embed(title = "", description = text5[2048:], colour=0xDEADBF)
await message.channel.send(embed = em5_2)
except:
logThis("Something fucked up (error code 600)",str(message.channel))
await message.channel.send("Something fucked up (error code 600)")
# Sends an image of the Senkulpa map
elif content.startswith("map"):
try:
await message.channel.send("https://i.imgur.com/diMXXJs.jpg")
except:
logThis("Something fucked up (error code 320)",str(message.channel))
await message.channel.send("Something fucked up (error code 320)")
# Finds a random image on the internet with the imageFuncs function from
# funcs/gwendolynpy
elif content.startswith("image"):
try:
randomImage = imageFunc()
await message.channel.send(randomImage)
except:
logThis("Something fucked up (error code 700)",str(message.channel))
await message.channel.send("Something fucked up (error code 700)")
# Sends information about a random movie with the movieFunc function from
# funcs/other/movie.py
elif content.startswith("movie"):
try:
async with message.channel.typing():
title, plot, cover, cast = movieFunc()
if title == "error":
await message.channel.send("An error occurred. Try again (error code "+plot+")")
else:
try:
embed = discord.Embed(title=title, description=plot, color=0x24ec19)
embed.set_thumbnail(url=cover)
embed.add_field(name="Cast", value=cast,inline = True)
await message.channel.send(embed = embed)
except:
logThis("Error embedding (error code 805)")
except:
logThis("Something fucked up (error code 800)",str(message.channel))
await message.channel.send("Something fucked up (error code 800)")
# Generates a random name with the nameGen function from funcs/other/generators.py
elif content.startswith("name"):
try:
await message.channel.send(nameGen())
except:
logThis("Something fucked up (error code 330)",str(message.channel))
await message.channel.send("Something fucked up (error code 330)")
# Generates a random tavern name with the tavernGen function from funcs/other/generators.py
elif content.startswith("tavern"):
try:
await message.channel.send(tavernGen())
except:
logThis("Something fucked up (error code 340)",str(message.channel))
await message.channel.send("Something fucked up (error code 340)")
# Changes the "Playing this game" thing in Discord
elif content.startswith("game "):
try:
gamePlaying = cap(content.replace("game ",""))
game = discord.Game(gamePlaying)
await client.change_presence(activity=game)
except:
logThis("Something fucked up (error code 350)",str(message.channel))
await message.channel.send("Something fucked up (error code 350)")
# Rolls star wars dice with the parseRoll function from funcs/swfuncs/swroll.py
elif content.startswith("swroll"):
try:
command = cap(content.replace("swroll",""))
newMessage = parseRoll("#"+str(message.author.id),command)
messageList = newMessage.split("\n")
for messageItem in messageList:
await message.channel.send(messageItem)
except:
logThis("Something fucked up (error code 910)",str(message.channel))
await message.channel.send("Something fucked up (error code 910)")
# Deals with Destiny Points and stuff
elif content.startswith("swd"):
try:
command = content.replace("swd","")
newMessage = parseDestiny("#"+str(message.author.id),command)
messageList = newMessage.split("\n")
for messageItem in messageList:
await message.channel.send(messageItem)
except:
logThis("Something fucked up (error code 920)",str(message.channel))
await message.channel.send("Something fucked up (error code 920)")
# Rolls for critical injuries
elif content.startswith("swcrit"):
try:
command = content.replace("swcrit","").replace(" ","").replace("+","")
if command == "":
command = 0
try:
newMessage = critRoll(int(command))
except:
logThis("They didn't include a number (error code 931)",str(message.channel))
newMessage = "Try using a number, stupid (error code 931)"
messageList = newMessage.split("\n")
for messageItem in messageList:
await message.channel.send(messageItem)
except:
logThis("Something fucked up (error code 930)",str(message.channel))
await message.channel.send("Something fucked up (error code 930)")
# Accesses and changes character sheet data with the parseChar function
# from funcs/swfuncs/swchar.py
elif content.startswith("swchar") or content.startswith("sw"):
try:
command = string.capwords(content.replace("swchar","").replace("sw","").replace("+","+ ").replace("-","- ").replace(",",", "))
title, desc = parseChar("#"+str(message.author.id),command)
if title != "":
em1 = discord.Embed(title = title, description = desc, colour=0xDEADBF)
await message.channel.send(embed = em1)
else:
await message.channel.send(desc)
except:
logThis("Something fucked up (error code 940)",str(message.channel))
await message.channel.send("Something fucked up (error code 940)")
# Searches for a specific page on the Senkulpa Wiki
elif content.startswith("wiki "):
try:
async with message.channel.typing():
command = string.capwords(content.replace("wiki ",""))
title, content, thumbnail = findWikiPage(command)
if title != "":
logThis("Sending the embedded message",str(message.channel))
content += "\n[Læs mere](https://senkulpa.fandom.com/da/wiki/"+title.replace(" ","_")+")"
embed = discord.Embed(title = title, description = content, colour=0xDEADBF)
if thumbnail != "":
embed.set_thumbnail(url=thumbnail)
await message.channel.send(embed = embed)
else:
await message.channel.send(content)
except:
logThis("Something fucked up (error code 1000)",str(message.channel))
await message.channel.send("Something fucked up (error code 1000)")
# Runs a trivia game
elif content.startswith("trivia"):
try:
if content == "trivia" or content == "trivia ":
question, answers, correctAnswer = triviaStart(str(message.channel))
if answers != "":
results = "**"+question+"**\n"
for answer in range(len(answers)):
results += chr(answer+97) + ") "+answers[answer]+"\n"
await message.channel.send(results)
await asyncio.sleep(60)
triviaCountPoints(str(message.channel))
deleteGame("trivia questions",str(message.channel))
logThis("Time's up for the trivia question",str(message.channel))
await message.channel.send("Time's up The answer was \""+chr(correctAnswer)+") "+answers[correctAnswer-97]+"\". Anyone who answered that has gotten 1 GwendoBuck")
else:
await message.channel.send(question)
elif content.startswith("trivia "):
command = content.replace("trivia ","")
response = triviaAnswer("#"+str(message.author.id),str(message.channel),command)
if response.startswith("Locked in "):
await message.add_reaction("👍")
else:
await message.channel.send(response)
else:
logThis("I didn't understand that (error code 1101)",str(message.channel))
await message.channel.send("I didn't understand that (error code 1101)")
except:
logThis("Something fucked up (error code 1100)",str(message.channel))
await message.channel.send("Something fucked up (error code 1100)")
# Checks your GwendoBucks balance
elif content.startswith("balance"):
try:
response = checkBalance("#"+str(message.author.id))
if response == 1:
new_message = message.author.display_name + " has " + str(response) + " GwendoBuck"
else:
new_message = message.author.display_name + " has " + str(response) + " GwendoBucks"
await message.channel.send(new_message)
except:
logThis("Something fucked up (error code 1210)",str(message.channel))
await message.channel.send("Something fucked up (error code 1210)")
# Gives money to other player
elif content.startswith("give "):
try:
commands = content.split(" ")
if len(commands) >= 3:
try:
amount = int(commands[2])
except:
logThis("Conversion error (error code 1221)",str(message.channel))
await message.channel.send("I didn't quite understand that (error code 1221)")
else:
response = giveMoney("#"+str(message.author.id),commands[1],amount)
await message.channel.send(response)
else:
logThis("I didn't understand that (error code 1222)",str(message.channel))
await message.channel.send("I didn't understand that (error code 1222)")
except:
logThis("Something fucked up (error code 1220)",str(message.channel))
await message.channel.send("Something fucked up (error code 1220)")
# Runs a game of Blackjack
elif content.startswith("blackjack"):
try:
# Starts the game
if content == "blackjack" or content == "blackjack ":
cardsLeft = 0
if os.path.exists("resources/games/blackjackCards/"+str(message.channel)+".txt"):
with open("resources/games/blackjackCards/"+str(message.channel)+".txt","r") as f:
for _ in f:
cardsLeft += 1
# Shuffles if not enough cards
if cardsLeft < blackjackMinCards:
blackjackShuffle(blackjackDecks,str(message.channel))
logThis("Shuffling the blackjack deck...",str(message.channel))
await message.channel.send("Shuffling the deck...")
new_message = blackjackStart(str(message.channel))
if new_message == "started":
new_message = "Blackjack game started. Use \""+commandPrefix+"blackjack bet [amount]\" to enter the game within the next 30 seconds."
await message.channel.send(new_message)
oldImage = await message.channel.send(file = discord.File("resources/games/blackjackTables/blackjackTable"+str(message.channel)+".png"))
with open("resources/games/oldImages/blackjack"+str(message.channel), "w") as f:
f.write(str(oldImage.id))
await asyncio.sleep(30)
gamedone = False
with open("resources/games/games.json", "r") as f:
data = json.load(f)
if len(data["blackjack games"][str(message.channel)]["user hands"]) == 0:
gamedone = True
await message.channel.send("No one entered the game. Ending the game.")
gameID = data["blackjack games"][str(message.channel)]["id"]
# Loop of game rounds
if gamedone == False:
logThis("!blackjack calling blackjackLoop()",str(message.channel))
await blackjackLoop(message.channel,1,gameID)
else:
new_message = blackjackFinish(str(message.channel))
await message.channel.send(new_message)
else:
await message.channel.send(new_message)
# Entering game and placing bet
elif content.startswith("blackjack bet"):
commands = content.split(" ")
try:
amount = int(commands[2])
except:
logThis("I didn't understand that",str(message.channel))
response = "I didn't understand that"
else:
response = blackjackPlayerDrawHand(str(message.channel),"#"+str(message.author.id),amount)
await message.channel.send(response)
# Hitting
elif content.startswith("blackjack hit"):
if content == "blackjack hit" or content == "blackjack hit ":
response = blackjackHit(str(message.channel),"#"+str(message.author.id))
else:
commands = content.split(" ")
try:
handNumber = int(commands[2])
except:
handNumber = 0
response = blackjackHit(str(message.channel),"#"+str(message.author.id),handNumber)
if response.startswith("accept"):
await message.add_reaction("👍")
try:
if response[6] == "T":
with open("resources/games/games.json", "r") as f:
gameID = json.load(f)["blackjack games"][str(message.channel)]["id"]
logThis("Hit calling blackjackLoop()",str(message.channel))
await blackjackLoop(message.channel,int(response[7:])+1,gameID)
except:
logThis("Something fucked up (error code 1320)",str(message.channel))
else:
await message.channel.send(response)
# Standing
elif content.startswith("blackjack stand"):
if content == "blackjack hit" or content == "blackjack hit ":
response = blackjackStand(str(message.channel),"#"+str(message.author.id))
else:
commands = content.split(" ")
try:
handNumber = int(commands[2])
except:
handNumber = 0
response = blackjackStand(str(message.channel),"#"+str(message.author.id),handNumber)
if response.startswith("accept"):
await message.add_reaction("👍")
try:
if response[6] == "T":
with open("resources/games/games.json", "r") as f:
gameID = json.load(f)["blackjack games"][str(message.channel)]["id"]
logThis("Stand calling blackjackLoop()",str(message.channel))
await blackjackLoop(message.channel,int(response[7:])+1,gameID)
except:
logThis("Something fucked up (error code 1320)",str(message.channel))
else:
await message.channel.send(response)
# Doubling bet
elif content.startswith("blackjack double"):
commands = content.split(" ")
try:
handNumber = int(commands[2])
except:
handNumber = 0
response, roundDone = blackjackDouble(str(message.channel),"#"+str(message.author.id),handNumber)
await message.channel.send(response)
try:
if roundDone[0] == "T":
with open("resources/games/games.json", "r") as f:
gameID = json.load(f)["blackjack games"][str(message.channel)]["id"]
logThis("Double calling blackjackLoop()",str(message.channel))
await blackjackLoop(message.channel,int(roundDone[1:])+1,gameID)
except:
logThis("Something fucked up (error code 1320)",str(message.channel))
# Splitting hand
elif content.startswith("blackjack split"):
commands = content.split(" ")
try:
handNumber = int(commands[2])
except:
handNumber = 0
response, roundDone = blackjackSplit(str(message.channel),"#"+str(message.author.id),handNumber)
await message.channel.send(response)
try:
if roundDone[0] == "T":
with open("resources/games/games.json", "r") as f:
gameID = json.load(f)["blackjack games"][str(message.channel)]["id"]
logThis("Split calling blackjackLoop()",str(message.channel))
await blackjackLoop(message.channel,int(roundDone[1:])+1,gameID)
except:
logThis("Something fucked up (error code 1320)")
# Returning current hi-lo value
elif content.startswith("blackjack hilo") and "#"+str(message.author.id) == "#266269899859427329":
if os.path.exists("resources/games/blackjackCards/"+str(message.channel)+".txt"):
with open("resources/games/hilo/"+str(message.channel)+".txt", "r") as f:
data = f.read()
else:
data = "0"
await message.channel.send(data)
# Shuffles the blackjack deck
elif content.startswith("blackjack shuffle"):
blackjackShuffle(blackjackDecks,str(message.channel))
logThis("Shuffling the blackjack deck...",str(message.channel))
await message.channel.send("Shuffling the deck...")
# Tells you the amount of cards left
elif content.startswith("blackjack cards"):
cardsLeft = 0
if os.path.exists("resources/games/blackjackCards/"+str(message.channel)+".txt"):
with open("resources/games/blackjackCards/"+str(message.channel)+".txt","r") as f:
for _ in f:
cardsLeft += 1
decksLeft = round(cardsLeft/52,1)
await message.channel.send(str(cardsLeft)+" cards, "+str(decksLeft)+" decks")
else:
logThis("Not a command (error code 1301)")
await message.channel.send("I didn't quite understand that (error code 1301)")
except:
logThis("Something went wrong (error code 1300)")
# Runs a game of four in a row
elif content.startswith("fourinarow"):
try:
command = content.replace("fourinarow","")
await fiar(message.channel,command,"#"+str(message.author.id))
except:
logThis("Something went wrong (error code 1400)")
# Runs a game of Hex
elif content.startswith("hex"):
try:
command = content.replace("hex","")
await runHex(message.channel,command,"#"+str(message.author.id))
except:
logThis("Something went wrong (error code 1500)")
# Not a command
else:
logThis("That's not a command (error code 001)",str(message.channel))
await message.channel.send("That's not a command (error code 001)")
# Makes files if they don't exist yet
makeFiles()
# Gets secret bot token
with open("token.txt","r") as f:
token = f.read().replace("\n","")
client = discord.Client()
client = commands.Bot(command_prefix=commandPrefix)
# Logs in
@client.event
@ -590,36 +14,39 @@ async def on_ready():
game = discord.Game("Some weeb shit")
await client.change_presence(activity=game)
# Reads messages and tests if they are Gwendolyn commands
@client.event
async def on_message(message):
try:
content = message.content
if content.startswith(commandPrefix):
logThis(message.author.display_name+" ("+"#"+str(message.author.id)+") ran \""+content+"\"",str(message.channel))
addToDict("#"+str(message.author.id),message.author.display_name)
await parseCommands(message,content.lower()[1:])
except:
logThis("Something fucked up (error code 000)")
await message.channel.send("Something fucked up (error code 000)")
# Loads and unloads cogs
# Is a bit sassy sometimes
if ("gwendolyn" in message.content.lower() or message.content.startswith(commandPrefix)) and any(x in message.content.lower() for x in meanWords) and "ikke" not in message.content.lower() and "not" not in message.content.lower():
logThis(message.author.display_name+" was a bit mean",str(message.channel))
emoji = random.choice(["😠", "🖕", "👎"])
await message.add_reaction(emoji)
@client.command()
async def load(ctx,extension):
client.load_extension(f"cogs.{extension}")
@client.command()
async def unload(ctx,extension):
client.unload_extension(f"cogs.{extension}")
@client.event
async def on_reaction_add(reaction,user):
if user.bot == False:
message = reaction.message
channel = message.channel
logThis(user.display_name+" reacted to a message",str(channel))
fourInARowTheirTurn, piece = fiarReactionTest(channel,message,"#"+str(user.id))
async def on_command(ctx):
logThis(f"{ctx.message.author.display_name} ran {ctx.message.content}")
if fourInARowTheirTurn:
place = emojiToNumber(reaction.emoji)
await fiar(channel," place "+str(piece)+" "+str(place),user.id)
# Logs if a command experiences an error
@client.event
async def on_command_error(ctx, error):
if isinstance(error, commands.CommandNotFound):
await ctx.send("That's not a command (error code 001)")
else:
logThis(f"Something went wrong, {error}",str(ctx.message.channel.id))
await ctx.send("Something went wrong (error code 000)")
for filename in os.listdir("./cogs"):
if filename.endswith(".py"):
client.load_extension(f"cogs.{filename[:-3]}")
# Creates the required files
makeFiles()
# Gets secret bot token
with open("token.txt","r") as f:
token = f.read().replace("\n","")
# Runs the whole shabang
client.run(token)

268
cogs/GamesCog.py Normal file
View File

@ -0,0 +1,268 @@
import discord, asyncio, os, json
from discord.ext import commands
from funcs import logThis, triviaAnswer, triviaCountPoints, triviaStart, deleteGame, checkBalance, giveMoney, blackjackShuffle, blackjackStart, blackjackPlayerDrawHand, blackjackHit, blackjackDouble, blackjackFinish, blackjackSplit, blackjackStand
from gameLoops import blackjackLoop, fiar, runMonopoly, runHex
class GamesCog(commands.Cog):
def __init__(self,client):
"""Runs game stuff."""
self.client = client
# Checks user balance
@commands.command(aliases = ["b"])
async def balance(self, ctx):
response = checkBalance("#"+str(ctx.message.author.id))
if response == 1:
new_message = ctx.message.author.display_name + " has " + str(response) + " GwendoBuck"
else:
new_message = ctx.message.author.display_name + " has " + str(response) + " GwendoBucks"
await ctx.send(new_message)
# Gives another user an amount of GwendoBucks
@commands.command()
async def give(self, ctx, *, content):
commands = content.split(" ")
if len(commands) == 2:
print(commands)
amount = int(commands[1])
response = giveMoney("#"+str(ctx.message.author.id),commands[0],amount)
await ctx.send(response)
else:
logThis("I didn't understand that (error code 1222)",str(ctx.message.channel.id))
await ctx.send("I didn't understand that (error code 1222)")
# Runs a game of trivia
@commands.command()
async def trivia(self, ctx, *, content = ""):
if content == "":
question, answers, correctAnswer = triviaStart(str(ctx.message.channel.id))
if answers != "":
results = "**"+question+"**\n"
for answer in range(len(answers)):
results += chr(answer+97) + ") "+answers[answer]+"\n"
await ctx.send(results)
await asyncio.sleep(60)
triviaCountPoints(str(ctx.message.channel.id))
deleteGame("trivia questions",str(ctx.message.channel.id))
logThis("Time's up for the trivia question",str(ctx.message.channel.id))
await ctx.send("Time's up The answer was \""+chr(correctAnswer)+") "+answers[correctAnswer-97]+"\". Anyone who answered that has gotten 1 GwendoBuck")
else:
await ctx.send(question)
elif content in ["a","b","c","d"]:
response = triviaAnswer("#"+str(ctx.message.author.id),str(ctx.message.channel.id),content)
if response.startswith("Locked in "):
await ctx.message.add_reaction("👍")
else:
await ctx.send(response)
else:
logThis("I didn't understand that (error code 1101)",str(ctx.message.channel.id))
await ctx.send("I didn't understand that (error code 1101)")
# Runs a game of blackjack
@commands.command(aliases = ["bj"])
async def blackjack(self, ctx, *, content = ""):
# Blackjack shuffle variables
blackjackMinCards = 50
blackjackDecks = 4
channel = ctx.message.channel.id
# Starts the game
if content == "":
cardsLeft = 0
if os.path.exists("resources/games/blackjackCards/"+str(channel)+".txt"):
with open("resources/games/blackjackCards/"+str(channel)+".txt","r") as f:
for _ in f:
cardsLeft += 1
# Shuffles if not enough cards
if cardsLeft < blackjackMinCards:
blackjackShuffle(blackjackDecks,str(channel))
logThis("Shuffling the blackjack deck...",str(channel))
await ctx.send("Shuffling the deck...")
new_message = blackjackStart(str(channel))
if new_message == "started":
new_message = "Blackjack game started. Use \"!blackjack bet [amount]\" to enter the game within the next 30 seconds."
await ctx.send(new_message)
oldImage = await ctx.send(file = discord.File("resources/games/blackjackTables/blackjackTable"+str(channel)+".png"))
with open("resources/games/oldImages/blackjack"+str(channel), "w") as f:
f.write(str(oldImage.id))
await asyncio.sleep(30)
gamedone = False
with open("resources/games/games.json", "r") as f:
data = json.load(f)
if len(data["blackjack games"][str(channel)]["user hands"]) == 0:
gamedone = True
await ctx.send("No one entered the game. Ending the game.")
gameID = data["blackjack games"][str(channel)]["id"]
# Loop of game rounds
if gamedone == False:
logThis("!blackjack calling blackjackLoop()",str(channel))
await blackjackLoop(ctx.message.channel,1,gameID)
else:
new_message = blackjackFinish(str(channel))
await ctx.send(new_message)
else:
await ctx.send(new_message)
# Entering game and placing bet
elif content.startswith("bet"):
commands = content.split(" ")
amount = int(commands[1])
response = blackjackPlayerDrawHand(str(channel),"#"+str(ctx.message.author.id),amount)
await ctx.send(response)
# Hitting
elif content.startswith("hit"):
if content == "hit":
response = blackjackHit(str(channel),"#"+str(ctx.message.author.id))
else:
commands = content.split(" ")
try:
handNumber = int(commands[1])
except:
handNumber = 0
response = blackjackHit(str(channel),"#"+str(ctx.message.author.id),handNumber)
if response.startswith("accept"):
await ctx.message.add_reaction("👍")
try:
if response[6] == "T":
with open("resources/games/games.json", "r") as f:
gameID = json.load(f)["blackjack games"][str(channel)]["id"]
logThis("Hit calling blackjackLoop()",str(channel))
await blackjackLoop(ctx.message.channel,int(response[7:])+1,gameID)
except:
logThis("Something fucked up (error code 1320)",str(channel))
else:
await ctx.send(response)
# Standing
elif content.startswith("stand"):
if content == "hit":
response = blackjackStand(str(channel),"#"+str(ctx.message.author.id))
else:
commands = content.split(" ")
try:
handNumber = int(commands[1])
except:
handNumber = 0
response = blackjackStand(str(channel),"#"+str(ctx.message.author.id),handNumber)
if response.startswith("accept"):
await ctx.message.add_reaction("👍")
try:
if response[6] == "T":
with open("resources/games/games.json", "r") as f:
gameID = json.load(f)["blackjack games"][str(channel)]["id"]
logThis("Stand calling blackjackLoop()",str(channel))
await blackjackLoop(ctx.message.channel,int(response[7:])+1,gameID)
except:
logThis("Something fucked up (error code 1320)",str(channel))
else:
await ctx.send(response)
# Doubling bet
elif content.startswith("double"):
commands = content.split(" ")
try:
handNumber = int(commands[1])
except:
handNumber = 0
response, roundDone = blackjackDouble(str(channel),"#"+str(ctx.message.author.id),handNumber)
await ctx.send(response)
try:
if roundDone[0] == "T":
with open("resources/games/games.json", "r") as f:
gameID = json.load(f)["blackjack games"][str(channel)]["id"]
logThis("Double calling blackjackLoop()",str(channel))
await blackjackLoop(ctx.message.channel,int(roundDone[1:])+1,gameID)
except:
logThis("Something fucked up (error code 1320)",str(channel))
# Splitting hand
elif content.startswith("split"):
commands = content.split(" ")
try:
handNumber = int(commands[1])
except:
handNumber = 0
response, roundDone = blackjackSplit(str(channel),"#"+str(ctx.message.author.id),handNumber)
await ctx.send(response)
try:
if roundDone[0] == "T":
with open("resources/games/games.json", "r") as f:
gameID = json.load(f)["blackjack games"][str(channel)]["id"]
logThis("Split calling blackjackLoop()",str(channel))
await blackjackLoop(ctx.message.channel,int(roundDone[1:])+1,gameID)
except:
logThis("Something fucked up (error code 1320)")
# Returning current hi-lo value
elif content.startswith("hilo") and "#"+str(ctx.message.author.id) == "#266269899859427329":
if os.path.exists("resources/games/blackjackCards/"+str(channel)+".txt"):
with open("resources/games/hilo/"+str(channel)+".txt", "r") as f:
data = f.read()
else:
data = "0"
await ctx.send(data)
# Shuffles the blackjack deck
elif content.startswith("shuffle"):
blackjackShuffle(blackjackDecks,str(channel))
logThis("Shuffling the blackjack deck...",str(channel))
await ctx.send("Shuffling the deck...")
# Tells you the amount of cards left
elif content.startswith("cards"):
cardsLeft = 0
if os.path.exists("resources/games/blackjackCards/"+str(channel)+".txt"):
with open("resources/games/blackjackCards/"+str(channel)+".txt","r") as f:
for _ in f:
cardsLeft += 1
decksLeft = round(cardsLeft/52,1)
await ctx.send(str(cardsLeft)+" cards, "+str(decksLeft)+" decks")
else:
logThis("Not a command (error code 1301)")
await ctx.send("I didn't quite understand that (error code 1301)")
# Runs a game of Connect four
@commands.command(aliases = ["fiar","connect4","connectfour","4iar","4inarow"])
async def fourinarow(self, ctx, *, content = ""):
await fiar(ctx.message.channel,content,"#"+str(ctx.message.author.id))
# Runs a game of Hex
@commands.command(name="hex")
async def hexCommand(self, ctx, *, content = ""):
await runHex(ctx.message.channel,content,"#"+str(ctx.message.author.id))
# Runs a game of Monopoly
@commands.command(aliases = ["m","mon","mono"])
async def monopoly(self, ctx, *, content = ""):
await runMonopoly(ctx.message.channel,content,"#"+str(ctx.message.author.id))
def setup(client):
client.add_cog(GamesCog(client))

69
cogs/LookupCog.py Normal file
View File

@ -0,0 +1,69 @@
import discord
from discord.ext import commands
from funcs import spellFunc, monsterFunc, cap
class LookupCog(commands.Cog):
def __init__(self,client):
"""Runs lookup commands."""
self.client = client
# Looks up a spell
@commands.command()
async def spell(self, ctx, *, content):
spell = spellFunc(cap(content))
if len(spell) > 2000:
await ctx.send(spell[:2000])
await ctx.send(spell[2000:])
else:
await ctx.send(spell)
# Looks up a monster
@commands.command()
async def monster(self, ctx, *, content):
title, text1, text2, text3, text4, text5 = monsterFunc(cap(content))
em1 = discord.Embed(title = title, description = text1, colour=0xDEADBF)
# Sends the received information. Seperates into seperate messages if
# there is too much text
await ctx.send(embed = em1)
if text2 != "":
if len(text2) < 2048:
em2 = discord.Embed(title = "Special Abilities", description = text2, colour=0xDEADBF)
await ctx.send(embed = em2)
else:
em2 = discord.Embed(title = "Special Abilities", description = text2[:2048], colour=0xDEADBF)
await ctx.send(embed = em2)
em2_2 = discord.Embed(title = "", description = text2[2048:], colour=0xDEADBF)
await ctx.send(embed = em2_2)
if text3 != "":
if len(text3) < 2048:
em3 = discord.Embed(title = "Actions", description = text3, colour=0xDEADBF)
await ctx.send(embed = em3)
else:
em3 = discord.Embed(title = "Actions", description = text3[:2048], colour=0xDEADBF)
await ctx.send(embed = em3)
em3_2 = discord.Embed(title = "", description = text3[2048:], colour=0xDEADBF)
await ctx.send(embed = em3_2)
if text4 != "":
if len(text4) < 2048:
em4 = discord.Embed(title = "Reactions", description = text4, colour=0xDEADBF)
await ctx.send(embed = em4)
else:
em4 = discord.Embed(title = "Reactions", description = text4[:2048], colour=0xDEADBF)
await ctx.send(embed = em4)
em4_2 = discord.Embed(title = "", description = text4[2048:], colour=0xDEADBF)
await ctx.send(embed = em4_2)
if text5 != "":
if len(text5) < 2048:
em5 = discord.Embed(title = "Legendary Actions", description = text5, colour=0xDEADBF)
await ctx.send(embed = em5)
else:
em5 = discord.Embed(title = "Legendary Actions", description = text5[:2048], colour=0xDEADBF)
await ctx.send(embed = em5)
em5_2 = discord.Embed(title = "", description = text5[2048:], colour=0xDEADBF)
await ctx.send(embed = em5_2)
def setup(client):
client.add_cog(LookupCog(client))

122
cogs/MiscCog.py Normal file
View File

@ -0,0 +1,122 @@
import discord, codecs, string
from discord.ext import commands
from funcs import logThis, stopServer, helloFunc, roll_dice, imageFunc, nameGen, tavernGen, movieFunc, cap, findWikiPage
class MiscCog(commands.Cog):
def __init__(self,client):
"""Runs misc commands."""
self.client = client
self.client.remove_command("help")
@commands.command(name = "help")
async def helpCommand(self, ctx, *, content = ""):
if content == "":
with codecs.open("resources/help/help.txt",encoding="utf-8") as f:
text = f.read()
em = discord.Embed(title = "Help", description = text,colour = 0x59f442)
await ctx.send(embed = em)
else:
logThis(f"Looking for help-{content}.txt",str(ctx.message.channel.id))
with codecs.open(f"resources/help/help-{content}.txt",encoding="utf-8") as f:
text = f.read()
em = discord.Embed(title = content.capitalize(), description = text,colour = 0x59f442)
await ctx.send(embed = em)
# Sends the bot's latency
@commands.command()
async def ping(self, ctx):
await ctx.send(f"Pong!\nLatency is {round(self.client.latency * 1000)} ms")
# Logs whatever is written
@commands.command(hidden = True)
async def log(self, ctx, *, content):
logThis(content,str("Logged by "+ctx.message.author.display_name))
# Stops the bot
@commands.command(hidden = True)
async def stop(self, ctx):
if "#"+str(ctx.message.author.id) in ["#266269899859427329", "#380732645602230272"]:
await ctx.send("Logging out...")
stopServer()
await self.client.logout()
else:
logThis(f"{ctx.message.author.display_name} tried to stop me! (error code 201)",str(ctx.message.channel.id))
await ctx.send(f"I don't think I will, {ctx.message.author.display_name} (error code 201)")
# Sends a friendly message
@commands.command(aliases = ["hi","howdy"])
async def hello(self, ctx):
await ctx.send(helloFunc(ctx.message.author.display_name))
# Rolls dice
@commands.command()
async def roll(self, ctx, *, content = "1d20"):
await ctx.send(roll_dice(ctx.message.author.display_name,content))
# Sends an image of the Senkulpa map
@commands.command(name="map")
async def mapCommand(self, ctx):
await ctx.send("https://i.imgur.com/diMXXJs.jpg")
# Sends a random image
@commands.command(aliases = ["img"])
async def image(self, ctx):
randomImage = imageFunc()
await ctx.send(randomImage)
# Finds a random movie
@commands.command()
async def movie(self,ctx):
async with ctx.typing():
title, plot, cover, cast = movieFunc()
if title == "error":
await ctx.send("An error occurred. Try again (error code "+plot+")")
else:
try:
embed = discord.Embed(title=title, description=plot, color=0x24ec19)
embed.set_thumbnail(url=cover)
embed.add_field(name="Cast", value=cast,inline = True)
await ctx.send(embed = embed)
except:
logThis("Error embedding (error code 805)")
# Generates a random name
@commands.command()
async def name(self, ctx):
await ctx.send(nameGen())
# Generates a random tavern name
@commands.command()
async def tavern(self, ctx):
await ctx.send(tavernGen())
# Sets the game Gwendolyn's playing
@commands.command()
async def game(self, ctx, *, content):
gamePlaying = cap(content)
game = discord.Game(gamePlaying)
await self.client.change_presence(activity=game)
# Finds a page on the Senkulpa wiki
@commands.command(aliases = ["wikia"])
async def wiki(self, ctx, *, content):
async with ctx.message.channel.typing():
command = string.capwords(content)
title, content, thumbnail = findWikiPage(command)
if title != "":
logThis("Sending the embedded message",str(ctx.message.channel.id))
content += "\n[Læs mere](https://senkulpa.fandom.com/da/wiki/"+title.replace(" ","_")+")"
embed = discord.Embed(title = title, description = content, colour=0xDEADBF)
if thumbnail != "":
embed.set_thumbnail(url=thumbnail)
await ctx.send(embed = embed)
else:
await ctx.send(content)
def setup(client):
client.add_cog(MiscCog(client))

28
cogs/ReactionCog.py Normal file
View File

@ -0,0 +1,28 @@
from discord.ext import commands
from funcs import logThis, fiarReactionTest, monopolyReactionTest, emojiToCommand
from gameLoops import fiar, runMonopoly
class ReactionCog(commands.Cog):
def __init__(self, client):
"""Listens for reactions."""
self.client = client
@commands.Cog.listener()
async def on_reaction_add(self, reaction,user):
if user.bot == False:
message = reaction.message
channel = message.channel
logThis(user.display_name+" reacted to a message",str(channel.id))
try:
fourInARowTheirTurn, piece = fiarReactionTest(channel,message,"#"+str(user.id))
except:
fourInARowTheirTurn = False
if fourInARowTheirTurn:
place = emojiToCommand(reaction.emoji)
await fiar(channel," place "+str(piece)+" "+str(place),user.id)
elif monopolyReactionTest(channel,message):
await runMonopoly(channel,"roll","#"+str(user.id))
def setup(client):
client.add_cog(ReactionCog(client))

51
cogs/SwCog.py Normal file
View File

@ -0,0 +1,51 @@
import discord, string
from discord.ext import commands
from funcs import parseRoll, parseDestiny, critRoll, parseChar, cap
class SwCog(commands.Cog):
def __init__(self,client):
"""Runs star wars commands."""
self.client = client
# Rolls star wars dice
@commands.command()
async def swroll(self, ctx, *, content):
command = cap(content)
newMessage = parseRoll("#"+str(ctx.message.author.id),command)
messageList = newMessage.split("\n")
for messageItem in messageList:
await ctx.send(messageItem)
# Controls destiny points
@commands.command()
async def swd(self, ctx, *, content):
newMessage = parseDestiny("#"+str(ctx.message.author.id),content)
messageList = newMessage.split("\n")
for messageItem in messageList:
await ctx.send(messageItem)
# Rolls for critical injuries
@commands.command()
async def swcrit(self, ctx, arg : int = 0):
newMessage = critRoll(int(arg))
messageList = newMessage.split("\n")
for messageItem in messageList:
await ctx.send(messageItem)
# Accesses and changes character sheet data with the parseChar function
# from funcs/swfuncs/swchar.py
@commands.command(aliases=["sw"])
async def swchar(self, ctx, *, content = ""):
command = string.capwords(content.replace("+","+ ").replace("-","- ").replace(",",", "))
title, desc = parseChar("#"+str(ctx.message.author.id),command)
if title != "":
em1 = discord.Embed(title = title, description = desc, colour=0xDEADBF)
await ctx.send(embed = em1)
else:
await ctx.send(desc)
def setup(client):
client.add_cog(SwCog(client))

View File

@ -1,10 +1,10 @@
"""A collection of all Gwendolyn functions."""
__all__ = ["helloFunc", "cap", "imageFunc", "logThis", "findWikiPage", "makeFiles", "emojiToNumber", "fiarReactionTest", "deleteGame", "stopServer", "checkBalance", "giveMoney", "addMoney", "triviaCountPoints", "triviaStart", "triviaAnswer", "blackjackShuffle", "blackjackStart", "blackjackPlayerDrawHand", "blackjackContinue", "blackjackFinish", "blackjackHit", "blackjackStand", "blackjackDouble", "blackjackSplit", "parseFourInARow", "fourInARowAI", "spellFunc", "monsterFunc", "nameGen", "tavernGen", "movieFunc", "roll_dice", "parseChar", "parseRoll", "critRoll", "parseDestiny", "parseHex", "hexAI", "addToDict", "getName", "getID"]
__all__ = ["helloFunc", "cap", "imageFunc", "logThis", "findWikiPage", "makeFiles", "emojiToCommand", "fiarReactionTest", "deleteGame", "stopServer", "checkBalance", "giveMoney", "addMoney", "triviaCountPoints", "triviaStart", "triviaAnswer", "blackjackShuffle", "blackjackStart", "blackjackPlayerDrawHand", "blackjackContinue", "blackjackFinish", "blackjackHit", "blackjackStand", "blackjackDouble", "blackjackSplit", "parseFourInARow", "fourInARowAI", "spellFunc", "monsterFunc", "nameGen", "tavernGen", "movieFunc", "roll_dice", "parseChar", "parseRoll", "critRoll", "parseDestiny", "parseHex", "addToDict", "getName", "getID", "replaceMultiple", "hexAI", "parseMonopoly", "monopolyContinue", "monopolyReactionTest"]
from .miscFuncs import helloFunc, cap, imageFunc, logThis, findWikiPage, makeFiles, replaceMultiple, emojiToNumber, fiarReactionTest, deleteGame, stopServer, addToDict, getName, getID
from .miscFuncs import helloFunc, cap, imageFunc, logThis, findWikiPage, makeFiles, replaceMultiple, emojiToCommand, fiarReactionTest, deleteGame, stopServer, addToDict, getName, getID, monopolyReactionTest
from .games import checkBalance, giveMoney, addMoney, triviaCountPoints, triviaStart, triviaAnswer, blackjackShuffle, blackjackStart, blackjackPlayerDrawHand, blackjackContinue, blackjackFinish, blackjackHit, blackjackStand, blackjackDouble, blackjackSplit, parseFourInARow, fourInARowAI, parseHex, hexAI
from .games import checkBalance, giveMoney, addMoney, triviaCountPoints, triviaStart, triviaAnswer, blackjackShuffle, blackjackStart, blackjackPlayerDrawHand, blackjackContinue, blackjackFinish, blackjackHit, blackjackStand, blackjackDouble, blackjackSplit, parseFourInARow, fourInARowAI, parseHex, hexAI, parseMonopoly, monopolyContinue
from .lookup import spellFunc, monsterFunc
@ -13,4 +13,3 @@ from .other import nameGen, tavernGen, movieFunc
from .roll import roll_dice
from .swfuncs import parseChar, parseRoll, parseDestiny, critRoll

View File

@ -1,9 +1,10 @@
"""Functions for games Gwendolyn can play."""
__all__ = ["checkBalance", "giveMoney", "addMoney","triviaCountPoints", "triviaStart", "triviaAnswer", "blackjackShuffle", "blackjackStart", "blackjackPlayerDrawHand", "blackjackContinue", "blackjackFinish", "blackjackHit", "blackjackStand", "blackjackDouble", "blackjackSplit", "parseFourInARow", "fourInARowAI", "parseHex","hexAI"]
__all__ = ["checkBalance", "giveMoney", "addMoney","triviaCountPoints", "triviaStart", "triviaAnswer", "blackjackShuffle", "blackjackStart", "blackjackPlayerDrawHand", "blackjackContinue", "blackjackFinish", "blackjackHit", "blackjackStand", "blackjackDouble", "blackjackSplit", "parseFourInARow", "fourInARowAI", "parseHex", "hexAI", "parseMonopoly", "monopolyContinue"]
from .money import checkBalance, giveMoney, addMoney
from .trivia import triviaCountPoints, triviaStart, triviaAnswer
from .blackjack import blackjackShuffle, blackjackStart, blackjackPlayerDrawHand, blackjackContinue, blackjackFinish, blackjackHit, blackjackStand, blackjackDouble, blackjackSplit
from .fourInARow import parseFourInARow, fourInARowAI
from .hex import parseHex, hexAI
from .monopoly import parseMonopoly, monopolyContinue

View File

@ -197,26 +197,11 @@ def blackjackHit(channel,user,handNumber = 0):
data = json.load(f)
if user in data["blackjack games"][channel]["user hands"]:
if data["blackjack games"][channel]["user hands"][user]["split"] == 0:
hand = data["blackjack games"][channel]["user hands"][user]
handNumber = 0
else:
if handNumber != 0:
if handNumber == 1:
hand = data["blackjack games"][channel]["user hands"][user]
elif handNumber == 2:
hand = data["blackjack games"][channel]["user hands"][user]["other hand"]
elif handNumber == 3:
hand = data["blackjack games"][channel]["user hands"][user]["third hand"]
elif handNumber == 4:
hand = data["blackjack games"][channel]["user hands"][user]["fourth hand"]
else:
logThis(user+" tried to hit without specifying which hand")
return "You have to specify the hand you're hitting with."
else:
logThis(user+" tried to hit without specifying which hand")
return "You have to specify the hand you're hitting with."
hand, handNumber = getHandNumber(data["blackjack games"][channel]["user hands"][user],handNumber)
print(hand)
if hand != None:
if data["blackjack games"][channel]["round"] > 0:
if hand["hit"] == False:
if hand["standing"] == False:
@ -241,23 +226,7 @@ def blackjackHit(channel,user,handNumber = 0):
json.dump(data,f,indent=4)
response = "accept"
roundDone = True
for person in data["blackjack games"][channel]["user hands"].values():
if person["hit"] == False and person["standing"] == False:
roundDone = False
if person["split"] > 0:
if person["other hand"]["hit"] == False and person["other hand"]["standing"] == False:
roundDone = False
if person["split"] > 1:
if person["third hand"]["hit"] == False and person["third hand"]["standing"] == False:
roundDone = False
if person["split"] > 2:
if person["fourth hand"]["hit"] == False and person["fourth hand"]["standing"] == False:
roundDone = False
roundDone = isRoundDone(data["blackjack games"][channel])
return response + str(roundDone)[0] + str(data["blackjack games"][channel]["round"])
else:
@ -269,6 +238,9 @@ def blackjackHit(channel,user,handNumber = 0):
else:
logThis(user+" tried to hit on the 0th round")
return "You can't hit before you see your cards"
else:
logThis(user+" didn't specify a hand")
return "You need to specify a hand"
else:
logThis(user+" tried to hit without being in the game")
return "You have to enter the game before you can hit"
@ -279,27 +251,10 @@ def blackjackDouble(channel,user,handNumber = 0):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
if data["blackjack games"][channel]["user hands"][user]["split"] == 0:
hand = data["blackjack games"][channel]["user hands"][user]
handNumber = 0
else:
if handNumber != 0:
if handNumber == 1:
hand = data["blackjack games"][channel]["user hands"][user]
elif handNumber == 2:
hand = data["blackjack games"][channel]["user hands"][user]["other hand"]
elif handNumber == 3:
hand = data["blackjack games"][channel]["user hands"][user]["third hand"]
elif handNumber == 4:
hand = data["blackjack games"][channel]["user hands"][user]["fourth hand"]
else:
logThis(user+" tried to double without specifying which hand")
return "You have to specify the hand you're doubling down.",""
else:
logThis(user+" tried to double without specifying which hand")
return "You have to specify the hand you're doubling down.",""
if user in data["blackjack games"][channel]["user hands"]:
hand, handNumber = getHandNumber(data["blackjack games"][channel]["user hands"][user],handNumber)
if hand != None:
if data["blackjack games"][channel]["round"] > 0:
if hand["hit"] == False:
if hand["standing"] == False:
@ -333,24 +288,7 @@ def blackjackDouble(channel,user,handNumber = 0):
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
roundDone = True
for person in data["blackjack games"][channel]["user hands"].values():
if person["hit"] == False and person["standing"] == False:
roundDone = False
if person["split"] > 0:
if person["other hand"]["hit"] == False and person["other hand"]["standing"] == False:
roundDone = False
if person["split"] > 1:
if person["third hand"]["hit"] == False and person["third hand"]["standing"] == False:
roundDone = False
if person["split"] > 2:
if person["fourth hand"]["hit"] == False and person["fourth hand"]["standing"] == False:
roundDone = False
roundDone = isRoundDone(data["blackjack games"][channel])
return "Adding another "+str(bet)+" GwendoBucks to "+getName(user)+"'s bet and drawing another card.",str(roundDone)[0] + str(data["blackjack games"][channel]["round"])
else:
@ -368,6 +306,12 @@ def blackjackDouble(channel,user,handNumber = 0):
else:
logThis(user+" tried to double on the 0th round")
return "You can't double down before you see your cards",""
else:
logThis(user+" didn't specify a hand")
return "You need to specify which hand"
else:
logThis(user+" tried to double without being in the game")
return "You can't double when you're not in the game",""
# When players try to stand
def blackjackStand(channel,user,handNumber = 0):
@ -375,26 +319,10 @@ def blackjackStand(channel,user,handNumber = 0):
data = json.load(f)
if user in data["blackjack games"][channel]["user hands"]:
if data["blackjack games"][channel]["user hands"][user]["split"] == 0:
hand = data["blackjack games"][channel]["user hands"][user]
handNumber = 0
else:
if handNumber != 0:
if handNumber == 1:
hand = data["blackjack games"][channel]["user hands"][user]
elif handNumber == 2:
hand = data["blackjack games"][channel]["user hands"][user]["other hand"]
elif handNumber == 3:
hand = data["blackjack games"][channel]["user hands"][user]["third hand"]
elif handNumber == 4:
hand = data["blackjack games"][channel]["user hands"][user]["fourth hand"]
else:
logThis(user+" tried to hit without specifying which hand")
return "You have to specify the hand you're hitting with."
else:
logThis(user+" tried to hit without specifying which hand")
return "You have to specify the hand you're hitting with."
hand, handNumber = getHandNumber(data["blackjack games"][channel]["user hands"][user],handNumber)
if hand != None:
if data["blackjack games"][channel]["round"] > 0:
if hand["hit"] == False:
if hand["standing"] == False:
@ -403,23 +331,7 @@ def blackjackStand(channel,user,handNumber = 0):
json.dump(data,f,indent=4)
response = "accept"
roundDone = True
for person in data["blackjack games"][channel]["user hands"].values():
if person["hit"] == False and person["standing"] == False:
roundDone = False
if person["split"] > 0:
if person["other hand"]["hit"] == False and person["other hand"]["standing"] == False:
roundDone = False
if person["split"] > 1:
if person["third hand"]["hit"] == False and person["third hand"]["standing"] == False:
roundDone = False
if person["split"] > 2:
if person["fourth hand"]["hit"] == False and person["fourth hand"]["standing"] == False:
roundDone = False
roundDone = isRoundDone(data["blackjack games"][channel])
return response + str(roundDone)[0] + str(data["blackjack games"][channel]["round"])
else:
@ -431,6 +343,9 @@ def blackjackStand(channel,user,handNumber = 0):
else:
logThis(user+" tried to stand on the first round")
return "You can't stand before you see your cards"
else:
logThis(user+" didn't specify a hand")
return "You need to specify which hand"
else:
logThis(user+" tried to stand without being in the game")
return "You have to enter the game before you can stand"
@ -526,23 +441,7 @@ def blackjackSplit(channel,user,handNumber = 0):
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
roundDone = True
for person in data["blackjack games"][channel]["user hands"].values():
if person["hit"] == False and person["standing"] == False:
roundDone = False
if person["split"] > 0:
if person["other hand"]["hit"] == False and person["other hand"]["standing"] == False:
roundDone = False
if person["split"] > 1:
if person["third hand"]["hit"] == False and person["third hand"]["standing"] == False:
roundDone = False
if person["split"] > 2:
if person["fourth hand"]["hit"] == False and person["fourth hand"]["standing"] == False:
roundDone = False
roundDone = isRoundDone(data["blackjack games"][channel])
return "Splitting "+getName(user)+"'s hand into 2. Adding their original bet to the second hand. You can use \"!Blackjack hit/stand/double 1\" and \"!Blackjack hit/stand/double 2\" to play the different hands.",str(roundDone)[0] + str(data["blackjack games"][channel]["round"])
else:
@ -745,3 +644,46 @@ def calcWinnings(hand, dealerValue, topLevel, dealerBlackjack, dealerBusted):
reason += reasonTemp
return winnings, netWinnings, reason
def getHandNumber(user,handNumber):
try:
hand = None
if user["split"] == 0:
hand = user
handNumber = 0
else:
if handNumber != 0:
if handNumber == 1:
hand = user
elif handNumber == 2:
hand = user["other hand"]
elif handNumber == 3:
hand = user["third hand"]
elif handNumber == 4:
hand = user["fourth hand"]
return hand, handNumber
except:
logThis("Problem with getHandNumber() (error code 1322)")
def isRoundDone(game):
roundDone = True
for person in game["user hands"].values():
if person["hit"] == False and person["standing"] == False:
roundDone = False
if person["split"] > 0:
if person["other hand"]["hit"] == False and person["other hand"]["standing"] == False:
roundDone = False
if person["split"] > 1:
if person["third hand"]["hit"] == False and person["third hand"]["standing"] == False:
roundDone = False
if person["split"] > 2:
if person["fourth hand"]["hit"] == False and person["fourth hand"]["standing"] == False:
roundDone = False
return roundDone

View File

@ -36,7 +36,7 @@ def drawImage(channel):
for x in range(len(hands)):
key, value = list(hands.items())[x]
key = getName(key)
logThis("drawing "+key+"'s hand")
#logThis("Drawing "+key+"'s hand")
userHand = drawHand(value["hand"],False,value["busted"],value["blackjack"])
try:
if value["split"] == 3:

View File

@ -20,6 +20,9 @@ def drawImage(channel):
exampleCircles = 100
w, h = 2800,2000
backgroundColor = (128,128,128,255)
outlineColor = (0,0,0)
player1Color = (200,0,0)
player2Color = (255,255,0)
boardColor = (0,0,170)
placeSize = 285
white = (255,255,255,160)
@ -48,35 +51,33 @@ def drawImage(channel):
# This whole part was the easiest way to make a rectangle with rounded corners and an outline
# - Corners:
d.ellipse([(border,border),(border+cornerSize,border+cornerSize)],fill=boardColor,outline=(0,0,0),width=outlineSize)
d.ellipse([(w-(border+cornerSize),h-(border+cornerSize)),(w-border,h-border)],fill=boardColor,outline=(0,0,0),width=outlineSize)
d.ellipse([(border,h-(border+cornerSize)),(border+cornerSize,h-border)],fill=boardColor,outline=(0,0,0),width=outlineSize)
d.ellipse([(w-(border+cornerSize),border),(w-border,border+cornerSize)],fill=boardColor,outline=(0,0,0),width=outlineSize)
d.ellipse([(border,border),(border+cornerSize,border+cornerSize)],fill=boardColor,outline=outlineColor,width=outlineSize)
d.ellipse([(w-(border+cornerSize),h-(border+cornerSize)),(w-border,h-border)],fill=boardColor,outline=outlineColor,width=outlineSize)
d.ellipse([(border,h-(border+cornerSize)),(border+cornerSize,h-border)],fill=boardColor,outline=outlineColor,width=outlineSize)
d.ellipse([(w-(border+cornerSize),border),(w-border,border+cornerSize)],fill=boardColor,outline=outlineColor,width=outlineSize)
# - Rectangle:
d.rectangle([(border+math.floor(cornerSize/2),border),(w-(border+math.floor(cornerSize/2)),h-border)],fill=boardColor,outline=(0,0,0),width=outlineSize)
d.rectangle([(border,border+math.floor(cornerSize/2)),(w-border,h-(border+math.floor(cornerSize/2)))],fill=boardColor,outline=(0,0,0),width=outlineSize)
d.rectangle([(border+math.floor(cornerSize/2),border),(w-(border+math.floor(cornerSize/2)),h-border)],fill=boardColor,outline=outlineColor,width=outlineSize)
d.rectangle([(border,border+math.floor(cornerSize/2)),(w-border,h-(border+math.floor(cornerSize/2)))],fill=boardColor,outline=outlineColor,width=outlineSize)
# - Removing outline on the inside:
d.rectangle([(border+math.floor(cornerSize/2),border+math.floor(cornerSize/2)),(w-(border+math.floor(cornerSize/2)),h-(border+math.floor(cornerSize/2)))],fill=boardColor)
d.ellipse([(border+outlineSize,border+outlineSize),(border+cornerSize-outlineSize,border+cornerSize-outlineSize)],fill=boardColor)
d.ellipse([(w-(border+cornerSize)+outlineSize,h-(border+cornerSize)+outlineSize),(w-border-outlineSize,h-border-outlineSize)],fill=boardColor)
d.ellipse([(border+outlineSize,h-(border+cornerSize)+outlineSize),(border+cornerSize-outlineSize,h-border-outlineSize)],fill=boardColor)
d.ellipse([(w-(border+cornerSize)+outlineSize,border+outlineSize),(w-border-outlineSize,border+cornerSize-outlineSize)],fill=boardColor)
d.rectangle([(border+math.floor(cornerSize/2),border+outlineSize),(w-(border+math.floor(cornerSize/2)),h-(border+outlineSize))],fill=boardColor)
d.rectangle([(border+outlineSize,border+math.floor(cornerSize/2)),(w-(border+outlineSize),h-(border+math.floor(cornerSize/2)))],fill=boardColor)
for line in range(len(board)):
for place in range(len(board[line])):
piece = board[line][place]
if piece == 1:
pieceColor = (255,255,0)
pieceColor = player1Color
elif piece == 2:
pieceColor = (200,0,0)
pieceColor = player2Color
else:
pieceColor = backgroundColor
startx = pieceStartx + placeGridSize[0]*place
starty = pieceStarty + placeGridSize[1]*line
d.ellipse([(startx,starty),(startx+placeSize,starty+placeSize)],fill=pieceColor,outline=(0,0,0),width=outlineSize)
d.ellipse([(startx,starty),(startx+placeSize,starty+placeSize)],fill=pieceColor,outline=outlineColor,width=outlineSize)
if data["4 in a row games"][channel]["winner"] != 0:
coordinates = data["4 in a row games"][channel]["win coordinates"]
@ -121,7 +122,6 @@ def drawImage(channel):
startx -= placeGridSize[0]*3 + border
starty -= gridBorder + border
mask = winBar.copy()#.convert("L")
#mask.putalpha(128)
#mask.save("test.png")
@ -133,11 +133,11 @@ def drawImage(channel):
textPadding = 20
exampleHeight = h - border + int((bottomBorder+border)/2) - int(exampleCircles/2)
d.ellipse([(border,exampleHeight),(border+exampleCircles),(exampleHeight+exampleCircles)],fill=(255,255,0),outline=(0,0,0),width=3)
d.ellipse([(border,exampleHeight),(border+exampleCircles),(exampleHeight+exampleCircles)],fill=player1Color,outline=outlineColor,width=3)
d.text((border+exampleCircles+textPadding,exampleHeight),player1,font=fnt,fill=(0,0,0))
textWidth = fnt.getsize(player2)[0]
d.ellipse([(w-border-exampleCircles-textWidth-textPadding,exampleHeight),(w-border-textWidth-textPadding),(exampleHeight+exampleCircles)],fill=(255,0,0),outline=(0,0,0),width=3)
d.ellipse([(w-border-exampleCircles-textWidth-textPadding,exampleHeight),(w-border-textWidth-textPadding),(exampleHeight+exampleCircles)],fill=player2Color,outline=outlineColor,width=3)
d.text((w-border-textWidth,exampleHeight),player2,font=fnt,fill=(0,0,0))

View File

@ -36,7 +36,7 @@ def giveMoney(user,targetUser,amount):
targetUser = getID(targetUser)
if amount > 0:
if targetUser.startswith("#"):
if targetUser != None:
if user in data:
if data[user]["money"] >= amount:
addMoney(user,-1 * amount)

141
funcs/games/monopoly.py Normal file
View File

@ -0,0 +1,141 @@
import json, random
from funcs import getName, logThis
from . import monopolyDraw
rulesAndTerms = {
"pass go money" : 200,
"money term" : "GP"
}
def monopolyStart(channel):
logThis("Starting a monopoly game")
with open("resources/games/monopolyGames.json", "r") as f:
data = json.load(f)
if channel not in data:
buildings = [0] * 40
data[channel] = {"players" : {}, "player list" : [],"turn" : 0, "buildings" : buildings, "last roll" : [0,0], "started" : False}
with open("resources/games/monopolyGames.json", "w") as f:
json.dump(data,f,indent=4)
try:
monopolyDraw.drawImage(channel)
except:
logThis("Error drawing board (error code 1640)")
return "Started a monopoly game. Use \"!monopoly join\" to join within the next minute.", True, False, True, True
else:
return "There's already a monopoly game going on.", False, False, False, False
def monopolyJoin(channel,user):
with open("resources/games/monopolyGames.json", "r") as f:
data = json.load(f)
if channel in data:
if not data[channel]["started"]:
if user not in data[channel]["players"]:
if len(data[channel]["players"]) < 6:
data[channel]["players"][user] = {"position" : 0, "properties" : [], "money" : 1500, "doubles" : 0}
with open("resources/games/monopolyGames.json", "w") as f:
json.dump(data,f,indent=4)
return getName(user)+" has joined the game.", False, False, False, False
else:
return "There are already 6 players in the game.", False, False, False, False
else:
return "You're already in the game!", False, False, False, False
else:
return "It's too late to join.", False, False, False, False
else:
return "There's no game going on.", False, False, False, False
def parseMonopoly(command, channel, user):
logThis("Parsing "+command)
commands = command.split()
if command in [" ", ""] or commands[0] == "start":
try:
return monopolyStart(channel)
except:
logThis("Error starting game (error code 1620)")
elif commands[0] == "join":
try:
return monopolyJoin(channel,user)
except:
logThis("Error joining game (error code 1630)")
elif commands[0] == "roll":
try:
return monopolyRoll(channel,user)
except:
logThis("Error rolling (error code 1650)")
else:
return "I didn't understand that (error code 1602)", False, False, False, False
def monopolyContinue(channel):
with open("resources/games/monopolyGames.json", "r") as f:
data = json.load(f)
if channel in data:
if data[channel]["started"] == False:
data[channel]["started"] = True
playerList = list(data[channel]["players"].keys())
random.shuffle(playerList)
data[channel]["player list"] = playerList
turn = 0
else:
if data[channel]["last roll"][0] == data[channel]["last roll"][1]:
turn = data[channel]["turn"]
else:
turn = (data[channel]["turn"] + 1)%len(data[channel]["player list"])
data[channel]["turn"] = turn
playerList = list(data[channel]["players"].keys())
with open("resources/games/monopolyGames.json", "w") as f:
json.dump(data,f,indent=4)
try:
monopolyDraw.drawImage(channel)
except:
logThis("Error drawing board (error code 1640)")
message = "It's "+getName(playerList[turn])+"'s turn. Use the 🎲 reaction to roll. You can also use \"!monopoly trade\" at any time."
return message, True, True, False
def monopolyRoll(channel,user):
with open("resources/games/monopolyGames.json", "r") as f:
data = json.load(f)
turn = data[channel]["turn"]
currentPlayer = data[channel]["player list"][turn]
if user == currentPlayer:
rolls = [random.randint(1,6),random.randint(1,6)]
message = getName(user)+" rolled a "+str(rolls[0])+" and a "+str(rolls[1])+"."
if rolls[0] == rolls[1]:
message += " Doubbles!"
roll = rolls[0] + rolls[1]
oldPosition = data[channel]["players"][user]["position"]
newPosition = (oldPosition + roll)%40
if newPosition < oldPosition:
data[channel]["players"][user]["money"] += rulesAndTerms["pass go money"]
message += "\nYou passed go and got "+str(rulesAndTerms["pass go money"])+" "+rulesAndTerms["money term"]+"."
data[channel]["players"][user]["position"] = newPosition
data[channel]["last roll"] = rolls
with open("resources/games/monopolyGames.json", "w") as f:
json.dump(data,f,indent=4)
try:
monopolyDraw.drawImage(channel)
except:
logThis("Error drawing board (error code 1640)")
return message, True, True, False, True
else: return "", False, False, False, False

View File

@ -0,0 +1,57 @@
import math, json
from funcs import logThis
from PIL import Image, ImageDraw
w, h = 1440, 1440
largeSpace = 191
smallSpace = math.floor((w - 2*largeSpace)/9)
avatarSize = 50
avatarHalf = math.floor(avatarSize/2)
def drawImage(channel):
logThis("Drawing monopoly board for "+channel)
with open("resources/games/monopolyGames.json", "r") as f:
data = json.load(f)
board = Image.open("resources/games/monopolyBoard.png")
d = ImageDraw.Draw(board,"RGBA")
for key, value in list(data[channel]["players"].items()):
logThis("Drawing "+key)
try:
x, y = getPosition(value["position"])
except:
logThis("Error getting position (error code 1641)")
print(str(x)+", "+str(y))
d.ellipse([(x-avatarHalf,y-avatarHalf),(x+avatarHalf,y+avatarHalf)],fill=(255,0,0))
board.save("resources/games/monopolyBoards/monopolyBoard"+channel+".png")
def getPosition(positionNumber):
print(positionNumber)
x, y = 0, 0
if positionNumber == 0 or positionNumber >= 30:
x = math.floor(largeSpace/2)
elif positionNumber > 0 and positionNumber < 10:
x = math.floor(largeSpace - (smallSpace/2)) + (smallSpace*positionNumber)
elif positionNumber >= 10 and positionNumber <= 20:
x = w - math.floor(largeSpace/2)
elif positionNumber > 20 and positionNumber < 30:
x = w - math.floor(largeSpace - (smallSpace/2)) - (smallSpace*(positionNumber - 20))
if positionNumber >= 0 and positionNumber <= 20:
y = math.floor(largeSpace/2)
elif positionNumber > 10 and positionNumber < 20:
y = math.floor(largeSpace - (smallSpace/2)) + (smallSpace*(positionNumber-10))
elif positionNumber >= 20 and positionNumber <= 30:
y = h - math.floor(largeSpace/2)
elif positionNumber > 30:
y = h - math.floor(largeSpace - (smallSpace/2)) - (smallSpace*(positionNumber - 30))
return x, y

View File

@ -13,6 +13,7 @@ logging.basicConfig(filename="gwendolyn.log", level=logging.INFO)
# Capitalizes all words except some of them
no_caps_list = ["of","the"]
def cap(s):
# Capitalizes a strink like a movie title
word_number = 0
lst = s.split()
res = ''
@ -25,7 +26,7 @@ def cap(s):
return res
def time_in_range(start, end, x):
"""Return true if x is in the range [start, end]"""
# Return true if x is in the range [start, end]
if start <= end:
return start <= x <= end
else:
@ -134,146 +135,45 @@ def findWikiPage(search : str):
logThis("Couldn't find the page (error code 1002)")
return "", "Couldn't find page (error code 1002)", ""
def makeJsonFile(path,content):
# Creates json file if it doesn't exist
try:
f = open(path,"r")
except:
logThis(path.split("/")[-1]+" didn't exist. Making it now.")
with open(path,"w") as f:
json.dump(content,f,indent = 4)
finally:
f.close()
def makeTxtFile(path,content):
# Creates txt file if it doesn't exist
try:
f = open(path,"r")
except:
logThis(path.split("/")[-1]+" didn't exist. Making it now.")
with open(path,"w") as f:
f.write(content)
finally:
f.close()
def makeFolder(path):
if os.path.isdir(path) == False:
os.makedirs(path)
logThis("The "+path.split("/")[-1]+" directory didn't exist")
def makeFiles():
# Creates swcharacters.json if it doesn't exist
try:
f = open("resources/starWars/swcharacters.json","r")
except:
logThis("swcharacters.json didn't exist. Making it now.")
emptyDict = {}
with open("resources/starWars/swcharacters.json","w") as f:
json.dump(emptyDict,f,indent = 4)
finally:
f.close()
with open("resources/startingFiles.json") as f:
data = json.load(f)
# Creates games.json if it doesn't exist
try:
f = open("resources/games/games.json","r")
except:
logThis("games.json didn't exist. Making it now.")
data = {"trivia questions":{},"blackjack games":{},"4 in a row games": {},"users":{}}
with open("resources/games/games.json","w") as f:
json.dump(data,f,indent = 4)
finally:
f.close()
for path, content in data["json"].items():
makeJsonFile(path,content)
# Creates hexGames.json if it doesn't exist
try:
f = open("resources/games/hexGames.json","r")
except:
logThis("hexGames.json didn't exist. Making it now.")
data = {}
with open("resources/games/hexGames.json","w") as f:
json.dump(data,f,indent = 4)
finally:
f.close()
for path, content in data["txt"].items():
makeTxtFile(path,content)
# Creates monsters.json if it doesn't exist
try:
f = open("resources/lookup/monsters.json","r")
except:
logThis("monsters.json didn't exist. Making it now.")
with open("resources/lookup/lookupExamples.json") as f:
data = json.load(f)["monster"]
with open("resources/lookup/monsters.json","w") as f:
json.dump(data,f,indent = 4)
finally:
f.close()
# Creates spells.json if it doesn't exist
try:
f = open("resources/lookup/spells.json","r")
except:
logThis("spells.json didn't exist. Making it now.")
with open("resources/lookup/lookupExamples.json") as f:
data = json.load(f)["spell"]
with open("resources/lookup/spells.json","w") as f:
json.dump(data,f,indent = 4)
finally:
f.close()
# Creates users.json if it doesn't exist
try:
f = open("resources/users.json","r")
except:
logThis("users.json didn't exist. Making it now.")
data = {}
with open("resources/users.json","w") as f:
json.dump(data,f,indent = 4)
finally:
f.close()
# Creates destinyPoints.txt if it doesn't exist
try:
f = open("resources/starWars/destinyPoints.txt","r")
except:
logThis("destinyPoints.txt didn't exist. Making it now.")
with open("resources/starWars/destinyPoints.txt","w") as f:
f.write("")
finally:
f.close()
# Creates movies.txt if it doesn't exist
try:
f = open("resources/movies.txt","r")
except:
logThis("movies.txt didn't exist. Making it now.")
with open("resources/movies.txt","w") as f:
f.write("The Room")
finally:
f.close()
# Creates names.txt if it doesn't exist
try:
f = open("resources/names.txt","r")
except:
logThis("names.txt didn't exist. Making it now.")
with open("resources/names.txt","w") as f:
f.write("Gandalf")
finally:
f.close()
# Creates token.txt if it doesn't exist
try:
f = open("token.txt","r")
except:
logThis("token.txt didn't exist. Write your bot token below, or in token.txt later.")
token = input()
with open("token.txt","w") as f:
f.write(token)
finally:
f.close()
# Creates the blackjacktables foulder if it doesn't exist
if os.path.isdir("resources/games/blackjackTables") == False:
os.makedirs("resources/games/blackjackTables")
logThis("The tables directory didn't exist")
# Creates the 4InARowBoards foulder if it doesn't exist
if os.path.isdir("resources/games/4InARowBoards") == False:
os.makedirs("resources/games/4InARowBoards")
logThis("The 4 in a row boards directory didn't exist")
# Creates the hexBoards foulder if it doesn't exist
if os.path.isdir("resources/games/hexBoards") == False:
os.makedirs("resources/games/hexBoards")
logThis("The Hex boards directory didn't exist")
# Creates the oldImages foulder if it doesn't exist
if os.path.isdir("resources/games/oldImages") == False:
os.makedirs("resources/games/oldImages")
logThis("The old images directory didn't exist")
# Creates the blackjackCards foulder if it doesn't exist
if os.path.isdir("resources/games/blackjackCards") == False:
os.makedirs("resources/games/blackjackCards")
logThis("The blackjack cards directory didn't exist")
# Creates the hilo foulder if it doesn't exist
if os.path.isdir("resources/games/hilo") == False:
os.makedirs("resources/games/hilo")
logThis("The hi-lo directory didn't exist")
for path in data["folder"]:
makeFolder(path)
# Replaces multiple things with the same thing
def replaceMultiple(mainString, toBeReplaces, newString):
@ -286,7 +186,7 @@ def replaceMultiple(mainString, toBeReplaces, newString):
return mainString
def emojiToNumber(emoji):
def emojiToCommand(emoji):
if emoji == "1":
return 1
elif emoji == "2":
@ -301,21 +201,21 @@ def emojiToNumber(emoji):
return 6
elif emoji == "7":
return 7
elif emoji == "🎲":
return "roll"
else: return ""
def fiarReactionTest(channel,message,user):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
with open("resources/games/oldImages/fourInARow"+str(channel), "r") as f:
with open("resources/games/oldImages/fourInARow"+str(channel.id), "r") as f:
oldImage = int(f.read())
if message.id == oldImage:
logThis("They reacted to the fourinarow game")
turn = data["4 in a row games"][str(channel)]["turn"]
print(user)
print(data["4 in a row games"][str(channel)]["players"][turn])
if user == data["4 in a row games"][str(channel)]["players"][turn]:
turn = data["4 in a row games"][str(channel.id)]["turn"]
if user == data["4 in a row games"][str(channel.id)]["players"][turn]:
return True, turn+1
else:
logThis("It wasn't their turn")
@ -323,16 +223,31 @@ def fiarReactionTest(channel,message,user):
else:
return False, 0
def monopolyReactionTest(channel,message):
with open("resources/games/oldImages/monopoly"+str(channel.id), "r") as f:
oldImage = int(f.read())
if message.id == oldImage:
logThis("They reacted to the monopoly game")
return True
else:
return False
def stopServer():
with open("resources/games/games.json","r") as f:
data = json.load(f)
games = json.load(f)
data["trivia questions"] = {}
data["blackjack games"] = {}
data["4 in a row games"] = {}
games["trivia questions"] = {}
games["blackjack games"] = {}
games["4 in a row games"] = {}
with open("resources/games/games.json","w") as f:
json.dump(data,f,indent=4)
json.dump(games,f,indent=4)
emptyDict = {}
with open("resources/games/monopolyGames.json", "w") as f:
json.dump(emptyDict,f,indent=4)
def deleteGame(gameType,channel):
with open("resources/games/games.json", "r") as f:

View File

@ -1,4 +1,4 @@
"""I stole this."""
"""Rolling dice."""
__all__ = ["roll_dice"]

View File

@ -1,560 +1,20 @@
import random
import re
import traceback
from heapq import nlargest, nsmallest
from math import floor
from re import IGNORECASE
import d20
import numexpr
class MyStringifier(d20.MarkdownStringifier):
from . import errors
#from funcs import logThis
def _str_expression(self, node):
VALID_OPERATORS = 'k|rr|ro|mi|ma|ra|e|p'
VALID_OPERATORS_ARRAY = VALID_OPERATORS.split('|')
VALID_OPERATORS_2 = re.compile('|'.join(["({})".format(i) for i in VALID_OPERATORS_ARRAY]))
DICE_PATTERN = re.compile(
r'^\s*(?:(?:(\d*d\d+)(?:(?:' + VALID_OPERATORS + r')(?:[lh<>]?\d+))*|(\d+)|([-+*/().=])?)\s*(\[.*\])?)(.*?)\s*$',
IGNORECASE)
def roll_dice(author : str, rollStr : str = "1d20"):
if rollStr == '0/0': # easter eggs
return("What do you expect me to do, destroy the universe?")
adv = 0
if re.search('(^|\s+)(adv|dis)(\s+|$)', rollStr) is not None:
adv = 1 if re.search('(^|\s+)adv(\s+|$)', rollStr) is not None else -1
rollStr = re.sub('(adv|dis)(\s+|$)', '', rollStr)
res = roll(rollStr, adv=adv)
out = res.result
outStr = author + ' :game_die:\n' + out
if len(outStr) > 1999:
outputs = author + ' :game_die:\n[Output truncated due to length]\n**Result:** ' + str(res.plain)
if node.comment == None:
resultText = "Result"
else:
outputs = outStr
return(outputs)
resultText = node.comment.capitalize()
def list_get(index, default, l):
try:
a = l[index]
except IndexError:
a = default
return a
return f"**{resultText}**: {self._stringify(node.roll)}\n**Total**: {int(node.total)}"
def roll_dice(user, rollString):
while len(rollString) > 1 and rollString[0] == " ":
rollString = rollString[1:]
return user+" :game_die:\n"+str(d20.roll(rollString, allow_comments=True,stringifier=MyStringifier()))
def roll(rollStr, adv: int = 0, rollFor='', inline=False, double=False, show_blurbs=True, **kwargs):
roller = Roll()
result = roller.roll(rollStr, adv, rollFor, inline, double, show_blurbs, **kwargs)
return result
def get_roll_comment(rollStr):
"""Returns: A two-tuple (dice without comment, comment)"""
try:
comment = ''
no_comment = ''
dice_set = re.split('([-+*/().=])', rollStr)
dice_set = [d for d in dice_set if not d in (None, '')]
#logThis("Found dice set: " + str(dice_set))
for index, dice in enumerate(dice_set):
match = DICE_PATTERN.match(dice)
#logThis("Found dice group: " + str(match.groups()))
no_comment += dice.replace(match.group(5), '')
if match.group(5):
comment = match.group(5) + ''.join(dice_set[index + 1:])
break
return no_comment, comment
except:
pass
return rollStr, ''
class Roll(object):
def __init__(self, parts=None):
if parts ==None:
parts = []
self.parts = parts
def get_crit(self):
"""Returns: 0 for no crit, 1 for 20, 2 for 1."""
try:
crit = next(p.get_crit() for p in self.parts if isinstance(p, SingleDiceGroup))
except StopIteration:
crit = 0
return crit
def get_total(self):
"""Returns: int"""
return numexpr.evaluate(''.join(p.get_eval() for p in self.parts if not isinstance(p, Comment)))
# # Dice Roller
def roll(self, rollStr, adv: int = 0, rollFor='', inline=False, double=False, show_blurbs=True, **kwargs):
try:
if '**' in rollStr:
raise errors.InvalidArgument("Exponents are currently disabled.")
self.parts = []
# split roll string into XdYoptsSel [comment] or Op
# set remainder to comment
# parse each, returning a SingleDiceResult
dice_set = re.split('([-+*/().=])', rollStr)
dice_set = [d for d in dice_set if not d in (None, '')]
#logThis("Found dice set: " + str(dice_set))
for index, dice in enumerate(dice_set):
match = DICE_PATTERN.match(dice)
#logThis("Found dice group: " + str(match.groups()))
# check if it's dice
if match.group(1):
roll = self.roll_one(dice.replace(match.group(5), ''), adv)
self.parts.append(roll)
# or a constant
elif match.group(2):
self.parts.append(Constant(value=int(match.group(2)), annotation=match.group(4)))
# or an operator
elif not match.group(5):
self.parts.append(Operator(op=match.group(3), annotation=match.group(4)))
if match.group(5):
self.parts.append(Comment(match.group(5) + ''.join(dice_set[index + 1:])))
break
# calculate total
crit = self.get_crit()
try:
total = self.get_total()
except SyntaxError:
raise errors.InvalidArgument("No dice found to roll.")
rolled = ' '.join(str(res) for res in self.parts if not isinstance(res, Comment))
if rollFor =='':
rollFor = ''.join(str(c) for c in self.parts if isinstance(c, Comment))
# return final solution
if not inline:
# Builds end result while showing rolls
reply = ' '.join(
str(res) for res in self.parts if not isinstance(res, Comment)) + '\n**Total:** ' + str(
floor(total))
skeletonReply = reply
rollFor = rollFor if rollFor != '' else 'Result'
reply = '**{}:** '.format(rollFor) + reply
if show_blurbs:
if adv == 1:
reply += '\n**Rolled with Advantage**'
elif adv == -1:
reply += '\n**Rolled with Disadvantage**'
if crit == 1:
critStr = "\n_**Critical Hit!**_ "
reply += critStr
elif crit == 2:
critStr = "\n_**Critical Fail!**_ "
reply += critStr
else:
# Builds end result while showing rolls
reply = ' '.join(str(res) for res in self.parts if not isinstance(res, Comment)) + ' = `' + str(
floor(total)) + '`'
skeletonReply = reply
rollFor = rollFor if rollFor != '' else 'Result'
reply = '**{}:** '.format(rollFor) + reply
if show_blurbs:
if adv == 1:
reply += '\n**Rolled with Advantage**'
elif adv == -1:
reply += '\n**Rolled with Disadvantage**'
if crit == 1:
critStr = "\n_**Critical Hit!**_ "
reply += critStr
elif crit == 2:
critStr = "\n_**Critical Fail!**_ "
reply += critStr
reply = re.sub(' +', ' ', reply)
skeletonReply = re.sub(' +', ' ', str(skeletonReply))
return DiceResult(result=int(floor(total)), verbose_result=reply, crit=crit, rolled=rolled,
skeleton=skeletonReply, raw_dice=self)
except Exception as ex:
if not isinstance(ex, (SyntaxError, KeyError, errors.AvraeException)):
#logThis('Error in roll() caused by roll {}:'.format(rollStr))
traceback.print_exc()
return DiceResult(verbose_result="Invalid input: {}".format(ex))
def roll_one(self, dice, adv: int = 0):
result = SingleDiceGroup()
result.rolled = []
# splits dice and comments
split = re.match(r'^([^\[\]]*?)\s*(\[.*\])?\s*$', dice)
dice = split.group(1).strip()
annotation = split.group(2)
result.annotation = annotation if annotation != None else ''
# Recognizes dice
obj = re.findall('\d+', dice)
obj = [int(x) for x in obj]
numArgs = len(obj)
ops = []
if numArgs == 1:
if not dice.startswith('d'):
raise errors.InvalidArgument('Please pass in the value of the dice.')
numDice = 1
diceVal = obj[0]
if adv != 0 and diceVal == 20:
numDice = 2
ops = ['k', 'h1'] if adv ==1 else ['k', 'l1']
elif numArgs == 2:
numDice = obj[0]
diceVal = obj[-1]
if adv != 0 and diceVal == 20:
ops = ['k', 'h' + str(numDice)] if adv ==1 else ['k', 'l' + str(numDice)]
numDice = numDice * 2
else: # split into xdy and operators
numDice = obj[0]
diceVal = obj[1]
dice = re.split('(\d+d\d+)', dice)[-1]
ops = VALID_OPERATORS_2.split(dice)
ops = [a for a in ops if a != None]
# dice repair/modification
if numDice > 300 or diceVal < 1:
raise errors.InvalidArgument('Too many dice rolled.')
result.max_value = diceVal
result.num_dice = numDice
result.operators = ops
for _ in range(numDice):
try:
tempdice = SingleDice()
tempdice.value = random.randint(1, diceVal)
tempdice.rolls = [tempdice.value]
tempdice.max_value = diceVal
tempdice.kept = True
result.rolled.append(tempdice)
except:
result.rolled.append(SingleDice())
if ops != None:
rerollList = []
reroll_once = []
keep = None
to_explode = []
to_reroll_add = []
valid_operators = VALID_OPERATORS_ARRAY
last_operator = None
for index, op in enumerate(ops):
if last_operator != None and op in valid_operators and not op == last_operator:
result.reroll(reroll_once, 1)
reroll_once = []
result.reroll(rerollList, greedy=True)
rerollList = []
result.keep(keep)
keep = None
result.reroll(to_reroll_add, 1, keep_rerolled=True, unique=True)
to_reroll_add = []
result.reroll(to_explode, greedy=True, keep_rerolled=True)
to_explode = []
if op == 'rr':
rerollList += parse_selectors([list_get(index + 1, 0, ops)], result, greedy=True)
if op == 'k':
keep = [] if keep ==None else keep
keep += parse_selectors([list_get(index + 1, 0, ops)], result)
if op == 'p':
keep = [] if keep ==None else keep
keep += parse_selectors([list_get(index + 1, 0, ops)], result, inverse=True)
if op == 'ro':
reroll_once += parse_selectors([list_get(index + 1, 0, ops)], result)
if op == 'mi':
_min = list_get(index + 1, 0, ops)
for r in result.rolled:
if r.value < int(_min):
r.update(int(_min))
if op == 'ma':
_max = list_get(index + 1, 0, ops)
for r in result.rolled:
if r.value > int(_max):
r.update(int(_max))
if op == 'ra':
to_reroll_add += parse_selectors([list_get(index + 1, 0, ops)], result)
if op == 'e':
to_explode += parse_selectors([list_get(index + 1, 0, ops)], result, greedy=True)
if op in valid_operators:
last_operator = op
result.reroll(reroll_once, 1)
result.reroll(rerollList, greedy=True)
result.keep(keep)
result.reroll(to_reroll_add, 1, keep_rerolled=True, unique=True)
result.reroll(to_explode, greedy=True, keep_rerolled=True)
return result
class Part:
"""Class to hold one part of the roll string."""
pass
class SingleDiceGroup(Part):
def __init__(self, num_dice: int = 0, max_value: int = 0, rolled=None, annotation: str = "", result: str = "",
operators=None):
if operators ==None:
operators = []
if rolled ==None:
rolled = []
self.num_dice = num_dice
self.max_value = max_value
self.rolled = rolled # list of SingleDice
self.annotation = annotation
self.result = result
self.operators = operators
def keep(self, rolls_to_keep):
if rolls_to_keep ==None: return
for _roll in self.rolled:
if not _roll.value in rolls_to_keep:
_roll.kept = False
elif _roll.kept:
rolls_to_keep.remove(_roll.value)
def reroll(self, rerollList, max_iterations=1000, greedy=False, keep_rerolled=False, unique=False):
if not rerollList: return # don't reroll nothing - minor optimization
if unique:
rerollList = list(set(rerollList)) # remove duplicates
if len(rerollList) > 100:
raise OverflowError("Too many dice to reroll (max 100)")
last_index = 0
count = 0
should_continue = True
while should_continue: # let's only iterate 250 times for sanity
should_continue = False
if any(d.value in set(rerollList) for d in self.rolled[last_index:] if d.kept and not d.exploded):
should_continue = True
to_extend = []
for r in self.rolled[last_index:]: # no need to recheck everything
count += 1
if count > max_iterations:
should_continue = False
if r.value in rerollList and r.kept and not r.exploded:
try:
tempdice = SingleDice()
tempdice.value = random.randint(1, self.max_value)
tempdice.rolls = [tempdice.value]
tempdice.max_value = self.max_value
tempdice.kept = True
to_extend.append(tempdice)
if not keep_rerolled:
r.drop()
else:
r.explode()
except:
to_extend.append(SingleDice())
if not keep_rerolled:
r.drop()
else:
r.explode()
if not greedy:
rerollList.remove(r.value)
last_index = len(self.rolled)
self.rolled.extend(to_extend)
def get_total(self):
"""Returns:
int - The total value of the dice."""
return sum(r.value for r in self.rolled if r.kept)
def get_eval(self):
return str(self.get_total())
def get_num_kept(self):
return sum(1 for r in self.rolled if r.kept)
def get_crit(self):
"""Returns:
int - 0 for no crit, 1 for crit, 2 for crit fail."""
if self.get_num_kept() == 1 and self.max_value == 20:
if self.get_total() == 20:
return 1
elif self.get_total() == 1:
return 2
return 0
def __str__(self):
return "{0.num_dice}d{0.max_value}{1} ({2}) {0.annotation}".format(
self, ''.join(self.operators), ', '.join(str(r) for r in self.rolled))
def to_dict(self):
return {'type': 'dice', 'dice': [d.to_dict() for d in self.rolled], 'annotation': self.annotation,
'value': self.get_total(), 'is_crit': self.get_crit(), 'num_kept': self.get_num_kept(),
'text': str(self), 'num_dice': self.num_dice, 'dice_size': self.max_value, 'operators': self.operators}
class SingleDice:
def __init__(self, value: int = 0, max_value: int = 0, kept: bool = True, exploded: bool = False):
self.value = value
self.max_value = max_value
self.kept = kept
self.rolls = [value] # list of ints (for X -> Y -> Z)
self.exploded = exploded
def drop(self):
self.kept = False
def explode(self):
self.exploded = True
def update(self, new_value):
self.value = new_value
self.rolls.append(new_value)
def __str__(self):
formatted_rolls = [str(r) for r in self.rolls]
if int(formatted_rolls[-1]) == self.max_value or int(formatted_rolls[-1]) == 1:
formatted_rolls[-1] = '**' + formatted_rolls[-1] + '**'
if self.exploded:
formatted_rolls[-1] = '__' + formatted_rolls[-1] + '__'
if self.kept:
return ' -> '.join(formatted_rolls)
else:
return '~~' + ' -> '.join(formatted_rolls) + '~~'
def __repr__(self):
return "<SingleDice object: value={0.value}, max_value={0.max_value}, kept={0.kept}, rolls={0.rolls}>".format(
self)
def to_dict(self):
return {'type': 'single_dice', 'value': self.value, 'size': self.max_value, 'is_kept': self.kept,
'rolls': self.rolls, 'exploded': self.exploded}
class Constant(Part):
def __init__(self, value: int = 0, annotation: str = ""):
self.value = value
self.annotation = annotation if annotation != None else ''
def __str__(self):
return "{0.value} {0.annotation}".format(self)
def get_eval(self):
return str(self.value)
def to_dict(self):
return {'type': 'constant', 'value': self.value, 'annotation': self.annotation}
class Operator(Part):
def __init__(self, op: str = "+", annotation: str = ""):
self.op = op if op != None else ''
self.annotation = annotation if annotation != None else ''
def __str__(self):
return "{0.op} {0.annotation}".format(self)
def get_eval(self):
return self.op
def to_dict(self):
return {'type': 'operator', 'value': self.op, 'annotation': self.annotation}
class Comment(Part):
def __init__(self, comment: str = ""):
self.comment = comment
def __str__(self):
return self.comment.strip()
def to_dict(self):
return {'type': 'comment', 'value': self.comment}
def parse_selectors(opts, res, greedy=False, inverse=False):
"""Returns a list of ints."""
for o in range(len(opts)):
if opts[o][0] =='h':
opts[o] = nlargest(int(opts[o].split('h')[1]), (d.value for d in res.rolled if d.kept))
elif opts[o][0] =='l':
opts[o] = nsmallest(int(opts[o].split('l')[1]), (d.value for d in res.rolled if d.kept))
elif opts[o][0] =='>':
if greedy:
opts[o] = list(range(int(opts[o].split('>')[1]) + 1, res.max_value + 1))
else:
opts[o] = [d.value for d in res.rolled if d.value > int(opts[o].split('>')[1])]
elif opts[o][0] =='<':
if greedy:
opts[o] = list(range(1, int(opts[o].split('<')[1])))
else:
opts[o] = [d.value for d in res.rolled if d.value < int(opts[o].split('<')[1])]
out = []
for o in opts:
if isinstance(o, list):
out.extend(int(l) for l in o)
elif not greedy:
out.extend(int(o) for a in res.rolled if a.value ==int(o) and a.kept)
else:
out.append(int(o))
if not inverse:
return out
inverse_out = []
for rolled in res.rolled:
if rolled.kept and rolled.value in out:
out.remove(rolled.value)
elif rolled.kept:
inverse_out.append(rolled.value)
return inverse_out
class DiceResult:
"""Class to hold the output of a dice roll."""
def __init__(self, result: int = 0, verbose_result: str = '', crit: int = 0, rolled: str = '', skeleton: str = '',
raw_dice: Roll = None):
self.plain = result
self.total = result
self.result = verbose_result
self.crit = crit
self.rolled = rolled
self.skeleton = skeleton if skeleton != '' else verbose_result
self.raw_dice = raw_dice # Roll
def __str__(self):
return self.result
def __repr__(self):
return '<DiceResult object: total={}>'.format(self.total)
def consolidated(self):
"""Gets the most simplified version of the roll string."""
if self.raw_dice ==None:
return "0"
parts = [] # list of (part, annotation)
last_part = ""
for p in self.raw_dice.parts:
if isinstance(p, SingleDiceGroup):
last_part += str(p.get_total())
else:
last_part += str(p)
if not isinstance(p, Comment) and p.annotation:
parts.append((last_part, p.annotation))
last_part = ""
if last_part:
parts.append((last_part, ""))
to_roll = ""
last_annotation = ""
out = ""
for numbers, annotation in parts:
if annotation and annotation != last_annotation and to_roll:
out += f"{roll(to_roll).total:+} {last_annotation}"
to_roll = ""
if annotation:
last_annotation = annotation
to_roll += numbers
if to_roll:
out += f"{roll(to_roll).total:+} {last_annotation}"
out = out.strip('+ ')
return out
if __name__ == '__main__':
while True:
print(roll(input().strip()))

View File

@ -1,162 +0,0 @@
class AvraeException(Exception):
"""A base exception class."""
def __init__(self, msg):
super().__init__(msg)
class NoCharacter(AvraeException):
"""Raised when a user has no active character."""
def __init__(self):
super().__init__("You have no character active.")
class NoActiveBrew(AvraeException):
"""Raised when a user has no active homebrew of a certain type."""
def __init__(self):
super().__init__("You have no homebrew of this type active.")
class ExternalImportError(AvraeException):
"""Raised when something fails to import."""
def __init__(self, msg):
super().__init__(msg)
class InvalidArgument(AvraeException):
"""Raised when an argument is invalid."""
pass
class EvaluationError(AvraeException):
"""Raised when a cvar evaluation causes an error."""
def __init__(self, original):
super().__init__(f"Error evaluating expression: {original}")
self.original = original
class FunctionRequiresCharacter(AvraeException):
"""
Raised when a function that requires a character is called without one.
"""
def __init__(self, msg=None):
super().__init__(msg or "This alias requires an active character.")
class OutdatedSheet(AvraeException):
"""Raised when a feature is used that requires an updated sheet."""
def __init__(self, msg=None):
super().__init__(msg or "This command requires an updated character sheet. Try running `!update`.")
class NoSpellDC(AvraeException):
def __init__(self):
super().__init__("No spell save DC found.")
class NoSpellAB(AvraeException):
def __init__(self):
super().__init__("No spell attack bonus found.")
class InvalidSaveType(AvraeException):
def __init__(self):
super().__init__("Invalid save type.")
class ConsumableException(AvraeException):
"""A base exception for consumable exceptions to stem from."""
pass
class ConsumableNotFound(ConsumableException):
"""Raised when a consumable is not found."""
def __init__(self):
super().__init__("The requested counter does not exist.")
class CounterOutOfBounds(ConsumableException):
"""Raised when a counter is set to a value out of bounds."""
def __init__(self):
super().__init__("The new value is out of bounds.")
class NoReset(ConsumableException):
"""Raised when a consumable without a reset is reset."""
def __init__(self):
super().__init__("The counter does not have a reset value.")
class InvalidSpellLevel(ConsumableException):
"""Raised when a spell level is invalid."""
def __init__(self):
super().__init__("The spell level is invalid.")
class SelectionException(AvraeException):
"""A base exception for message awaiting exceptions to stem from."""
pass
class NoSelectionElements(SelectionException):
"""Raised when get_selection() is called with no choices."""
def __init__(self, msg=None):
super().__init__(msg or "There are no choices to select from.")
class SelectionCancelled(SelectionException):
"""Raised when get_selection() is cancelled or times out."""
def __init__(self):
super().__init__("Selection timed out or was cancelled.")
class CombatException(AvraeException):
"""A base exception for combat-related exceptions to stem from."""
pass
class CombatNotFound(CombatException):
"""Raised when a channel is not in combat."""
def __init__(self):
super().__init__("This channel is not in combat.")
class RequiresContext(CombatException):
"""Raised when a combat is committed without context."""
def __init__(self):
super().__init__("Combat not contextualized.")
class ChannelInCombat(CombatException):
"""Raised when a combat is started with an already active combat."""
def __init__(self):
super().__init__("Channel already in combat.")
class CombatChannelNotFound(CombatException):
"""Raised when a combat's channel is not in the channel list."""
def __init__(self):
super().__init__("Combat channel does not exist.")
class NoCombatants(CombatException):
"""Raised when a combat tries to advance turn with no combatants."""
def __init__(self):
super().__init__("There are no combatants.")

View File

@ -2,7 +2,7 @@ import asyncio
import discord
import json
from funcs import logThis, addMoney, deleteGame, parseFourInARow, fourInARowAI, blackjackContinue, blackjackFinish, parseHex, hexAI
from funcs import logThis, addMoney, deleteGame, parseFourInARow, fourInARowAI, blackjackContinue, blackjackFinish, parseHex, hexAI, parseMonopoly, monopolyContinue
# Deletes a message
async def deleteMessage(imageLocation,channel):
@ -20,34 +20,34 @@ async def deleteMessage(imageLocation,channel):
# Runs Hex
async def runHex(channel,command,user):
try:
response, showImage, deleteImage, gameDone, gwendoTurn = parseHex(command,str(channel),user)
response, showImage, deleteImage, gameDone, gwendoTurn = parseHex(command,str(channel.id),user)
except:
logThis("Error parsing command (error code 1510)")
await channel.send(response)
logThis(response,str(channel))
logThis(response,str(channel.id))
if showImage:
if deleteImage:
try:
oldImage = await deleteMessage("hex"+str(channel),channel)
oldImage = await deleteMessage("hex"+str(channel.id),channel)
except:
logThis("Error deleting old image (error code 1501)")
oldImage = await channel.send(file = discord.File("resources/games/hexBoards/board"+str(channel)+".png"))
oldImage = await channel.send(file = discord.File("resources/games/hexBoards/board"+str(channel.id)+".png"))
if not gameDone:
if gwendoTurn:
try:
response, showImage, deleteImage, gameDone, gwendoTurn = hexAI(str(channel))
response, showImage, deleteImage, gameDone, gwendoTurn = hexAI(str(channel.id))
except:
logThis("AI error (error code 1520)")
await channel.send(response)
logThis(response,str(channel))
logThis(response,str(channel.id))
if showImage:
if deleteImage:
await oldImage.delete()
oldImage = await channel.send(file = discord.File("resources/games/hexBoards/board"+str(channel)+".png"))
oldImage = await channel.send(file = discord.File("resources/games/hexBoards/board"+str(channel.id)+".png"))
else:
with open("resources/games/oldImages/hex"+str(channel), "w") as f:
with open("resources/games/oldImages/hex"+str(channel.id), "w") as f:
f.write(str(oldImage.id))
if gameDone:
@ -55,52 +55,52 @@ async def runHex(channel,command,user):
data = json.load(f)
try:
with open("resources/games/oldImages/hex"+str(channel), "r") as f:
with open("resources/games/oldImages/hex"+str(channel.id), "r") as f:
oldImage = await channel.fetch_message(int(f.read()))
await oldImage.delete()
except:
logThis("The old image was already deleted")
winner = data["hex games"][str(channel)]["winner"]
winner = data["hex games"][str(channel.id)]["winner"]
if winner != 0:
addMoney(data["hex games"][str(channel)]["players"][winner-1].lower(),20)
addMoney(data["hex games"][str(channel.id)]["players"][winner-1].lower(),20)
with open("resources/games/games.json", "r") as f:
data = json.load(f) #why is this here?
deleteGame("hex games",str(channel))
deleteGame("hex games",str(channel.id))
# Runs Four in a Row
async def fiar(channel,command,user):
try:
response, showImage, deleteImage, gameDone, gwendoTurn = parseFourInARow(command,str(channel),user)
response, showImage, deleteImage, gameDone, gwendoTurn = parseFourInARow(command,str(channel.id),user)
except:
logThis("Error parsing command (error code 1410)")
await channel.send(response)
logThis(response,str(channel))
logThis(response,str(channel.id))
if showImage:
if deleteImage:
try:
oldImage = await deleteMessage("fourInARow"+str(channel),channel)
oldImage = await deleteMessage("fourInARow"+str(channel.id),channel)
except:
logThis("Error deleting message (error code 1401)")
oldImage = await channel.send(file = discord.File("resources/games/4InARowBoards/board"+str(channel)+".png"))
oldImage = await channel.send(file = discord.File("resources/games/4InARowBoards/board"+str(channel.id)+".png"))
if gameDone == False:
if gwendoTurn:
try:
response, showImage, deleteImage, gameDone, gwendoTurn = fourInARowAI(str(channel))
response, showImage, deleteImage, gameDone, gwendoTurn = fourInARowAI(str(channel.id))
except:
logThis("AI error (error code 1420)")
await channel.send(response)
logThis(response,str(channel))
logThis(response,str(channel.id))
if showImage:
if deleteImage:
await oldImage.delete()
oldImage = await channel.send(file = discord.File("resources/games/4InARowBoards/board"+str(channel)+".png"))
oldImage = await channel.send(file = discord.File("resources/games/4InARowBoards/board"+str(channel.id)+".png"))
if gameDone == False:
with open("resources/games/oldImages/fourInARow"+str(channel), "w") as f:
with open("resources/games/oldImages/fourInARow"+str(channel.id), "w") as f:
f.write(str(oldImage.id))
try:
reactions = ["1","2","3","4","5","6","7"]
@ -111,7 +111,7 @@ async def fiar(channel,command,user):
logThis("Image deleted before I could react to all of them")
else:
with open("resources/games/oldImages/fourInARow"+str(channel), "w") as f:
with open("resources/games/oldImages/fourInARow"+str(channel.id), "w") as f:
f.write(str(oldImage.id))
try:
reactions = ["1","2","3","4","5","6","7"]
@ -119,48 +119,45 @@ async def fiar(channel,command,user):
await oldImage.add_reaction(reaction)
except:
logThis("Image deleted before I could react to all of them")
# else:
# with open("resources/games/oldImages/fourInARow"+str(channel), "w") as f:
# f.write(str(oldImage.id))
if gameDone:
with open("resources/games/games.json", "r") as f:
data = json.load(f)
try:
with open("resources/games/oldImages/fourInARow"+str(channel), "r") as f:
with open("resources/games/oldImages/fourInARow"+str(channel.id), "r") as f:
oldImage = await channel.fetch_message(int(f.read()))
await oldImage.delete()
except:
logThis("The old image was already deleted")
winner = data["4 in a row games"][str(channel)]["winner"]
difficulty = int(data["4 in a row games"][str(channel)]["difficulty"])
winner = data["4 in a row games"][str(channel.id)]["winner"]
difficulty = int(data["4 in a row games"][str(channel.id)]["difficulty"])
reward = difficulty**2 + 5
if winner != 0:
if data["4 in a row games"][str(channel)]["players"][winner-1].lower() != "gwendolyn":
addMoney(data["4 in a row games"][str(channel)]["players"][winner-1].lower(),reward)
if data["4 in a row games"][str(channel.id)]["players"][winner-1].lower() != "gwendolyn":
addMoney(data["4 in a row games"][str(channel.id)]["players"][winner-1].lower(),reward)
with open("resources/games/games.json", "r") as f:
data = json.load(f) #why is this here?
deleteGame("4 in a row games",str(channel))
deleteGame("4 in a row games",str(channel.id))
# Loop of blackjack game rounds
async def blackjackLoop(channel,gameRound,gameID):
logThis("Loop "+str(gameRound),str(channel))
logThis("Loop "+str(gameRound),str(channel.id))
with open("resources/games/oldImages/blackjack"+str(channel), "r") as f:
with open("resources/games/oldImages/blackjack"+str(channel.id), "r") as f:
oldImage = await channel.fetch_message(int(f.read()))
new_message, allStanding, gamedone = blackjackContinue(str(channel))
new_message, allStanding, gamedone = blackjackContinue(str(channel.id))
if new_message != "":
logThis(new_message,str(channel))
logThis(new_message,str(channel.id))
await channel.send(new_message)
if gamedone == False:
await oldImage.delete()
oldImage = await channel.send(file = discord.File("resources/games/blackjackTables/blackjackTable"+str(channel)+".png"))
with open("resources/games/oldImages/blackjack"+str(channel), "w") as f:
oldImage = await channel.send(file = discord.File("resources/games/blackjackTables/blackjackTable"+str(channel.id)+".png"))
with open("resources/games/oldImages/blackjack"+str(channel.id), "w") as f:
f.write(str(oldImage.id))
try:
@ -174,21 +171,63 @@ async def blackjackLoop(channel,gameRound,gameID):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
if str(channel) in data["blackjack games"]:
realRound = data["blackjack games"][str(channel)]["round"]
realGameID = data["blackjack games"][str(channel)]["id"]
if str(channel.id) in data["blackjack games"]:
realRound = data["blackjack games"][str(channel.id)]["round"]
realGameID = data["blackjack games"][str(channel.id)]["id"]
if gameRound == realRound and realGameID == gameID:
if gamedone == False:
logThis("Loop "+str(gameRound)+" calling blackjackLoop()",str(channel))
logThis("Loop "+str(gameRound)+" calling blackjackLoop()",str(channel.id))
await blackjackLoop(channel,gameRound+1,gameID)
else:
try:
new_message = blackjackFinish(str(channel))
new_message = blackjackFinish(str(channel.id))
except:
logThis("Something fucked up (error code 1310)")
await channel.send(new_message)
else:
logThis("Ending loop on round "+str(gameRound),str(channel))
logThis("Ending loop on round "+str(gameRound),str(channel.id))
else:
logThis("Ending loop on round "+str(gameRound),str(channel))
logThis("Ending loop on round "+str(gameRound),str(channel.id))
async def runMonopoly(channel, command, user):
try:
response, showImage, deleteImage, gameStarted, gameContinue = parseMonopoly(command,str(channel.id),user)
except:
logThis("Error parsing command (error code 1610)")
if response != "":
await channel.send(response)
logThis(response,str(channel.id))
if showImage:
if deleteImage:
try:
oldImage = await deleteMessage("monopoly"+str(channel.id),channel)
except:
logThis("Error deleting message (error code 1601)")
oldImage = await channel.send(file = discord.File("resources/games/monopolyBoards/monopolyBoard"+str(channel.id)+".png"))
with open("resources/games/oldImages/monopoly"+str(channel.id), "w") as f:
f.write(str(oldImage.id))
if gameContinue:
if gameStarted:
await asyncio.sleep(60)
else:
await asyncio.sleep(3)
response, showImage, deleteImage, gameDone = monopolyContinue(str(channel.id))
em = discord.Embed(description=response,colour = 0x59f442)
await channel.send(embed=em)
if showImage:
if deleteImage:
try:
oldImage = await deleteMessage("monopoly"+str(channel.id),channel)
except:
logThis("Error deleting message (error code 1601)")
oldImage = await channel.send(file = discord.File("resources/games/monopolyBoards/monopolyBoard"+str(channel.id)+".png"))
with open("resources/games/oldImages/monopoly"+str(channel.id), "w") as f:
f.write(str(oldImage.id))
if gameDone == False:
try:
await oldImage.add_reaction("🎲")
except:
logThis("Image deleted before I could react to all of them")

View File

@ -93,6 +93,7 @@
1312 - Error in calcWinnings function
1320 - Unspecified loop error
1321 - Loop interrupted while waiting
1322 - Error with getHandNumber()
1330 - Unspecified continue error
1331 - Error in testIfStanding()
1340 - Error in drawing blackjack table
@ -112,3 +113,14 @@
1531 - Invalid position
1532 - Cannot place on existing piece
1533 - Position out of bounds
16 - Monopoly
1600 - Unspecified error
1601 - Error deleting old image
1602 - Not a command
1610 - Unspecified parsing error
1620 - Unspecified monopolyStart() error
1630 - Unspecified monopolyJoin() error
1640 - Unspecified monopolyDraw error
1641 - Error in getPosition()
1650 - Error in monopolyRoll()

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -1 +1 @@
Kommandoen "!blackjack" starter et spil blackjack. "!blackjack bet [beløb]" lader dig vædde en mængde af dine GwendoBucks. Du bruger "!blackjack hit", "!blackjack stand", "!blackjack split" og "!blackjack double" i løbet af spillet.
Kommandoen `!blackjack` starter et spil blackjack. `!blackjack bet [beløb]` lader dig vædde en mængde af dine GwendoBucks. Du bruger `!blackjack hit`, `!blackjack stand`, `!blackjack split` og `!blackjack double` i løbet af spillet.

View File

@ -1 +1 @@
Brug "!fourinarow start" til at starte et spil imod Gwendolyn. Brug "!fourinarow start [modstander]" for at spille imod en anden person.
Brug `!fourinarow start` til at starte et spil imod Gwendolyn. Brug `!fourinarow start [modstander]` for at spille imod en anden person. Du kan også bruge `!fourinarow start [1-5]`, hvor tallet er sværhedsgraden af Gwendolyn du gerne vil spille imod.

View File

@ -1 +1 @@
Du kan give GwendoBucks til andre med "!give [modtager] [antal]", hvor [modtager] er den der skal modtage GwendoBucks og [antal] er hvor mange GwendoBucks du giver dem.
Du kan give GwendoBucks til andre med `!give [modtager] [antal]`, hvor [modtager] er den der skal modtage GwendoBucks og [antal] er hvor mange GwendoBucks du giver dem.

View File

@ -1 +1 @@
Hvis du bruger kommandoen "!hello", sender Gwendolyn en venlig hilsen.
Hvis du bruger kommandoen `!hello`, sender Gwendolyn en venlig hilsen.

View File

@ -1 +1 @@
Brug "!hex start" til at starte et spil imod Gwendolyn. Brug "!hex start [modstander]" for at spille imod en anden person.
Brug `!hex start` til at starte et spil imod Gwendolyn. Brug "!hex start [modstander]" for at spille imod en anden person.

View File

@ -1,2 +1,2 @@
Søg efter et monster i D&D med "!monster [monster]", hvor [monster] er navnet på det monster du søger efter.
Søg efter et monster i D&D med `!monster [monster]`, hvor [monster] er navnet på det monster du søger efter.
Hvis Gwendolyn ikke kan finde det, er det ofte fordi du har skrevet navnet forkert.

View File

@ -1,8 +1,8 @@
Rul terninger i xdy format. Kan udføre matematik udover rullende. Kan også gøre følgende:
kx: Beholder kun rul med værdien x.
rox: Genrul rul med værdien x første gang.
rrx: Genrul alle rul med værdien x
mix: Gør alle rul under x til x.
max: Gør alle rul over x til x.
rax: Genruller og tilføjer rul med værdien x.
l/h før x: For de laveste/højeste x rul.
`kx` - Beholder kun rul med værdien x.
`rox` - Genrul rul med værdien x første gang.
`rrx` - Genrul alle rul med værdien x
`mix` - Gør alle rul under x til x.
`max` - Gør alle rul over x til x.
`rax` - Genruller og tilføjer rul med værdien x.
`l/h` før x - For de laveste/højeste x rul.

View File

@ -1,2 +1,2 @@
Søg efter en spell i D&D med "!spell [spell]", hvor [spell] er navnet på den spell du søger efter.
Søg efter en spell i D&D med `!spell [spell]`, hvor [spell] er navnet på den spell du søger efter.
Hvis Gwendolyn ikke kan finde den, er det ofte fordi du har skrevet navnet forkert.

View File

@ -1 +1 @@
Du kan bruge kommandoer som "!swchar name Jared" eller "!swchar skills astrogation 3" til at ændre din karakters info. Kommandoen "!swchar" vil give dig et character sheet for din karakter.
Du kan bruge kommandoer som `!swchar name Jared` eller `!swchar skills astrogation 3` til at ændre din karakters info. Kommandoen `!swchar` vil give dig et character sheet for din karakter.

View File

@ -1,4 +1,4 @@
Lader dig spille et spil trivia. "!trivia" starter spillet.
Lader dig spille et spil trivia. `!trivia` starter spillet.
Hvert spil trivia varer i 1 minut, og der kan kun være et enkelt spil i hver kanal ad gangen.
"!trivia [svar]" lader dig svare på det nuværende spørgsmål, hvor [svar] er a, b, c eller d.
`!trivia [svar]` lader dig svare på det nuværende spørgsmål, hvor [svar] er a, b, c eller d.
Hvis du svarer rigtigt får du 1 GwendoBuck.

View File

@ -1,35 +1,35 @@
**!hello** - En venlig hilsen.
`!hello` - En venlig hilsen.
**!roll** - Rul terninger i xdy format.
`!roll` - Rul terninger i xdy format.
**!spell** - Slå en besværgelse op.
`!spell` - Slå en besværgelse op.
**!monster** - Slå et monster op.
`!monster` - Slå et monster op.
**!map** - Få et billede af Senkulpa kortet.
`!map` - Få et billede af Senkulpa kortet.
**!image** - Finder et tilfældigt billede fra internettet.
`!image` - Finder et tilfældigt billede fra internettet.
**!movie** - Giver titlen på en tilfældig film fra Bedre Netflix
`!movie` - Giver titlen på en tilfældig film fra Bedre Netflix
**!name** - Genererer et tilfældigt navn.
`!name` - Genererer et tilfældigt navn.
**!tavern** - Genererer en tilfældig tavern.
`!tavern` - Genererer en tilfældig tavern.
**!give** - Lader dig give GwendoBucks til andre.
`!give` - Lader dig give GwendoBucks til andre.
**!swchar** - Lader dig lave en Star Wars karakter.
`!swchar` - Lader dig lave en Star Wars karakter.
**!swroll** - Lader dig rulle Star Wars terninger.
`!swroll` - Lader dig rulle Star Wars terninger.
**!balance** - Viser dig hvor mange GwendoBucks du har.
`!balance` - Viser dig hvor mange GwendoBucks du har.
**!blackjack** - Lader dig spille et spil blackjack.
`!blackjack` - Lader dig spille et spil blackjack.
**!trivia** - Lader dig spille et spil trivia, hvor du kan tjene GwendoBucks.
`!trivia` - Lader dig spille et spil trivia, hvor du kan tjene GwendoBucks.
**!fourinarow** - Lader dig spille et spil fire på stribe.
`!fourinarow` - Lader dig spille et spil fire på stribe.
**!hex** - Lader dig spille et spil Hex.
`!hex` - Lader dig spille et spil Hex.
Du kan få ekstra information om kommandoerne med "!help [kommando]".

View File

@ -1,56 +0,0 @@
{
"monster" : [
{
"name": "Bandit",
"size": "Medium",
"type": "humanoid",
"subtype": "any race",
"alignment": "any non-lawful alignment",
"armor_class": 12,
"hit_points": 11,
"hit_dice": "2d8",
"speed": "30 ft.",
"strength": 11,
"dexterity": 12,
"constitution": 12,
"intelligence": 10,
"wisdom": 10,
"charisma": 10,
"damage_vulnerabilities": "",
"damage_resistances": "",
"damage_immunities": "",
"condition_immunities": "",
"senses": "passive Perception 10",
"languages": "any one language (usually Common)",
"challenge_rating": "1/8",
"actions": [
{
"name": "Scimitar",
"desc": "Melee Weapon Attack: +3 to hit, reach 5 ft., one target. Hit: 4 (1d6 + 1) slashing damage.",
"attack_bonus": 3,
"damage_dice": "1d6",
"damage_bonus": 1
},
{
"name": "Light Crossbow",
"desc": "Ranged Weapon Attack: +3 to hit, range 80 ft./320 ft., one target. Hit: 5 (1d8 + 1) piercing damage.",
"attack_bonus": 3,
"damage_dice": "1d8",
"damage_bonus": 1
}
]
}
],
"spell": {
"Fireball" : {
"casting_time" : "1 action",
"components" : "V, S, M (a tiny ball of bat guano and sulfur)",
"description" : "A bright streak flashes from your pointing finger to a point you choose within range and then blossoms with a low roar into an explosion of flame. Each creature in a 20-foot-radius sphere centered on that point must make a Dexterity saving throw. A target takes 8d6 fire damage on a failed save, or half as much damage on a successful one. The fire spreads around corners. It ignites flammable objects in the area that arent being worn or carried. At Higher Levels. When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 3rd.",
"duration" : "Instantaneous",
"level" : "3rd",
"range" : "150 feet",
"school" : "Evocation",
"ritual" : false
}
}
}

View File

@ -0,0 +1,82 @@
{
"json":{
"resources/starWars/swcharacters.json" : {},
"resources/games/hexGames.json": {},
"resources/games/monopolyGames.json": {},
"resources/users.json" : {},
"resources/games/games.json" : {
"trivia questions":{},
"blackjack games":{},
"4 in a row games": {}
},
"resources/lookup/spells.json" : {
"Fireball" : {
"casting_time" : "1 action",
"components" : "V, S, M (a tiny ball of bat guano and sulfur)",
"description" : "A bright streak flashes from your pointing finger to a point you choose within range and then blossoms with a low roar into an explosion of flame. Each creature in a 20-foot-radius sphere centered on that point must make a Dexterity saving throw. A target takes 8d6 fire damage on a failed save, or half as much damage on a successful one. The fire spreads around corners. It ignites flammable objects in the area that arent being worn or carried. At Higher Levels. When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 3rd.",
"duration" : "Instantaneous",
"level" : "3rd",
"range" : "150 feet",
"school" : "Evocation",
"ritual" : false
}
},
"resources/lookup/monsters.json" : [
{
"name": "Bandit",
"size": "Medium",
"type": "humanoid",
"subtype": "any race",
"alignment": "any non-lawful alignment",
"armor_class": 12,
"hit_points": 11,
"hit_dice": "2d8",
"speed": "30 ft.",
"strength": 11,
"dexterity": 12,
"constitution": 12,
"intelligence": 10,
"wisdom": 10,
"charisma": 10,
"damage_vulnerabilities": "",
"damage_resistances": "",
"damage_immunities": "",
"condition_immunities": "",
"senses": "passive Perception 10",
"languages": "any one language (usually Common)",
"challenge_rating": "1/8",
"actions": [
{
"name": "Scimitar",
"desc": "Melee Weapon Attack: +3 to hit, reach 5 ft., one target. Hit: 4 (1d6 + 1) slashing damage.",
"attack_bonus": 3,
"damage_dice": "1d6",
"damage_bonus": 1
},
{
"name": "Light Crossbow",
"desc": "Ranged Weapon Attack: +3 to hit, range 80 ft./320 ft., one target. Hit: 5 (1d8 + 1) piercing damage.",
"attack_bonus": 3,
"damage_dice": "1d8",
"damage_bonus": 1
}
]
}
]
},
"txt": {
"resources/starWars/destinyPoints.txt": "",
"resources/movies.txt": "The Room",
"resources/names.txt": "Gandalf",
"token.txt" : "Write token here"
},
"folder" : [
"resources/games/blackjackTables",
"resources/games/4InARowBoards",
"resources/games/hexBoards",
"resources/games/oldImages",
"resources/games/blackjackCards",
"resources/games/hilo",
"resources/games/monopolyBoards"
]
}