Brandon Cornejo
5 years ago
commit
acb3621146
16 changed files with 833 additions and 0 deletions
-
15.gitignore
-
26acks/__init__.py
-
13acks/commands.py
-
10acks/models.py
-
184acks/npc/commands.py
-
23acks/npc/models.py
-
309acks/npc/npc_party.py
-
122acks/npc/templates/generate_npc_party.html
-
19acks/npc/views.py
-
29acks/templates/base.html
-
24acks/templates/handbook.html
-
11acks/templates/index.html
-
12acks/views.py
-
18requirements.txt
-
7start.py
-
11uwsgi.ini
@ -0,0 +1,15 @@ |
|||
# Python |
|||
*.py[co] |
|||
|
|||
# Vim |
|||
*.swp |
|||
|
|||
# Virtualenv |
|||
bin |
|||
data |
|||
include |
|||
lib |
|||
lib64 |
|||
__pycache__ |
|||
share |
|||
pyvenv.cfg |
@ -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 |
@ -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() |
|||
|
@ -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) |
@ -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() |
@ -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) |
@ -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) |
@ -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 %} |
@ -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) |
@ -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> |
@ -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 %} |
@ -0,0 +1,11 @@ |
|||
{% extends "base.html" %} |
|||
{% block title %}ACKS Toolset Home{% endblock %} |
|||
{% block content %} |
|||
<div> |
|||
</div> |
|||
{% endblock %} |
|||
|
|||
{% block head %} |
|||
<style> |
|||
</style> |
|||
{% endblock %} |
@ -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') |
@ -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 |
@ -0,0 +1,7 @@ |
|||
from acks import create_app |
|||
|
|||
|
|||
app = create_app() |
|||
|
|||
if __name__ == "__main__": |
|||
app.run() |
@ -0,0 +1,11 @@ |
|||
[uwsgi] |
|||
module = wsgi:application |
|||
|
|||
master = true |
|||
processes = 4 |
|||
|
|||
socket = ackstools.sock |
|||
chmod-scoket = 660 |
|||
vacuum = true |
|||
|
|||
die-on-term = true |
Write
Preview
Loading…
Cancel
Save
Reference in new issue