Commit code, circa 2010

This commit is contained in:
2026-05-18 12:28:52 -04:00
commit cc96cffe8e
4 changed files with 651 additions and 0 deletions

421
1eHitChart.py Executable file
View File

@@ -0,0 +1,421 @@
#!/usr/bin/python
import string
import sys
import getopt
# THACO charts for character classes and monstrous races
# [class name, THAC0 at 1st level, 2nd level, .... 20th
# level]
brief = False
thaco_charts = {
"fighter": [ 20, 20,
18, 18,
16, 16,
14, 14,
12, 12,
10, 10,
8, 8,
6, 6,
4, 4,
2, 2],
"paladin" : [ 20, 20,
18, 18,
16, 16,
14, 14,
12, 12,
10, 10,
8, 8,
6, 6,
4, 4,
2, 2],
"ranger" : [ 20, 20,
18, 18,
16, 16,
14, 14,
12, 12,
10, 10,
8, 8,
6, 6,
4, 4,
2, 2],
"bard" : [ 20, 20,
18, 18,
16, 16,
14, 14,
12, 12,
10, 10,
8, 8,
6, 6,
4, 4,
2, 2],
"cleric" : [ 20, 20, 20,
18, 18, 18,
16, 16, 16,
14, 14, 14,
12, 12, 12,
10, 10, 10,
9, 9],
"druid" : [ 20, 20, 20,
18, 18, 18,
16, 16, 16,
14, 14, 14,
12, 12, 12,
10, 10, 10,
9, 9],
"monk" : [ 20, 20, 20,
18, 18, 18,
16, 16, 16,
14, 14, 14,
12, 12, 12,
10, 10, 10,
9, 9],
"magic user" : [20, 20, 20, 20, 20,
19, 19, 19, 19, 19,
16, 16, 16, 16, 16,
13, 13, 13, 13, 13],
"illusionist" :[20, 20, 20, 20, 20,
19, 19, 19, 19, 19,
16, 16, 16, 16, 16,
13, 13, 13, 13, 13],
"thief" : [ 20, 20, 20, 20,
19, 19, 19, 19,
16, 16, 16, 16,
14, 14, 14, 14,
12, 12, 12, 12],
"assassin" : [ 20, 20, 20, 20,
19, 19, 19, 19,
16, 16, 16, 16,
14, 14, 14, 14,
12, 12, 12, 12],
"monster" : [ 19,
16, 16, 16,
15, 15,
13, 13,
12, 12,
10, 10,
9, 9,
8, 8,
7, 7, 7, 7]}
melee_weapon_charts = [
# name AC 10 to 2 (from 10 to 2)
["unarmed", 4, 0, 2, 0, 0, -1, -3, -5, -7],
["battle axe", 2, 1, 1, 0, 0, -1, -2, -2, -2],
["hand axe", 1, 1, 1, 0, 0, -1, -2, -2, -2],
["bardiche", 3, 2, 2, 1, 1, 0, 0, -1, -2],
["bec de corbin",
-1, 0, 0, 0, 0, 0, 2, 2, 2],
["bill-guisarme",
0, 0, 1, 0, 0, 0, 0, 0, 0],
["bo stick", 3, 0, 1, 0, -1, -3, -5, -7, -9],
["club", 1, 0, 0, -1, -1, -2, -3, -4, -5],
["dagger", 3, 1, 1, 0, 0, -2, -2, -3, -3],
["fauchard", -1, 1, 0, 0, 0, -1, -1, -2, -2],
["fauchard-fork",
1, 0, 1, 0, 0, 0, -1, -1, -1],
["footman's flail",
-1, 1, 1, 1, 1, 2, 1, 2, 2],
["horseman's flail",
0, 1, 1, 1, 0, 0, 0, 0, 0],
["military fork",
1, 0, 1, 1, 0, 0, -1, -2, -2],
["glaive", 0, 0, 0, 0, 0, 0, 0, -1, -1],
["glaive-guisarme",
0, 0, 0, 0, 0, 0, 0, -1, -1],
["guisarme", -1, -1, 0, 0, 0, -1, -1, -2, -2],
["guisarme-voulge",
0, 0, 0, 1, 1, 1, 0, -1, -1],
["halberd", 0, 1, 1, 2, 2, 2, 1, 1, 1],
["lucern hammer",
0, 0, 1, 1, 2, 2, 2, 1, 1],
["hammer", 0, 0, 0, 0, 0, 1, 0, 1, 0],
["jo stick", 2, 0, 1, 0, -1, -2, -4, -6, -8],
["heavy lance", 0, 0, 1, 1, 2, 2, 2, 3, 3],
["light lance", 0, 0, 0, 0, 0, 0, -1, -2, -2],
["medium lance",0, 0, 0, 0, 1, 1, 1, 1, 0],
["footman's mace",
-1, 1, 0, 0, 0, 0, 0, 1, 1],
["horseman's mace",
0, 0, 0, 0, 0, 0, 0, 1, 1],
["morning star",2, 2, 1, 1, 1, 1, 1, 1, 0],
["partisan", 0, 0, 0, 0, 0, 0, 0, 0, 0],
["military footman's pick",
-2, -1, -1, -1, 0, 1, 1, 2, 2],
["military horseman's pick",
-1, -1, -1, 0, 0, 1, 1, 1, 1],
["awl pike", -2, -1, 0, 0, 0, 0, 0, 0, -1],
["ranseur", 1, 0, 0, 0, 0, 0, -1, -1, -2],
["scimitar", 3, 1, 1, 0, 0, -1, -2, -2, -3],
["spear", 0, 0, 0, 0, 0, -1, -1, -1, -2],
["spetum", 2, 1, 0, 0, 0, 0, 0, -1, -2],
["quarter staff",
1, 1, 1, 0, 0, -1, -3, -5, -7],
["bastard sword",
0, 1, 1, 1, 1, 1, 1, 0, 0],
["broad sword", 2, 1, 1, 1, 0, 0, -1, -2, -3],
["long sword", 2, 1, 0, 0, 0, 0, 0, -1, -2],
["short sword", 2, 0, 1, 0, 0, 0, -1, -2, -3],
["two handed sword",
0, 1, 3, 3, 3, 2, 2, 2, 2],
["trident", 1, 0, 1, 0, 0, -1, -1, -2, -3],
["voulge", 0, 0, 0, 1, 1, 1, 0, -1, -1],
# placeholder...
["", 0, 0, 0, 0, 0, 0, 0, 0, 0]]
ranged_weapon_charts = [
["hand axe", 1, 0, 0, 0, -1, -1, -2, -3, -4],
["composite long bow",
3, 3, 2, 2, 1, 0, 0, -1, -2],
["composite short bow",
3, 2, 2, 2, 1, 0, -1, -3, -3],
["long bow", 3, 3, 3, 3, 2, 1, 0, 0, -1],
["short bow", 2, 2, 2, 1, 0, 0, -1, -4, -5],
["club", 0, 0, -1, -1, -1, -2, -3, -5, -7],
["heavy crossbow",
4, 4, 4, 3, 3, 2, 1, 0, -1],
["light crossbow",
3, 3, 3, 2, 1, 0, 0, -1, -2],
["dagger", 1, 0, 0, -1, -1, -2, -3, -4, -5],
["dart", 1, 0, 1, 0, -1, -2, -3, -4, -5],
["hammer", 1, 0, 0, 0, 0, 0, 0, -2, -2],
["javelin", 1, 0, 1, 0, -1, -2, -3, -4, -5],
["sling w/bullet",
3, 1, 2, 0, 0, 0, -1, -2, -2],
["sling w/stone",
3, 1, 2, 0, 0, -1, -2, -4, -5],
["spear", 0, 0, 0, 0, -1, -2, -2, -3, -3]]
strength_bonuses = [ 0, 0, 0, -3, -2, -2,
-1, -1, 0, 0, 0,
0, 0, 0, 0, 0,
0, 1, 1]
strength_bonuses_18 = { 50 : 1, 75: 2, 90 : 2, 99 : 2, 100: 3}
dexterity_bonuses = [ 0, 0, 0, -3, -2, -1,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 2, 3]
def findWeapon(type, name):
wlist = []
if ( type == "ranged" ):
wlist = ranged_weapon_charts
elif ( type == "melee" ):
wlist = melee_weapon_charts
else :
return []
for weapon in wlist:
#print "trying weapon %s (%s) against name %s" % (weapon, weapon[0], name)
if ( weapon[0].lower() == name.lower() ):
return weapon
return []
def strBonus(strength):
percent = 0
if ( string.find(str(type(strength)), "str") != -1) :
if ( strength.find("/") != -1):
tlist = strength.split("/")
percent = int(tlist[1])
if ( percent == 0 ) :
percent = 100
for perc in strength_bonuses_18.keys():
if ( perc >= percent ):
return strength_bonuses_18[perc]
else:
# print "recursing with strength %d..." % int(strength)
return strBonus(int(strength.strip()))
else:
if ( strength <= 17):
# print "trying to return from strength_bonuses (len %d ) %d" % (len(strength_bonuses), strength)
return strength_bonuses[strength-1]
if ( strength >= 19):
return strength_bonuses_18[100] + ((strength-19)/2)
return 0
def dexBonus(score):
# print "trying to return from dexterity_bonuses ( len %d ) %d" % (len(dexterity_bonuses), score)
if ( score <= 18):
return dexterity_bonuses[score]
else :
return dexterity_bonuses[18] + (score-18)
class character :
weapons = []
strength = 0
dexterity = 0
charts = {}
chartSteps = {}
pclass = ""
level = 0
def __init__ (self, className, str, dex, level):
self.pclass = className
self.level = level
self.weapons = []
self.strength = str
self.dexterity = dex
self.charts = {}
self.chartSteps = {}
# work out the THAC0 chart
THAC0chart = []
baseTHAC0 = thaco_charts[self.pclass][self.level]
for i in range(2, 11):
THAC0chart.append(baseTHAC0 - i)
#print "wrote thac0 chart %s" % THAC0chart
self.charts["Base To Hit"] = THAC0chart
def chartWeapon(self, weaponInfo):
"""chart a weapon for THACO given its type
and name"""
self.chartSteps[weaponInfo[1]] = {}
weaponModifiers = findWeapon(weaponInfo[0], weaponInfo[1])
weaponModifiers.reverse()
if ( len(weaponModifiers) == 0):
self.chartSteps[weaponInfo[1]]["base weapon modifiers"] = "Unable to chart %s" % weaponInfo[1]
return
else:
self.chartSteps[weaponInfo[1]]["base weapon modifiers"] = weaponModifiers[:9]
newChart = []
thacoChart = self.charts["Base To Hit"]
#print "weaponModifiers is : %s", str(weaponModifiers)
for ac in range(0, 9):
#print "trying ac of %d and modifier of %d : length of weaponModifiers is %d, THAC0 is %d" % (ac, ac, len(weaponModifiers), len(thacoChart))
newChart.append( thacoChart[ac] + -weaponModifiers[ac])
self.chartSteps[weaponInfo[1]]["applied to base THAC0"] = newChart
newestChart = []
for ac in newChart:
if ( weaponInfo[0] == "ranged"):
newestChart.append(ac + -dexBonus(self.dexterity))
else:
newestChart.append(ac + -strBonus(self.strength))
self.chartSteps[weaponInfo[1]]["after ability bonuses"] = newestChart
self.charts[weaponInfo[1]] = newestChart
weaponModifiers.reverse()
return 0
def printChart(self, weapName, chart, fileHandle, makeDashes = False):
printedChart = string.center(weapName, 30)
# print "chart is %d elements long : %s" % (len(chart), str(chart))
for ac in range(0, 9):
if ( chart[ac] <= 0 and makeDashes):
chart[ac] = "-"
printedChart += string.center(str(chart[ac]), 4)
printedChart += "\n"
fileHandle.write(printedChart)
def writeCharts(self, fileHandle):
global brief
for weapon in self.weapons:
self.chartWeapon(weapon)
ACChart = string.center("1st Edition AD&D To Hit Charts", 70) + "\n"
ACChart += string.center("%d level %s : strength %s (to hit +%d) dexterity %d ( RAA +%d)" % (self.level, self.pclass,
self.strength, strBonus(self.strength), self.dexterity, dexBonus(self.dexterity)), 70) + "\n\n"
ACChart += " "*30 + string.center("OPPONENT ARMOR CLASS", 40) + "\n"
ACChart += string.center("WEAPON", 30)
for ac in range(2, 11):
ACChart += string.center(str(ac), 4)
ACChart += "\n"
fileHandle.write(ACChart)
fileHandle.write("="*70 + "\n")
thecharts = self.charts.keys()
thecharts.sort()
for chart in thecharts:
self.printChart(chart.upper(), self.charts[chart], fileHandle, True)
#print "brief was %s" % str(brief)
if ( (chart != "Base To Hit") and (not brief)):
self.printChart("(Base To Hit)", self.charts["Base To Hit"], fileHandle)
self.printChart("(base modifiers)", self.chartSteps[chart]["base weapon modifiers"], fileHandle)
self.printChart("(applied to Base To Hit)", self.chartSteps[chart]["applied to base THAC0"], fileHandle)
self.printChart("(after ability bonuses)", self.chartSteps[chart]["after ability bonuses"], fileHandle)
if ( not brief) :
fileHandle.write("\n")
if ( not brief):
fileHandle.write("\n" + string.center("For ACs below 2, add that much to the indicated difficulty.", 70) + "\n")
fileHandle.write("\n" + string.center("A difficulty of \"-\" indicates that you can only miss", 70) + "\n" + string.center("this armor class with the given weapon on a botch.", 70) + "\n")
def main(argc, argv):
global brief
longopts = ["class=", "level=", "strength=",
"dexterity=", "ranged=", "melee=", "help",
"brief", "weaponlist"]
shortopts = "c:l:s:d:r:m:hbw"
usage = """
1eHitChart.py (2006 Gamecube)
usage: 1eHitChart.py <options>
options:
--class | -c : class name
--level | -l : level number
--strength | -s : strength score
--dexterity | -d : dexterity score
--ranged | -r : ranged weapons; use a comma
separated list
--melee | -m : melee weapons; use a comma
separated list
--brief | -b : do not print an explanatory
verbose summary; just print
the charts.
--weaponlist | -w : print out a list of all
weapons this program recognises
--help | -h : this help
"""
pclass = ""
level = 0
strength = ""
dexterity = 0
weapons = []
#print "got sys.argv %s" % str(sys.argv)
opts, args = getopt.getopt(argv[1:], shortopts, longopts)
#print "got opts %s args %s" % ( str(opts), str(args))
for pair in opts:
#print "checking pair %s" % str(pair)
if (pair[0] == "--class" or pair[0] == "-c"):
pclass = pair[1]
elif ( pair[0] == "--level" or pair[0] == "-l"):
level = int(pair[1])
elif ( pair[0] == "--strength" or pair[0] == "-s"):
strength = pair[1]
elif ( pair[0] == "--dexterity" or pair[0] == "-d"):
dexterity = int(pair[1])
elif ( pair[0] == "--ranged" or pair[0] == "-r"):
for item in pair[1].split(","):
weapons.append(["ranged", item.strip()])
elif ( pair[0] == "--melee" or pair[0] == "-m"):
for item in pair[1].split(","):
weapons.append(["melee", item.strip()])
elif ( pair[0] == "--help" or pair[0] == "-h"):
print usage
sys.exit(1)
elif ( pair[0] == "--brief" or pair[0] == "-b"):
brief = True
elif ( pair[0] == "--weaponlist" or pair[0] == "-w"):
print "Valid melee weapons:"
for i in range(0, len(melee_weapon_charts), 3):
print "%s%s%s" % ( string.center(melee_weapon_charts[i][0], 70/3), string.center(melee_weapon_charts[i+1][0], 70/3), string.center(melee_weapon_charts[i+2][0], 70/3))
print "\nValid ranged weapons:"
for i in range(0, len(ranged_weapon_charts), 3):
print "%s%s%s" % ( string.center(ranged_weapon_charts[i][0], 70/3), string.center(ranged_weapon_charts[i+1][0], 70/3), string.center(ranged_weapon_charts[i+2][0], 70/3))
sys.exit(0)
if ( not strength or not dexterity or not pclass or not level):
print usage
sys.exit(1)
#print "Trying with pclass %s level %d strength %s dex %d weapons %s" % (pclass, level, strength, dexterity, weapons)
pc = character(pclass, strength, dexterity, level)
pc.weapons = weapons
pc.writeCharts(sys.stdout)
#pc.weapons = [["ranged", "long bow"], ["melee", "long sword"]]
#pc.writeCharts(sys.stdout)
if ( __name__ == "__main__" ):
main(len(sys.argv), sys.argv)

69
addcurrconv Executable file
View File

@@ -0,0 +1,69 @@
#!/usr/bin/python
silverval = 0.0
fpp = 0.0
fgp = 0.0
fsp = 0.0
fcp = 0.0
fdol = 0.0
def getInput():
return raw_input(">> ")
print "AD&D Currency Converter - Converts between real and AD&D currency"
print "Enter a monetary value followed by the currency (dollars, gp, sp, cp, pp)"
print "Enter \"q\" by itself to quit."
print "Enter \"s <new value of a silver piece in modern dollars>\""
print " to set the value of silver."
while 1 :
value = getInput()
vlist = value.split(" ")
if vlist[0].isdigit() :
oldval = int(vlist[0])
if vlist[1].lower() == "gp":
fgp = oldval
fsp = fgp * 10
fcp = fsp * 10
fpp = fgp / 10
fdol = fsp * silverval
elif vlist[1].lower() == "sp":
fsp = oldval
fgp = fsp / 10
fcp = fsp * 10
fpp = fgp / 10
fdol = fsp * silverval
elif vlist[1].lower() == "cp":
fcp = oldval
fsp = fcp / 10
fgp = fsp / 10
fpp = fgp / 10
fdol = fsp * silverval
elif vlist[1].lower() == "dollars":
fsp = oldval / silverval
fcp = fsp * 10
fgp = fsp / 10
fpp = fgp / 10
else:
print "I didn't understand."
continue
print vlist[0], vlist[1], " converts to:"
print "\t", fpp, " platinum (or)"
print "\t", fgp, " gold pieces (or)"
print "\t", fsp, " silver pieces (or)"
print "\t", fcp, " copper pieces (or)"
print "\t", fdol, " dollars"
elif vlist[0].lower() == "q":
break
elif vlist[0].lower() == "s":
if vlist[1].isdigit():
silverval = int(vlist[1])
print "silver value set to : ", silverval
else :
print "Please provide a numeric value as the second argument to the"
print " \"s\" command."
else:
print "I didn't understand."
continue

102
giveStats Executable file
View File

@@ -0,0 +1,102 @@
#!/usr/bin/python
import random
import string
import getopt
import sys
def total(s):
toReturn =0
for i in s:
toReturn += int(string.strip(string.split(i)[0]))
return toReturn
def cloneArray(a):
b = []
for x in a:
b.append(x)
return b
def average(s):
toReturn =0
for i in s:
toReturn += i
return toReturn/len(s)
def allAboveTen(s):
#print "allAboveTen got ", str(s)
for i in s:
score = i
if ( score < 10):
#print "score was below ten : ", score
return False
return True
def suggest(l):
x = cloneArray(l)
s = []
for i in x:
s.append(int(string.strip(string.split(i)[0])))
if ( average(s[0:3]) > average(s[3:6]) and
average(s[0:3]) > average([s[1], s[3], s[4]]) ):
if ( s[5] > 15 and (average([s[2], s[1], s[3]]) < 13)):
return "Paladin"
elif ( average([s[2], s[1], s[3]]) > 13 and
s[4] > 12 ):
return "Ranger"
return "Fighter"
elif ( average(s[0:3]) > average(s[3:6]) and
average(s[0:3]) < average([s[1], s[3], s[4]]) ):
return "Rogue"
elif ( average(s[0:3]) < average(s[3:6]) ):
if ( s[3] > s[5] and s[3] > s[4] ):
return "Wizard"
elif ( s[3] > s[5] and s[3] < s[4]
and average([s[4], s[5], s[0]]) > 12):
return "Cleric"
elif ( s[3] < s[5]):
return "Sorceror"
return "Spellcaster"
elif ( average(s) < 11):
return "Slaad bait"
else:
return "No suggestion"
def signIntStr(i):
if ( i <= 9 ) :
return " " + str((i-10)/2)
else:
return " +" + str((i-10)/2)
if ( __name__ == "__main__" ):
sets = []
abilities = ["strength", "dexterity", "constitution", "intelligence", "wisdom", "charisma"]
currTotal = 0
currNum = 0
for setnum in range(0,3):
sets.append([])
currTotal = 0
for i in range(0,6):
if ( sys.argv.count("-a") > 0 or sys.argv.count("--aboveAverage") > 0):
while ( currNum < 9 ):
currNum = random.choice(range(3,18))
else:
currNum = random.choice(range(3,18))
sets[setnum].append(string.center(str(currNum) + signIntStr(currNum), 15))
currTotal += currNum
currNum = 0
sets[setnum].append(string.center(str(currTotal), 15))
print " "*20 + string.center(suggest(sets[0]), 15) + string.center(suggest(sets[1]), 15) + string.center(suggest(sets[2]), 15)
for i in range(0,6):
print string.center(abilities[i], 20) + sets[0][i] + sets[1][i] + sets[2][i]
print "-"*65
print string.center("totals", 20) + sets[0][6] + sets[1][6] + sets[2][6]

59
spellbook.py Executable file
View File

@@ -0,0 +1,59 @@
#!/usr/bin/python
import sys
import random
def main(argc, argv):
if ( argc < 2 ):
print "usage: spellbook <max_spell_level> <total_spells>"
print " pass =max_spell_level to generate total_spells all of"
print " level (max_spell_level). You can also pass =[x,x] to"
print " pass a list of spell levels."
return 1
minlevel = 1
tlist = None
if ( "=" in argv[1]):
if ( "," in argv[1]):
tlist = argv[1].strip("=").strip("[").strip("]").split(",")
for i in range(0, len(tlist)):
tlist[i] = int(tlist[i])
else:
tmp = argv[1].strip("=").strip()
minlevel = int(tmp)
maxlevel = int(tmp)
#print "Min level : %d Max level : %d" % (minlevel, maxlevel)
else:
maxlevel = int(argv[1])
total = int(argv[2])
PHBSpells = { 1: 30, 2: 24, 3: 34, 4: 24, 5: 24, 6: 24, 7: 16, 8: 16, 9: 12}
choices = [True, False]
spellLevels = {}
if ( tlist ) :
for i in range(0, total):
level = random.choice(tlist)
snum = random.choice(range(1, PHBSpells[level]+1))
if ( spellLevels.has_key(level)):
spellLevels[level].append(snum)
else:
spellLevels[level] = []
spellLevels[level].append(snum)
else:
for i in range(0, total):
#if ( random.choice(choices) ):
level = random.choice(range(minlevel, maxlevel+1))
snum = random.choice(range(1, PHBSpells[level]+1))
if ( spellLevels.has_key(level) ):
spellLevels[level].append(snum)
else:
spellLevels[level] = []
spellLevels[level].append(snum)
for i in range(1, 10):
if ( spellLevels.has_key(i) ):
spells = spellLevels[i]
spells.sort()
print "LEVEL %d : %s" % (i, str(spells))
if ( __name__ == "__main__" ):
main(len(sys.argv), sys.argv)