NPC Generator Source Code
npc.cgi
#!/var/www/venv-npc/bin/python
# Hello! This is my attempt at a practical application for the fantasychar module I created for SDE 188 using the mycgi and os modules for form handling.
# Note that I have no experience with HTML so a good portion of the HTML/CSS style and syntax was copied and pasted directly from stack overflow pages.
from mycgi import Form
import fantasychar
import os
import html
# Get form data (handles both GET and POST)
form = Form(environ=os.environ, keep_blank_values=True)
# Retrieve current values from form (defaults to a lesson on button-pushing on first load)
p_race = form.getvalue('p_race', 'Press the button to generate a new Race & Class!')
p_class = form.getvalue('p_class', '')
p_weap = form.getvalue('p_weap', 'Press the button to generate a new Weapon!')
# Check for action from form submit
action = form.getvalue('action')
# Uses functions from the fantasychar.py module to return a random Race, Class, & Weapon using form submit when buttons are clicked.
if action == 'gen_race':
fantasychar.random_char()
p_race = fantasychar.pRace
p_class = fantasychar.pClass
elif action == 'gen_weapon':
fantasychar.generate_weapon()
p_weap = fantasychar.pWeap
# Output HTML response
print("Content-type: text/html\n")
print("<html>")
print("<head>")
print("<title>NPC Generator</title>")
print("<style>")
print("body {")
print("background-color: #F4E4BC;")
print("font-family: 'Georgia', serif;")
print("text-align: center;")
print("margin: 0; padding: 20px;")
print("}")
print(".container {")
print("max-width: 600px;")
print("margin: 0 auto;")
print("padding: 20px;")
print("background-color: rgba(255, 255, 255, 0.2);")
print("border-radius: 10px;")
print("}")
print("h1 {")
print("color: #4A3728;")
print("font-size: 2em;")
print("}")
print("p {")
print("font-size: 1.2em;")
print("margin: 15px 0;")
print("}")
print("input[type='submit'] {")
print("background-color: #8B5A2B;")
print("color: white;")
print("padding: 10px 20px;")
print("border: none;")
print("border-radius: 5px;")
print("cursor: pointer;")
print("margin: 10px;")
print("font-size: 1em;")
print("}")
print("input[type='submit']:hover {")
print("background-color: #A0522D;")
print("}")
print(".source-button {")
print("position: fixed;")
print("top: 10px; right: 10px;")
print("background-color: #8B5A2B;")
print("color: white;")
print("padding: 5px 10px;")
print("text-decoration: none;")
print("border-radius: 5px;")
print("font-size: 0.8em;")
print("z-index: 1000;")
print("}")
print(".source-button:hover {")
print("background-color: #A0522D;")
print("}")
print("</style>")
print("</head>")
print("<body>")
print("<a href='/cgi-bin/source.cgi' class='source-button'>View Source</a>")
print("<div class='container'>")
print("<h1>NPC Generator</h1>")
print(f"<p>Race & Class: {html.escape(p_race)} {html.escape(p_class)}</p>")
print(f"<p>Weapon: {html.escape(p_weap)}</p>")
# Form for generating new race & class
print("<form method='post'>")
print(f"<input type='hidden' name='p_race' value='{html.escape(p_race)}'>")
print(f"<input type='hidden' name='p_class' value='{html.escape(p_class)}'>")
print(f"<input type='hidden' name='p_weap' value='{html.escape(p_weap)}'>")
print("<input type='hidden' name='action' value='gen_race'>")
print("<input type='submit' value='New Race & Class'>")
print("</form>")
# Form for generating new weapon
print("<form method='post'>")
print(f"<input type='hidden' name='p_race' value='{html.escape(p_race)}'>")
print(f"<input type='hidden' name='p_class' value='{html.escape(p_class)}'>")
print(f"<input type='hidden' name='p_weap' value='{html.escape(p_weap)}'>")
print("<input type='hidden' name='action' value='gen_weapon'>")
print("<input type='submit' value='New Weapon'>")
print("</form>")
print("</div>")
print("</body>")
print("</html>")
fantasychar.py
"""
Fantasy Character Creator Module:
Contains several functions for generating random D&D characters!
random_char() will generate a random race and class and assign them to the fantasychar.pRace and fantasychar.pClass variables.
generate_weap() will generate a random weapon for your character and assign it to the fantasychar.pWeap variable.
choose_spell() will generate a random cantrip for your character and assign it to the fantasychar.pSpell variable.
character_summary() will run each function and print a character summary containing each variable.
"""
# This section of the code imports the random module and defines the variables returned from each function in the global scope
import random
pRace = 0
pClass = 0
pSpell = 0
pWeap = 0
# This section of the code defines each function and returns a random player character attribute assigned to a variable.
def random_char():
race_list = ["Half-Elf", "Drow", "Wood Elf", "High Elf", "Half-Orc", "Hill Dwarf", "Mountain Dwarf", "Human", "Orc", "Halfling", "Dragonborn", "Aasimar", "Tiefling", "Goblin"]
class_list = ["Wizard", "Fighter", "Barbarian", "Bard", "Rogue", "Druid", "Cleric", "Ranger", "Paladin", "Monk", "Sorcerer", "Warlock", "Artificer"]
global pRace
global pClass
pRace = random.choice(race_list)
pClass = random.choice(class_list)
def generate_weapon():
weap_list = ["Bow", "Greatsword", "Axe", "Quarterstaff", "Dagger", "Spear", "Scimitar", "Mace", "Rapier", "Shortsword", "Javelin", "Crossbow", "Glaive", "Morningstar", "Trident", "Warhammer"]
global pWeap
pWeap = random.choice(weap_list)
def choose_spell():
spell_list = ["Fire Bolt", "Ray of Frost", "Thorn Whip", "Eldritch Blast", "Mending", "Acid Splash", "Prestidigitation"]
global pSpell
pSpell = random.choice(spell_list)
def character_summary():
random_char()
generate_weapon()
choose_spell()
print(f"Your character is a {pRace} {pClass} who wields a {pWeap} and can cast {pSpell}!")
if __name__ == "__main__":
character_summary()