Skip to content

Instantly share code, notes, and snippets.

@bferguson3
Last active August 14, 2025 17:02
Show Gist options
  • Save bferguson3/2159fd4b5a0a7f5a70e28a791185c311 to your computer and use it in GitHub Desktop.
Save bferguson3/2159fd4b5a0a7f5a70e28a791185c311 to your computer and use it in GitHub Desktop.
Sword World dice bot v02
# Sword World dice bot
#
# commands: !h[elp], !r[oll], !c[rit], !s[trike], !d[efense]
#
# (c)2025 bferguson3 @ github
import discord,os,random,re,math
intents = discord.Intents.all()
client = discord.Client(command_prefix="!", intents=intents)
users_list = []
class DiceUser():
def __init__(self, username="", crit=12):
self.username = username
self.crit = crit
###
###
strike_table=[
[0,0,0,1,2,2,3,3,4,4],
[0,0,0,1,2,2,3,3,4,4],
[0,0,0,1,2,3,4,4,4,4],
[0,0,1,1,2,3,4,4,4,5],
[0,0,1,2,2,3,4,4,5,5],
[0,1,1,2,2,3,4,5,5,5],
[0,1,1,2,3,3,4,5,5,5],
[0,1,1,2,3,4,4,5,5,6],
[0,1,2,2,3,4,4,5,6,6],
[0,1,2,3,3,4,4,5,6,7],
[1,1,2,3,3,4,5,5,6,7],
[1,2,2,3,3,4,5,6,6,7],
[1,2,2,3,4,4,5,6,6,7],
[1,2,3,3,4,4,5,6,7,7],
[1,2,3,4,4,4,5,6,7,8],
[1,2,3,4,4,5,5,6,7,8],
[1,2,3,4,4,5,6,7,7,8],
[1,2,3,4,5,5,6,7,7,8],
[1,2,3,4,5,6,6,7,7,8],
[1,2,3,4,5,6,7,7,8,9],
[1,2,3,4,5,6,7,8,9,10],
[1,2,3,4,6,6,7,8,9,10],
[1,2,3,5,6,6,7,8,9,10],
[2,2,3,5,6,7,7,8,9,10],
[2,3,4,5,6,7,7,8,9,10],
[2,3,4,5,6,7,8,8,9,10],
[2,3,4,5,6,8,8,9,9,10],
[2,3,4,6,6,8,8,9,9,10],
[2,3,4,6,6,8,9,9,10,10],
[2,3,4,6,7,8,9,9,10,10],
[2,4,4,6,7,8,9,10,10,10],
[2,4,5,6,7,8,9,10,10,11],
[3,4,5,6,7,8,10,10,10,11],
[3,4,5,6,8,8,10,10,10,11],
[3,4,5,6,8,9,10,10,11,11],
[3,4,5,7,8,9,10,10,11,12],
[3,5,5,7,8,9,10,11,11,12],
[3,5,6,7,8,9,10,11,12,12],
[3,5,6,7,8,10,10,11,12,13],
[4,5,6,7,8,10,11,11,12,13],
[4,5,6,7,9,10,11,11,12,13],
[4,6,6,7,9,10,11,12,12,13],
[4,6,7,7,9,10,11,12,13,13],
[4,6,7,8,9,10,11,12,13,14],
[4,6,7,8,10,10,11,12,13,14],
[4,6,7,9,10,10,11,12,13,14],
[4,6,7,9,10,10,12,13,13,14],
[4,6,7,9,10,11,12,13,13,15],
[4,6,7,9,10,12,12,13,13,15],
[4,6,7,10,10,12,12,13,14,15],
[4,6,8,10,10,12,12,13,15,15],
[5,7,8,10,10,12,12,13,15,15],
[5,7,8,10,11,12,12,13,15,15],
[5,7,9,10,11,12,12,14,15,15],
[5,7,9,10,11,12,13,14,15,16],
[5,7,10,10,11,12,13,14,16,16],
[5,8,10,10,11,12,13,15,16,16],
[5,8,10,11,11,12,13,15,16,17],
[5,8,10,11,12,12,13,15,16,17],
[5,9,10,11,12,12,14,15,16,17],
[5,9,10,11,12,13,14,15,16,18],
[5,9,10,11,12,13,14,16,17,18],
[5,9,10,11,13,13,14,16,17,18],
[5,9,10,11,13,13,15,17,17,18],
[5,9,10,11,13,14,15,17,17,18],
[5,9,10,12,13,14,15,17,18,18],
[5,9,10,12,13,15,15,17,18,19],
[5,9,10,12,13,15,16,17,19,19],
[5,9,10,12,14,15,16,17,19,19],
[5,9,10,12,14,16,16,17,19,19],
[5,9,10,12,14,16,17,18,19,19],
[5,9,10,13,14,16,17,18,19,20],
[5,9,10,13,15,16,17,18,19,20],
[5,9,10,13,15,16,17,19,20,21],
[6,9,10,13,15,16,18,19,20,21],
[6,9,10,13,16,16,18,19,20,21],
[6,9,10,13,16,17,18,19,20,21],
[6,9,10,13,16,17,18,20,21,22],
[6,9,10,13,16,17,19,20,22,23],
[6,9,10,13,16,18,19,20,22,23],
[6,9,10,13,16,18,20,21,22,23],
[6,9,10,13,17,18,20,21,22,23],
[6,9,10,14,17,18,20,21,23,24],
[6,9,11,14,17,18,20,21,23,24],
[6,9,11,14,17,19,20,21,23,24],
[6,9,11,14,17,19,21,22,23,24],
[7,10,11,14,17,19,21,22,23,25],
[7,10,12,14,17,19,21,22,24,25],
[7,10,12,14,18,19,21,22,24,25],
[7,10,12,15,18,19,21,22,24,26],
[7,10,12,15,18,19,21,23,25,26],
[7,11,13,15,18,19,21,23,25,26],
[7,11,13,15,18,20,21,23,25,27],
[8,11,13,15,18,20,22,23,25,27],
[8,11,13,16,18,20,22,23,25,28],
[8,11,14,16,18,20,22,23,26,28],
[8,11,14,16,19,20,22,23,26,28],
[8,12,14,16,19,20,22,24,26,28],
[8,12,15,16,19,20,22,24,27,28],
[8,12,15,17,19,20,22,24,27,29],
[8,12,15,18,19,20,22,24,27,30]
]
@client.event
async def on_ready():
print("We have logged in as {0.user}".format(client))
crit_target = 12
@client.event
async def on_message(message):
random.seed()
global crit_target
if message.author == client.user:
return
if message.content.lower().startswith("!r"):
try: # split at the "d":
if message.content.lower().find("d") != -1:
die = message.content.lower().split("d")[0]
die = die.split(" ")[1] # split at the space
mod = 0 # catch + or -
if message.content.find("+") != -1:
mod = int(message.content.split("+")[1])
if message.content.find("-") != -1:
mod = int(message.content.split("-")[1]) * -1
roll = []
tot = 0
die = float(die)
if(math.floor(die) != die):
if message.content.find(".5") == -1: # validation: ".5" strings only
await message.channel.send("Error: only use 0.5 die increments!")
return
roll.append(random.randint(1, 3))
tot += roll[len(roll)-1]
die = math.floor(die) # cast to int
while die > 0:
roll.append(random.randint(1, 6))
tot += roll[len(roll)-1]
die -= 1
if(len(roll) == 2):
if(tot == 2):
await message.channel.send("Auto-fail!! (1, 1)")
return
if(tot == 12):
await message.channel.send("Auto-success!! (6, 6)")
return
msg = "Result: " + str(tot + mod) + " ("
for r in roll:
msg += str(r) + ", "
msg = msg[:len(msg)-2]
msg += " + " + str(mod) + ")"
await message.channel.send(msg)
else:
await message.channel.send("Use dice format: xd+n")
except Exception as e:
await message.channel.send("Use dice format: xd+n")
###
elif message.content.lower().startswith("!s"):
try:
sp = int(re.sub('\\D','',message.content.lower()))
if (sp < 0) or (sp > 100):
await message.channel.send("Strike range is between 0-100")
return
roll = random.randint(1, 6)
roll += random.randint(1, 6)
if roll == 2:
await message.channel.send("Miss!! (Auto-fail)")
return
bonus_dmg = 0
msg = ""
burst = False
_fnd = False
for u in users_list:
if message.author.display_name == u.username:
_fnd = True
crit_target = u.crit
if _fnd == False:
users_list.append(DiceUser(username=message.author.display_name, crit=12))
crit_target = 12
if roll >= crit_target:
msg += "Critical! "
f = random.randint(1, 6) + random.randint(1, 6)
bonus_dmg += strike_table[sp][f - 3]
while(f >= crit_target):
msg += "Bursting!! "
burst = True
f = random.randint(1, 6) + random.randint(1, 6)
if(f == 2):
break
bonus_dmg += strike_table[sp][f - 3]
roll -= 3 # range of 0-9
v = strike_table[sp][roll]
await message.channel.send("Damage: " + msg + str(v + bonus_dmg) + " (rolled " + str(roll+3) + ")")
except Exception as e:
await message.channel.send("Not a valid number?", e)
###
elif message.content.lower().startswith("!d"):
try:
sp = int(re.sub('\\D','',message.content.lower()))
if (sp < 0) or (sp > 100):
await message.channel.send("Defense range is between 0-100")
return
roll = random.randint(1, 6)
roll += random.randint(1, 6)
if roll == 2:
await message.channel.send("Zero!! (Auto-fail)")
return
bonus_dmg = 0
msg = ""
roll -= 3 # range of 0-9
v = strike_table[sp][roll]
await message.channel.send("Defense: " + msg + str(v + bonus_dmg) + " (rolled " + str(roll+3) + ")")
except Exception as e:
await message.channel.send("Not a valid number?", e)
###
elif message.content.lower().startswith("!c"):
crit_target = int(re.sub('\\D','',message.content.lower()))
_aut = message.author.display_name
_found = False
for u in users_list:
if u.username == _aut:
_found = True
u.crit = crit_target
break
if _found == False:
_new = DiceUser()
_new.username = _aut
_new.crit = crit_target
users_list.append(_new)
await message.channel.send(_aut + ", critical target set to " + str(crit_target))
###
elif message.content.lower().startswith("!h"):
await message.channel.send("To use:\n!r or !roll *x*d+*n* to roll dice\n!s or !strike *n* to do a strike check (!d/efend for defense check)\n!c or !crit to set the current critical num\n!h or !help to see this text\n")
###
f = open("discord_bot_key.txt", "r")
key = f.read()
f.close()
client.run(key)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment