Beginning to add DB backend
This commit is contained in:
commit
acb3621146
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# Python
|
||||
*.py[co]
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
|
||||
# Virtualenv
|
||||
bin
|
||||
data
|
||||
include
|
||||
lib
|
||||
lib64
|
||||
__pycache__
|
||||
share
|
||||
pyvenv.cfg
|
26
acks/__init__.py
Normal file
26
acks/__init__.py
Normal file
@ -0,0 +1,26 @@
|
||||
from flask import Flask
|
||||
|
||||
def create_app():
|
||||
app = Flask(__name__)
|
||||
|
||||
# Prep the database
|
||||
from acks.models import db
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///../data/acks.db'
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
db.init_app(app)
|
||||
|
||||
# Load our views
|
||||
from acks.views import default_views
|
||||
app.register_blueprint(default_views)
|
||||
|
||||
from acks.npc.views import npc_views
|
||||
app.register_blueprint(npc_views)
|
||||
|
||||
# Load our CLI commands
|
||||
from acks.commands import default_cli
|
||||
app.cli.add_command(default_cli)
|
||||
|
||||
from acks.npc.commands import npc_cli
|
||||
app.cli.add_command(npc_cli)
|
||||
|
||||
return app
|
13
acks/commands.py
Normal file
13
acks/commands.py
Normal file
@ -0,0 +1,13 @@
|
||||
import click
|
||||
from flask.cli import AppGroup
|
||||
|
||||
from acks.models import db
|
||||
|
||||
default_cli = AppGroup('acks')
|
||||
|
||||
@default_cli.command('initdb')
|
||||
def initialize_database():
|
||||
from acks import models
|
||||
from acks.npc import models
|
||||
db.create_all()
|
||||
|
10
acks/models.py
Normal file
10
acks/models.py
Normal file
@ -0,0 +1,10 @@
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
|
||||
|
||||
db = SQLAlchemy()
|
||||
|
||||
class BaseModel(db.Model):
|
||||
__abstract__ = True
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
created_at = db.Column(db.DateTime)
|
184
acks/npc/commands.py
Normal file
184
acks/npc/commands.py
Normal file
@ -0,0 +1,184 @@
|
||||
import click
|
||||
from flask.cli import AppGroup
|
||||
|
||||
from ..models import db
|
||||
|
||||
|
||||
npc_cli = AppGroup('npc')
|
||||
|
||||
@npc_cli.command('create classes')
|
||||
def create_classes():
|
||||
from .models import CharacterClass
|
||||
|
||||
classes = []
|
||||
|
||||
classes.append(CharacterClass(
|
||||
name = 'Elven Nightblade',
|
||||
bucket = 'Demi-Human',
|
||||
prime_requisite = 'D+I',
|
||||
hit_die_size = 6,
|
||||
maximum_level = 11,
|
||||
armour_modifier = -4,
|
||||
melee_light = 1,
|
||||
melee_medium = 2,
|
||||
melee_heavy = 0,
|
||||
ranged_light = 0,
|
||||
ranged_heavy = 0
|
||||
))
|
||||
|
||||
classes.append(CharacterClass(
|
||||
name = 'Elven Spellsword',
|
||||
bucket = 'Demi-Human',
|
||||
prime_requisite = 'S+I',
|
||||
hit_die_size = 6,
|
||||
maximum_level = 10,
|
||||
armour_modifier = -4,
|
||||
melee_light = 0,
|
||||
melee_medium = 1,
|
||||
melee_heavy = 0,
|
||||
ranged_light = 0,
|
||||
ranged_heavy = 0
|
||||
))
|
||||
|
||||
classes.append(CharacterClass(
|
||||
name = 'Explorer',
|
||||
bucket = 'Campaign',
|
||||
prime_requisite = 'S+D',
|
||||
hit_die_size = 6,
|
||||
maximum_level = 14,
|
||||
armour_modifier = -3,
|
||||
melee_light = 1,
|
||||
melee_medium = 1,
|
||||
melee_heavy = 0,
|
||||
ranged_light = 0,
|
||||
ranged_heavy = 1
|
||||
))
|
||||
|
||||
classes.append(CharacterClass(
|
||||
name = 'Bladedancer',
|
||||
bucket = 'Campaign',
|
||||
prime_requisite = 'W+D',
|
||||
hit_die_size = 6,
|
||||
maximum_level = 14,
|
||||
armour_modifier = -2,
|
||||
melee_light = 0,
|
||||
melee_medium = 1,
|
||||
melee_heavy = 0,
|
||||
ranged_light = 0,
|
||||
ranged_heavy = 0
|
||||
))
|
||||
|
||||
classes.append(CharacterClass(
|
||||
name = 'Cleric',
|
||||
bucket = 'Core',
|
||||
prime_requisite = 'WIS',
|
||||
hit_die_size = 6,
|
||||
maximum_level = 14,
|
||||
armour_modifier = 0,
|
||||
melee_light = 1,
|
||||
melee_medium = 3,
|
||||
melee_heavy = 1,
|
||||
ranged_light = 1,
|
||||
ranged_heavy = 3
|
||||
))
|
||||
|
||||
classes.append(CharacterClass(
|
||||
name = 'Fighter',
|
||||
bucket = 'Core',
|
||||
prime_requisite = 'STR',
|
||||
hit_die_size = 8,
|
||||
maximum_level = 14,
|
||||
armour_modifier = 1,
|
||||
melee_light = 1,
|
||||
melee_medium = 4,
|
||||
melee_heavy = 1,
|
||||
ranged_light = 1,
|
||||
ranged_heavy = 1
|
||||
))
|
||||
|
||||
classes.append(CharacterClass(
|
||||
name = 'Thief',
|
||||
bucket = 'Core',
|
||||
prime_requisite = 'DEX',
|
||||
hit_die_size = 4,
|
||||
maximum_level = 14,
|
||||
armour_modifier = -6,
|
||||
melee_light = 1,
|
||||
melee_medium = 1,
|
||||
melee_heavy = 0,
|
||||
ranged_light = 1,
|
||||
ranged_heavy = 0
|
||||
))
|
||||
|
||||
classes.append(CharacterClass(
|
||||
name = 'Mage',
|
||||
bucket = 'Core',
|
||||
prime_requisite = 'INT',
|
||||
hit_die_size = 4,
|
||||
maximum_level = 14,
|
||||
armour_modifier = -8,
|
||||
melee_light = 1,
|
||||
melee_medium = 0,
|
||||
melee_heavy = 0,
|
||||
ranged_light = 0,
|
||||
ranged_heavy = 0
|
||||
))
|
||||
|
||||
classes.append(CharacterClass(
|
||||
name = 'Assassin',
|
||||
bucket = 'Campaign',
|
||||
prime_requisite = 'S+D',
|
||||
hit_die_size = 6,
|
||||
maximum_level = 14,
|
||||
armour_modifier = -6,
|
||||
melee_light = 1,
|
||||
melee_medium = 2,
|
||||
melee_heavy = 0,
|
||||
ranged_light = 1,
|
||||
ranged_heavy = 0
|
||||
))
|
||||
|
||||
classes.append(CharacterClass(
|
||||
name = 'Bard',
|
||||
bucket = 'Campaign',
|
||||
prime_requisite = 'D+H',
|
||||
hit_die_size = 6,
|
||||
maximum_level = 14,
|
||||
armour_modifier = -3,
|
||||
melee_light = 1,
|
||||
melee_medium = 2,
|
||||
melee_heavy = 0,
|
||||
ranged_light = 1,
|
||||
ranged_heavy = 0
|
||||
))
|
||||
|
||||
classes.append(CharacterClass(
|
||||
name = 'Dwarven Vaultguard',
|
||||
bucket = 'Demi-Human',
|
||||
prime_requisite = 'STR',
|
||||
hit_die_size = 8,
|
||||
maximum_level = 13,
|
||||
armour_modifier = -1,
|
||||
melee_light = 0,
|
||||
melee_medium = 3,
|
||||
melee_heavy = 1,
|
||||
ranged_light = 1,
|
||||
ranged_heavy = 1
|
||||
))
|
||||
|
||||
classes.append(CharacterClass(
|
||||
name = 'Dwarven Craftpriest',
|
||||
bucket = 'Demi-Human',
|
||||
prime_requisite = 'WIS',
|
||||
hit_die_size = 6,
|
||||
maximum_level = 10,
|
||||
armour_modifier = -2,
|
||||
melee_light = 0,
|
||||
melee_medium = 1,
|
||||
melee_heavy = 0,
|
||||
ranged_light = 1,
|
||||
ranged_heavy = 0
|
||||
))
|
||||
|
||||
db.session.bulk_save_objects(classes)
|
||||
db.session.commit()
|
23
acks/npc/models.py
Normal file
23
acks/npc/models.py
Normal file
@ -0,0 +1,23 @@
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from ..models import db, BaseModel
|
||||
|
||||
|
||||
class CharacterClass(BaseModel):
|
||||
__tablename__ = 'character_class'
|
||||
|
||||
name = db.Column(db.String(50), unique=True, nullable=False)
|
||||
bucket = db.Column(db.String(50))
|
||||
|
||||
prime_requisite = db.Column(db.String(3))
|
||||
hit_die_size = db.Column(db.Integer)
|
||||
maximum_level = db.Column(db.Integer)
|
||||
|
||||
armour_modifier = db.Column(db.Integer)
|
||||
melee_light = db.Column(db.Integer)
|
||||
melee_medium = db.Column(db.Integer)
|
||||
melee_heavy = db.Column(db.Integer)
|
||||
ranged_light = db.Column(db.Integer)
|
||||
ranged_heavy = db.Column(db.Integer)
|
||||
|
||||
def __repr__(self):
|
||||
return '<CharacterClass {0}>'.format(self.name)
|
309
acks/npc/npc_party.py
Normal file
309
acks/npc/npc_party.py
Normal file
@ -0,0 +1,309 @@
|
||||
from random import randint
|
||||
|
||||
|
||||
def number_encountered():
|
||||
return (randint(1, 4) + 2)
|
||||
|
||||
def npc_class():
|
||||
roll = (randint(1, 6) + randint(1, 6) + randint(1, 6))
|
||||
if roll == 3 or roll == 4:
|
||||
return 'Elven Nightblade'
|
||||
elif roll == 5:
|
||||
return 'Elven Spellsword'
|
||||
elif roll == 6:
|
||||
return 'Explorer'
|
||||
elif roll == 7:
|
||||
return 'Bladedancer'
|
||||
elif roll == 8:
|
||||
return 'Cleric'
|
||||
elif roll == 9 or roll == 10 or roll == 11:
|
||||
return 'Fighter'
|
||||
elif roll == 12:
|
||||
return 'Thief'
|
||||
elif roll == 13:
|
||||
return 'Mage'
|
||||
elif roll == 14:
|
||||
return 'Assassin'
|
||||
elif roll == 15:
|
||||
return 'Bard'
|
||||
elif roll == 16:
|
||||
return 'Dwarven Vaultguard'
|
||||
elif roll == 17 or roll == 18:
|
||||
return 'Dwarven Craftpriest'
|
||||
|
||||
def npc_alignment():
|
||||
roll = randint(1, 6)
|
||||
if roll == 1 or roll == 2:
|
||||
return 'Lawful'
|
||||
elif roll == 3 or roll == 4 or roll == 5:
|
||||
return 'Neutral'
|
||||
elif roll == 6:
|
||||
return 'Chaotic'
|
||||
|
||||
def npc_baselevel(base_level):
|
||||
roll = randint(1, 6)
|
||||
mod = 0
|
||||
if roll == 1:
|
||||
mod = -2
|
||||
elif roll == 2:
|
||||
mod = -1
|
||||
elif roll == 3 or roll == 4:
|
||||
mod = 0
|
||||
elif roll == 5:
|
||||
mod = 1
|
||||
elif roll == 6:
|
||||
mod = 2
|
||||
|
||||
base_level += mod
|
||||
if base_level < 1:
|
||||
base_level = 1
|
||||
|
||||
return base_level
|
||||
|
||||
def npc_abilities():
|
||||
return [(randint(1, 6) + randint(1, 6) + randint(1, 6)) for x in range(0,6)]
|
||||
|
||||
def attribute_mod(atr):
|
||||
mod = 0
|
||||
|
||||
if atr <= 3: mod = -3
|
||||
if atr >= 4 and atr <= 5: mod = -2
|
||||
if atr >= 6 and atr <= 8: mod = -1
|
||||
if atr >= 9 and atr <= 12: mod = 0
|
||||
if atr >= 13 and atr <= 15: mod = 1
|
||||
if atr >= 16 and atr <= 17: mod = 2
|
||||
if atr >= 18: mod = 3
|
||||
|
||||
return mod
|
||||
|
||||
|
||||
npc_class_data = {
|
||||
'Elven Nightblade': {
|
||||
'hd': [1, 6],
|
||||
'armour': -4,
|
||||
'melee': [0, 2, 1],
|
||||
'ranged': [0, 0, 1]
|
||||
},
|
||||
|
||||
'Elven Spellsword': {
|
||||
'hd': [1, 6],
|
||||
'armour': -4,
|
||||
'melee': [0, 1, 0],
|
||||
'ranged': [0, 0, 1]
|
||||
},
|
||||
|
||||
'Explorer': {
|
||||
'hd': [1, 6],
|
||||
'armour': -3,
|
||||
'melee': [0, 1, 1],
|
||||
'ranged': [0, 1, 2]
|
||||
},
|
||||
|
||||
'Bladedancer': {
|
||||
'hd': [1, 6],
|
||||
'armour': -2,
|
||||
'melee': [0, 1, 0],
|
||||
'ranged': [0, 0, 1]
|
||||
},
|
||||
|
||||
'Cleric': {
|
||||
'hd': [1, 6],
|
||||
'armour': 0,
|
||||
'melee': [1, 3, 1],
|
||||
'ranged': [1, 3, 4]
|
||||
},
|
||||
|
||||
'Fighter': {
|
||||
'hd': [1, 8],
|
||||
'armour': 1,
|
||||
'melee': [1, 4, 1],
|
||||
'ranged': [1, 1, 4],
|
||||
},
|
||||
|
||||
'Thief': {
|
||||
'hd': [1, 4],
|
||||
'armour': -6,
|
||||
'melee': [0, 1, 1],
|
||||
'ranged': [1, 0, 6]
|
||||
},
|
||||
|
||||
'Mage': {
|
||||
'hd': [1, 4],
|
||||
'armour': -8,
|
||||
'melee': [0, 0, 1],
|
||||
'ranged': [0, 0, 1]
|
||||
},
|
||||
|
||||
'Assassin': {
|
||||
'hd': [1, 6],
|
||||
'armour': -6,
|
||||
'melee': [0, 2, 1],
|
||||
'ranged': [1, 0, 5]
|
||||
},
|
||||
|
||||
'Bard': {
|
||||
'hd': [1, 6],
|
||||
'armour': -3,
|
||||
'melee': [0, 2, 1],
|
||||
'ranged': [1, 0, 4]
|
||||
},
|
||||
|
||||
'Dwarven Vaultguard': {
|
||||
'hd': [1, 8],
|
||||
'armour': -1,
|
||||
'melee': [1, 3, 0],
|
||||
'ranged': [1, 1, 6]
|
||||
},
|
||||
|
||||
'Dwarven Craftpriest': {
|
||||
'hd': [1, 6],
|
||||
'armour': -2,
|
||||
'melee': [0, 1, 0],
|
||||
'ranged': [1, 0, 5]
|
||||
}
|
||||
}
|
||||
|
||||
npc_armour_list = [
|
||||
['Clothing Only', 0, 0],
|
||||
['Hide and Fur Armour', 10, 1],
|
||||
['Leather Armour', 20, 2],
|
||||
['Ring Mail Armour', 30, 3],
|
||||
['Scale Mail Armour', 30, 3],
|
||||
['Chain Mail Armour', 40, 4],
|
||||
['Banded Plate', 50, 5],
|
||||
['Lamellar Armour', 50, 5],
|
||||
['Plate Armour', 60, 6],
|
||||
]
|
||||
|
||||
npc_melee_weapons_data = {
|
||||
'light': [
|
||||
['Club', 1, '1d4'],
|
||||
['Dagger', 3, '1d4'],
|
||||
['Sap', 1, '1d4'],
|
||||
['Staff (1h)', 1, '1d4'],
|
||||
['Staff (2h)', 1, '1d6'],
|
||||
['Whip', 5, '1d2']
|
||||
],
|
||||
'medium': [
|
||||
['Battle Axe (1h)', 7, '1d6'],
|
||||
['Battle Axe (2h)', 7, '1d8'],
|
||||
['Hand Axe', 4, '1d6'],
|
||||
['Flail (1h)', 5, '1d6'],
|
||||
['Flail (2h)', 5, '1d8'],
|
||||
['Mace (1h)', 5, '1d6'],
|
||||
['Mace (2h)', 5, '1d8'],
|
||||
['War Hammer (1h)', 5, '1d6'],
|
||||
['War Hammer (2h)', 5, '1d8'],
|
||||
['Spear (1h)', 3, '1d6'],
|
||||
['Spear (2h)', 3, '1d8'],
|
||||
['Short Sword', 7, '1d6'],
|
||||
['Sword (1h)', 10, '1d6'],
|
||||
['Sword (2h)', 10, '1d8']
|
||||
],
|
||||
'heavy': [
|
||||
['Great Axe (2h)', 10, '1d10'],
|
||||
['Morning Star (2h)', 10, '1d10'],
|
||||
['Pole Arm (2h)', 7, '1d10'],
|
||||
['Two-Handed Sword (2h)', 15, '1d10']
|
||||
]
|
||||
}
|
||||
|
||||
npc_ranged_weapons_data = {
|
||||
'light': [
|
||||
['Crossbow', 30, '1d6'],
|
||||
['Shortbow', 3, '1d6'],
|
||||
['Javelin', 1, '1d6'],
|
||||
],
|
||||
'heavy': [
|
||||
['Arbalest', 50, '1d8'],
|
||||
['Composite Bow', 40, '1d6'],
|
||||
['Longbow', 7, '1d6'],
|
||||
]
|
||||
}
|
||||
|
||||
def select_melee_weapon(guild):
|
||||
melee = npc_class_data[guild]['melee']
|
||||
weapons = []
|
||||
for x in range(0, melee[0]):
|
||||
weapons.extend(npc_melee_weapons_data['heavy'])
|
||||
for x in range(0, melee[1]):
|
||||
weapons.extend(npc_melee_weapons_data['medium'])
|
||||
for x in range(0, melee[2]):
|
||||
weapons.extend(npc_melee_weapons_data['light'])
|
||||
|
||||
selection = randint(0, len(weapons) - 1)
|
||||
return weapons[selection]
|
||||
|
||||
def select_ranged_weapon(guild):
|
||||
ranged = npc_class_data[guild]['ranged']
|
||||
weapons = []
|
||||
for x in range(0, ranged[0]):
|
||||
weapons.extend(npc_ranged_weapons_data['light'])
|
||||
for x in range(0, ranged[1]):
|
||||
weapons.extend(npc_ranged_weapons_data['heavy'])
|
||||
for x in range(0, ranged[2]):
|
||||
weapons.append(None)
|
||||
|
||||
selection = randint(0, len(weapons) - 1)
|
||||
return weapons[selection]
|
||||
|
||||
def generate_npc(base_level):
|
||||
attributes = npc_abilities()
|
||||
|
||||
npc = {}
|
||||
npc['guild'] = npc_class()
|
||||
npc['level'] = npc_baselevel(base_level)
|
||||
npc['str'] = attributes[0]
|
||||
npc['int'] = attributes[1]
|
||||
npc['wis'] = attributes[2]
|
||||
npc['dex'] = attributes[3]
|
||||
npc['con'] = attributes[4]
|
||||
npc['chr'] = attributes[5]
|
||||
|
||||
npc['hp'] = 0
|
||||
conmod = attribute_mod(npc['con'])
|
||||
for x in range(0, npc['level']):
|
||||
hitdice = [randint(1, npc_class_data[npc['guild']]['hd'][1]) for x in range(0, npc_class_data[npc['guild']]['hd'][0])]
|
||||
for die in hitdice:
|
||||
die += conmod
|
||||
if die < 1:
|
||||
die = 1
|
||||
npc['hp'] += die
|
||||
|
||||
armourval = randint(0, len(npc_armour_list) - 1) + npc_class_data[npc['guild']]['armour']
|
||||
if armourval < 0:
|
||||
armourval = 0
|
||||
if armourval > len(npc_armour_list) - 1:
|
||||
armourval = len(npc_armour_list) - 1
|
||||
npc['armour'] = npc_armour_list[armourval]
|
||||
npc['melee'] = select_melee_weapon(npc['guild'])
|
||||
npc['ranged'] = select_ranged_weapon(npc['guild'])
|
||||
|
||||
return npc
|
||||
|
||||
def create_party(base_level):
|
||||
party_size = number_encountered()
|
||||
return [generate_npc(base_level) for x in range(0, party_size)]
|
||||
|
||||
def print_party(party):
|
||||
def print_npc(npc):
|
||||
print('Level {0} NPC, {1}, {2} HP'.format(npc['level'], npc['guild'], npc['hp']))
|
||||
print('{0} Str, {1} Int, {2} Wis, {3} Dex, {4} Con, {5} Chr'.format(
|
||||
npc['str'], npc['int'], npc['wis'],
|
||||
npc['dex'], npc['con'], npc['chr']
|
||||
))
|
||||
print('Armour Class: {0} - {1}, {2}gp'.format(npc['armour'][2], npc['armour'][0], npc['armour'][1]))
|
||||
print('{:^16} - {:^10} - {:^10} - {:^10}'.format('Weapon', 'Gold', 'Throw Mod', 'Damage'))
|
||||
print('-------------------------------------------------------')
|
||||
print('{:^16} | {:^10} | {:^10} | {:^10}'.format(npc['melee'][0], npc['melee'][1], 0, npc['melee'][2]))
|
||||
if npc['ranged']:
|
||||
print('{:^16} | {:^10} | {:^10} | {:^10}'.format(npc['ranged'][0], npc['ranged'][1], 0, npc['ranged'][2]))
|
||||
print('\n')
|
||||
|
||||
for npc in party:
|
||||
print_npc(npc)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
party = create_party(2)
|
||||
print_party(party)
|
122
acks/npc/templates/generate_npc_party.html
Normal file
122
acks/npc/templates/generate_npc_party.html
Normal file
@ -0,0 +1,122 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}NPC Party Generation{% endblock %}
|
||||
{% block content %}
|
||||
<div>
|
||||
<label for="base_level">Base level of party to generate: </label>
|
||||
<input type="number" name="base_level" id="base_level" default="1">
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="generateParty();">Generate</button>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
{% if party %}
|
||||
<h3>NPC Party of Size {{ party | length }}</h3>
|
||||
|
||||
<div class="uk-grid-medium uk-grid-match" uk-grid>
|
||||
{% for npc in party %}
|
||||
<div class="acks-npc-card">
|
||||
<div class="uk-card uk-card-body uk-card-default">
|
||||
<h4 class="uk-card-title">{{ npc.guild }}</h4>
|
||||
<div class="uk-card-badge uk-label">Level {{ npc.level }}</div>
|
||||
<div class="uk-flex uk-flex-around uk-text-center uk-margin-bottom">
|
||||
<div>
|
||||
<div>{{ npc.hp }}</div>
|
||||
<div>HP</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ npc.armour[2] }}</div>
|
||||
<div>AC</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-flex uk-flex-around stat-block">
|
||||
<div>
|
||||
<div>{{ npc.str }}</div>
|
||||
<div>Str</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ npc.int }}</div>
|
||||
<div>Int</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ npc.wis }}</div>
|
||||
<div>Wis</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ npc.dex }}</div>
|
||||
<div>Dex</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ npc.con }}</div>
|
||||
<div>Con</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ npc.chr }}</div>
|
||||
<div>Chr</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class="uk-table uk-table-hover uk-table-small item-table">
|
||||
<thead>
|
||||
<tr> <th>Name</th><th>Worth</th><th>Thr</th><th>Dmg</th> </tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ npc.melee[0] }}</td>
|
||||
<td>{{ npc.melee[1] }}gp</td>
|
||||
<td>0</td>
|
||||
<td>{{ npc.melee[2] }}</td>
|
||||
</tr>
|
||||
{% if npc.ranged %}
|
||||
<tr>
|
||||
<td>{{ npc.ranged[0] }}</td>
|
||||
<td>{{ npc.ranged[1] }}gp</td>
|
||||
<td>0</td>
|
||||
<td>{{ npc.ranged[2] }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td>{{ npc.armour[0] }}</td>
|
||||
<td>{{ npc.armour[1] }}gp</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<br>
|
||||
|
||||
<style>
|
||||
table.item-table, table.item-table th {
|
||||
font-size: 12px;
|
||||
}
|
||||
div.stat-block > div {
|
||||
text-align: center;
|
||||
padding: 3px;
|
||||
width: 26px;
|
||||
}
|
||||
div.stat-block > div > div:first-child {
|
||||
font-weight: bold;
|
||||
color: green;
|
||||
}
|
||||
div.stat-block > div > div:last-child {
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
}
|
||||
div.acks-npc-card {
|
||||
width: 370px;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function generateParty() {
|
||||
let bl = document.querySelector('#base_level').value;
|
||||
window.location = "/npcparty/" + bl.toString();
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
19
acks/npc/views.py
Normal file
19
acks/npc/views.py
Normal file
@ -0,0 +1,19 @@
|
||||
from flask import current_app, Blueprint, render_template
|
||||
|
||||
from .npc_party import create_party
|
||||
|
||||
|
||||
npc_views = Blueprint(
|
||||
'npc_views',
|
||||
__name__,
|
||||
template_folder='templates',
|
||||
url_prefix='/npc'
|
||||
)
|
||||
|
||||
@npc_views.route('/party')
|
||||
@npc_views.route('/party/<int:base_level>')
|
||||
def generate_npc_party(base_level=None):
|
||||
party = None
|
||||
if base_level:
|
||||
party = create_party(base_level)
|
||||
return render_template('generate_npc_party.html', party=party)
|
29
acks/templates/base.html
Normal file
29
acks/templates/base.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{% block title %}{% endblock %} - Atr0phy ACKS</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" contents="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.0/css/uikit.min.css" integrity="sha256-5YtK9j+Nl/245lAkSjrIs600d6edKTevi+3JYdjuHhY=" crossorigin="anonymous" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.0/js/uikit.min.js" integrity="sha256-rhLALrRmAQVu/OxzVDpQaiHAEMxiRSN8h8RDydUEh2g=" crossorigin="anonymous"></script>
|
||||
{% block head %} {% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<nav class="uk-navbar-container" uk-navbar>
|
||||
<div class="uk-navbar-left">
|
||||
<a href="" class="uk-navbar-item uk-logo">Atr0phy ACKS</a>
|
||||
</div>
|
||||
<div class="uk-navbar-center">
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/handbook">Handbook</a></li>
|
||||
<li class="uk-active"><a href="/npc/party">NPC Party</a></li>
|
||||
<li><a href="">Treasure</a></li>
|
||||
<li><a href="">Henchmen</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="uk-container">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
24
acks/templates/handbook.html
Normal file
24
acks/templates/handbook.html
Normal file
@ -0,0 +1,24 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}ACKS Handbook{% endblock %}
|
||||
{% block content %}
|
||||
<div id="frame-container">
|
||||
<iframe id="handbook-frame" src="https://atr0phy.net/acks/handbook"/>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
<style>
|
||||
#frame-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 85vh;
|
||||
flex-direction: column:
|
||||
}
|
||||
#handbook-frame {
|
||||
flex-grow: 1;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
11
acks/templates/index.html
Normal file
11
acks/templates/index.html
Normal file
@ -0,0 +1,11 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}ACKS Toolset Home{% endblock %}
|
||||
{% block content %}
|
||||
<div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
<style>
|
||||
</style>
|
||||
{% endblock %}
|
12
acks/views.py
Normal file
12
acks/views.py
Normal file
@ -0,0 +1,12 @@
|
||||
from flask import current_app, Blueprint, render_template
|
||||
|
||||
|
||||
default_views = Blueprint('default_views', __name__, url_prefix='/')
|
||||
|
||||
@default_views.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
@default_views.route('/handbook')
|
||||
def handbook():
|
||||
return render_template('handbook.html')
|
18
requirements.txt
Normal file
18
requirements.txt
Normal file
@ -0,0 +1,18 @@
|
||||
ansi2html==1.5.2
|
||||
cryptography==1.7.1
|
||||
culour==0.1
|
||||
enum34==1.1.6
|
||||
idna==2.2
|
||||
ipaddress==1.0.17
|
||||
keyring==10.1
|
||||
keyrings.alt==1.3
|
||||
pudb==2018.1
|
||||
pyasn1==0.1.9
|
||||
pycrypto==2.6.1
|
||||
Pygments==2.3.1
|
||||
pygobject==3.22.0
|
||||
pyxdg==0.25
|
||||
SecretStorage==2.3.1
|
||||
six==1.12.0
|
||||
urwid==2.0.1
|
||||
virtualenv==16.6.1
|
7
start.py
Normal file
7
start.py
Normal file
@ -0,0 +1,7 @@
|
||||
from acks import create_app
|
||||
|
||||
|
||||
app = create_app()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
Loading…
x
Reference in New Issue
Block a user