Compare commits
23 Commits
master
...
aedifex-re
Author | SHA1 | Date |
---|---|---|
|
95264be64d | |
|
6fab2976cf | |
|
1c08e51b0d | |
|
0e790415c7 | |
|
ef2bbc9812 | |
|
70f5d9eb15 | |
|
efe7c07817 | |
|
1c3b6c3c5e | |
|
4ac589d5fb | |
|
bd5f69e20e | |
|
3ec54868f9 | |
|
e6182865dc | |
|
1674ab9f1c | |
|
41dc6bf34e | |
|
43c88e908b | |
|
592e9328c8 | |
|
17e3150fc7 | |
|
d9ab60a190 | |
|
b0ea7abcd9 | |
|
0ce6b6a351 | |
|
b95d755d6e | |
|
bd84a1e9bc | |
|
809fa78d35 |
1
index.js
1
index.js
|
@ -78,6 +78,7 @@ try {
|
||||||
console.log('...ok')
|
console.log('...ok')
|
||||||
plugins.push(plugin)
|
plugins.push(plugin)
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
console.error(err)
|
||||||
if (err.code === 'MODULE_NOT_FOUND') {
|
if (err.code === 'MODULE_NOT_FOUND') {
|
||||||
console.error('plugin', plugin_path, 'is not a valid module')
|
console.error('plugin', plugin_path, 'is not a valid module')
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
class AedifexError extends Error {
|
||||||
|
constructor(message) {
|
||||||
|
super(message)
|
||||||
|
this.name = 'AedifexError'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnhandledTypeError extends AedifexError {
|
||||||
|
constructor(received) {
|
||||||
|
super(`unhandled aedifex type "${received}"`)
|
||||||
|
this.name = 'UnhandleTypeError'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IncorrectTypeError extends AedifexError {
|
||||||
|
constructor(expected, received) {
|
||||||
|
super(`expected "${expected}", received "${received}"`)
|
||||||
|
this.name = 'IncorrectTypeError'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IncorrectPropertyError extends AedifexError {
|
||||||
|
constructor(field, expected, received) {
|
||||||
|
super(`expected property "${field}" to be "${expected}", received type "${received}"`)
|
||||||
|
this.name = 'IncorrectPropertyError'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MismatchedVersionError extends AedifexError {
|
||||||
|
constructor(expected, received) {
|
||||||
|
super(`expected version "${expected}", received "${received}"`)
|
||||||
|
this.name = 'MismatchedVersionError'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
AedifexError,
|
||||||
|
UnhandledTypeError,
|
||||||
|
IncorrectTypeError,
|
||||||
|
IncorrectPropertyError,
|
||||||
|
MismatchedVersionError,
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
const semver = require('semver')
|
||||||
|
|
||||||
|
const { IncorrectTypeError, IncorrectPropertyError, MismatchedVersionError } = require('./errors.js')
|
||||||
|
|
||||||
|
function readGear(collection, v) {
|
||||||
|
if (v.type !== 'hord-gear') {
|
||||||
|
throw new IncorrectTypeError('hord-gear', v.type)
|
||||||
|
}
|
||||||
|
if (!Array.isArray(v.gear)) {
|
||||||
|
throw new IncorrectPropertyError('gear', typeof [], typeof v.gear)
|
||||||
|
}
|
||||||
|
if (!v.version || !semver.satisfies(v.version, '1.x')) {
|
||||||
|
throw new MismatchedVersionError('1.x', v.version)
|
||||||
|
}
|
||||||
|
for (let g of v.gear) {
|
||||||
|
collection.insert(g)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
readGear,
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
const path = require('path')
|
||||||
|
const chokidar = require('chokidar')
|
||||||
|
const YAML = require('yaml')
|
||||||
|
const fs = require('fs')
|
||||||
|
const loki = require('lokijs')
|
||||||
|
|
||||||
|
const { readSpecimens } = require('./specimen.js')
|
||||||
|
const { readGear } = require('./gear.js')
|
||||||
|
|
||||||
|
const { UnhandledTypeError } = require('./errors.js')
|
||||||
|
|
||||||
|
const refresh = async (plugin, app, db_dir) => {
|
||||||
|
let files = await fs.promises.readdir(path.join(db_dir))
|
||||||
|
|
||||||
|
let db = new loki('Hord')
|
||||||
|
let specimens = db.getCollection('specimens') || db.addCollection('specimens', {indices: ['family', 'name']})
|
||||||
|
let gear = db.getCollection('gear') || db.addCollection('gear', {indices: ['type', 'name']})
|
||||||
|
|
||||||
|
for (let file of files) {
|
||||||
|
if (path.extname(file) === '.aedifex' || path.extname(file) === '.aed') {
|
||||||
|
plugin.log(`parsing aedifex file: "${path.join(db_dir, file)}"`)
|
||||||
|
let o = YAML.parse(await fs.promises.readFile(path.join(db_dir, file), { encoding: 'utf8' }))
|
||||||
|
try {
|
||||||
|
switch(o.type) {
|
||||||
|
case 'hord-specimens':
|
||||||
|
readSpecimens(specimens, o)
|
||||||
|
break;
|
||||||
|
case 'hord-gear':
|
||||||
|
readGear(gear, o)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnhandledTypeError(o.type)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
plugin.error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.live = {
|
||||||
|
...app.live,
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
priority: 1,
|
||||||
|
load: async (plugin, app) => {
|
||||||
|
// Load up our DB.
|
||||||
|
const db_dir = path.resolve(app.config.aedifex)
|
||||||
|
|
||||||
|
await refresh(plugin, app, db_dir)
|
||||||
|
|
||||||
|
const watcher = chokidar.watch(db_dir, {persistent: true})
|
||||||
|
watcher.on('change', p => {
|
||||||
|
refresh(plugin, app, db_dir)
|
||||||
|
})
|
||||||
|
plugin.log('watching', db_dir)
|
||||||
|
|
||||||
|
app.express.use(require('./route.js')(plugin, app))
|
||||||
|
},
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "srd-gear-router",
|
"name": "srd-aedifex-router",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
|
@ -9,11 +9,13 @@
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": "^3.5.1",
|
"chokidar": "^3.5.1",
|
||||||
|
"lokijs": "^1.5.12",
|
||||||
"markdown-it": "^12.0.6",
|
"markdown-it": "^12.0.6",
|
||||||
"markdown-it-anchor": "^7.1.0",
|
"markdown-it-anchor": "^7.1.0",
|
||||||
"markdown-it-attrs": "^4.0.0",
|
"markdown-it-attrs": "^4.0.0",
|
||||||
"markdown-it-title": "^3.0.0",
|
"markdown-it-title": "^3.0.0",
|
||||||
"memory-cache": "^0.2.0",
|
"memory-cache": "^0.2.0",
|
||||||
|
"semver": "^7.3.5",
|
||||||
"yaml": "^1.10.2"
|
"yaml": "^1.10.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -162,6 +164,22 @@
|
||||||
"uc.micro": "^1.0.1"
|
"uc.micro": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lokijs": {
|
||||||
|
"version": "1.5.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.12.tgz",
|
||||||
|
"integrity": "sha512-Q5ALD6JiS6xAUWCwX3taQmgwxyveCtIIuL08+ml0nHwT3k0S/GIFJN+Hd38b1qYIMaE5X++iqsqWVksz7SYW+Q=="
|
||||||
|
},
|
||||||
|
"node_modules/lru-cache": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
|
"dependencies": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/markdown-it": {
|
"node_modules/markdown-it": {
|
||||||
"version": "12.0.6",
|
"version": "12.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.6.tgz",
|
||||||
|
@ -241,6 +259,20 @@
|
||||||
"node": ">=8.10.0"
|
"node": ">=8.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/semver": {
|
||||||
|
"version": "7.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||||
|
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/to-regex-range": {
|
"node_modules/to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
@ -257,6 +289,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||||
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||||
|
},
|
||||||
"node_modules/yaml": {
|
"node_modules/yaml": {
|
||||||
"version": "1.10.2",
|
"version": "1.10.2",
|
||||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
||||||
|
@ -370,6 +407,19 @@
|
||||||
"uc.micro": "^1.0.1"
|
"uc.micro": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"lokijs": {
|
||||||
|
"version": "1.5.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.12.tgz",
|
||||||
|
"integrity": "sha512-Q5ALD6JiS6xAUWCwX3taQmgwxyveCtIIuL08+ml0nHwT3k0S/GIFJN+Hd38b1qYIMaE5X++iqsqWVksz7SYW+Q=="
|
||||||
|
},
|
||||||
|
"lru-cache": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
|
"requires": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"markdown-it": {
|
"markdown-it": {
|
||||||
"version": "12.0.6",
|
"version": "12.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.6.tgz",
|
||||||
|
@ -427,6 +477,14 @@
|
||||||
"picomatch": "^2.2.1"
|
"picomatch": "^2.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "7.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||||
|
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||||
|
"requires": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"to-regex-range": {
|
"to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
@ -440,6 +498,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||||
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
||||||
},
|
},
|
||||||
|
"yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||||
|
},
|
||||||
"yaml": {
|
"yaml": {
|
||||||
"version": "1.10.2",
|
"version": "1.10.2",
|
||||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "srd-gear-router",
|
"name": "srd-aedifex-router",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
@ -11,11 +11,13 @@
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": "^3.5.1",
|
"chokidar": "^3.5.1",
|
||||||
|
"lokijs": "^1.5.12",
|
||||||
"markdown-it": "^12.0.6",
|
"markdown-it": "^12.0.6",
|
||||||
"markdown-it-anchor": "^7.1.0",
|
"markdown-it-anchor": "^7.1.0",
|
||||||
"markdown-it-attrs": "^4.0.0",
|
"markdown-it-attrs": "^4.0.0",
|
||||||
"markdown-it-title": "^3.0.0",
|
"markdown-it-title": "^3.0.0",
|
||||||
"memory-cache": "^0.2.0",
|
"memory-cache": "^0.2.0",
|
||||||
|
"semver": "^7.3.5",
|
||||||
"yaml": "^1.10.2"
|
"yaml": "^1.10.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
const router = require('express').Router()
|
||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
module.exports = (plugin, app) => {
|
||||||
|
router.get(['/db/:collection', '/db/:collection/:type', '/db/:collection/:type/:name'], async function(req, res) {
|
||||||
|
let collection = app.live.db.getCollection(req.params.collection).chain()
|
||||||
|
let results = []
|
||||||
|
let error = ''
|
||||||
|
let errorCode = 0
|
||||||
|
if (!collection) {
|
||||||
|
// TODO: 404 - collection missing
|
||||||
|
} else {
|
||||||
|
if (req.params.name) {
|
||||||
|
results = collection.find({type: req.params.type, name: req.params.name})
|
||||||
|
if (results.length === 0) {
|
||||||
|
error = `No such entry "${req.params.name}"`
|
||||||
|
errorCode = 404
|
||||||
|
}
|
||||||
|
} else if (req.params.type) {
|
||||||
|
results = collection.find({type: req.params.type})
|
||||||
|
if (results.length === 0) {
|
||||||
|
error = `No such collection type "${req.params.type}"`
|
||||||
|
errorCode = 404
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
results = collection.find({})
|
||||||
|
if (results.length === 0) {
|
||||||
|
error = `Collection empty`
|
||||||
|
errorCode = 404
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (req.query['sort-by']) {
|
||||||
|
results.simplesort(req.query['sort-by'])
|
||||||
|
}
|
||||||
|
results = results.data()
|
||||||
|
|
||||||
|
let content
|
||||||
|
if (errorCode > 0) {
|
||||||
|
content = error
|
||||||
|
} else {
|
||||||
|
content = app.dot.tables({...req.params, results, type: req.params.type, name: req.params.name, collection: req.params.collection})
|
||||||
|
}
|
||||||
|
|
||||||
|
// build the location
|
||||||
|
let loc = '<a href="/">'+app.live.conf['shortname']+'</a>'
|
||||||
|
let crumbs = req.path.split('/')
|
||||||
|
let title = [...crumbs].reverse().filter(v=>v!==''&&v!=='db').map(v=>v.charAt(0).toUpperCase()+v.slice(1)).join(' - ')
|
||||||
|
for (let i = 1; i < crumbs.length; i++) {
|
||||||
|
if (crumbs[i] == '') continue
|
||||||
|
loc += ' → <a href="'+crumbs.slice(0,i).join('/')+'/'+crumbs[i]+'/">'+(crumbs[i].replace('-', ' '))+'</a>'
|
||||||
|
}
|
||||||
|
|
||||||
|
res.render('index', {
|
||||||
|
content,
|
||||||
|
menu: app.live.menu,
|
||||||
|
location: loc,
|
||||||
|
title: title,
|
||||||
|
www_name: app.live.conf.www_name,
|
||||||
|
www_copyright: app.live.conf.www_copyright,
|
||||||
|
scripts: ['/js/gear.js'],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
plugin.log('added aedifex route')
|
||||||
|
|
||||||
|
return router
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
const semver = require('semver')
|
||||||
|
|
||||||
|
const { IncorrectTypeError, IncorrectPropertyError, MismatchedVersionError } = require('./errors.js')
|
||||||
|
|
||||||
|
function readSpecimens(collection, v) {
|
||||||
|
if (v.type !== 'hord-specimens') {
|
||||||
|
throw new IncorrectTypeError('hord-specimens', v.type)
|
||||||
|
}
|
||||||
|
if (!Array.isArray(v.specimens)) {
|
||||||
|
throw new IncorrectPropertyError('specimens', typeof [], typeof v.specimens)
|
||||||
|
}
|
||||||
|
if (!v.version || !semver.satisfies(v.version, '1.x')) {
|
||||||
|
throw new MismatchedVersionError('1.x', v.version)
|
||||||
|
}
|
||||||
|
for (let s of v.specimens) {
|
||||||
|
// Assign file family to specimen type just for sorting simplicity.
|
||||||
|
s.type = v.family
|
||||||
|
s.combatvalue = calculateCV(s)
|
||||||
|
collection.insert(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateCV(t) {
|
||||||
|
if (!t) return 0
|
||||||
|
if (t.combatvalue) return t.combatvalue
|
||||||
|
let v = 0
|
||||||
|
if (t.health) {
|
||||||
|
v += 1 + t.health/2
|
||||||
|
}
|
||||||
|
if(t.move) {
|
||||||
|
v += t.move
|
||||||
|
}
|
||||||
|
if (t.attack) {
|
||||||
|
v += t.attack
|
||||||
|
}
|
||||||
|
if (Array.isArray(t.attacks) && t.attacks.length > 0) {
|
||||||
|
let avgDmg = 0
|
||||||
|
let avgAtk = 0
|
||||||
|
let hasOpportunity = 0
|
||||||
|
for (let a of t.attacks) {
|
||||||
|
let aDmg = 0
|
||||||
|
for (let d of a.damage) {
|
||||||
|
aDmg += d.value
|
||||||
|
}
|
||||||
|
avgDmg += aDmg / a.damage.length
|
||||||
|
avgAtk += a.attack
|
||||||
|
if (a.opportunistic) {
|
||||||
|
hasOpportunity = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
avgDmg /= t.attacks.length
|
||||||
|
avgAtk /= t.attacks.length
|
||||||
|
v += avgDmg / avgAtk + hasOpportunity
|
||||||
|
}
|
||||||
|
if (Array.isArray(t.defenses)) {
|
||||||
|
let maxDef = 0
|
||||||
|
let defs = t.defenses.length
|
||||||
|
let perfects = 0
|
||||||
|
for (let d of t.defenses) {
|
||||||
|
if (d.perfect) {
|
||||||
|
perfects++
|
||||||
|
}
|
||||||
|
maxDef = Math.max(maxDef, d.value)
|
||||||
|
}
|
||||||
|
v += maxDef + defs + perfects
|
||||||
|
}
|
||||||
|
if (Array.isArray(t.specials)) {
|
||||||
|
v += t.specials.length
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.round(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
readSpecimens,
|
||||||
|
}
|
|
@ -1,47 +0,0 @@
|
||||||
const path = require('path')
|
|
||||||
const chokidar = require('chokidar')
|
|
||||||
const YAML = require('yaml')
|
|
||||||
const fs = require('fs')
|
|
||||||
|
|
||||||
const refresh = async (app, db_dir) => {
|
|
||||||
const gear_path = path.join(db_dir, 'gear.yaml')
|
|
||||||
|
|
||||||
let gear = {}
|
|
||||||
|
|
||||||
YAML.parse(await fs.promises.readFile(gear_path, { encoding: 'utf8' })).forEach((v,i) => {
|
|
||||||
let type = 'untyped'
|
|
||||||
if (v.type) {
|
|
||||||
type = v.type+'s'
|
|
||||||
}
|
|
||||||
if (!gear[type]) {
|
|
||||||
gear[type] = []
|
|
||||||
}
|
|
||||||
gear[type].push(v)
|
|
||||||
})
|
|
||||||
|
|
||||||
app.live = {
|
|
||||||
...app.live,
|
|
||||||
db: {
|
|
||||||
...app.live.db,
|
|
||||||
gear: gear,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
priority: 1,
|
|
||||||
load: async (plugin, app) => {
|
|
||||||
// Load up our DB.
|
|
||||||
const db_dir = path.resolve(path.join(app.config.srd, 'db'))
|
|
||||||
|
|
||||||
await refresh(app, db_dir)
|
|
||||||
|
|
||||||
const watcher = chokidar.watch(db_dir, {persistent: true})
|
|
||||||
watcher.on('change', p => {
|
|
||||||
refresh(app, db_dir)
|
|
||||||
})
|
|
||||||
plugin.log('watching', db_dir)
|
|
||||||
|
|
||||||
app.express.use(require('./route.js')(plugin, app))
|
|
||||||
},
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
const router = require('express').Router()
|
|
||||||
const fs = require('fs')
|
|
||||||
const path = require('path')
|
|
||||||
|
|
||||||
module.exports = (plugin, app) => {
|
|
||||||
// gear, gear/type, gear/type/name
|
|
||||||
router.get(['/gear', '/gear/:type', '/gear/:type/:name'], async function(req, res) {
|
|
||||||
let entry = null
|
|
||||||
if (req.params.name) {
|
|
||||||
if (!app.live.db.gear[req.params.type]) {
|
|
||||||
// TODO: 404 - no such gear type
|
|
||||||
} else {
|
|
||||||
entry = app.live.db.gear[req.params.type].find(v=>v.name===req.params.name)
|
|
||||||
if (!entry) {
|
|
||||||
// TODO: 404 - no such gear by name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res.render('index', {
|
|
||||||
content: app.dot.tables({...req.params, db: app.live.db.gear, entry: entry}),
|
|
||||||
menu: app.live.menu,
|
|
||||||
title: 'gear',
|
|
||||||
www_name: app.live.conf.www_name,
|
|
||||||
www_copyright: app.live.conf.www_copyright,
|
|
||||||
scripts: ['/js/gear.js'],
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
plugin.log('added gear route')
|
|
||||||
|
|
||||||
return router
|
|
||||||
}
|
|
|
@ -11,6 +11,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"markdown-it": "^12.0.6",
|
"markdown-it": "^12.0.6",
|
||||||
"markdown-it-anchor": "^7.1.0",
|
"markdown-it-anchor": "^7.1.0",
|
||||||
|
"markdown-it-attrs": "^4.0.0",
|
||||||
"markdown-it-title": "^3.0.0",
|
"markdown-it-title": "^3.0.0",
|
||||||
"memory-cache": "^0.2.0"
|
"memory-cache": "^0.2.0"
|
||||||
}
|
}
|
||||||
|
@ -59,6 +60,17 @@
|
||||||
"markdown-it": "*"
|
"markdown-it": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/markdown-it-attrs": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-uLjtdCmhhmL3BuZsReYkFxk74qKjj5ahe34teBpOCJ4hYZZl7/ftLyXWLowngC2moRkbLEvKwN/7TMwbhbHE/A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"markdown-it": ">= 9.0.0 < 13.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/markdown-it-title": {
|
"node_modules/markdown-it-title": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/markdown-it-title/-/markdown-it-title-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/markdown-it-title/-/markdown-it-title-3.0.0.tgz",
|
||||||
|
@ -117,6 +129,12 @@
|
||||||
"integrity": "sha512-loQggrwsIkkP7TOrESvmYkV2ikbQNNKhHcWyqC7/C2CmfHl1tkUizJJU8C5aGgg7J6oXVQJx17gk7i47tNn/lQ==",
|
"integrity": "sha512-loQggrwsIkkP7TOrESvmYkV2ikbQNNKhHcWyqC7/C2CmfHl1tkUizJJU8C5aGgg7J6oXVQJx17gk7i47tNn/lQ==",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
|
"markdown-it-attrs": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-uLjtdCmhhmL3BuZsReYkFxk74qKjj5ahe34teBpOCJ4hYZZl7/ftLyXWLowngC2moRkbLEvKwN/7TMwbhbHE/A==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"markdown-it-title": {
|
"markdown-it-title": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/markdown-it-title/-/markdown-it-title-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/markdown-it-title/-/markdown-it-title-3.0.0.tgz",
|
||||||
|
|
|
@ -61,6 +61,7 @@ body {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
background-color: var(--menu-background);
|
background-color: var(--menu-background);
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
#menu a, #menu a:visited {
|
#menu a, #menu a:visited {
|
||||||
color: var(--menu-foreground);
|
color: var(--menu-foreground);
|
||||||
|
@ -149,9 +150,23 @@ p img, li img {
|
||||||
}
|
}
|
||||||
h2 {
|
h2 {
|
||||||
border-bottom: 1px solid #dde;
|
border-bottom: 1px solid #dde;
|
||||||
|
color: #df3f3f;
|
||||||
|
}
|
||||||
|
h2 > a {
|
||||||
|
color: #df3f3f !important;
|
||||||
}
|
}
|
||||||
h3 {
|
h3 {
|
||||||
border-bottom: 1px solid #dfdfef;
|
border-bottom: 1px solid #dfdfef;
|
||||||
|
color: #dfdf5f;
|
||||||
|
}
|
||||||
|
h3 > a {
|
||||||
|
color: #dfdf5f !important;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
color: #df9fdf;
|
||||||
|
}
|
||||||
|
h4 > a {
|
||||||
|
color: #df9fdf !important;
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
transition: .05s ease-in-out;
|
transition: .05s ease-in-out;
|
||||||
|
@ -226,12 +241,30 @@ td:last-child {
|
||||||
}
|
}
|
||||||
.indent2 {
|
.indent2 {
|
||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
|
color: #df3f3f;
|
||||||
|
}
|
||||||
|
.indent2 a {
|
||||||
|
color: #df3f3f;
|
||||||
}
|
}
|
||||||
.indent3 {
|
.indent3 {
|
||||||
margin-left: 2em;
|
margin-left: 2em;
|
||||||
|
color: #dfdf5f;
|
||||||
|
}
|
||||||
|
.indent3 a {
|
||||||
|
color: #dfdf5f;
|
||||||
}
|
}
|
||||||
.indent4 {
|
.indent4 {
|
||||||
margin-left: 3em;
|
margin-left: 3em;
|
||||||
|
color: #df9fdf;
|
||||||
|
}
|
||||||
|
.indent4 a {
|
||||||
|
color: #df9fdf;
|
||||||
|
}
|
||||||
|
.indent5 {
|
||||||
|
margin-left: 4em;
|
||||||
|
}
|
||||||
|
.indent6 {
|
||||||
|
margin-left: 5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#menu ul, #menu li {
|
#menu ul, #menu li {
|
||||||
|
@ -310,3 +343,7 @@ td:last-child {
|
||||||
cursor: copy;
|
cursor: copy;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 70%;
|
||||||
|
}
|
210
views/tables.dot
210
views/tables.dot
|
@ -1,9 +1,15 @@
|
||||||
{{##def.weapons_table_entry:item:
|
{{##def.weapons_table_entry:item:
|
||||||
<tr data-json='{{=JSON.stringify(item)}}'>
|
<tr data-json='{{=JSON.stringify(item)}}'>
|
||||||
<td><a href="/gear/weapons/{{=item.name||''}}"</a>{{=item.name || ''}}</td>
|
<td><a href="/gear/weapon/{{=item.name||''}}"</a>{{=item.name || ''}}</td>
|
||||||
|
<td>{{=item.description || ''}}</td>
|
||||||
<td>{{=item.attack || ''}}</td>
|
<td>{{=item.attack || ''}}</td>
|
||||||
<td>{{=item.damage || ''}}</td>
|
<td>
|
||||||
<td>{{=item.damagetype || ''}}</td>
|
{{~item.damage :damage}}
|
||||||
|
{{=damage.type || 'unknown'}}
|
||||||
|
{{=damage.value || '0' }}
|
||||||
|
{{~}}
|
||||||
|
</td>
|
||||||
|
<td>{{=item.weapontype || ''}}</td>
|
||||||
<td>{{=item.range || ''}}</td>
|
<td>{{=item.range || ''}}</td>
|
||||||
<td>{{=item.radius || ''}}</td>
|
<td>{{=item.radius || ''}}</td>
|
||||||
<td>{{=item.capacity || ''}}</td>
|
<td>{{=item.capacity || ''}}</td>
|
||||||
|
@ -16,16 +22,17 @@
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th><a href="?sort-by=name">Name</a></th>
|
||||||
<th>Attack</th>
|
<th>Description</th>
|
||||||
<th>Damage</th>
|
<th><a href="?sort-by=attack">Attack</a></th>
|
||||||
<th>Type</th>
|
<th><a href="?sort-by=damage">Damage</a></th>
|
||||||
<th>Range</th>
|
<th><a href="?sort-by=weapontype">Type</a></th>
|
||||||
|
<th><a href="?sort-by=range">Range</a></th>
|
||||||
<th>Radius</th>
|
<th>Radius</th>
|
||||||
<th>Capacity</th>
|
<th>Capacity</th>
|
||||||
<th>Duration</th>
|
<th>Duration</th>
|
||||||
<th>Properties</th>
|
<th>Properties</th>
|
||||||
<th>Worth</th>
|
<th><a href="?sort-by=worth">Worth</a></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -36,33 +43,105 @@
|
||||||
</table>
|
</table>
|
||||||
#}}
|
#}}
|
||||||
|
|
||||||
{{##def.consumables_table_entry:item:
|
{{##def.armor_table_entry:item:
|
||||||
<tr data-json='{{=JSON.stringify(item)}}'>
|
<tr data-json='{{=JSON.stringify(item)}}'>
|
||||||
<td><a href="/gear/consumables/{{=item.name||''}}"</a>{{=item.name || ''}}</td>
|
<td><a href="/gear/armor/{{=item.name||''}}"</a>{{=item.name || ''}}</td>
|
||||||
<td>{{=item.duration || ''}}</td>
|
<td>{{=item.description || ''}}</td>
|
||||||
|
<td>
|
||||||
|
{{~item.defense :defense}}
|
||||||
|
{{=defense.type || 'unknown'}}
|
||||||
|
{{=defense.value || '0' }}
|
||||||
|
{{? defense.perfect }}+ {{?}}
|
||||||
|
{{~}}
|
||||||
|
</td>
|
||||||
<td>{{=item.properties || ''}}</td>
|
<td>{{=item.properties || ''}}</td>
|
||||||
<td>{{=item.worth || ''}}</td>
|
<td>{{=item.worth || ''}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
#}}
|
#}}
|
||||||
|
{{##def.armor_table:it:
|
||||||
{{##def.consumables_table:it:
|
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th><a href="?sort-by=name">Name</a></th>
|
||||||
<th>Duration</th>
|
<th>Description</th>
|
||||||
|
<th>Defense</th>
|
||||||
<th>Properties</th>
|
<th>Properties</th>
|
||||||
<th>Worth</th>
|
<th><a href="?sort-by=worth">Worth</a></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{~it :item:index}}
|
{{~it :item:index}}
|
||||||
{{#def.consumables_table_entry:item || ''}}
|
{{#def.armor_table_entry:item || ''}}
|
||||||
{{~}}
|
{{~}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
#}}
|
#}}
|
||||||
|
|
||||||
|
{{##def.misc_table_entry:item:
|
||||||
|
<tr data-json='{{=JSON.stringify(item)}}'>
|
||||||
|
<td><a href="/gear/misc/{{=item.name||''}}"</a>{{=item.name || ''}}</td>
|
||||||
|
<td>{{=item.description || ''}}</td>
|
||||||
|
<td>{{=item.properties || ''}}</td>
|
||||||
|
<td>{{=item.worth || ''}}</td>
|
||||||
|
</tr>
|
||||||
|
#}}
|
||||||
|
{{##def.misc_table:it:
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><a href="?sort-by=name">Name</a></th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Properties</th>
|
||||||
|
<th><a href="?sort-by=worth">Worth</a></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{~it :item:index}}
|
||||||
|
{{#def.misc_table_entry:item || ''}}
|
||||||
|
{{~}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
#}}
|
||||||
|
|
||||||
|
{{##def.consumables_table_entry:item:
|
||||||
|
<h3><a href="/db/consumables/{{=item.name || ''}}">{{=item.name || ''}}</a> <span data-json='{{=JSON.stringify(item)}}'></span> </h3>
|
||||||
|
<p>{{=item.description || ''}}</p>
|
||||||
|
{{?item.properties.length}}
|
||||||
|
{{~item.properties :property}}
|
||||||
|
<strong><em>{{=property.name}}</em></strong>:
|
||||||
|
{{=property.description}}
|
||||||
|
<br/>
|
||||||
|
{{~}}
|
||||||
|
{{?}}
|
||||||
|
|
||||||
|
{{?item.range}}
|
||||||
|
<strong>Range</strong> {{=item.range}};
|
||||||
|
{{?}}
|
||||||
|
{{?item.radius}}
|
||||||
|
<strong>Radius</strong> {{=item.radius}};
|
||||||
|
{{?}}
|
||||||
|
{{?item.duration}}
|
||||||
|
<strong>Duration</strong> {{=item.duration}};
|
||||||
|
{{?}}
|
||||||
|
{{?item.worth}}
|
||||||
|
<strong>Worth</strong> {{=item.worth}};
|
||||||
|
{{?}}
|
||||||
|
<br/>
|
||||||
|
{{?item.damage.length}}
|
||||||
|
<strong>Damage</strong>
|
||||||
|
{{~item.damage :damage}}
|
||||||
|
{{=damage.value || '0' }}({{=damage.type || 'unknown'}})
|
||||||
|
{{~}}
|
||||||
|
{{?}}
|
||||||
|
#}}
|
||||||
|
|
||||||
|
{{##def.consumables_table:it:
|
||||||
|
Sort: <a href="?sort-by=name">Name</a> <a href="?sort-by=worth">Worth</a>
|
||||||
|
{{~it :item:index}}
|
||||||
|
{{#def.consumables_table_entry:item || ''}}
|
||||||
|
{{~}}
|
||||||
|
#}}
|
||||||
|
|
||||||
{{##def.entry:it:
|
{{##def.entry:it:
|
||||||
<h1>{{=it.name || ''}}</h1>
|
<h1>{{=it.name || ''}}</h1>
|
||||||
<dl>
|
<dl>
|
||||||
|
@ -79,9 +158,88 @@
|
||||||
</dl>
|
</dl>
|
||||||
#}}
|
#}}
|
||||||
|
|
||||||
{{? it.entry }}
|
{{##def.specimens_table_entry:item:
|
||||||
{{#def.entry:it.entry || ''}}
|
<h2><a href="/db/specimens/{{=item.type||''}}/{{=item.name || ''}}">{{=item.name || ''}}</a><span data-json='{{=JSON.stringify(item)}}'></span> </h2>
|
||||||
{{?? !it.type }}
|
<p>{{=item.description || ''}}</p>
|
||||||
|
<strong>Move</strong> {{=item.move || ''}};
|
||||||
|
<strong>Attack</strong> {{=item.attack || ''}};
|
||||||
|
<strong>Health</strong> {{=item.health || ''}} (<a href="#" data-flip="+{{=item.health}}"></a>);
|
||||||
|
<strong>CV</strong> {{=item.combatvalue || ''}}
|
||||||
|
<h3>Attacks</h3>
|
||||||
|
{{~item.attacks :attack}}
|
||||||
|
<h4> {{=attack.name || 'unknown'}} ({{=attack.attacktype || 'melee' }}) </h4>
|
||||||
|
<strong>Attack</strong>: {{=attack.attack || '0' }};
|
||||||
|
<strong>Damage</strong>:
|
||||||
|
{{~attack.damage :damage}}
|
||||||
|
{{=damage.value || '0' }}({{=damage.type || 'unknown'}})
|
||||||
|
{{~}};
|
||||||
|
<strong>Range</strong>: {{=damage.range || '-' }};
|
||||||
|
<strong>Radius</strong>: {{=damage.radius || '-' }}
|
||||||
|
<br/>
|
||||||
|
{{~attack.properties :prop}}
|
||||||
|
<strong>{{=prop.name || ''}}</strong>
|
||||||
|
<br/>
|
||||||
|
<p>{{=prop.description || ''}}</p>
|
||||||
|
{{~}}
|
||||||
|
{{~}}
|
||||||
|
<h3>Specials</h3>
|
||||||
|
{{~item.specials :special}}
|
||||||
|
<h4> {{=special.name || 'unknown'}} </h4>
|
||||||
|
<p> {{=special.description || ''}} </p>
|
||||||
|
{{~}}
|
||||||
|
#}}
|
||||||
|
{{##def.specimens_table:it:
|
||||||
|
{{~it :item:index}}
|
||||||
|
{{#def.specimens_table_entry:item || ''}}
|
||||||
|
{{~}}
|
||||||
|
#}}
|
||||||
|
|
||||||
|
{{? it.results }}
|
||||||
|
{{#def.entry:it.results[0] || ''}}
|
||||||
|
{{? it.collection === "gear" }}
|
||||||
|
<h1><a href="/db/gear/">Gear</a></h1>
|
||||||
|
{{? it.type }}
|
||||||
|
{{? it.type === "weapon"}}
|
||||||
|
<h2>Weapons</h2>
|
||||||
|
{{#def.weapons_table:it.results || ''}}
|
||||||
|
{{?? it.type === "armor"}}
|
||||||
|
<h2>Armor</h2>
|
||||||
|
{{#def.armor_table:it.results || ''}}
|
||||||
|
{{?? it.type === "consumable"}}
|
||||||
|
<h2>Consumables</h2>
|
||||||
|
{{#def.consumables_table:it.results || ''}}
|
||||||
|
{{?? it.type === "misc"}}
|
||||||
|
<h2>Misc</h2>
|
||||||
|
{{#def.misc_table:it.results || ''}}
|
||||||
|
{{?}}
|
||||||
|
{{?? true }}
|
||||||
|
<h2><a href="armor/">Armor</a></h2>
|
||||||
|
<h2><a href="misc/">Misc</a></h2>
|
||||||
|
<h2><a href="weapon/">Weapons</a></h2>
|
||||||
|
<h2><a href="consumable/">Consumables</a></h2>
|
||||||
|
{{?}}
|
||||||
|
{{?? it.collection === "specimens" }}
|
||||||
|
{{? it.type }}
|
||||||
|
<h1>Specimens: Hord</h1>
|
||||||
|
{{#def.specimens_table:it.results || ''}}
|
||||||
|
{{?? true }}
|
||||||
|
<h1>Specimens</h1>
|
||||||
|
TODO: listing
|
||||||
|
{{?}}
|
||||||
|
|
||||||
|
{{?}}
|
||||||
|
|
||||||
|
{{?? !it.name }}
|
||||||
|
{{? it.type === "weapon"}}
|
||||||
|
<h1>Weapons</h1>
|
||||||
|
{{#def.weapons_table:it.results || ''}}
|
||||||
|
{{?? it.type === "consumable"}}
|
||||||
|
<h1>Consumables</h1>
|
||||||
|
{{#def.consumables_table:it.results || ''}}
|
||||||
|
{{?? true }}
|
||||||
|
Bad type
|
||||||
|
{{?}}
|
||||||
|
{{?? true }}
|
||||||
<h1>Gear</h1>
|
<h1>Gear</h1>
|
||||||
{{? it.db.weapons }}
|
{{? it.db.weapons }}
|
||||||
<h2><a href="gear/weapons">Weapons</a></h2>
|
<h2><a href="gear/weapons">Weapons</a></h2>
|
||||||
|
@ -92,14 +250,4 @@
|
||||||
<h2><a href="gear/consumables">Consumables</a></h2>
|
<h2><a href="gear/consumables">Consumables</a></h2>
|
||||||
{{#def.consumables_table:it.db.consumables || ''}}
|
{{#def.consumables_table:it.db.consumables || ''}}
|
||||||
{{?}}
|
{{?}}
|
||||||
{{?? true }}
|
|
||||||
{{? it.type === "weapons"}}
|
|
||||||
<h1>Weapons</h1>
|
|
||||||
{{#def.weapons_table:it.db.weapons || ''}}
|
|
||||||
{{?? it.type === "consumables"}}
|
|
||||||
<h1>Consumables</h1>
|
|
||||||
{{#def.consumables_table:it.db.consumables || ''}}
|
|
||||||
{{?? true }}
|
|
||||||
Bad type
|
|
||||||
{{?}}
|
|
||||||
{{?}}
|
{{?}}
|
||||||
|
|
Loading…
Reference in New Issue