making the ui nicer

This commit is contained in:
Zachary Watts
2026-04-28 16:12:21 -04:00
parent 0ca25f9f91
commit dad1a4c588
12 changed files with 207 additions and 31 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,7 @@
#!/usr/bin/python3
import random
from equipment import *
from spells import *
# functions
def roll_dice(count, sides):
@@ -22,7 +23,7 @@ class Adventurer:
self.gold= roll_dice(3,6)
self.torches = roll_dice(1,6)
self.rations = roll_dice(1,6)
self.equipment = [ 'backpack', 'tinderbox', 'waterskin' ]
self.equipment = self.roll_equipment()
# all armor, individual classes may have overrides
self.possible_armor = list(armor.keys())
# all weapons, individual classes may have overrides
@@ -32,6 +33,11 @@ class Adventurer:
# each character should get 1 melee and 1 random (missle or melee)
self.weapons = [ random.choice(self.possible_melee_weapons), random.choice(self.possible_weapons) ]
self.armor = random.choice(self.possible_armor)
# special abilities
self.spells = None
self.spell_book = None
self.thief_skills = None
self.turn_undead = None
def __str__(self):
return f"{self.player_class}"
@@ -51,6 +57,9 @@ class Adventurer:
sheet.append('{0: <28}'.format(f"| {self.weapons[0]['name'].title()}"))
sheet.append('{0: <28}'.format(f"| {self.weapons[1]['name'].title()}"))
sheet.append('{0: <28}'.format(f"| Equipment:"))
for item in self.equipment:
item_string = "| " + '{0:22}'.format(f"{item}").title()
sheet += ['{0: <28}'.format(item_string)]
sheet.append('{0: <28}'.format(f"| "))
sheet.append('{0: <28}'.format(f"| Gold: {self.gold}"))
sheet.append('| ------------------------- ')
@@ -58,6 +67,9 @@ class Adventurer:
key_string = "| " + '{0:22}'.format(f"{key}").title() + f" {val}"
sheet += ['{0: <28}'.format(key_string)]
sheet.append('| ------------------------- ')
#if self.spells:
# sheet.append('{0: <28}'.format("| Spellbook: "))
# sheet += ['{0: <28}'.format(f"| {spell.title()}") for spell in self.spell_book ]
# append a | to each string, after the formatted whitespace
sheet = [ line + "|" for line in sheet ]
return sheet
@@ -73,7 +85,24 @@ class Adventurer:
return max(prime_attributes, key=prime_attributes.get)
def roll_equipment(self):
print("testing!")
equipment = [ 'backpack', 'tinderbox', 'waterskin' ]
random_items = [ random.choice(adventuring_gear) for i in range(2) ]
for item in random_items:
equipment += item.split("+")
while len(equipment) < 7:
equipment.append("")
return equipment
def select_spells(self):
spell_book = []
for spell_level, count in self.spells.items():
if count != "-":
for i in range(count):
random_spell = ""
while random_spell not in spell_book:
random_spell = random.choice(magic_user_spells[spell_level])
spell_book.append(random_spell)
return spell_book
class Fighter(Adventurer):
@@ -101,6 +130,7 @@ class Fighter(Adventurer):
self.progression = Fighter.progression
self.hp = roll_dice(self.level, 8)
self.ac = armor[self.armor]
self.vertical_sheet = self.character_sheet()
class MagicUser(Adventurer):
prime_requisite = "intelligence"
@@ -121,6 +151,22 @@ class MagicUser(Adventurer):
{ "level" : 13, "xp" : 900000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death / poison" : 8, "wands" : 9, "paralysis / petrify" : 8, "breath attack" : 8, "spells / rods / staves" : 8 }},
{ "level" : 14, "xp" : 1050000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death / poison" : 8, "wands" : 9, "paralysis / petrify" : 8, "breath attack" : 8, "spells / rods / staves" : 8 }}
]
spells = {
1: { 1: 1, 2: '-', 3: '-', 4: '-', 5: '-', 6: '-'},
2: { 1: 2, 2: '-', 3: '-', 4: '-', 5: '-', 6: '-'},
3: { 1: 2, 2: 1, 3: '-', 4: '-', 5: '-', 6: '-'},
4: { 1: 2, 2: 2, 3: '-', 4: '-', 5: '-', 6: '-'},
5: { 1: 2, 2: 2, 3: 1, 4: '-', 5: '-', 6: '-'},
6: { 1: 2, 2: 2, 3: 2, 4: '-', 5: '-', 6: '-'},
7: { 1: 3, 2: 2, 3: 2, 4: 1, 5: '-', 6: '-'},
8: { 1: 3, 2: 3, 3: 2, 4: 2, 5: '-', 6: '-'},
9: { 1: 3, 2: 3, 3: 3, 4: 2, 5: 1, 6: '-'},
10: { 1: 3, 2: 3, 3: 3, 4: 3, 5: 2, 6: '-'},
11: { 1: 4, 2: 3, 3: 3, 4: 3, 5: 2, 6: 1 },
12: { 1: 4, 2: 4, 3: 3, 4: 3, 5: 2, 6: 1 },
13: { 1: 4, 2: 4, 3: 4, 4: 3, 5: 3, 6: 3 },
14: { 1: 4, 2: 4, 3: 4, 4: 4, 5: 3, 6: 3 }
}
def __init__(self, level, attributes={}) -> None:
Adventurer.__init__(self, level, attributes)
self.player_class = "magic user"
@@ -129,6 +175,9 @@ class MagicUser(Adventurer):
self.armor = "None"
self.ac = armor[self.armor]
self.weapons = [ list(filter(lambda d: 'silver dagger' in d['name'],weapons))[0], { "name" : "" } ]
self.spells = MagicUser.spells[self.level]
self.spell_book = self.select_spells()
self.vertical_sheet = self.character_sheet()
class Cleric(Adventurer):
@@ -150,6 +199,22 @@ class Cleric(Adventurer):
{ "level" : 13, "xp" : 600000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death / poison" : 3, "wands" : 5, "paralysis / petrify" : 7, "breath attack" : 8, "spells / rods / staves" : 7 }},
{ "level" : 14, "xp" : 700000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death / poison" : 3, "wands" : 5, "paralysis / petrify" : 7, "breath attack" : 8, "spells / rods / staves" : 7 }}
]
spells = {
1: { 1: '-', 2: '-', 3: '-', 4: '-', 5: '-'},
2: { 1: 1, 2: '-', 3: '-', 4: '-', 5: '-'},
3: { 1: 2, 2: '-', 3: '-', 4: '-', 5: '-'},
4: { 1: 2, 2: 1, 3: '-', 4: '-', 5: '-'},
5: { 1: 2, 2: 2, 3: '-', 4: '-', 5: '-'},
6: { 1: 2, 2: 2, 3: 1, 4: 1, 5: '-'},
7: { 1: 2, 2: 2, 3: 2, 4: 1, 5: 1 },
8: { 1: 3, 2: 3, 3: 2, 4: 2, 5: 1 },
9: { 1: 3, 2: 3, 3: 3, 4: 2, 5: 2 },
10: { 1: 4, 2: 4, 3: 3, 4: 3, 5: 2 },
11: { 1: 4, 2: 4, 3: 4, 4: 3, 5: 3 },
12: { 1: 5, 2: 5, 3: 4, 4: 4, 5: 3 },
13: { 1: 5, 2: 5, 3: 4, 4: 4, 5: 4 },
14: { 1: 6, 2: 5, 3: 5, 4: 5, 5: 4 }
}
def __init__(self, level, attributes={}) -> None:
Adventurer.__init__(self, level, attributes)
self.player_class = "cleric"
@@ -161,6 +226,9 @@ class Cleric(Adventurer):
self.possible_melee_weapons = list(filter(lambda d: 'blunt' in d['traits'] and 'melee' in d['traits'], weapons))
self.possible_weapons = list(filter(lambda d: 'blunt' in d['traits'], weapons))
self.weapons = [ random.choice(self.possible_melee_weapons), random.choice(self.possible_weapons) ]
self.spells = Cleric.spells[self.level]
self.spell_book = self.select_spells()
self.vertical_sheet = self.character_sheet()
class Thief(Adventurer):
prime_requisite = "dexterity"
@@ -188,6 +256,7 @@ class Thief(Adventurer):
self.hp = roll_dice(self.level, 4)
self.armor = random.choice(list(armor.keys()))
self.ac = armor[self.armor]
self.vertical_sheet = self.character_sheet()
class Dwarf(Adventurer):
prime_requisite = "strength"
@@ -213,6 +282,7 @@ class Dwarf(Adventurer):
self.hp = roll_dice(self.level, 8)
self.armor = random.choice(list(armor.keys()))
self.ac = armor[self.armor]
self.vertical_sheet = self.character_sheet()
class Elf(Adventurer):
prime_requisite = "intellgence"
@@ -229,6 +299,18 @@ class Elf(Adventurer):
{ "level" : 9, "xp" : 400000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death / poison" : 8, "wands" : 9, "paralysis / petrify" : 9, "breath attack" : 10, "spells / rods / staves" : 10 }},
{ "level" : 10, "xp" : 600000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death / poison" : 6, "wands" : 7, "paralysis / petrify" : 8, "breath attack" : 8, "spells / rods / staves" : 8 }}
]
spells = {
1: { 1: 1, 2: '-', 3: '-', 4: '-', 5: '-', 6: '-'},
2: { 1: 2, 2: '-', 3: '-', 4: '-', 5: '-', 6: '-'},
3: { 1: 2, 2: 1, 3: '-', 4: '-', 5: '-', 6: '-'},
4: { 1: 2, 2: 2, 3: '-', 4: '-', 5: '-', 6: '-'},
5: { 1: 2, 2: 2, 3: 1, 4: '-', 5: '-', 6: '-'},
6: { 1: 2, 2: 2, 3: 2, 4: '-', 5: '-', 6: '-'},
7: { 1: 3, 2: 2, 3: 2, 4: 1, 5: '-', 6: '-'},
8: { 1: 3, 2: 3, 3: 2, 4: 2, 5: '-', 6: '-'},
9: { 1: 3, 2: 3, 3: 3, 4: 2, 5: 1, 6: '-'},
10: { 1: 3, 2: 3, 3: 3, 4: 3, 5: 2, 6: '-'}
}
def __init__(self, level, attributes={}) -> None:
Adventurer.__init__(self, level, attributes)
self.player_class = "elf"
@@ -236,6 +318,9 @@ class Elf(Adventurer):
self.hp = roll_dice(self.level, 6)
self.armor = random.choice(list(armor.keys()))
self.ac = armor[self.armor]
self.spells = Elf.spells[self.level]
self.spell_book = self.select_spells()
self.vertical_sheet = self.character_sheet()
class Halfling(Adventurer):
prime_requisite = "dexterity"
@@ -257,3 +342,4 @@ class Halfling(Adventurer):
self.hp = roll_dice(self.level, 6)
self.armor = random.choice(list(armor.keys()))
self.ac = armor[self.armor]
self.vertical_sheet = self.character_sheet()

17
app.py
View File

@@ -1,11 +1,22 @@
#!/usr/bin/python3
from main import *
from flask import Flask, render_template
from flask import Flask, render_template, redirect, request
app = Flask(__name__)
@app.route('/')
def index():
sheets = returnSheets('test')
return render_template("sheet.html", sheets=sheets)
return render_template("index.html")
@app.route('/party', methods = ["GET","POST"])
def party():
if request.method == "GET":
count = request.args.get("count", default=4, type=int)
adv_party = returnParty(count)
return render_template("party_sheet.html", adv_party=adv_party, count=count)
@app.route('/character')
def characters():
adv_party = returnParty(1)
return render_template("party_sheet.html", adv_party=adv_party)

View File

@@ -19,3 +19,7 @@ weapons = [
{ 'name' : 'war hammer', 'damage-dice' : 6, 'traits' : [ 'melee', 'blunt' ] }
]
adventuring_gear = [
"crowbar", "hammer (small)+12 iron spikes", "holy water", "lantern+3 flasks of oil", "mirror (small, steel)", "pole (10' long, wooden)",
"rope (50')", "rope (50')+grappling hook", "sack (large)", "sack (small)", "stakes (3)+mallet", "wolfsbane (1 bunch)"
]

21
main.py
View File

@@ -40,7 +40,7 @@ class ClassSelector():
return selected_class
class PartyGenerator():
def __init__(self, party_size=4) -> None:
def __init__(self, party_size: int) -> None:
self.size = party_size
self.adventurers = []
self.adventurer_types = []
@@ -63,26 +63,21 @@ class PartyGenerator():
character_sheets = []
for c in self.adventurers:
character_sheets.append(c.character_sheet())
for i in range(15):
for j in range(len(self.adventurers)):
adv = self.adventurers[j]
sheet_string += adv.character_sheet()[i]
sheet_string += '|\n'
return character_sheets
def __str__(self):
return f"{self.adventurers}"
def returnSheets(foo):
new_party = PartyGenerator()
def returnParty(party_size):
new_party = PartyGenerator(party_size)
new_party.gen_party()
return new_party.get_character_sheets()
return new_party
def main():
character_sheets = returnSheets('foo')
for c in character_sheets:
for l in c:
print(f"{l}|")
adventurer_party = returnParty(party_size=5)
for adv in adventurer_party.adventurers:
for line in adv.vertical_sheet:
print(f"{line}")
print()
if __name__ == "__main__":

6
spells.py Normal file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/python3
magic_user_spells = {
1 : [ "charm person", "detect magic", "floating disc", "hold portal", "light (darkness)", "magic missile", "protection from evil", "read languages", "shield", "sleep", "ventriloquism" ],
2 : [ "continual light", "detect evil", "detect invisible", "ESP", "invisibility", "knock", "levitate", "locate object", "mirror image", "phantasmal force", "web", "wizard lock" ]
}

View File

@@ -23,12 +23,12 @@
<div id="navbarBasicExample" class="navbar-menu">
<div class="navbar-start">
<a class="navbar-item">
Characters
<a class="navbar-item" href="party">
Generate Adventurer Party
</a>
<a class="navbar-item">
VTT
<a class="navbar-item" href="character">
Generate Single Adventurer
</a>
</div>
@@ -43,16 +43,8 @@
<div class="card-content">
<div class="content">
<h2>Welcome to the Dungeon</h2>
<p>Below are your randomly generated characters!</p>
<p>You can generate characters on this app</p>
<div class="columns">
{%for character in sheets%}
<div class="column is-narrow" >
<h3> Character!</h3>
<pre>{{character | join("\n")}}</pre>
</div>
{%endfor%}
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html>
<head>
<title>D&D Characters</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bulma@1.0.2/css/bulma.min.css"
>
</head>
<body>
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="navbarBasicExample" class="navbar-menu">
<div class="navbar-start">
<a class="navbar-item">
Characters
</a>
<a class="navbar-item">
VTT
</a>
</div>
</div>
</div>
</nav>
<div class="card">
<div class="container">
<div class="content">
<div class="card-content">
<div class="content">
<h2>Welcome to the Dungeon</h2>
<p>How many party members?</p>
<div class="buttons">
{%for i in range(2,6)%}
{% if count|int() == i|int() %}
<a class="button is-primary" href="{{ '/party?count=%s'%i }}">{{i}}</a>
{% else %}
<a class="button" href="{{ '/party?count=%s'%i }}">{{i}}</a>
{% endif %}
{%endfor%}
</div>
<div class="block has-text-centered">
<div class="columns">
{%for character in adv_party.adventurers%}
<div class="column" >
<div class="block has-text-centered">
<button class="button is-focused">Select this {{character.player_class.title()}}</button>
</div>
<pre>{{character.vertical_sheet | join("\n")}}</pre>
</div>
{%endfor%}
</div>
</div>
</div>
</div>
<div class="block has-text-centered">
<button class="button is-primary is-fillwidth">Select this adventuring party!</button>
<div>
<br>
</div>
</div>
</div>
</body>
</html>