Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
e88c8486a1 | |||
16dbc6c4e2 | |||
14f8f134bc | |||
ea30628ef8 | |||
e1d7c7fcc7 | |||
ee5bcd23fa | |||
b6add64d14 | |||
19e34583d1 | |||
7e296b2468 | |||
e9988d4a14 | |||
4ccbd17607 | |||
7eb1ad9f7d | |||
14bc0c1e64 | |||
4d1e8d6753 | |||
468d48cc00 | |||
778a9882b8 | |||
60985c8c09 | |||
e2d32ab0a0 | |||
136e85dd14 | |||
2fc3338d0f |
74
.gitlab-ci.yml
Normal file
74
.gitlab-ci.yml
Normal file
@ -0,0 +1,74 @@
|
||||
stages:
|
||||
- prepare
|
||||
- build
|
||||
- test
|
||||
- update
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
TIMEZONE: "America/New_York" # For the system in general
|
||||
DATE_TIMEZONE: ${TIMEZONE} # For PHP
|
||||
|
||||
GIT_DEPTH: 1
|
||||
GITLAB_API_URL: ${CI_API_V4_URL}
|
||||
TARGET_BRANCH: ${CI_COMMIT_REF_NAME} # This is the branch chosen in the `Pipeline Schedule`
|
||||
TARGET_REMOTE: "https://${GITLAB_USERNAME}:${GITLAB_ACCESS_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}.git"
|
||||
|
||||
# These could/should be overridden in an extending job:
|
||||
UPDATE_BRANCH_PREFIX: "update_PHP_deps_" # Used for the update branch name, it will be followed by the datetime
|
||||
GIT_USER: "DependBot" # Used for the update commit
|
||||
GIT_EMAIL: "webmaster@thetempusproject.com" # Used for the update commit
|
||||
GITLAB_USERNAME: "root" # Used for pushing the new branch and opening the MR
|
||||
GITLAB_ACCESS_TOKEN: "glpat-PKEmivGtBfbz4DVPdhzk" # Used for pushing the new branch and opening the MR
|
||||
MERGE_IF_SUCCESSFUL: "true" # Set to true, to merge automatically if the pipeline succeeds
|
||||
SECONDS_BETWEEN_POOLING: 10 # Nbr of seconds between checking if the MR pipeline is successful, so then it will merge
|
||||
JOB_GIT_FLAGS: ""
|
||||
JOB_CURL_FLAGS: ""
|
||||
JOB_COMPOSER_FLAGS: ""
|
||||
|
||||
composer_update:
|
||||
stage: update
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == "main"'
|
||||
image: composer:latest
|
||||
interruptible: true # allows to stop the job if a newer pipeline starts, saving resources and allowing new jobs to start because job concurrency is limited
|
||||
script:
|
||||
- git ${JOB_GIT_FLAGS} fetch origin ${TARGET_BRANCH}
|
||||
- git ${JOB_GIT_FLAGS} checkout ${TARGET_BRANCH}
|
||||
- git reset --hard origin/main
|
||||
- git pull --allow-unrelated-histories
|
||||
- export DATE_TIME="$(date '+%Y%m%d%H%M%S')"
|
||||
- export MR_BRANCH="${UPDATE_BRANCH_PREFIX}${DATE_TIME}"
|
||||
- git ${JOB_GIT_FLAGS} checkout -b "${MR_BRANCH}"
|
||||
- composer update ${JOB_COMPOSER_FLAGS}
|
||||
- if [ "$(git diff)" == "" ]; then echo "No updates needed!"; exit 0; fi
|
||||
- export TITLE="Update PHP dependencies [${DATE_TIME}]"
|
||||
- git ${JOB_GIT_FLAGS} commit -a -m "${TITLE}"
|
||||
- git ${JOB_GIT_FLAGS} push "${TARGET_REMOTE}" "${MR_BRANCH}"
|
||||
artifacts:
|
||||
paths:
|
||||
- vendor/
|
||||
cache:
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
paths:
|
||||
- vendor/
|
||||
|
||||
prepare:
|
||||
stage: prepare
|
||||
script:
|
||||
- echo "Preparing environment..."
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- echo "Building the project..."
|
||||
|
||||
test:
|
||||
stage: test
|
||||
script:
|
||||
- echo "Running tests..."
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "Deploying the project..."
|
@ -326,7 +326,7 @@ class Installer {
|
||||
}
|
||||
|
||||
if ( empty( $module_data->class_object ) ) {
|
||||
self::$errors[] = [ 'errorInfo' => 'Class not found: ' . $module_data->class ];
|
||||
self::$errors[] = [ 'errorInfo' => 'installPlugin: class_object not found: ' . $module_data->class ];
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -373,7 +373,7 @@ class Installer {
|
||||
$errors = [];
|
||||
|
||||
if ( empty( $module_data->class_object ) ) {
|
||||
self::$errors[] = [ 'errorInfo' => 'Class not found: ' . $module_data->class ];
|
||||
self::$errors[] = [ 'errorInfo' => 'uninstallPlugin: class_object not found: ' . $module_data->class ];
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -408,7 +408,7 @@ class Installer {
|
||||
}
|
||||
|
||||
if ( empty( $module_data->class_object ) ) {
|
||||
self::$errors[] = [ 'errorInfo' => 'Class not found: ' . $module_data->class ];
|
||||
self::$errors[] = [ 'errorInfo' => 'installModel class_object not found: ' . $module_data->class ];
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -475,7 +475,7 @@ class Installer {
|
||||
$errors = [];
|
||||
|
||||
if ( empty( $module_data->class_object ) ) {
|
||||
self::$errors[] = [ 'errorInfo' => 'Class not found: ' . $module_data->class ];
|
||||
self::$errors[] = [ 'errorInfo' => 'uninstallModel: class_object not found: ' . $module_data->class ];
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dashboards/controllers/dice.php
|
||||
*
|
||||
* This is the home controller for the dashboards plugin.
|
||||
*
|
||||
* @package TP Dashboards
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Controllers;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Classes\Controller;
|
||||
use TheTempusProject\Houdini\Classes\Template;
|
||||
|
||||
class Dashboards extends Controller {
|
||||
public function index() {
|
||||
self::$title = 'Dashboards - {SITENAME}';
|
||||
self::$pageDescription = 'Your new home on the internet.';
|
||||
Template::setTemplate( 'dashboards' );
|
||||
Views::view( 'dashboards.index' );
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/* for the google form */
|
||||
form {
|
||||
display: flex;
|
||||
}
|
||||
input[type="text"] {
|
||||
padding: 10px;
|
||||
font-size: 16px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px 0 0 4px;
|
||||
outline: none;
|
||||
}
|
||||
button {
|
||||
padding: 10px 20px;
|
||||
font-size: 16px;
|
||||
border: 1px solid #ccc;
|
||||
border-left: none;
|
||||
border-radius: 0 4px 4px 0;
|
||||
background-color: #f8f8f8;
|
||||
cursor: pointer;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* for the weather */
|
||||
|
||||
#weather-widget {
|
||||
border: 1px solid #ccc;
|
||||
padding: 20px;
|
||||
width: 300px;
|
||||
margin: 20px auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#zipcode {
|
||||
padding: 5px;
|
||||
width: calc(100% - 12px);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#lookup-btn {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
#weather-result {
|
||||
margin-top: 20px;
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
// chatGPT
|
||||
function forwardToChatGPT() {
|
||||
var query = document.getElementById("chatgptQuery").value;
|
||||
var url = "https://chat.openai.com/?q=" + encodeURIComponent(query);
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// base script
|
||||
$( document ).ready( function () {
|
||||
console.log('dashboards.js loaded');
|
||||
|
||||
|
||||
|
||||
const apiKey = 'b502235c1de669b105047b6896f81eb6'; // Replace with your weather API key
|
||||
const geoApiKey = '2c50be5398ec45e79655a590d62d6fd8'; // Replace with your geolocation API key
|
||||
|
||||
const zipcodeInput = document.getElementById('zipcode');
|
||||
const lookupBtn = document.getElementById('lookup-btn');
|
||||
const weatherResult = document.getElementById('weather-result');
|
||||
|
||||
// Get the stored zip code from cookies
|
||||
const storedZipCode = getCookie('zipcode');
|
||||
if (storedZipCode) {
|
||||
zipcodeInput.value = storedZipCode;
|
||||
getWeather(storedZipCode);
|
||||
} else {
|
||||
getZipCodeFromIP();
|
||||
}
|
||||
|
||||
lookupBtn.addEventListener('click', function() {
|
||||
const zipcode = zipcodeInput.value;
|
||||
if (zipcode) {
|
||||
setCookie('zipcode', zipcode, 7); // Store the zip code in a cookie for 7 days
|
||||
getWeather(zipcode);
|
||||
}
|
||||
});
|
||||
|
||||
function getZipCodeFromIP() {
|
||||
fetch(`https://api.ipgeolocation.io/ipgeo?apiKey=${geoApiKey}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const zipcode = data.zipcode;
|
||||
zipcodeInput.value = zipcode;
|
||||
setCookie('zipcode', zipcode, 7);
|
||||
getWeather(zipcode);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error getting location:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function getWeather(zipcode) {
|
||||
fetch(`https://api.openweathermap.org/data/2.5/weather?zip=${zipcode}&appid=${apiKey}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
displayWeather(data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching weather data:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function displayWeather(data) {
|
||||
if (data.cod === 200) {
|
||||
weatherResult.innerHTML = `
|
||||
<h4>Weather for ${data.name}</h4>
|
||||
<p>Temperature: ${(data.main.temp - 273.15).toFixed(2)}°C</p>
|
||||
<p>Condition: ${data.weather[0].description}</p>
|
||||
`;
|
||||
} else {
|
||||
weatherResult.innerHTML = `<p>Error: ${data.message}</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
function setCookie(name, value, days) {
|
||||
const d = new Date();
|
||||
d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
const expires = "expires=" + d.toUTCString();
|
||||
document.cookie = name + "=" + value + ";" + expires + ";path=/";
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
const nameEQ = name + "=";
|
||||
const ca = document.cookie.split(';');
|
||||
for(let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
|
||||
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
});
|
@ -1,54 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dashboards/models/dashboards.php
|
||||
*
|
||||
* This class is used for the manipulation of the dashboards database table.
|
||||
*
|
||||
* @todo make this send a confirmation email
|
||||
*
|
||||
* @package TP Dashboards
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\Plugins\Dashboards as Plugin;
|
||||
|
||||
class Dashboards extends DatabaseModel {
|
||||
public $tableName = 'dashboards';
|
||||
public $databaseMatrix = [
|
||||
[ 'name', 'varchar', '128' ],
|
||||
];
|
||||
public $plugin;
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->plugin = new Plugin;
|
||||
}
|
||||
public function create( $name, $email, $dashboard ) {
|
||||
if ( !$this->plugin->checkEnabled() ) {
|
||||
Debug::info( 'Dashboards are disabled in the config.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'time' => time(),
|
||||
'ip' => $_SERVER['REMOTE_ADDR'],
|
||||
];
|
||||
if ( !self::$db->insert( $this->tableName, $fields ) ) {
|
||||
Debug::info( 'Dashboards::create - failed to insert to db' );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dashboards/plugin.php
|
||||
*
|
||||
* This houses all of the main plugin info and functionality.
|
||||
*
|
||||
* @package TP Testing
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Plugins;
|
||||
|
||||
use TheTempusProject\Classes\Plugin;
|
||||
|
||||
class Dashboards extends Plugin {
|
||||
public $pluginName = 'TP Dashboards';
|
||||
public $pluginAuthor = 'JoeyK';
|
||||
public $pluginWebsite = 'https://TheTempusProject.com';
|
||||
public $modelVersion = '1.0';
|
||||
public $pluginVersion = '3.0';
|
||||
public $pluginDescription = 'A simple plugin for adding and showing custom user dashboards.';
|
||||
|
||||
public function __construct( $load = false ) {
|
||||
parent::__construct( $load );
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dashboards/templates/dashboards.inc.php
|
||||
*
|
||||
* This is the loader for the dashboards template.
|
||||
*
|
||||
* @package TP Dashboards
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Templates;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Houdini\Classes\Navigation;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Models\Dashboards;
|
||||
|
||||
class DashboardsLoader extends DefaultLoader {
|
||||
/**
|
||||
* This is the function used to generate any components that may be
|
||||
* needed by this template.
|
||||
*/
|
||||
public function __construct() {
|
||||
$dashboards = new Dashboards;
|
||||
$this->addJs( '<script language="JavaScript" crossorigin="anonymous" type="text/javascript" src="{ROOT_URL}app/plugins/dashboards/js/dashboards.js"></script>' );
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--
|
||||
* app/plugins/dashboards/templates/dashboards.tpl
|
||||
*
|
||||
* @package TP Dashboards
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta property="og:url" content="{CURRENT_URL}">
|
||||
<meta name='twitter:card' content='summary' />
|
||||
<title>{TITLE}</title>
|
||||
<meta itemprop="name" content="{TITLE}">
|
||||
<meta name="twitter:title" content="{TITLE}">
|
||||
<meta property="og:title" content="{TITLE}">
|
||||
<meta name="description" content="{PAGE_DESCRIPTION}">
|
||||
<meta itemprop="description" content="{PAGE_DESCRIPTION}">
|
||||
<meta name="twitter:description" content="{PAGE_DESCRIPTION}">
|
||||
<meta property="og:description" content="{PAGE_DESCRIPTION}">
|
||||
<meta itemprop="image" content="{META_IMAGE}">
|
||||
<meta name="twitter:image" content="{META_IMAGE}">
|
||||
<meta property="og:image" content="{META_IMAGE}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="author" content="The Tempus Project">
|
||||
{ROBOT}
|
||||
<link rel="alternate" hreflang="en-us" href="alternateURL">
|
||||
<link rel="icon" href="{ROOT_URL}images/favicon.ico">
|
||||
<!-- Required CSS -->
|
||||
<link rel="stylesheet" href="{FONT_AWESOME_URL}font-awesome.min.css" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="{BOOTSTRAP_CDN}css/bootstrap-theme.min.css" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="{BOOTSTRAP_CDN}css/bootstrap.min.css" crossorigin="anonymous">
|
||||
<!-- RSS -->
|
||||
<link rel="alternate" href="{ROOT_URL}blog/rss" title="{TITLE} Feed" type="application/rss+xml" />
|
||||
<!-- Custom styles for this template -->
|
||||
{TEMPLATE_CSS_INCLUDES}
|
||||
<link rel="stylesheet" href="{ROOT_URL}app/plugins/dashboards/css/dashboards.css" />
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||
<!--Brand and toggle should get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<a href="{ROOT_URL}" class="navbar-brand">{SITENAME}</a>
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse" style="">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="collapse navbar-collapse navbar-ex1-collapse">
|
||||
{topNavLeft}
|
||||
<div class="navbar-right">
|
||||
<ul class="nav navbar-nav">
|
||||
{topNavRight}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container-fluid top-pad foot-pad">
|
||||
{ISSUES}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
{ERROR}
|
||||
{NOTICE}
|
||||
{SUCCESS}
|
||||
{INFO}
|
||||
</div>
|
||||
</div>
|
||||
{/ISSUES}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
{CONTENT}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
{COPY}
|
||||
</footer>
|
||||
|
||||
<!-- Bootstrap core JavaScript and jquery -->
|
||||
<script src="{JQUERY_CDN}jquery.min.js" crossorigin="anonymous"></script>
|
||||
<script src="{BOOTSTRAP_CDN}js/bootstrap.min.js" crossorigin="anonymous"></script>
|
||||
<!-- Custom javascript for this template -->
|
||||
{TEMPLATE_JS_INCLUDES}
|
||||
</body>
|
||||
</html>
|
@ -1,27 +0,0 @@
|
||||
this is the dashboard index
|
||||
|
||||
|
||||
|
||||
<h3>Google Search</h3>
|
||||
<form action="https://www.google.com/search" method="GET">
|
||||
<input type="text" name="q" placeholder="Search Google" required>
|
||||
<button type="submit">Search</button>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
<h3>Ask ChatGPT</h3>
|
||||
<form onsubmit="event.preventDefault(); forwardToChatGPT();">
|
||||
<textarea id="chatgptQuery" rows="10" cols="50" maxlength="4096"></textarea><br>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Weather Lookup</h3>
|
||||
<div id="weather-widget">
|
||||
<input type="text" id="zipcode" placeholder="Enter Zip Code">
|
||||
<button id="lookup-btn">Lookup Weather</button>
|
||||
<div id="weather-result"></div>
|
||||
</div>
|
@ -1,43 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dice/controllers/dice.php
|
||||
*
|
||||
* This is the home controller for the dice plugin.
|
||||
*
|
||||
* @package TP Dice
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Controllers;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Classes\Controller;
|
||||
use TheTempusProject\Models\Dicehistory;
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
|
||||
class Dice extends Controller {
|
||||
protected static $diceHistory;
|
||||
|
||||
public function __construct() {
|
||||
self::$title = 'Dice Rollers - {SITENAME}';
|
||||
self::$pageDescription = 'These dice should be able to help you roll just about any combination you would encounter in normal play.';
|
||||
self::$diceHistory = new Dicehistory;
|
||||
if ( ! App::$isLoggedIn ) {
|
||||
Issues::add( 'info', 'If you register an account and log in, you can save your dice roll history.' );
|
||||
Components::set( 'diceHistory', '' );
|
||||
} else {
|
||||
$history = self::$diceHistory->userHistory();
|
||||
$historyView = Views::simpleView( 'dice.historyElement', $history );
|
||||
Components::set( 'diceHistory', $historyView );
|
||||
}
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function index() {
|
||||
Views::view( 'dice.index' );
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
.die-btn {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 30px;
|
||||
width: 145px;
|
||||
}
|
||||
|
||||
.input-number {
|
||||
width: 185px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.center-inputs {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.roll-result-well {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.round-footer {
|
||||
padding-right: 15px;
|
||||
padding-bottom: 40px;
|
||||
padding-left: 15px;
|
||||
}
|
@ -1,416 +0,0 @@
|
||||
const d2Btn = document.getElementById('d2-roll');
|
||||
const d4Btn = document.getElementById('d4-roll');
|
||||
const d6Btn = document.getElementById('d6-roll');
|
||||
const d8Btn = document.getElementById('d8-roll');
|
||||
const d10Btn = document.getElementById('d10-roll');
|
||||
const d12Btn = document.getElementById('d12-roll');
|
||||
const d20Btn = document.getElementById('d20-roll');
|
||||
const d100Btn = document.getElementById('d100-roll');
|
||||
const dxBtn = document.getElementById('dx-roll');
|
||||
|
||||
const dice = document.getElementById('last-roll-dice');
|
||||
const mods = document.getElementById('last-roll-dice-with-mods');
|
||||
const bonuses = document.getElementById('dice-total-with-bonuses');
|
||||
const total = document.getElementById('dice-total');
|
||||
const results = document.getElementById('roll-results');
|
||||
const history = document.getElementById('roll-history');
|
||||
const rollType = document.getElementById('roll-type');
|
||||
|
||||
window.addEventListener('DOMContentLoaded', (event) => {
|
||||
d2Btn.addEventListener('click', rollD2);
|
||||
d4Btn.addEventListener('click', rollD4);
|
||||
d6Btn.addEventListener('click', rollD6);
|
||||
d8Btn.addEventListener('click', rollD8);
|
||||
d10Btn.addEventListener('click', rollD10);
|
||||
d12Btn.addEventListener('click', rollD12);
|
||||
d20Btn.addEventListener('click', rollD20);
|
||||
d100Btn.addEventListener('click', rollD100);
|
||||
dxBtn.addEventListener('click', rollDx);
|
||||
});
|
||||
|
||||
$(document).ready(function() {
|
||||
$(document).on('click', '.mod-minus', function() {
|
||||
var inputValue = $(this).closest('.input-group').find('input').val();
|
||||
var newValue;
|
||||
if ( inputValue ) {
|
||||
newValue = parseInt(inputValue, 10) - 1;
|
||||
} else {
|
||||
newValue = -1;
|
||||
}
|
||||
$(this).closest('.input-group').find('input').val( newValue );
|
||||
});
|
||||
$(document).on('click', '.mod-plus', function() {
|
||||
var inputValue = $(this).closest('.input-group').find('input').val();
|
||||
var newValue;
|
||||
if ( inputValue ) {
|
||||
newValue = parseInt(inputValue, 10) + 1;
|
||||
} else {
|
||||
newValue = 1;
|
||||
}
|
||||
$(this).closest('.input-group').find('input').val( newValue );
|
||||
});
|
||||
$(document).on('click', '.bonus-minus', function() {
|
||||
var inputValue = $(this).closest('.input-group').find('input').val();
|
||||
var newValue;
|
||||
if ( inputValue ) {
|
||||
newValue = parseInt(inputValue, 10) - 1;
|
||||
} else {
|
||||
newValue = -1;
|
||||
}
|
||||
$(this).closest('.input-group').find('input').val( newValue );
|
||||
});
|
||||
$(document).on('click', '.bonus-plus', function() {
|
||||
var inputValue = $(this).closest('.input-group').find('input').val();
|
||||
var newValue;
|
||||
if ( inputValue ) {
|
||||
newValue = parseInt(inputValue, 10) + 1;
|
||||
} else {
|
||||
newValue = 1;
|
||||
}
|
||||
$(this).closest('.input-group').find('input').val( newValue );
|
||||
});
|
||||
$(document).on('click', '.die-minus', function() {
|
||||
var inputValue = $(this).closest('.input-group').find('input').val();
|
||||
var newValue;
|
||||
if ( '1' == inputValue ) {
|
||||
return;
|
||||
}
|
||||
if ( !inputValue ) {
|
||||
newValue = '1';
|
||||
} else {
|
||||
newValue = parseInt(inputValue, 10) - 1;
|
||||
}
|
||||
$(this).closest('.input-group').find('input').val( newValue );
|
||||
});
|
||||
$(document).on('click', '.die-plus', function() {
|
||||
var inputValue = $(this).closest('.input-group').find('input').val();
|
||||
var newValue;
|
||||
if ( inputValue ) {
|
||||
newValue = parseInt(inputValue, 10) + 1;
|
||||
} else {
|
||||
newValue = 2;
|
||||
}
|
||||
$(this).closest('.input-group').find('input').val( newValue );
|
||||
});
|
||||
$(document).on('click', '.face-minus', function() {
|
||||
var inputValue = $(this).closest('.input-group').find('input').val();
|
||||
var newValue;
|
||||
if ( '2' == inputValue ) {
|
||||
return;
|
||||
}
|
||||
if ( !inputValue ) {
|
||||
newValue = '2';
|
||||
} else {
|
||||
newValue = parseInt(inputValue, 10) - 1;
|
||||
}
|
||||
$(this).closest('.input-group').find('input').val( newValue );
|
||||
});
|
||||
$(document).on('click', '.face-plus', function() {
|
||||
var inputValue = $(this).closest('.input-group').find('input').val();
|
||||
var newValue;
|
||||
if ( inputValue ) {
|
||||
newValue = parseInt(inputValue, 10) + 1;
|
||||
} else {
|
||||
newValue = 3;
|
||||
}
|
||||
$(this).closest('.input-group').find('input').val( newValue );
|
||||
});
|
||||
$(document).on('click', '.history-remove', function() {
|
||||
$(this).closest('tr').remove();
|
||||
});
|
||||
$(document).on('click', '#history-clear', function() {
|
||||
$('#roll-history-table').empty();
|
||||
});
|
||||
});
|
||||
|
||||
const rollD2 = async function (event) {
|
||||
event.preventDefault();
|
||||
var resultDiv = document.getElementById('d2-last-roll');
|
||||
var dieCount = document.getElementById('d2-die-count').value;
|
||||
let rolls = [];
|
||||
if ( !dieCount ) {
|
||||
dieCount = 1;
|
||||
}
|
||||
for (let index = 0; index < dieCount; index++) {
|
||||
var roll = getRandomInt( 1, 3 );
|
||||
if ( roll > 1 ) {
|
||||
roll = 'Heads';
|
||||
} else {
|
||||
roll = 'Tails';
|
||||
}
|
||||
rolls.push( roll );
|
||||
}
|
||||
resetResults();
|
||||
updateLastRollDice( rolls );
|
||||
rollType.innerText = 'Coin';
|
||||
resultDiv.innerText = rolls.filter(result => result === 'Heads').length + ' ("Heads")';
|
||||
addRollHistory();
|
||||
}
|
||||
|
||||
const rollD4 = async function (event) {
|
||||
event.preventDefault();
|
||||
var resultDiv = document.getElementById('d4-last-roll');
|
||||
var mod = document.getElementById('d4-mod').value;
|
||||
var bonus = document.getElementById('d4-bonus').value;
|
||||
var dieCount = document.getElementById('d4-die-count').value;
|
||||
let rolls = [];
|
||||
if ( !dieCount ) {
|
||||
dieCount = 1;
|
||||
}
|
||||
for (let index = 0; index < dieCount; index++) {
|
||||
rolls.push( getRandomInt( 1, 5 ) );
|
||||
}
|
||||
updateLastRoll( rolls, mod, bonus );
|
||||
rollType.innerText = 'D4';
|
||||
resultDiv.innerText = calculateTotalWithModAndBonus( rolls, mod, bonus );
|
||||
addRollHistory();
|
||||
}
|
||||
|
||||
const rollD6 = async function (event) {
|
||||
event.preventDefault();
|
||||
var resultDiv = document.getElementById('d6-last-roll');
|
||||
var mod = document.getElementById('d6-mod').value;
|
||||
var bonus = document.getElementById('d6-bonus').value;
|
||||
var dieCount = document.getElementById('d6-die-count').value;
|
||||
let rolls = [];
|
||||
if ( !dieCount ) {
|
||||
dieCount = 1;
|
||||
}
|
||||
for (let index = 0; index < dieCount; index++) {
|
||||
rolls.push( getRandomInt( 1, 7 ) );
|
||||
}
|
||||
updateLastRoll( rolls, mod, bonus );
|
||||
rollType.innerText = 'D6';
|
||||
resultDiv.innerText = calculateTotalWithModAndBonus( rolls, mod, bonus );
|
||||
addRollHistory();
|
||||
}
|
||||
|
||||
const rollD8 = async function (event) {
|
||||
event.preventDefault();
|
||||
var resultDiv = document.getElementById('d8-last-roll');
|
||||
var mod = document.getElementById('d8-mod').value;
|
||||
var bonus = document.getElementById('d8-bonus').value;
|
||||
var dieCount = document.getElementById('d8-die-count').value;
|
||||
let rolls = [];
|
||||
if ( !dieCount ) {
|
||||
dieCount = 1;
|
||||
}
|
||||
for (let index = 0; index < dieCount; index++) {
|
||||
rolls.push( getRandomInt( 1, 9 ) );
|
||||
}
|
||||
updateLastRoll( rolls, mod, bonus );
|
||||
rollType.innerText = 'D8';
|
||||
resultDiv.innerText = calculateTotalWithModAndBonus( rolls, mod, bonus );
|
||||
addRollHistory();
|
||||
}
|
||||
|
||||
const rollD10 = async function (event) {
|
||||
event.preventDefault();
|
||||
var resultDiv = document.getElementById('d10-last-roll');
|
||||
var mod = document.getElementById('d10-mod').value;
|
||||
var bonus = document.getElementById('d10-bonus').value;
|
||||
var dieCount = document.getElementById('d10-die-count').value;
|
||||
let rolls = [];
|
||||
if ( !dieCount ) {
|
||||
dieCount = 1;
|
||||
}
|
||||
for (let index = 0; index < dieCount; index++) {
|
||||
rolls.push( getRandomInt( 1, 11 ) );
|
||||
}
|
||||
updateLastRoll( rolls, mod, bonus );
|
||||
rollType.innerText = 'D10';
|
||||
resultDiv.innerText = calculateTotalWithModAndBonus( rolls, mod, bonus );
|
||||
addRollHistory();
|
||||
}
|
||||
|
||||
const rollD12 = async function (event) {
|
||||
event.preventDefault();
|
||||
var resultDiv = document.getElementById('d12-last-roll');
|
||||
var mod = document.getElementById('d12-mod').value;
|
||||
var bonus = document.getElementById('d12-bonus').value;
|
||||
var dieCount = document.getElementById('d12-die-count').value;
|
||||
let rolls = [];
|
||||
if ( !dieCount ) {
|
||||
dieCount = 1;
|
||||
}
|
||||
for (let index = 0; index < dieCount; index++) {
|
||||
rolls.push( getRandomInt( 1, 13 ) );
|
||||
}
|
||||
updateLastRoll( rolls, mod, bonus );
|
||||
rollType.innerText = 'D12';
|
||||
resultDiv.innerText = calculateTotalWithModAndBonus( rolls, mod, bonus );
|
||||
addRollHistory();
|
||||
}
|
||||
|
||||
const rollD20 = async function (event) {
|
||||
event.preventDefault();
|
||||
var resultDiv = document.getElementById('d20-last-roll');
|
||||
var mod = document.getElementById('d20-mod').value;
|
||||
var bonus = document.getElementById('d20-bonus').value;
|
||||
var dieCount = document.getElementById('d20-die-count').value;
|
||||
let rolls = [];
|
||||
if ( !dieCount ) {
|
||||
dieCount = 1;
|
||||
}
|
||||
for (let index = 0; index < dieCount; index++) {
|
||||
rolls.push( getRandomInt( 1, 21 ) );
|
||||
}
|
||||
updateLastRoll( rolls, mod, bonus );
|
||||
rollType.innerText = 'D20';
|
||||
resultDiv.innerText = calculateTotalWithModAndBonus( rolls, mod, bonus );
|
||||
addRollHistory();
|
||||
}
|
||||
|
||||
const rollD100 = async function (event) {
|
||||
event.preventDefault();
|
||||
var resultDiv = document.getElementById('d100-last-roll');
|
||||
var mod = document.getElementById('d100-mod').value;
|
||||
var bonus = document.getElementById('d100-bonus').value;
|
||||
var dieCount = document.getElementById('d100-die-count').value;
|
||||
let rolls = [];
|
||||
if ( !dieCount ) {
|
||||
dieCount = 1;
|
||||
}
|
||||
for (let index = 0; index < dieCount; index++) {
|
||||
rolls.push( getRandomInt( 1, 101 ) );
|
||||
}
|
||||
updateLastRoll( rolls, mod, bonus );
|
||||
rollType.innerText = 'Percentile';
|
||||
resultDiv.innerText = calculateTotalWithModAndBonus( rolls, mod, bonus );
|
||||
addRollHistory();
|
||||
}
|
||||
|
||||
const rollDx = async function (event) {
|
||||
event.preventDefault();
|
||||
var resultDiv = document.getElementById('dx-last-roll');
|
||||
var mod = document.getElementById('dx-mod').value;
|
||||
var bonus = document.getElementById('dx-bonus').value;
|
||||
var faceCount = document.getElementById('dx-face-count').value;
|
||||
var dieCount = document.getElementById('dx-die-count').value;
|
||||
let rolls = [];
|
||||
if ( !dieCount ) {
|
||||
dieCount = 1;
|
||||
}
|
||||
if ( !faceCount ) {
|
||||
faceCount = 2;
|
||||
}
|
||||
faceCount++;
|
||||
|
||||
for (let index = 0; index < dieCount; index++) {
|
||||
rolls.push( getRandomInt( 1, faceCount ) );
|
||||
}
|
||||
|
||||
updateLastRoll( rolls, mod, bonus );
|
||||
rollType.innerText = 'D' + faceCount;
|
||||
resultDiv.innerText = calculateTotalWithModAndBonus( rolls, mod, bonus );
|
||||
addRollHistory();
|
||||
}
|
||||
|
||||
function getRandomInt(min, max) {
|
||||
const minCeiled = Math.ceil(min);
|
||||
const maxFloored = Math.floor(max);
|
||||
return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled);
|
||||
}
|
||||
|
||||
function resetResults() {
|
||||
dice.innerHTML = '';
|
||||
mods.innerHTML = '';
|
||||
bonuses.innerHTML = '';
|
||||
total.innerHTML = '';
|
||||
}
|
||||
|
||||
function updateLastRollDiceMod( rolls, mod ) {
|
||||
if (!rolls) {
|
||||
rolls = [];
|
||||
}
|
||||
if (!mod) {
|
||||
mod = 0;
|
||||
}
|
||||
var rollsStringWithMods = '';
|
||||
for (let i = 0; i < rolls.length; i++) {
|
||||
rollsStringWithMods = rollsStringWithMods + '<b>' + ( parseInt( rolls[i] ) + parseInt( mod )) + '</b> (' + rolls[i] + '+' + mod + '), ';
|
||||
}
|
||||
mods.innerHTML = rollsStringWithMods;
|
||||
}
|
||||
|
||||
function updateLastRollDice( rolls ) {
|
||||
results.style.display = '';
|
||||
if (!rolls) {
|
||||
rolls = [];
|
||||
}
|
||||
var rollsString = rolls.join(', ');
|
||||
dice.innerHTML = rollsString + ' <b>('+rolls.length+')</b>';
|
||||
}
|
||||
|
||||
function addRollHistory() {
|
||||
history.style.display = '';
|
||||
var tpeValue = rollType.innerText
|
||||
var diceValue = dice.innerHTML
|
||||
var modsValue = mods.innerHTML
|
||||
var totalValue = total.innerHTML
|
||||
var bonusesValue = bonuses.innerHTML
|
||||
|
||||
var rollList = document.getElementById('roll-history-table');
|
||||
var row = document.createElement('tr');
|
||||
|
||||
row.innerHTML = `
|
||||
<td class="text-center">${tpeValue}</td>
|
||||
<td class="text-center">${diceValue}</td>
|
||||
<td class="text-center">${modsValue}</td>
|
||||
<td class="text-center">${totalValue}</td>
|
||||
<td class="text-center">${bonusesValue}</td>
|
||||
<td class="text-right"><button class="btn btn-danger btn-sm history-remove" aria-label="Remove "><span class="glyphicon glyphicon-trash"></span></button></td>
|
||||
`;
|
||||
|
||||
var firstRow = rollList.rows[0];
|
||||
if (firstRow) {
|
||||
rollList.insertBefore(row, firstRow);
|
||||
} else {
|
||||
rollList.appendChild(row);
|
||||
}
|
||||
}
|
||||
|
||||
function updateLastRollTotal( rolls ) {
|
||||
if (!rolls) {
|
||||
rolls = [];
|
||||
}
|
||||
var sum = rolls.reduce((total, currentValue) => total + currentValue, 0);
|
||||
total.innerHTML = '<b>' + sum + '</b>';
|
||||
}
|
||||
|
||||
function calculateTotalWithModAndBonus( rolls, mod, bonus ) {
|
||||
if (!rolls) {
|
||||
rolls = [];
|
||||
}
|
||||
if (!bonus) {
|
||||
bonus = 0;
|
||||
}
|
||||
if (!mod) {
|
||||
mod = 0;
|
||||
}
|
||||
|
||||
var sum = rolls.reduce((total, currentValue) => total + currentValue, 0);
|
||||
var sumWithMods;
|
||||
if ( 0 == mod ) {
|
||||
sumWithMods = sum;
|
||||
} else {
|
||||
sumWithMods = parseInt(sum) + ( rolls.length * parseInt(mod) );
|
||||
}
|
||||
var total = parseInt(sumWithMods) + parseInt(bonus);
|
||||
return total;
|
||||
}
|
||||
|
||||
function updateLastRoll( rolls, mod, bonus ) {
|
||||
resetResults();
|
||||
updateLastRollDice( rolls );
|
||||
updateLastRollDiceMod( rolls, mod );
|
||||
updateLastRollTotal( rolls );
|
||||
var sum = rolls.reduce((total, currentValue) => total + currentValue, 0);
|
||||
if (!bonus) {
|
||||
bonus = '0';
|
||||
}
|
||||
if (!mod) {
|
||||
mod = '0';
|
||||
}
|
||||
bonuses.innerHTML = '<b>' + calculateTotalWithModAndBonus( rolls, mod, bonus ) + '</b> ( '+sum+' + ( '+rolls.length+' * '+mod+' ) + '+bonus+' )';
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/feedback/models/feedback.php
|
||||
*
|
||||
* This class is used for the manipulation of the feedback database table.
|
||||
*
|
||||
* @todo make this send a confirmation email
|
||||
*
|
||||
* @package TP Feedback
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\Plugins\Feedback as Plugin;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
|
||||
class Dicehistory extends DatabaseModel {
|
||||
public $tableName = 'feedback';
|
||||
public $databaseMatrix = [
|
||||
[ 'name', 'varchar', '128' ],
|
||||
[ 'time', 'int', '10' ],
|
||||
[ 'email', 'varchar', '128' ],
|
||||
[ 'ip', 'varchar', '64' ],
|
||||
[ 'feedback', 'text', '' ],
|
||||
// face_count ( d2, d20, d100, etc.. )
|
||||
// die_count ( how many dice were rolled )
|
||||
// dice_values ( json array of the dice values )
|
||||
// bonus
|
||||
// modifier
|
||||
// roll_total ( all dice added together )
|
||||
// modified_total ( all dice added together with modifiers )
|
||||
// final_total ( all dice added together, with modifiers, and bonus )
|
||||
// userID
|
||||
// createdAt
|
||||
|
||||
];
|
||||
public $plugin;
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->plugin = new Plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a feedback form to the db.
|
||||
*
|
||||
* @param string $name -the name on the form
|
||||
* @param string $email -the email provided
|
||||
* @param string $feedback -contents of the feedback form.
|
||||
* @return bool
|
||||
*/
|
||||
public function create( $name, $email, $feedback ) {
|
||||
if ( !$this->plugin->checkEnabled() ) {
|
||||
Debug::info( 'Feedback is disabled in the config.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'feedback' => $feedback,
|
||||
'time' => time(),
|
||||
'ip' => $_SERVER['REMOTE_ADDR'],
|
||||
];
|
||||
if ( !self::$db->insert( $this->tableName, $fields ) ) {
|
||||
Debug::info( 'Feedback::create - failed to insert to db' );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to clear feedback from the DB.
|
||||
*
|
||||
* @todo is there a way i could check for success here I'm pretty sure this is just a bad idea?
|
||||
* @return bool
|
||||
*/
|
||||
public function clear() {
|
||||
if ( empty( self::$log ) ) {
|
||||
self::$log = new Log;
|
||||
}
|
||||
self::$db->delete( $this->tableName, ['ID', '>=', '0'] );
|
||||
self::$log->admin( 'Cleared Feedback' );
|
||||
Debug::info( 'Feedback Cleared' );
|
||||
return true;
|
||||
}
|
||||
|
||||
public function userHistory( $limit = 0 ) {
|
||||
$whereClause = [
|
||||
'userID', '=', App::$activeUser->ID,
|
||||
'AND',
|
||||
'deletedAt', '=', '0',
|
||||
'AND',
|
||||
'expiresAt', '<', time(),
|
||||
];
|
||||
if ( empty( $limit ) ) {
|
||||
$notifications = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$notifications = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$notifications->count() ) {
|
||||
Debug::info( 'No Notifications found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $notifications->results() );
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dice/plugin.php
|
||||
*
|
||||
* This houses all of the main plugin info and functionality.
|
||||
*
|
||||
* @package TP Dice
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Plugins;
|
||||
|
||||
use TheTempusProject\Classes\Plugin;
|
||||
|
||||
class Dice extends Plugin {
|
||||
public $pluginName = 'TP Dice';
|
||||
public $pluginAuthor = 'JoeyK';
|
||||
public $pluginWebsite = 'https://TheTempusProject.com';
|
||||
public $modelVersion = '1.0';
|
||||
public $pluginVersion = '3.0';
|
||||
public $pluginDescription = 'A simple plugin which adds various dice for tabletop gaming.';
|
||||
public $configName = 'dice';
|
||||
public $configMatrix = [
|
||||
'enabled' => [
|
||||
'type' => 'radio',
|
||||
'pretty' => 'Enable dice usage.',
|
||||
'default' => true,
|
||||
],
|
||||
];
|
||||
public $permissionMatrix = [
|
||||
'dice' => [
|
||||
'pretty' => 'Can use dice',
|
||||
'default' => true,
|
||||
],
|
||||
];
|
||||
public $main_links = [
|
||||
[
|
||||
'text' => 'Dice',
|
||||
'url' => '{ROOT_URL}dice/index',
|
||||
],
|
||||
];
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
{LOOP}
|
||||
<tr data-id="{ID}">
|
||||
<th class="text-center">Roll Type</th>
|
||||
<th class="text-center">Dice Values</th>
|
||||
<th class="text-center">Modified Dice Values</th>
|
||||
<th class="text-center">Dice Total</th>
|
||||
<th class="text-center">Modified Total</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr><td colspan="6" class="text-center">No rolls have been saved / made yet.</td></tr>
|
||||
{/ALT}
|
@ -1,429 +0,0 @@
|
||||
<link rel="stylesheet" href="{ROOT_URL}app/plugins/dice/css/dice.css" crossorigin="anonymous">
|
||||
<script src="{ROOT_URL}app/plugins/dice/js/dice.js" type="module" defer></script>
|
||||
|
||||
<h1 class="text-center">Dice</h1>
|
||||
<div id="roll-results" class="row well well-sm" style="display: none;">
|
||||
<dl class="dl-horizontal roll-result-well">
|
||||
<dt>Dice</dt>
|
||||
<dd id="last-roll-dice"></dd>
|
||||
<dt>Dice (with Modifiers)</dt>
|
||||
<dd id="last-roll-dice-with-mods"></dd>
|
||||
<dt>Dice Total</dt>
|
||||
<dd id="dice-total"></dd>
|
||||
<dt>Total Value</dt>
|
||||
<dd id="dice-total-with-bonuses"></dd>
|
||||
</dl>
|
||||
<div id="roll-type" style="display: none;"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- Coin Flip -->
|
||||
<div class="col-lg-4 center-inputs">
|
||||
<div class="col-lg-12 text-center">
|
||||
<label class="sr-only" for="d2-last-roll">Last Flip</label>
|
||||
<h3 id="d2-last-roll">-</h3>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d2-die-count">Coin Count</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d2-minus" class="die-minus btn btn-danger" aria-label="Remove Die">-</button>
|
||||
</div>
|
||||
<input type="number" id="d2-die-count" name="d2-die-count" class="form-control" autocomplete="on" aria-label="Coin Count" placeholder="Coin Count">
|
||||
<div class="input-group-btn">
|
||||
<button id="d2-plus" class="die-plus btn btn-success" aria-label="Add Die">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 text-center">
|
||||
<button id="d2-roll" class="d2-die die-btn btn btn-primary">
|
||||
Flip Coin(s)
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- D4 -->
|
||||
<div class="col-lg-4 center-inputs">
|
||||
<div class="col-lg-12 text-center">
|
||||
<label class="sr-only" for="d4-last-roll">Last Roll</label>
|
||||
<h3 id="d4-last-roll">0</h3>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d4-die-count">Die Count</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d4-minus" class="die-minus btn btn-danger" aria-label="Remove Die">-</button>
|
||||
</div>
|
||||
<input type="number" id="d4-die-count" name="d4-die-count" class="form-control" autocomplete="on" aria-label="Die Count" placeholder="Die Count">
|
||||
<div class="input-group-btn">
|
||||
<button id="d4-plus" class="die-plus btn btn-success" aria-label="Add Die">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d4-mod">Modifier</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d4-mod-minus" class="mod-minus btn btn-danger" aria-label="Decrease Modifier">-</button>
|
||||
</div>
|
||||
<input type="number" id="d4-mod" name="d4-mod" class="form-control" autocomplete="on" aria-label="Modifier" placeholder="Modifier">
|
||||
<div class="input-group-btn">
|
||||
<button id="d4-mod-plus" class="mod-plus btn btn-success" aria-label="Increase Modifier">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d4-bonus">Bonus</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d4-bonus-minus" class="bonus-minus btn btn-danger" aria-label="Decrease Bonus">-</button>
|
||||
</div>
|
||||
<input type="number" id="d4-bonus" name="d4-bonus" class="form-control" autocomplete="on" aria-label="Bonus" placeholder="Bonus">
|
||||
<div class="input-group-btn">
|
||||
<button id="d4-bonus-plus" class="bonus-plus btn btn-success" aria-label="Increase Bonus">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 text-center">
|
||||
<button id="d4-roll" class="d4-die die-btn btn btn-primary">
|
||||
D4
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- D6 -->
|
||||
<div class="col-lg-4 center-inputs">
|
||||
<div class="col-lg-12 text-center">
|
||||
<label class="sr-only" for="d6-last-roll">Last Roll</label>
|
||||
<h3 id="d6-last-roll">0</h3>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d6-die-count">Die Count</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d6-minus" class="die-minus btn btn-danger" aria-label="Remove Die">-</button>
|
||||
</div>
|
||||
<input type="number" id="d6-die-count" name="d6-die-count" class="form-control" autocomplete="on" aria-label="Die Count" placeholder="Die Count">
|
||||
<div class="input-group-btn">
|
||||
<button id="d6-plus" class="die-plus btn btn-success" aria-label="Add Die">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d6-mod">Modifier</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d6-mod-minus" class="mod-minus btn btn-danger" aria-label="Decrease Modifier">-</button>
|
||||
</div>
|
||||
<input type="number" id="d6-mod" name="d6-mod" class="form-control" autocomplete="on" aria-label="Modifier" placeholder="Modifier">
|
||||
<div class="input-group-btn">
|
||||
<button id="d6-mod-plus" class="mod-plus btn btn-success" aria-label="Increase Modifier">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d6-bonus">Bonus</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d6-bonus-minus" class="bonus-minus btn btn-danger" aria-label="Decrease Bonus">-</button>
|
||||
</div>
|
||||
<input type="number" id="d6-bonus" name="d6-bonus" class="form-control" autocomplete="on" aria-label="Bonus" placeholder="Bonus">
|
||||
<div class="input-group-btn">
|
||||
<button id="d6-bonus-plus" class="bonus-plus btn btn-success" aria-label="Increase Bonus">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 text-center">
|
||||
<button id="d6-roll" class="d6-die die-btn btn btn-primary">
|
||||
D6
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- D8 -->
|
||||
<div class="col-lg-4 center-inputs">
|
||||
<div class="col-lg-12 text-center">
|
||||
<label class="sr-only" for="d8-last-roll">Last Roll</label>
|
||||
<h3 id="d8-last-roll">0</h3>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d8-die-count">Die Count</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d8-minus" class="die-minus btn btn-danger" aria-label="Remove Die">-</button>
|
||||
</div>
|
||||
<input type="number" id="d8-die-count" name="d8-die-count" class="form-control" autocomplete="on" aria-label="Die Count" placeholder="Die Count">
|
||||
<div class="input-group-btn">
|
||||
<button id="d8-plus" class="die-plus btn btn-success" aria-label="Add Die">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d8-mod">Modifier</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d8-mod-minus" class="mod-minus btn btn-danger" aria-label="Decrease Modifier">-</button>
|
||||
</div>
|
||||
<input type="number" id="d8-mod" name="d8-mod" class="form-control" autocomplete="on" aria-label="Modifier" placeholder="Modifier">
|
||||
<div class="input-group-btn">
|
||||
<button id="d8-mod-plus" class="mod-plus btn btn-success" aria-label="Increase Modifier">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d8-bonus">Bonus</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d8-bonus-minus" class="bonus-minus btn btn-danger" aria-label="Decrease Bonus">-</button>
|
||||
</div>
|
||||
<input type="number" id="d8-bonus" name="d8-bonus" class="form-control" autocomplete="on" aria-label="Bonus" placeholder="Bonus">
|
||||
<div class="input-group-btn">
|
||||
<button id="d8-bonus-plus" class="bonus-plus btn btn-success" aria-label="Increase Bonus">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 text-center">
|
||||
<button id="d8-roll" class="d8-die die-btn btn btn-primary">
|
||||
D8
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- D10 -->
|
||||
<div class="col-lg-4 center-inputs">
|
||||
<div class="col-lg-12 text-center">
|
||||
<label class="sr-only" for="d10-last-roll">Last Roll</label>
|
||||
<h3 id="d10-last-roll">0</h3>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d10-die-count">Die Count</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d10-minus" class="die-minus btn btn-danger" aria-label="Remove Die">-</button>
|
||||
</div>
|
||||
<input type="number" id="d10-die-count" name="d10-die-count" class="form-control" autocomplete="on" aria-label="Die Count" placeholder="Die Count">
|
||||
<div class="input-group-btn">
|
||||
<button id="d10-plus" class="die-plus btn btn-success" aria-label="Add Die">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d10-mod">Modifier</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d10-mod-minus" class="mod-minus btn btn-danger" aria-label="Decrease Modifier">-</button>
|
||||
</div>
|
||||
<input type="number" id="d10-mod" name="d10-mod" class="form-control" autocomplete="on" aria-label="Modifier" placeholder="Modifier">
|
||||
<div class="input-group-btn">
|
||||
<button id="d10-mod-plus" class="mod-plus btn btn-success" aria-label="Increase Modifier">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d10-bonus">Bonus</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d10-bonus-minus" class="bonus-minus btn btn-danger" aria-label="Decrease Bonus">-</button>
|
||||
</div>
|
||||
<input type="number" id="d10-bonus" name="d10-bonus" class="form-control" autocomplete="on" aria-label="Bonus" placeholder="Bonus">
|
||||
<div class="input-group-btn">
|
||||
<button id="d10-bonus-plus" class="bonus-plus btn btn-success" aria-label="Increase Bonus">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 text-center">
|
||||
<button id="d10-roll" class="d10-die die-btn btn btn-primary">
|
||||
D10
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- D12 -->
|
||||
<div class="col-lg-4 center-inputs">
|
||||
<div class="col-lg-12 text-center">
|
||||
<label class="sr-only" for="d12-last-roll">Last Roll</label>
|
||||
<h3 id="d12-last-roll">0</h3>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d12-die-count">Die Count</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d12-minus" class="die-minus btn btn-danger" aria-label="Remove Die">-</button>
|
||||
</div>
|
||||
<input type="number" id="d12-die-count" name="d12-die-count" class="form-control" autocomplete="on" aria-label="Die Count" placeholder="Die Count">
|
||||
<div class="input-group-btn">
|
||||
<button id="d12-plus" class="die-plus btn btn-success" aria-label="Add Die">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d12-mod">Modifier</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d12-mod-minus" class="mod-minus btn btn-danger" aria-label="Decrease Modifier">-</button>
|
||||
</div>
|
||||
<input type="number" id="d12-mod" name="d12-mod" class="form-control" autocomplete="on" aria-label="Modifier" placeholder="Modifier">
|
||||
<div class="input-group-btn">
|
||||
<button id="d12-mod-plus" class="mod-plus btn btn-success" aria-label="Increase Modifier">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d12-bonus">Bonus</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d12-bonus-minus" class="bonus-minus btn btn-danger" aria-label="Decrease Bonus">-</button>
|
||||
</div>
|
||||
<input type="number" id="d12-bonus" name="d12-bonus" class="form-control" autocomplete="on" aria-label="Bonus" placeholder="Bonus">
|
||||
<div class="input-group-btn">
|
||||
<button id="d12-bonus-plus" class="bonus-plus btn btn-success" aria-label="Increase Bonus">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 text-center">
|
||||
<button id="d12-roll" class="d12-die die-btn btn btn-primary">
|
||||
D12
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- D20 -->
|
||||
<div class="col-lg-4 center-inputs">
|
||||
<div class="col-lg-12 text-center">
|
||||
<label class="sr-only" for="d20-last-roll">Last Roll</label>
|
||||
<h3 id="d20-last-roll">0</h3>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d20-die-count">Die Count</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d20-minus" class="die-minus btn btn-danger" aria-label="Remove Die">-</button>
|
||||
</div>
|
||||
<input type="number" id="d20-die-count" name="d20-die-count" class="form-control" autocomplete="on" aria-label="Die Count" placeholder="Die Count">
|
||||
<div class="input-group-btn">
|
||||
<button id="d20-plus" class="die-plus btn btn-success" aria-label="Add Die">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d20-mod">Modifier</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d20-mod-minus" class="mod-minus btn btn-danger" aria-label="Decrease Modifier">-</button>
|
||||
</div>
|
||||
<input type="number" id="d20-mod" name="d20-mod" class="form-control" autocomplete="on" aria-label="Modifier" placeholder="Modifier">
|
||||
<div class="input-group-btn">
|
||||
<button id="d20-mod-plus" class="mod-plus btn btn-success" aria-label="Increase Modifier">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d20-bonus">Bonus</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d20-bonus-minus" class="bonus-minus btn btn-danger" aria-label="Decrease Bonus">-</button>
|
||||
</div>
|
||||
<input type="number" id="d20-bonus" name="d20-bonus" class="form-control" autocomplete="on" aria-label="Bonus" placeholder="Bonus">
|
||||
<div class="input-group-btn">
|
||||
<button id="d20-bonus-plus" class="bonus-plus btn btn-success" aria-label="Increase Bonus">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 text-center">
|
||||
<button id="d20-roll" class="d20-die die-btn btn btn-primary">
|
||||
D20
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Percentile -->
|
||||
<div class="col-lg-4 center-inputs">
|
||||
<div class="col-lg-12 text-center">
|
||||
<label class="sr-only" for="d100-last-roll">Last Roll</label>
|
||||
<h3 id="d100-last-roll">0</h3>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d100-die-count">Die Count</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d100-minus" class="die-minus btn btn-danger" aria-label="Remove Die">-</button>
|
||||
</div>
|
||||
<input type="number" id="d100-die-count" name="d100-die-count" class="form-control" autocomplete="on" aria-label="Die Count" placeholder="Die Count">
|
||||
<div class="input-group-btn">
|
||||
<button id="d100-plus" class="die-plus btn btn-success" aria-label="Add Die">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d100-mod">Modifier</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d100-mod-minus" class="mod-minus btn btn-danger" aria-label="Decrease Modifier">-</button>
|
||||
</div>
|
||||
<input type="number" id="d100-mod" name="d100-mod" class="form-control" autocomplete="on" aria-label="Modifier" placeholder="Modifier">
|
||||
<div class="input-group-btn">
|
||||
<button id="d100-mod-plus" class="mod-plus btn btn-success" aria-label="Increase Modifier">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="d100-bonus">Bonus</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="d100-bonus-minus" class="bonus-minus btn btn-danger" aria-label="Decrease Bonus">-</button>
|
||||
</div>
|
||||
<input type="number" id="d100-bonus" name="d100-bonus" class="form-control" autocomplete="on" aria-label="Bonus" placeholder="Bonus">
|
||||
<div class="input-group-btn">
|
||||
<button id="d100-bonus-plus" class="bonus-plus btn btn-success" aria-label="Increase Bonus">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 text-center">
|
||||
<button id="d100-roll" class="d100-die die-btn btn btn-primary">
|
||||
Percentile (D-100)
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Custom Die -->
|
||||
<div class="col-lg-4 center-inputs">
|
||||
<div class="col-lg-12 text-center">
|
||||
<label class="sr-only" for="dx-last-roll">Last Roll</label>
|
||||
<h3 id="dx-last-roll">0</h3>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="dx-face-count">Face Count</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="dx-minus" class="face-minus btn btn-danger" aria-label="Remove Face">-</button>
|
||||
</div>
|
||||
<input type="number" id="dx-face-count" name="dx-face-count" class="form-control" autocomplete="on" aria-label="Face Count" placeholder="Face Count">
|
||||
<div class="input-group-btn">
|
||||
<button id="dx-plus" class="face-plus btn btn-success" aria-label="Add Face">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="dx-die-count">Die Count</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="dx-minus" class="die-minus btn btn-danger" aria-label="Remove Die">-</button>
|
||||
</div>
|
||||
<input type="number" id="dx-die-count" name="dx-die-count" class="form-control" autocomplete="on" aria-label="Die Count" placeholder="Die Count">
|
||||
<div class="input-group-btn">
|
||||
<button id="dx-plus" class="die-plus btn btn-success" aria-label="Add Die">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="dx-mod">Modifier</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="dx-mod-minus" class="mod-minus btn btn-danger" aria-label="Decrease Modifier">-</button>
|
||||
</div>
|
||||
<input type="number" id="dx-mod" name="dx-mod" class="form-control" autocomplete="on" aria-label="Modifier" placeholder="Modifier">
|
||||
<div class="input-group-btn">
|
||||
<button id="dx-mod-plus" class="mod-plus btn btn-success" aria-label="Increase Modifier">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group input-number">
|
||||
<label class="sr-only" for="dx-bonus">Bonus</label>
|
||||
<div class="input-group-btn">
|
||||
<button id="dx-bonus-minus" class="bonus-minus btn btn-danger" aria-label="Decrease Bonus">-</button>
|
||||
</div>
|
||||
<input type="number" id="dx-bonus" name="dx-bonus" class="form-control" autocomplete="on" aria-label="Bonus" placeholder="Bonus">
|
||||
<div class="input-group-btn">
|
||||
<button id="dx-bonus-plus" class="bonus-plus btn btn-success" aria-label="Increase Bonus">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 text-center">
|
||||
<button id="dx-roll" class="dx-die die-btn btn btn-primary">
|
||||
Custom (D-X)
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Roll History -->
|
||||
<div id="roll-history" class="row" style="display: none;">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Roll History</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">Roll Type</th>
|
||||
<th class="text-center">Dice Values</th>
|
||||
<th class="text-center">Modified Dice Values</th>
|
||||
<th class="text-center">Dice Total</th>
|
||||
<th class="text-center">Modified Total</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="roll-history-table">
|
||||
{diceHistory}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="panel-footer round-footer">
|
||||
<span class="pull-right">
|
||||
<button id="history-clear" class="btn btn-danger">
|
||||
Clear History
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// The intent here is that this class will load all the various thing that will adjust the character overall
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// features() - returns an array of all the feats the character has
|
||||
// traits() - returns an array of all the traits the character has
|
||||
// skills() - returns an array of all the skills the character has
|
||||
// proficiencies() - returns an array of all the proficiencies the character has
|
||||
// addProficiency() - adds a proficiency to the character
|
||||
// race() - returns the race object for the character
|
||||
// class() - returns the class object for the character
|
||||
// spells() - returns an array of all the spells the character can "EVER" have access to IE: level too high for the current level
|
||||
// spellSlots() - returns an array of all the spell slots the character has, what's in them
|
||||
// items() - returns an array of all the items the character has
|
||||
// equipment() - returns an array of all the equipment the character has
|
||||
|
||||
|
||||
// resistances() - returns an array of all the resistances the character has
|
||||
// addResistance() - adds a resistance to the character
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/controllers/admin/classes.php
|
||||
*
|
||||
* This is the classes admin controller.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Controllers\Admin;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Classes\AdminController;
|
||||
use TheTempusProject\Models\Classes as ClassesModel;
|
||||
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
|
||||
|
||||
class Classes extends AdminController {
|
||||
protected static $classes;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$title = 'Admin - D&D Classes';
|
||||
self::$classes = new ClassesModel;
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'dnd.admin.classes.list', self::$classes->list() );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
$data = self::$classes->findById( $id );
|
||||
if ( $data == false ) {
|
||||
Issues::add( 'error', 'Class not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
Views::view( 'dnd.admin.classes.view', $data );
|
||||
}
|
||||
|
||||
public function create( $data = null ) {
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown') );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown') );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', 'none', self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
Views::view( 'dnd.admin.classes.create' );
|
||||
}
|
||||
if ( !Forms::check( 'createClass' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.classes.create' );
|
||||
}
|
||||
if ( self::$classes->create( Input::post( 'name' )) ) {
|
||||
Issues::add( 'success', 'Class created' );
|
||||
return $this->index();
|
||||
} else {
|
||||
Issues::add( 'error', 'There was an error creating your class.' );
|
||||
return Views::view( 'dnd.admin.classes.create' );
|
||||
}
|
||||
}
|
||||
|
||||
public function edit( $id = null ) {
|
||||
$data = self::$classes->findById( $id );
|
||||
if ( false == $data ) {
|
||||
return $this->index();
|
||||
}
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown', $data) );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown', $data) );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', $data->sourcebookID, self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'dnd.admin.classes.edit', $data );
|
||||
}
|
||||
if ( !Forms::check( 'editClass' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.classes.edit', $data );
|
||||
}
|
||||
if ( self::$classes->update( $id, Input::post( 'title' ), Input::post( 'suggestion' ), Input::post( 'approved' ) ) ) {
|
||||
Issues::add( 'success', 'Class updated' );
|
||||
} else {
|
||||
return Views::view( 'dnd.admin.classes.edit', $data );
|
||||
}
|
||||
}
|
||||
|
||||
public function delete( $data = null ) {
|
||||
if ( Input::exists( 'submit' ) ) {
|
||||
$data = Input::post( 'CL_' );
|
||||
}
|
||||
if ( !self::$classes->delete( $data ) ) {
|
||||
Issues::add( 'error', 'There was an error with your request.' );
|
||||
} else {
|
||||
Issues::add( 'success', 'Class has been deleted' );
|
||||
}
|
||||
$this->index();
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/controllers/admin/gods.php
|
||||
*
|
||||
* This is the gods admin controller.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Controllers\Admin;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Classes\AdminController;
|
||||
use TheTempusProject\Models\Gods as GodsModel;
|
||||
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
|
||||
|
||||
class Gods extends AdminController {
|
||||
protected static $gods;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$title = 'Admin - D&D Gods';
|
||||
self::$gods = new GodsModel;
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'dnd.admin.gods.list', self::$gods->list() );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
$data = self::$gods->findById( $id );
|
||||
if ( $data == false ) {
|
||||
Issues::add( 'error', 'God not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
Views::view( 'dnd.admin.gods.view', $data );
|
||||
}
|
||||
|
||||
public function create( $data = null ) {
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown') );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown') );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', 'none', self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
Views::view( 'dnd.admin.gods.create' );
|
||||
}
|
||||
if ( !Forms::check( 'createGod' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.gods.create' );
|
||||
}
|
||||
if ( self::$gods->create( Input::post( 'name' )) ) {
|
||||
Issues::add( 'success', 'God created' );
|
||||
return $this->index();
|
||||
} else {
|
||||
Issues::add( 'error', 'There was an error creating your god.' );
|
||||
return Views::view( 'dnd.admin.gods.create' );
|
||||
}
|
||||
}
|
||||
|
||||
public function edit( $id = null ) {
|
||||
$data = self::$gods->findById( $id );
|
||||
if ( false == $data ) {
|
||||
return $this->index();
|
||||
}
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown', $data) );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown', $data) );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', $data->sourcebookID, self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'dnd.admin.gods.edit', $data );
|
||||
}
|
||||
if ( !Forms::check( 'editGod' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.gods.edit', $data );
|
||||
}
|
||||
if ( self::$gods->update( $id, Input::post( 'title' ), Input::post( 'suggestion' ), Input::post( 'approved' ) ) ) {
|
||||
Issues::add( 'success', 'God updated' );
|
||||
} else {
|
||||
return Views::view( 'dnd.admin.gods.edit', $data );
|
||||
}
|
||||
}
|
||||
|
||||
public function delete( $data = null ) {
|
||||
if ( Input::exists( 'submit' ) ) {
|
||||
$data = Input::post( 'GD_' );
|
||||
}
|
||||
if ( !self::$gods->delete( $data ) ) {
|
||||
Issues::add( 'error', 'There was an error with your request.' );
|
||||
} else {
|
||||
Issues::add( 'success', 'God has been deleted' );
|
||||
}
|
||||
$this->index();
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/controllers/admin/items.php
|
||||
*
|
||||
* This is the items admin controller.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Controllers\Admin;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Classes\AdminController;
|
||||
use TheTempusProject\Models\Items as ItemsModel;
|
||||
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
|
||||
|
||||
class Items extends AdminController {
|
||||
protected static $items;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$title = 'Admin - D&D Items';
|
||||
self::$items = new ItemsModel;
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'dnd.admin.items.list', self::$items->list() );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
$data = self::$items->findById( $id );
|
||||
if ( $data == false ) {
|
||||
Issues::add( 'error', 'Item not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
Views::view( 'dnd.admin.items.view', $data );
|
||||
}
|
||||
|
||||
public function create( $data = null ) {
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown') );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown') );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', 'none', self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
Views::view( 'dnd.admin.items.create' );
|
||||
}
|
||||
if ( !Forms::check( 'createItem' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.items.create' );
|
||||
}
|
||||
if ( self::$items->create( Input::post( 'name' )) ) {
|
||||
Issues::add( 'success', 'Item created' );
|
||||
return $this->index();
|
||||
} else {
|
||||
Issues::add( 'error', 'There was an error creating your item.' );
|
||||
return Views::view( 'dnd.admin.items.create' );
|
||||
}
|
||||
}
|
||||
|
||||
public function edit( $id = null ) {
|
||||
$data = self::$items->findById( $id );
|
||||
if ( false == $data ) {
|
||||
return $this->index();
|
||||
}
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown', $data) );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown', $data) );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', $data->sourcebookID, self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'dnd.admin.items.edit', $data );
|
||||
}
|
||||
if ( !Forms::check( 'editItem' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.items.edit', $data );
|
||||
}
|
||||
if ( self::$items->update( $id, Input::post( 'title' ), Input::post( 'suggestion' ), Input::post( 'approved' ) ) ) {
|
||||
Issues::add( 'success', 'Item updated' );
|
||||
} else {
|
||||
return Views::view( 'dnd.admin.items.edit', $data );
|
||||
}
|
||||
}
|
||||
|
||||
public function delete( $data = null ) {
|
||||
if ( Input::exists( 'submit' ) ) {
|
||||
$data = Input::post( 'It_' );
|
||||
}
|
||||
if ( !self::$items->delete( $data ) ) {
|
||||
Issues::add( 'error', 'There was an error with your request.' );
|
||||
} else {
|
||||
Issues::add( 'success', 'Item has been deleted' );
|
||||
}
|
||||
$this->index();
|
||||
}
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/controllers/admin/languages.php
|
||||
*
|
||||
* This is the languages admin controller.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Controllers\Admin;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Classes\AdminController;
|
||||
use TheTempusProject\Models\Languages as LanguagesModel;
|
||||
use TheTempusProject\Houdini\Classes\Navigation;
|
||||
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
|
||||
use TheTempusProject\Models\Sourcebooks as SourcebooksModel;
|
||||
|
||||
class Languages extends AdminController {
|
||||
protected static $languages;
|
||||
protected static $sourcebooks;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$title = 'Admin - D&D Languages';
|
||||
self::$languages = new LanguagesModel;
|
||||
self::$sourcebooks = new SourcebooksModel;
|
||||
$view = Navigation::activePageSelect( 'nav.admin', '/admin/languages' );
|
||||
Components::set( 'ADMINNAV', $view );
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'dnd.admin.languages.list', self::$languages->paginatedList() );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
$data = self::$languages->findById( $id );
|
||||
if ( $data == false ) {
|
||||
Issues::add( 'error', 'Language not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
Views::view( 'dnd.admin.languages.view', $data );
|
||||
}
|
||||
|
||||
public function create( $data = null ) {
|
||||
Components::set( 'languageTypeDropdown', Views::simpleView('dnd.forms.languageTypeDropdown') );
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown') );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown') );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', 'none', self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'dnd.admin.languages.create' );
|
||||
}
|
||||
if ( !Forms::check( 'createLanguage' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.languages.create' );
|
||||
}
|
||||
|
||||
// create( $name, $privacy, $version, $sourcebookID, $type, $typical_speakers, $script, $sound, $description, $shortDescription' )
|
||||
if ( self::$languages->create(
|
||||
Input::post( 'name' ),
|
||||
Input::post( 'privacy' ),
|
||||
Input::post( 'version' ),
|
||||
Input::post( 'sourcebookID' ),
|
||||
Input::post( 'type' ),
|
||||
Input::post( 'typical_speakers' ),
|
||||
Input::post( 'script' ),
|
||||
Input::post( 'sound' ),
|
||||
Input::post( 'description' ),
|
||||
Input::post( 'shortDescription' )
|
||||
) ) {
|
||||
Issues::add( 'success', 'Language created' );
|
||||
return $this->index();
|
||||
} else {
|
||||
Issues::add( 'error', 'There was an error creating your language.' );
|
||||
return Views::view( 'dnd.admin.languages.create' );
|
||||
}
|
||||
}
|
||||
|
||||
public function edit( $id = null ) {
|
||||
$data = self::$languages->findById( $id );
|
||||
if ( false == $data ) {
|
||||
return $this->index();
|
||||
}
|
||||
Components::set( 'languageTypeDropdown', Views::simpleView('dnd.forms.languageTypeDropdown', $data) );
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown', $data) );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown', $data) );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', $data->sourcebookID, self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'dnd.admin.languages.edit', $data );
|
||||
}
|
||||
if ( !Forms::check( 'editLanguage' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.languages.edit', $data );
|
||||
}
|
||||
|
||||
// update( $id, $name, $privacy, $version, $sourcebookID, $type, $typical_speakers, $script, $sound, $description, $shortDescription' )
|
||||
if ( self::$languages->update(
|
||||
$id,
|
||||
Input::post( 'name' ),
|
||||
Input::post( 'privacy' ),
|
||||
Input::post( 'version' ),
|
||||
Input::post( 'sourcebookID' ),
|
||||
Input::post( 'type' ),
|
||||
Input::post( 'typical_speakers' ),
|
||||
Input::post( 'script' ),
|
||||
Input::post( 'sound' ),
|
||||
Input::post( 'description' ),
|
||||
Input::post( 'shortDescription' )
|
||||
) ) {
|
||||
Issues::add( 'success', 'Language updated' );
|
||||
} else {
|
||||
return Views::view( 'dnd.admin.languages.edit', $data );
|
||||
}
|
||||
}
|
||||
|
||||
public function delete( $data = null ) {
|
||||
if ( !self::$languages->delete( $data ) ) {
|
||||
Issues::add( 'error', 'There was an error with your request.' );
|
||||
} else {
|
||||
Issues::add( 'success', 'Language has been deleted' );
|
||||
}
|
||||
$this->index();
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/controllers/admin/monsters.php
|
||||
*
|
||||
* This is the monsters admin controller.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Controllers\Admin;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Classes\AdminController;
|
||||
use TheTempusProject\Models\Monsters as MonstersModel;
|
||||
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
|
||||
|
||||
class Monsters extends AdminController {
|
||||
protected static $monsters;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$title = 'Admin - D&D Monsters';
|
||||
self::$monsters = new MonstersModel;
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'dnd.admin.monsters.list', self::$monsters->list() );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
$data = self::$monsters->findById( $id );
|
||||
if ( $data == false ) {
|
||||
Issues::add( 'error', 'Monster not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
Views::view( 'dnd.admin.monsters.view', $data );
|
||||
}
|
||||
|
||||
public function create( $data = null ) {
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown') );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown') );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', 'none', self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
Views::view( 'dnd.admin.monsters.create' );
|
||||
}
|
||||
if ( !Forms::check( 'createMonster' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.monsters.create' );
|
||||
}
|
||||
if ( self::$monsters->create( Input::post( 'name' )) ) {
|
||||
Issues::add( 'success', 'Monster created' );
|
||||
return $this->index();
|
||||
} else {
|
||||
Issues::add( 'error', 'There was an error creating your monster.' );
|
||||
return Views::view( 'dnd.admin.monsters.create' );
|
||||
}
|
||||
}
|
||||
|
||||
public function edit( $id = null ) {
|
||||
$data = self::$monsters->findById( $id );
|
||||
if ( false == $data ) {
|
||||
return $this->index();
|
||||
}
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown', $data) );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown', $data) );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', $data->sourcebookID, self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'dnd.admin.monsters.edit', $data );
|
||||
}
|
||||
if ( !Forms::check( 'editMonster' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.monsters.edit', $data );
|
||||
}
|
||||
if ( self::$monsters->update( $id, Input::post( 'title' ), Input::post( 'suggestion' ), Input::post( 'approved' ) ) ) {
|
||||
Issues::add( 'success', 'Monster updated' );
|
||||
} else {
|
||||
return Views::view( 'dnd.admin.monsters.edit', $data );
|
||||
}
|
||||
}
|
||||
|
||||
public function delete( $data = null ) {
|
||||
if ( Input::exists( 'submit' ) ) {
|
||||
$data = Input::post( 'MO_' );
|
||||
}
|
||||
if ( !self::$monsters->delete( $data ) ) {
|
||||
Issues::add( 'error', 'There was an error with your request.' );
|
||||
} else {
|
||||
Issues::add( 'success', 'Monster has been deleted' );
|
||||
}
|
||||
$this->index();
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/controllers/admin/races.php
|
||||
*
|
||||
* This is the races admin controller.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Controllers\Admin;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Classes\AdminController;
|
||||
use TheTempusProject\Models\Races as RacesModel;
|
||||
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
|
||||
|
||||
class Races extends AdminController {
|
||||
protected static $races;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$title = 'Admin - D&D Races';
|
||||
self::$races = new RacesModel;
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'dnd.admin.races.list', self::$races->list() );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
$data = self::$races->findById( $id );
|
||||
if ( $data == false ) {
|
||||
Issues::add( 'error', 'Race not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
Views::view( 'dnd.admin.races.view', $data );
|
||||
}
|
||||
|
||||
public function create( $data = null ) {
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown') );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown') );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', 'none', self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
Views::view( 'dnd.admin.races.create' );
|
||||
}
|
||||
if ( !Forms::check( 'createRace' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.races.create' );
|
||||
}
|
||||
if ( self::$races->create( Input::post( 'name' )) ) {
|
||||
Issues::add( 'success', 'Race created' );
|
||||
return $this->index();
|
||||
} else {
|
||||
Issues::add( 'error', 'There was an error creating your race.' );
|
||||
return Views::view( 'dnd.admin.races.create' );
|
||||
}
|
||||
}
|
||||
|
||||
public function edit( $id = null ) {
|
||||
$data = self::$races->findById( $id );
|
||||
if ( false == $data ) {
|
||||
return $this->index();
|
||||
}
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown', $data) );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown', $data) );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', $data->sourcebookID, self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'dnd.admin.races.edit', $data );
|
||||
}
|
||||
if ( !Forms::check( 'editRace' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.races.edit', $data );
|
||||
}
|
||||
if ( self::$races->update( $id, Input::post( 'title' ), Input::post( 'suggestion' ), Input::post( 'approved' ) ) ) {
|
||||
Issues::add( 'success', 'Race updated' );
|
||||
} else {
|
||||
return Views::view( 'dnd.admin.races.edit', $data );
|
||||
}
|
||||
}
|
||||
|
||||
public function delete( $data = null ) {
|
||||
if ( Input::exists( 'submit' ) ) {
|
||||
$data = Input::post( 'RA_' );
|
||||
}
|
||||
if ( !self::$races->delete( $data ) ) {
|
||||
Issues::add( 'error', 'There was an error with your request.' );
|
||||
} else {
|
||||
Issues::add( 'success', 'Race has been deleted' );
|
||||
}
|
||||
$this->index();
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/controllers/admin/skills.php
|
||||
*
|
||||
* This is the skills admin controller.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Controllers\Admin;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Classes\AdminController;
|
||||
use TheTempusProject\Models\Skills as SkillsModel;
|
||||
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
|
||||
|
||||
class Skills extends AdminController {
|
||||
protected static $skills;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$title = 'Admin - D&D Skills';
|
||||
self::$skills = new SkillsModel;
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'dnd.admin.skills.list', self::$skills->list() );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
$data = self::$skills->findById( $id );
|
||||
if ( $data == false ) {
|
||||
Issues::add( 'error', 'Skill not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
Views::view( 'dnd.admin.skills.view', $data );
|
||||
}
|
||||
|
||||
public function create( $data = null ) {
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown') );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown') );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', 'none', self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
Views::view( 'dnd.admin.skills.create' );
|
||||
}
|
||||
if ( !Forms::check( 'createSkill' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.skills.create' );
|
||||
}
|
||||
if ( self::$skills->create( Input::post( 'name' )) ) {
|
||||
Issues::add( 'success', 'Skill created' );
|
||||
return $this->index();
|
||||
} else {
|
||||
Issues::add( 'error', 'There was an error creating your skill.' );
|
||||
return Views::view( 'dnd.admin.skills.create' );
|
||||
}
|
||||
}
|
||||
|
||||
public function edit( $id = null ) {
|
||||
$data = self::$skills->findById( $id );
|
||||
if ( false == $data ) {
|
||||
return $this->index();
|
||||
}
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown', $data) );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown', $data) );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', $data->sourcebookID, self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'dnd.admin.skills.edit', $data );
|
||||
}
|
||||
if ( !Forms::check( 'editSkill' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.skills.edit', $data );
|
||||
}
|
||||
if ( self::$skills->update( $id, Input::post( 'title' ), Input::post( 'suggestion' ), Input::post( 'approved' ) ) ) {
|
||||
Issues::add( 'success', 'Skill updated' );
|
||||
} else {
|
||||
return Views::view( 'dnd.admin.skills.edit', $data );
|
||||
}
|
||||
}
|
||||
|
||||
public function delete( $data = null ) {
|
||||
if ( Input::exists( 'submit' ) ) {
|
||||
$data = Input::post( 'SK_' );
|
||||
}
|
||||
if ( !self::$skills->delete( $data ) ) {
|
||||
Issues::add( 'error', 'There was an error with your request.' );
|
||||
} else {
|
||||
Issues::add( 'success', 'Skill has been deleted' );
|
||||
}
|
||||
$this->index();
|
||||
}
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/controllers/admin/sourcebooks.php
|
||||
*
|
||||
* This is the sourcebooks admin controller.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Controllers\Admin;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Classes\AdminController;
|
||||
use TheTempusProject\Models\Sourcebooks as SourcebooksModel;
|
||||
use TheTempusProject\Houdini\Classes\Navigation;
|
||||
|
||||
class Sourcebooks extends AdminController {
|
||||
protected static $sourcebooks;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$title = 'Admin - D&D Sourcebooks';
|
||||
self::$sourcebooks = new SourcebooksModel;
|
||||
$view = Navigation::activePageSelect( 'nav.admin', '/admin/sourcebooks' );
|
||||
Components::set( 'ADMINNAV', $view );
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'dnd.admin.sourcebooks.list', self::$sourcebooks->paginatedList() );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
$data = self::$sourcebooks->findById( $id );
|
||||
if ( $data == false ) {
|
||||
Issues::add( 'error', 'Sourcebook not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
Views::view( 'dnd.admin.sourcebooks.view', $data );
|
||||
}
|
||||
|
||||
public function create() {
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown') );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown') );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'dnd.admin.sourcebooks.create' );
|
||||
}
|
||||
if ( !Forms::check( 'createSourcebook' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.sourcebooks.create' );
|
||||
}
|
||||
if ( self::$sourcebooks->create(
|
||||
Input::post( 'name' ),
|
||||
Input::post( 'privacy' ),
|
||||
Input::post( 'version' ),
|
||||
Input::post( 'sourceType' ),
|
||||
Input::post( 'year' ),
|
||||
Input::post( 'amazonUrl' ),
|
||||
Input::post( 'description' ),
|
||||
Input::post( 'shortDescription' )
|
||||
) ) {
|
||||
Issues::add( 'success', 'Sourcebook created' );
|
||||
return $this->index();
|
||||
} else {
|
||||
Issues::add( 'error', 'There was an error creating your sourcebook.' );
|
||||
return Views::view( 'dnd.admin.sourcebooks.create' );
|
||||
}
|
||||
}
|
||||
|
||||
public function edit( $id = null ) {
|
||||
$data = self::$sourcebooks->findById( $id );
|
||||
if ( false == $data ) {
|
||||
return $this->index();
|
||||
}
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown', $data) );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown', $data) );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'dnd.admin.sourcebooks.edit', $data );
|
||||
}
|
||||
if ( !Forms::check( 'editSourcebook' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.sourcebooks.edit', $data );
|
||||
}
|
||||
if ( self::$sourcebooks->update( $id, Input::post( 'title' ), Input::post( 'suggestion' ), Input::post( 'approved' ) ) ) {
|
||||
Issues::add( 'success', 'Sourcebook updated' );
|
||||
} else {
|
||||
return Views::view( 'dnd.admin.sourcebooks.edit', $data );
|
||||
}
|
||||
}
|
||||
|
||||
public function delete( $data = null ) {
|
||||
if ( Input::exists( 'submit' ) ) {
|
||||
$data = Input::post( 'SB_' );
|
||||
}
|
||||
if ( !self::$sourcebooks->delete( $data ) ) {
|
||||
Issues::add( 'error', 'There was an error with your request.' );
|
||||
} else {
|
||||
Issues::add( 'success', 'Sourcebook has been deleted' );
|
||||
}
|
||||
$this->index();
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/controllers/admin/spells.php
|
||||
*
|
||||
* This is the spells admin controller.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Controllers\Admin;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Classes\AdminController;
|
||||
use TheTempusProject\Models\Spells as SpellsModel;
|
||||
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
|
||||
|
||||
class Spells extends AdminController {
|
||||
protected static $spells;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$title = 'Admin - D&D Spells';
|
||||
self::$spells = new SpellsModel;
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'dnd.admin.spells.list', self::$spells->list() );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
$data = self::$spells->findById( $id );
|
||||
if ( $data == false ) {
|
||||
Issues::add( 'error', 'Spell not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
Views::view( 'dnd.admin.spells.view', $data );
|
||||
}
|
||||
|
||||
public function create( $data = null ) {
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown') );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown') );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', 'none', self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
Views::view( 'dnd.admin.spells.create' );
|
||||
}
|
||||
if ( !Forms::check( 'createSpell' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.spells.create' );
|
||||
}
|
||||
if ( self::$spells->create( Input::post( 'name' )) ) {
|
||||
Issues::add( 'success', 'Spell created' );
|
||||
return $this->index();
|
||||
} else {
|
||||
Issues::add( 'error', 'There was an error creating your spell.' );
|
||||
return Views::view( 'dnd.admin.spells.create' );
|
||||
}
|
||||
}
|
||||
|
||||
public function edit( $id = null ) {
|
||||
$data = self::$spells->findById( $id );
|
||||
if ( false == $data ) {
|
||||
return $this->index();
|
||||
}
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown', $data) );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown', $data) );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', $data->sourcebookID, self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'dnd.admin.spells.edit', $data );
|
||||
}
|
||||
if ( !Forms::check( 'editSpell' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.spells.edit', $data );
|
||||
}
|
||||
if ( self::$spells->update( $id, Input::post( 'title' ), Input::post( 'suggestion' ), Input::post( 'approved' ) ) ) {
|
||||
Issues::add( 'success', 'Spell updated' );
|
||||
} else {
|
||||
return Views::view( 'dnd.admin.spells.edit', $data );
|
||||
}
|
||||
}
|
||||
|
||||
public function delete( $data = null ) {
|
||||
if ( Input::exists( 'submit' ) ) {
|
||||
$data = Input::post( 'SP_' );
|
||||
}
|
||||
if ( !self::$spells->delete( $data ) ) {
|
||||
Issues::add( 'error', 'There was an error with your request.' );
|
||||
} else {
|
||||
Issues::add( 'success', 'Spell has been deleted' );
|
||||
}
|
||||
$this->index();
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/controllers/admin/traits.php
|
||||
*
|
||||
* This is the traits admin controller.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Controllers\Admin;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Classes\AdminController;
|
||||
use TheTempusProject\Models\Traits as TraitsModel;
|
||||
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
|
||||
|
||||
class Traits extends AdminController {
|
||||
protected static $traits;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$title = 'Admin - D&D Traits';
|
||||
self::$traits = new TraitsModel;
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'dnd.admin.traits.list', self::$traits->list() );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
$data = self::$traits->findById( $id );
|
||||
if ( $data == false ) {
|
||||
Issues::add( 'error', 'Trait not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
Views::view( 'dnd.admin.traits.view', $data );
|
||||
}
|
||||
|
||||
public function create( $data = null ) {
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown') );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown') );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', 'none', self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
Views::view( 'dnd.admin.traits.create' );
|
||||
}
|
||||
if ( !Forms::check( 'createTrait' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.traits.create' );
|
||||
}
|
||||
if ( self::$traits->create( Input::post( 'name' )) ) {
|
||||
Issues::add( 'success', 'Trait created' );
|
||||
return $this->index();
|
||||
} else {
|
||||
Issues::add( 'error', 'There was an error creating your trait.' );
|
||||
return Views::view( 'dnd.admin.traits.create' );
|
||||
}
|
||||
}
|
||||
|
||||
public function edit( $id = null ) {
|
||||
$data = self::$traits->findById( $id );
|
||||
if ( false == $data ) {
|
||||
return $this->index();
|
||||
}
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown', $data) );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown', $data) );
|
||||
$sourcebookSelect = HoudiniForms::getFormFieldHtml( 'sourcebookID', 'SourceBook', 'select', $data->sourcebookID, self::$sourcebooks->simpleList() );
|
||||
Components::set( 'sourcebookSelect', $sourcebookSelect );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'dnd.admin.traits.edit', $data );
|
||||
}
|
||||
if ( !Forms::check( 'editTrait' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.admin.traits.edit', $data );
|
||||
}
|
||||
if ( self::$traits->update( $id, Input::post( 'title' ), Input::post( 'suggestion' ), Input::post( 'approved' ) ) ) {
|
||||
Issues::add( 'success', 'Trait updated' );
|
||||
} else {
|
||||
return Views::view( 'dnd.admin.traits.edit', $data );
|
||||
}
|
||||
}
|
||||
|
||||
public function delete( $data = null ) {
|
||||
if ( Input::exists( 'submit' ) ) {
|
||||
$data = Input::post( 'TR_' );
|
||||
}
|
||||
if ( !self::$traits->delete( $data ) ) {
|
||||
Issues::add( 'error', 'There was an error with your request.' );
|
||||
} else {
|
||||
Issues::add( 'success', 'Trait has been deleted' );
|
||||
}
|
||||
$this->index();
|
||||
}
|
||||
}
|
@ -1,280 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/controllers/creator.php
|
||||
*
|
||||
* This is the Character Creation controller.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Controllers;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Classes\Controller;
|
||||
use TheTempusProject\Models\Characters as CharacterModel;
|
||||
use TheTempusProject\Models\Classes;
|
||||
use TheTempusProject\Models\Races;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
|
||||
class Characters extends Controller {
|
||||
protected static $characters;
|
||||
protected static $classes;
|
||||
protected static $races;
|
||||
|
||||
public function index() {
|
||||
self::$title = 'Character Creator - {SITENAME}';
|
||||
self::$pageDescription = 'This is for creating and managing various TT characters.';
|
||||
self::$characters = new CharacterModel;
|
||||
self::$classes = new Classes;
|
||||
self::$races = new Races;
|
||||
Views::view( 'dnd.index' );
|
||||
|
||||
$characterListView = Views::simpleView('dnd.characters.list', self::$characters->byUser() );
|
||||
Components::set( 'characterList', $characterListView );
|
||||
}
|
||||
|
||||
public function characters( $id = 0 ) {}
|
||||
public function editCharacter() {}
|
||||
public function deleteCharacter() {}
|
||||
|
||||
public function createCharacter() {
|
||||
if ( ! Input::exists() ) {
|
||||
return $this->createCharacterScreenOne();
|
||||
}
|
||||
return $this->saveAndLoad();
|
||||
}
|
||||
|
||||
private function saveAndLoad() {
|
||||
if ( empty( Input::post( 'characterID' ) ) ) {
|
||||
if ( ! Forms::check( 'createCharacterScreenOne' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
|
||||
return $this->createCharacterScreenOne();
|
||||
}
|
||||
$avatar = ''; // @TODO: come back and actually add the avatar upload functionality
|
||||
$id = self::$characters->createFromScreenOne(
|
||||
Input::post('first_name'),
|
||||
Input::post('last_name'),
|
||||
Input::post('privacy'),
|
||||
Input::post('version'),
|
||||
Input::post('prefix'),
|
||||
Input::post('middle_name'),
|
||||
Input::post('suffix'),
|
||||
$avatar
|
||||
);
|
||||
if ( ! $id ) {
|
||||
Issues::add( 'error', [ 'There was an error saving your character.' => Check::userErrors() ] );
|
||||
return $this->createCharacterScreenOne();
|
||||
}
|
||||
} else {
|
||||
$id = Input::post( 'characterID' );
|
||||
}
|
||||
$character = $this->findCharacterOrFail( $id );
|
||||
Components::set( 'characterID', $character->ID );
|
||||
if ( empty( $character->raceID ) ) {
|
||||
return $this->createCharacterScreenTwo( $character->ID );
|
||||
}
|
||||
if ( empty( $character->classID ) ) {
|
||||
return $this->createCharacterScreenThree( $character->ID );
|
||||
}
|
||||
if ( empty( $character->level ) ) {
|
||||
return $this->createCharacterScreenFour( $character->ID );
|
||||
}
|
||||
if ( empty( $character->strength ) ) {
|
||||
return $this->createCharacterScreenFive( $character->ID );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if ( empty( $character->strength ) ) {
|
||||
return $this->createCharacterScreenFive( $character->ID );
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Name, Version, Privacy
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function createCharacterScreenOne() {
|
||||
Components::set( 'privacyDropdown', Views::simpleView('dnd.forms.privacyDropdown') );
|
||||
Components::set( 'versionDropdown', Views::simpleView('dnd.forms.versionDropdown') );
|
||||
Components::set( 'hitpointRollDropdown', Views::simpleView('dnd.forms.hitpointRollDropdown') );
|
||||
return Views::view( 'dnd.creator.screen1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Race
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function createCharacterScreenTwo( $id ) {
|
||||
Components::set( 'raceSelect', self::$races->getAll() );
|
||||
if ( ! Forms::check( 'createCharacterScreenTwo' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.creator.screen2' );
|
||||
}
|
||||
$result = self::$characters->updateFromScreenTwo(
|
||||
Input::post('race')
|
||||
);
|
||||
if ( ! $result ) {
|
||||
Issues::add( 'error', [ 'There was an error saving your character.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.creator.screen2' );
|
||||
}
|
||||
return $this->createCharacterScreenThree( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function createCharacterScreenThree( $id ) {
|
||||
Components::set( 'classSelect', self::$classes->getAll() );
|
||||
if ( ! Forms::check( 'createCharacterScreenThree' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.creator.screen3' );
|
||||
}
|
||||
$result = self::$characters->updateFromScreenThree(
|
||||
Input::post('class')
|
||||
);
|
||||
if ( ! $result ) {
|
||||
Issues::add( 'error', [ 'There was an error saving your character.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.creator.screen3' );
|
||||
}
|
||||
return $this->createCharacterScreenFour( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Level / Race & class selections
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function createCharacterScreenFour( $id ) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ability Scores - Str, Dex, Int, Wis, Char, Con
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function createCharacterScreenFive( $id ) {
|
||||
if ( ! Forms::check( 'createCharacterScreenFive' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.creator.screen5' );
|
||||
}
|
||||
$result = self::$characters->updateFromScreenFive(
|
||||
Input::post('strength'),
|
||||
Input::post('dexterity'),
|
||||
Input::post('constitution'),
|
||||
Input::post('charisma'),
|
||||
Input::post('intelligence'),
|
||||
Input::post('wisdom')
|
||||
);
|
||||
if ( ! $result ) {
|
||||
Issues::add( 'error', [ 'There was an error saving your character.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.creator.screen5' );
|
||||
}
|
||||
return $this->createCharacterScreenSix( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Character Info - Religion, family, associations
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function createCharacterScreenSix( $id ) {
|
||||
Components::set( 'orderDropdown', Views::simpleView('dnd.forms.orderDropdown') );
|
||||
Components::set( 'moralityDropdown', Views::simpleView('dnd.forms.moralityDropdown') );
|
||||
if ( ! Forms::check( 'createCharacterScreenSix' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.creator.screen6' );
|
||||
}
|
||||
$result = self::$characters->updateFromScreenSix(
|
||||
Input::post('order'),
|
||||
Input::post('morality'),
|
||||
Input::post('story'),
|
||||
Input::post('allies'),
|
||||
Input::post('enemies'),
|
||||
Input::post('organizations'),
|
||||
Input::post('flaws'),
|
||||
Input::post('bonds'),
|
||||
Input::post('ideals'),
|
||||
Input::post('traits'),
|
||||
Input::post('oaths'),
|
||||
Input::post('motto'),
|
||||
Input::post('creed')
|
||||
);
|
||||
if ( ! $result ) {
|
||||
Issues::add( 'error', [ 'There was an error saving your character.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.creator.screen6' );
|
||||
}
|
||||
return $this->createCharacterScreenSeven( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Character Info - Appearance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function createCharacterScreenSeven( $id ) {
|
||||
if ( ! Forms::check( 'createCharacterScreenSeven' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.creator.screen7' );
|
||||
}
|
||||
$result = self::$characters->updateFromScreenSeven(
|
||||
Input::post('age'),
|
||||
Input::post('height'),
|
||||
Input::post('weight'),
|
||||
Input::post('eyes'),
|
||||
Input::post('skin'),
|
||||
Input::post('hair'),
|
||||
Input::post('gender'),
|
||||
Input::post('appearance')
|
||||
);
|
||||
if ( ! $result ) {
|
||||
Issues::add( 'error', [ 'There was an error saving your character.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.creator.screen7' );
|
||||
}
|
||||
return $this->createCharacterScreenEight( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Equipment and Inventory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function createCharacterScreenEight( $id ) {
|
||||
if ( ! Forms::check( 'createCharacterScreenEight' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.creator.screen8' );
|
||||
}
|
||||
$result = self::$characters->updateFromScreenEight(
|
||||
);
|
||||
if ( ! $result ) {
|
||||
Issues::add( 'error', [ 'There was an error saving your character.' => Check::userErrors() ] );
|
||||
return Views::view( 'dnd.creator.screen8' );
|
||||
}
|
||||
Session::flash( 'success', 'Character Created' );
|
||||
Redirect::to( 'dnd/index' );
|
||||
}
|
||||
|
||||
private function findCharacterOrFail( $id = null ) {
|
||||
$character = self::$characters->findById( $id );
|
||||
if ( $character == false ) {
|
||||
Session::flash( 'error', 'Character not found.' );
|
||||
Redirect::to( 'dnd/index/' );
|
||||
}
|
||||
if ( $character->createdBy != App::$activeUser->ID ) {
|
||||
Session::flash( 'error', 'Permissions Error.' );
|
||||
Redirect::to( 'dnd/index/' );
|
||||
}
|
||||
return $character;
|
||||
}
|
||||
}
|
||||
|
||||
// Associations
|
||||
// ( family and friends )
|
@ -1,62 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/charactercreator/controllers/creator.php
|
||||
*
|
||||
* This is the Character Creation controller.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Controllers;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Classes\Controller;
|
||||
use TheTempusProject\Models\Classes;
|
||||
use TheTempusProject\Models\Items;
|
||||
use TheTempusProject\Models\Monsters;
|
||||
use TheTempusProject\Models\Races;
|
||||
use TheTempusProject\Models\Skills;
|
||||
use TheTempusProject\Models\Sourcebooks;
|
||||
use TheTempusProject\Models\Spells;
|
||||
|
||||
class Creator extends Controller {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$title = 'D&D Databases - {SITENAME}';
|
||||
self::$pageDescription = 'This is for referencing any number of game features in D&D..';
|
||||
}
|
||||
public function index() {
|
||||
Views::view( 'dnd.dndatabase.index' );
|
||||
}
|
||||
public function classes() {
|
||||
$classes = new Classes;
|
||||
Views::view( 'dnd.dndatabase.classes.list', $classes );
|
||||
}
|
||||
public function items() {
|
||||
$items = new Items;
|
||||
Views::view( 'dnd.dndatabase.items.list', $items );
|
||||
}
|
||||
public function monsters() {
|
||||
$monsters = new Monsters;
|
||||
Views::view( 'dnd.dndatabase.monsters.list', $monsters );
|
||||
}
|
||||
public function races() {
|
||||
$races = new Races;
|
||||
Views::view( 'dnd.dndatabase.races.list', $races );
|
||||
}
|
||||
public function skills() {
|
||||
$skills = new Skills;
|
||||
Views::view( 'dnd.dndatabase.skills.list', $skills );
|
||||
}
|
||||
public function sourcebooks() {
|
||||
$sourcebooks = new Sourcebooks;
|
||||
Views::view( 'dnd.dndatabase.sourcebooks.list', $sourcebooks );
|
||||
}
|
||||
public function spells() {
|
||||
$spells = new Spells;
|
||||
Views::view( 'dnd.dndatabase.spells.list', $spells );
|
||||
}
|
||||
}
|
@ -1,344 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/forms.php
|
||||
*
|
||||
* This houses all of the form checking functions for this plugin.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Plugins\Dnd;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
|
||||
class DnDForms extends Forms {
|
||||
/**
|
||||
* Adds these functions to the form list.
|
||||
*/
|
||||
public function __construct() {
|
||||
// admin
|
||||
self::addHandler( 'createTrait', __CLASS__, 'createTrait' );
|
||||
self::addHandler( 'editTrait', __CLASS__, 'editTrait' );
|
||||
self::addHandler( 'createSpell', __CLASS__, 'createSpell' );
|
||||
self::addHandler( 'editSpell', __CLASS__, 'editSpell' );
|
||||
self::addHandler( 'createSourcebook', __CLASS__, 'createSourcebook' );
|
||||
self::addHandler( 'editSourcebook', __CLASS__, 'editSourcebook' );
|
||||
self::addHandler( 'createSkill', __CLASS__, 'createSkill' );
|
||||
self::addHandler( 'editSkill', __CLASS__, 'editSkill' );
|
||||
self::addHandler( 'createRace', __CLASS__, 'createRace' );
|
||||
self::addHandler( 'editRace', __CLASS__, 'editRace' );
|
||||
self::addHandler( 'createMonster', __CLASS__, 'createMonster' );
|
||||
self::addHandler( 'editMonster', __CLASS__, 'editMonster' );
|
||||
self::addHandler( 'createLanguage', __CLASS__, 'createLanguage' );
|
||||
self::addHandler( 'editLanguage', __CLASS__, 'editLanguage' );
|
||||
self::addHandler( 'createItem', __CLASS__, 'createItem' );
|
||||
self::addHandler( 'editItem', __CLASS__, 'editItem' );
|
||||
self::addHandler( 'createGod', __CLASS__, 'createGod' );
|
||||
self::addHandler( 'editGod', __CLASS__, 'editGod' );
|
||||
self::addHandler( 'createClass', __CLASS__, 'createClass' );
|
||||
self::addHandler( 'editClass', __CLASS__, 'editClass' );
|
||||
|
||||
// character creator
|
||||
self::addHandler( 'createCharacterScreenOne', __CLASS__, 'createCharacterScreenOne' );
|
||||
self::addHandler( 'createCharacterScreenTwo', __CLASS__, 'createCharacterScreenTwo' );
|
||||
self::addHandler( 'createCharacterScreenThree', __CLASS__, 'createCharacterScreenThree' );
|
||||
self::addHandler( 'createCharacterScreenFour', __CLASS__, 'createCharacterScreenFour' );
|
||||
self::addHandler( 'createCharacterScreenFive', __CLASS__, 'createCharacterScreenFive' );
|
||||
self::addHandler( 'createCharacterScreenSix', __CLASS__, 'createCharacterScreenSix' );
|
||||
self::addHandler( 'createCharacterScreenSeven', __CLASS__, 'createCharacterScreenSeven' );
|
||||
self::addHandler( 'createCharacterScreenEight', __CLASS__, 'createCharacterScreenEight' );
|
||||
|
||||
}
|
||||
public static function createTrait() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function editTrait() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function createSpell() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function editSpell() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function createSourcebook() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
// if ( ! Input::exists( 'sourceType' ) ) {
|
||||
// Check::addUserError( 'You must provide a sourceType.' );
|
||||
// return false;
|
||||
// }
|
||||
if ( ! Input::exists( 'year' ) ) {
|
||||
Check::addUserError( 'You must provide a year.' );
|
||||
return false;
|
||||
}
|
||||
// if ( ! Input::exists( 'amazonUrl' ) ) {
|
||||
// Check::addUserError( 'You must provide a amazonUrl.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
public static function editSourcebook() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function createSkill() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function editSkill() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function createRace() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function editRace() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function createMonster() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function editMonster() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function createLanguage() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'privacy' ) ) {
|
||||
Check::addUserError( 'You must provide a privacy.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'version' ) ) {
|
||||
Check::addUserError( 'You must provide a version.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'sourcebookID' ) ) {
|
||||
Check::addUserError( 'You must provide a sourcebookID.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'type' ) ) {
|
||||
Check::addUserError( 'You must provide a type.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function editLanguage() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'privacy' ) ) {
|
||||
Check::addUserError( 'You must provide a privacy.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'version' ) ) {
|
||||
Check::addUserError( 'You must provide a version.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'sourcebookID' ) ) {
|
||||
Check::addUserError( 'You must provide a sourcebookID.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'type' ) ) {
|
||||
Check::addUserError( 'You must provide a type.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function createItem() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function editItem() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function createGod() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static function editGod() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createClass() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function editClass() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createCharacterScreenOne() {
|
||||
if ( ! Input::exists( 'first_name' ) ) {
|
||||
Check::addUserError( 'You must provide a first name.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'last_name' ) ) {
|
||||
Check::addUserError( 'You must provide a last name.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'privacy' ) ) {
|
||||
Check::addUserError( 'You must provide a privacy.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'version' ) ) {
|
||||
Check::addUserError( 'You must provide a version.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createCharacterScreenTwo() {
|
||||
if ( ! Input::exists( 'race' ) ) {
|
||||
Check::addUserError( 'You must provide a race.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createCharacterScreenThree() {
|
||||
if ( ! Input::exists( 'class' ) ) {
|
||||
Check::addUserError( 'You must provide a class.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createCharacterScreenFour() {
|
||||
if ( ! Input::exists( 'name' ) ) {
|
||||
Check::addUserError( 'You must provide a name.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createCharacterScreenFive() {
|
||||
if ( ! Input::exists( 'strength' ) ) {
|
||||
Check::addUserError( 'You must provide a strength.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'dexterity' ) ) {
|
||||
Check::addUserError( 'You must provide a dexterity.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'constitution' ) ) {
|
||||
Check::addUserError( 'You must provide a constitution.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'charisma' ) ) {
|
||||
Check::addUserError( 'You must provide a charisma.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'intelligence' ) ) {
|
||||
Check::addUserError( 'You must provide a intelligence.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'wisdom' ) ) {
|
||||
Check::addUserError( 'You must provide a wisdom.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createCharacterScreenSix() {
|
||||
if ( ! Input::exists( 'order' ) ) {
|
||||
Check::addUserError( 'You must provide a order.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'morality' ) ) {
|
||||
Check::addUserError( 'You must provide a morality.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createCharacterScreenSeven() {
|
||||
if ( ! Input::exists( 'age' ) ) {
|
||||
Check::addUserError( 'You must provide an age.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createCharacterScreenEight() {
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
Check::addUserError( 'You must provide a submit.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
new DnDForms;
|
File diff suppressed because it is too large
Load Diff
@ -1,377 +0,0 @@
|
||||
{
|
||||
"feats": [
|
||||
{
|
||||
"name": "Grappler",
|
||||
"description": "<p><em>Prerequisite: Strength 13 or higher </em></p>\n<p>You've developed the skills necessary to hold your own in close-quarters grappling.</p>\n<p>You gain the following benefits:</p>\n<ul>\n<li>You have advantage on attack rolls against a creature you are grappling.</li>\n<li>You can use your action to try to pin a creature grappled by you. To do so, make another grapple check. If you succeed, you and the creature are both restrained until the grapple ends.</li>\n</ul>",
|
||||
"source": "",
|
||||
"requirements": "STR 13 or higher"
|
||||
},
|
||||
{
|
||||
"name": "Infernal Constitution",
|
||||
"description": "<p><em>Prerequisites: Tiefling</em></p>\n<p><em>Fiendish blood runs strong in you, unlocking a resilience akin to that possessed by some fiends. You gain the following benefits:</em></p>\n<ul>\n<li><em>Increase your Constitution score by 1, to a maximum of 20.</em></li>\n<li><em>You have resistance to cold and poison damage.</em></li>\n<li><em>You have advantage on saving throws against being poisoned.</em></li>\n</ul>\n<p><em>Source: XGE, page 75</em></p>",
|
||||
"source": "XGE, page 75",
|
||||
"requirements": "Tiefling"
|
||||
},
|
||||
{
|
||||
"name": "Dungeon Delver",
|
||||
"description": "<p>Alert to the hidden traps and secret doors found in many dungeons, you gain the following benefits:</p>\n<ul>\n<li>You have advantage on Wisdom (Perception) and Intelligence (Investigation) checks made to detect the presence of secret doors.</li>\n<li>You have advantage on saving throws made to avoid or resist traps.</li>\n<li>You have resistance to the damage dealt by traps.</li>\n<li>Traveling at a fast pace doesn't impose the normal -5 penalty on your passive Wisdom (Perception) score.</li>\n</ul>\n<p>Source: PHB, page 166</p>",
|
||||
"source": "PHB, page 166",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Durable",
|
||||
"description": "<p><em>Hardy and resilient, you gain the following benefits:</em></p>\n<ul>\n<li><em>Increase your Constitution score by 1, to a maximum of 20.</em></li>\n<li><em>When you roll a Hit Die to regain hit points, the minimum number of hit points you regain from the roll equals twice your Constitution modifier (minimum of 2).</em></li>\n</ul>\n<p><em>Source: PHB, page 166</em></p>",
|
||||
"source": " PHB, page 166",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Second Chance",
|
||||
"description": "<p><em>Prerequisites: Halfling</em></p>\n<p><em>Fortune favors you when someone tries to strike you. You gain the following benefits:</em></p>\n<ul>\n<li><em>Increase your Dexterity, Constitution, or Charisma by 1, to a maximum of 20.</em></li>\n<li><em>When a creature you can see hits you with an attack roll, you can use your reaction to force that creature to reroll. Once you use this ability, you can't use it again until you roll initiative at the start of combat or until you finish a short or long rest.</em></li>\n</ul>\n<p><em>Source: XGE, page 75</em></p>",
|
||||
"source": "XGE, page 75",
|
||||
"requirements": "Halfling"
|
||||
},
|
||||
{
|
||||
"name": "Charger",
|
||||
"description": "<p><em>When you use your action to Dash, you can use a bonus action to make one melee weapon attack or to shove a creature.</em></p>\n<p><em>If you move at least 10 feet in a straight line immediately before taking this bonus action, you either gain a +5 bonus to the attack's damage roll (if you chose to make a melee attack and hit) or push the target up to 10 feet away from you (if you chose to shove and you succeed).</em></p>\n<p><em> </em></p>\n<p><em>Source: PHB, page 165</em></p>",
|
||||
"source": "PHB, page 165",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Medium Armor Master",
|
||||
"description": "<p><em>Prerequisites: Proficiency with medium armor</em></p>\n<p><em>You have practiced moving in medium armor to gain the following benefits:</em></p>\n<ul>\n<li><em>Wearing medium armor doesn't impose disadvantage on your Dexterity (Stealth) checks.</em></li>\n<li><em>When you wear medium armor, you can add 3, rather than 2, to your AC if you have a Dexterity of 16 or higher.</em></li>\n</ul>\n<p><em>Source: PHB, page 168</em></p>",
|
||||
"source": "PHB, page 168",
|
||||
"requirements": " Proficiency medium armor"
|
||||
},
|
||||
{
|
||||
"name": "Squat Nimbleness",
|
||||
"description": "<p><em>Prerequisites: Dwarf or a Small race</em></p>\n<ul>\n<li><em>You are uncommonly nimble for your race. You gain the following benefits:</em></li>\n<li><em>Increase your Strength or Dexterity by 1, to a maximum of 20.</em></li>\n<li><em>Increase your walking speed by 5 feet.</em></li>\n<li><em>You gain proficiency in the Acrobatics or Athletics skill (your choice).</em></li>\n<li><em>You have advantage on any Strength (Athletics) or Dexterity (Acrobatics) check you make to escape from being grappled.</em></li>\n</ul>\n<p><em>Source: XGE, page 75</em></p>",
|
||||
"source": "XGE, page 75",
|
||||
"requirements": "Dwarf or a Small race"
|
||||
},
|
||||
{
|
||||
"name": "Dual Wielder",
|
||||
"description": "<p>You master fighting with two weapons, gaining the following benefits:</p>\n<ul>\n<li>You gain a +1 bonus to AC while you are wielding a separate melee weapon in each hand.</li>\n<li>You can use two-weapon fighting even when the one-handed melee weapons you are wielding aren't light.</li>\n<li>You can draw or stow two one-handed weapons when you would normally be able to draw or stow only one.</li>\n</ul>\n<p>Source: PHB, page 165</p>",
|
||||
"source": " PHB, page 165",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Inspiring Leader",
|
||||
"description": "<p>Prerequisites: Charisma 13 or higher</p>\n<p>You can spend 10 minutes inspiring your companions, shoring up their resolve to fight. When you do so, choose up to six friendly creatures (which can include yourself) within 30 feet of you who can see or hear you and who can understand you. Each creature can gain temporary hit points equal to your level + your Charisma modifier. A creature can't gain temporary hit points from this feat again until it has finished a short or long rest.</p>\n<p>Source: PHB, page 167</p>",
|
||||
"source": "PHB, page 167",
|
||||
"requirements": "CHA 13 or higher"
|
||||
},
|
||||
{
|
||||
"name": "Drow High Magic",
|
||||
"description": "<p><em>Prerequisites: Elf (drow)</em></p>\n<p><em>You learn more of the magic typical of dark elves. You learn the detect magic spell and can cast it at will, without expending a spell slot. You also learn levitate and dispel magic, each of which you can cast once without expending a spell slot. You regain the ability to cast those two spells in this way when you finish a long rest. Charisma is your spellcasting ability for all three spells.</em></p>\n<p><em>Source: XGE, page 74</em></p>",
|
||||
"source": "XGE, page 74",
|
||||
"requirements": "Elf (drow)"
|
||||
},
|
||||
{
|
||||
"name": "Heavy Armor Master",
|
||||
"description": "<p>Prerequisites: Proficiency with heavy armor</p>\n<p>You can use your armor to deflect strikes that would kill others. You gain the following benefits:</p>\n<ul>\n<li>Increase your Strength score by 1, to a maximum of 20.</li>\n<li>While you are wearing heavy armor, bludgeoning, piercing, and slashing damage that you take from nonmagical weapons is reduced by 3.</li>\n</ul>\n<p>Source: PHB, page 167</p>",
|
||||
"source": "PHB, page 167",
|
||||
"requirements": "Proficiency heavy armor"
|
||||
},
|
||||
{
|
||||
"name": "Defensive Duelist",
|
||||
"description": "<p><em>Prerequisites: Dexterity 13 or higher</em></p>\n<p><em>When you are wielding a finesse weapon with which you are proficient and another creature hits you with a melee attack, you can use your reaction to add your proficiency bonus to your AC for that attack, potentially causing the attack to miss you.</em></p>\n<p><em>Source: PHB, page 165</em></p>",
|
||||
"source": "PHB, page 165",
|
||||
"requirements": "DEX 13 or higher"
|
||||
},
|
||||
{
|
||||
"name": "Magic Initiate",
|
||||
"description": "<p><em>Choose a class: bard, cleric, druid, sorcerer, warlock, or wizard. You learn two cantrips of your choice from that class's spell list.</em></p>\n<p><em>In addition, choose one 1st-level spell from that same list. You learn that spell and can cast it at its lowest level. Once you cast it, you must finish a long rest before you can cast it again using this feat.</em></p>\n<p><em>Your spellcasting ability for these spells depends on the class you chose: Charisma for bard, sorcerer, or warlock; Wisdom for cleric or druid; or Intelligence for wizard.</em></p>\n<p><em> </em></p>\n<p><em>Source: PHB, page 168</em></p>",
|
||||
"source": "PHB, page 168",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Great Weapon Master",
|
||||
"description": "<p>You've learned to put the weight of a weapon to your advantage, letting its momentum empower your strikes. You gain the following benefits:</p>\n<ul>\n<li>On your turn, when you score a critical hit with a melee weapon or reduce a creature to 0 hit points with one, you can make one melee weapon attack as a bonus action.</li>\n<li>Before you make a melee attack with a heavy weapon that you are proficient with, you can choose to take a -5 penalty to the attack roll. If the attack hits, you add +10 to the attack's damage.</li>\n</ul>\n<p>Source: PHB, page 167</p>",
|
||||
"source": "PHB, page 167",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Orcish Fury",
|
||||
"description": "<p><em>Prerequisites: Half-Orc</em></p>\n<p><em>Your fury burns tirelessly. You gain the following benefits:</em></p>\n<ul>\n<li><em>Increase your Strength or Constitution by 1, to a maximum of 20.</em></li>\n<li><em>When you hit with an attack using a simple or martial weapon, you can roll one of the weapon's damage dice an additional time and add it as extra damage of the weapon's damage type. Once you use this ability, you can't use it again until you finish a short or long rest.</em></li>\n<li><em>Immediately after you use your Relentless Endurance trait, you can use your reaction to make one weapon attack.</em></li>\n</ul>\n<p><em>Source: XGE, page 75</em></p>",
|
||||
"source": "XGE, page 75",
|
||||
"requirements": "Half-Orc"
|
||||
},
|
||||
{
|
||||
"name": "Svirfneblin Magic",
|
||||
"description": "<p><em>Prerequisites: Gnome (deep)</em></p>\n<p><em>You have inherited the innate spellcasting ability of your ancestors. This ability allows you to cast nondetection on yourself at will, without needing a material component. You can also cast each of the following spells once with this ability: blindness/deafness, blur, and disguise self. You regain the ability to cast these spells when you finish a long rest.</em></p>\n<p><em>Intelligence is your spellcasting ability for these spells, and you cast them at their lowest possible levels.</em></p>\n<p><em> </em></p>\n<p><em>Source: MTF, page 114. Additional information from EEPC, page 7; SCAG, page 115.</em></p>",
|
||||
"source": "MTF, page 114",
|
||||
"requirements": "Gnome (deep)"
|
||||
},
|
||||
{
|
||||
"name": "Tavern Brawler",
|
||||
"description": "<p><em>Accustomed to rough-and-tumble fighting using whatever weapons happen to be at hand, you gain the following benefits:</em></p>\n<ul>\n<li><em>Increase your Strength or Constitution by 1, to a maximum of 20.</em></li>\n<li><em>You are proficient with improvised weapons.</em></li>\n<li><em>Your unarmed strike uses a d4 for damage.</em></li>\n<li><em>When you hit a creature with an unarmed strike or an improvised weapon on your turn, you can use a bonus action to attempt to grapple the target.</em></li>\n</ul>\n<p><em>Source: PHB, page 170</em></p>",
|
||||
"source": "PHB, page 170",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Actor",
|
||||
"description": "<p><em>Skilled at mimicry and dramatics, you gain the following benefits:</em></p>\n<ul>\n<li><em>Increase your Charisma score by 1, to a maximum of 20.</em></li>\n<li><em>You have advantage on Charisma (Deception) and Charisma (Performance) checks when trying to pass yourself off as a different person.</em></li>\n<li><em>You can mimic the speech of another person or the sounds made by other creatures. You must have heard the person speaking, or heard the creature make the sound, for at least 1 minute. A successful Wisdom (Insight) check contested by your Charisma (Deception) check allows a listener to determine that the effect is faked.</em></li>\n</ul>\n<p><em>Source: PHB, page 165</em></p>",
|
||||
"source": "PHB, page 165",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Elemental Adept",
|
||||
"description": "<p>Prerequisites: The ability to cast at least one spell</p>\n<p>When you gain this feat, choose one of the following damage types: acid, cold, fire, lightning, or thunder.</p>\n<p>Spells you cast ignore resistance to damage of the chosen type. In addition, when you roll damage for a spell you cast that deals damage of that type, you can treat any 1 on a damage die as a 2.</p>\n<p> </p>\n<p>You can select this feat multiple times. Each time you do so, you must choose a different damage type.</p>\n<p> </p>\n<p>Source: PHB, page 166</p>",
|
||||
"source": " PHB, page 166",
|
||||
"requirements": "Caster"
|
||||
},
|
||||
{
|
||||
"name": "Fey Teleportation",
|
||||
"description": "<p>Prerequisites: Elf (high)</p>\n<p>Your study of high elven lore has unlocked fey power that few other elves possess, except your eladrin cousins. Drawing on your fey ancestry, you can momentarily stride through the Feywild to shorten your path from one place to another. You gain the following benefits:</p>\n<ul>\n<li>Increase your Intelligence or Charisma by 1, to a maximum of 20.</li>\n<li>You learn to speak, read, and write Sylvan.</li>\n<li>You learn the misty step spell and can cast it once without expending a spell slot. You regain the ability to cast it in this way when you finish a short or long rest. Intelligence is your spellcasting ability for this spell.</li>\n</ul>\n<p>Source: XGE, page 74</p>",
|
||||
"source": "XGE, page 74",
|
||||
"requirements": " Elf (high)"
|
||||
},
|
||||
{
|
||||
"name": "Flames of Phlegethos",
|
||||
"description": "<p>Prerequisites: Tiefling</p>\n<p>You learn to call on hellfire to serve your commands. You gain the following benefits:</p>\n<ul>\n<li>Increase your Intelligence or Charisma by 1, to a maximum of 20.</li>\n<li>When you roll fire damage for a spell you cast, you can reroll any roll of 1 on the fire damage dice, but you must use the new roll, even if it is another 1.</li>\n<li>Whenever you cast a spell that deals fire damage, you can cause flames to wreathe you until the end of your next turn. The flames don't harm you or your possessions, and they shed bright light out to 30 feet and dim light for an additional 30 feet. While the flames are present, any creature within 5 feet of you that hits you with a melee attack takes 1d4 fire damage.</li>\n</ul>\n<p>Source: XGE, page 74</p>",
|
||||
"source": "XGE, page 74",
|
||||
"requirements": "Tiefling"
|
||||
},
|
||||
{
|
||||
"name": "Skilled",
|
||||
"description": "<p><em>You gain proficiency in any combination of three skills or tools of your choice.</em></p>\n<p><em>Source: PHB, page 170</em></p>",
|
||||
"source": "PHB, page 170",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Linguist",
|
||||
"description": "<p><em>You have studied languages and codes, gaining the following benefits:</em></p>\n<ul>\n<li><em>Increase your Intelligence score by 1, to a maximum of 20.</em></li>\n<li><em>You learn three languages of your choice.</em></li>\n<li><em>You can ably create written ciphers. Others can't decipher a code you create unless you teach them, they succeed on an Intelligence check (DC equal to your Intelligence score + your proficiency bonus), or they use magic to decipher it.</em></li>\n</ul>\n<p><em>Source: PHB, page 167</em></p>",
|
||||
"source": "PHB, page 167",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Tough",
|
||||
"description": "<p><em>Your hit point maximum increases by an amount equal to twice your level when you gain this feat. Whenever you gain a level thereafter, your hit point maximum increases by an additional 2 hit points.</em></p>\n<p><em>Source: PHB, page 170</em></p>",
|
||||
"source": "PHB, page 170",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Elven Accuracy",
|
||||
"description": "<p>Prerequisites: Elf or half-elf</p>\n<p>The accuracy of elves is legendary, especially that of elf archers and spellcasters. You have uncanny aim with attacks that rely on precision rather than brute force. You gain the following benefits:</p>\n<ul>\n<li>Increase your Dexterity, Intelligence, Wisdom, or Charisma by 1, to a maximum of 20.</li>\n<li>Whenever you have advantage on an attack roll using Dexterity, Intelligence, Wisdom, or Charisma, you can reroll one of the dice once.</li>\n</ul>\n<p>Source: XGE, page 74</p>",
|
||||
"source": "XGE, page 74",
|
||||
"requirements": "Elf or half-elf"
|
||||
},
|
||||
{
|
||||
"name": "Skulker",
|
||||
"description": "<p><em>Prerequisites: Dexterity 13 or higher</em></p>\n<p><em>You are expert at slinking through shadows. You gain the following benefits:</em></p>\n<ul>\n<li><em>You can try to hide when you are lightly obscured from the creature from which you are hiding.</em></li>\n<li><em>When you are hidden from a creature and miss it with a ranged weapon attack, making the attack doesn't reveal your position.</em></li>\n<li><em>Dim light doesn't impose disadvantage on your Wisdom (Perception) checks relying on sight.</em></li>\n</ul>\n<p><em>Source: PHB, page 170</em></p>",
|
||||
"source": "PHB, page 170",
|
||||
"requirements": "DEX 13 or higher"
|
||||
},
|
||||
{
|
||||
"name": "Ritual Caster",
|
||||
"description": "<p><em>Prerequisites: Intelligence or Wisdom 13 or higher</em></p>\n<p><em>You have learned a number of spells that you can cast as rituals. These spells are written in a ritual book, which you must have in hand while casting one of them.</em></p>\n<p><em>When you choose this feat, you acquire a ritual book holding two 1st-level spells of your choice. Choose one of the following classes: bard, cleric, druid, sorcerer, warlock, or wizard. You must choose your spells from that class's spell list, and the spells you choose must have the ritual tag. The class you choose also determines your spellcasting ability for these spells: Charisma for bard, sorcerer, or warlock; Wisdom for cleric or druid; or Intelligence for wizard.</em></p>\n<p><em> </em></p>\n<p><em>If you come across a spell in written form, such as a magical spell scroll or a wizard's spellbook, you might be able to add it to your ritual book. The spell must be on the spell list for the class you chose, the spell's level can be no higher than half your level (rounded up), and it must have the ritual tag. The process of copying the spell into your ritual book takes 2 hours per level of the spell, and costs 50 gp per level. The cost represents material components you expend as you experiment with the spell to master it, as well as the fine inks you need to record it.</em></p>\n<p><em> </em></p>\n<p><em>Source: PHB, page 169</em></p>",
|
||||
"source": "PHB, page 169",
|
||||
"requirements": " INT or WIS 13 or higher"
|
||||
},
|
||||
{
|
||||
"name": "Athlete",
|
||||
"description": "<p>You have undergone extensive physical training to gain the following benefits:</p>\n<ul>\n<li>Increase your Strength or Dexterity by 1, to a maximum of 20.</li>\n<li>When you are prone, standing up uses only 5 feet of your movement.</li>\n<li>Climbing doesn't cost you extra movement.</li>\n<li>You can make a running long jump or a running high jump after moving only 5 feet on foot, rather than 10 feet.</li>\n</ul>\n<p>Source: PHB, page 165</p>",
|
||||
"source": "PHB, page 165",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Sharpshooter",
|
||||
"description": "<p><em>You have mastered ranged weapons and can make shots that others find impossible. You gain the following benefits:</em></p>\n<ul>\n<li><em>Attacking at long range doesn't impose disadvantage on your ranged weapon attack rolls.</em></li>\n<li><em>Your ranged weapon attacks ignore half cover and three-quarters cover.</em></li>\n<li><em>Before you make an attack with a ranged weapon that you are proficient with, you can choose to take a -5 penalty to the attack roll. If the attack hits, you add +10 to the attack's damage.</em></li>\n</ul>\n<p><em>Source: PHB, page 170</em></p>",
|
||||
"source": "PHB, page 170",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Fade Away",
|
||||
"description": "<p>Prerequisites: Gnome</p>\n<p>Your people are clever, with a knack for illusion magic. You have learned a magical trick for fading away when you suffer harm. You gain the following benefits:</p>\n<ul>\n<li>Increase your Dexterity or Intelligence by 1, to a maximum of 20.</li>\n<li>Immediately after you take damage, you can use a reaction to magically become invisible until the end of your next turn or until you attack, deal damage, or force someone to make a saving throw. Once you use this ability, you can't do so again until you finish a short or long rest.</li>\n</ul>\n<p>Source: XGE, page 74</p>",
|
||||
"source": "XGE, page 74",
|
||||
"requirements": "Gnome"
|
||||
},
|
||||
{
|
||||
"name": "Dwarven Fortitude",
|
||||
"description": "<p><em>Prerequisites: Dwarf</em></p>\n<p><em>You have the blood of dwarf heroes flowing through your veins. You gain the following benefits:</em></p>\n<ul>\n<li><em>Increase your Constitution score by 1, to a maximum of 20.</em></li>\n<li><em>Whenever you take the Dodge action in combat, you can spend one Hit Die to heal yourself. Roll the die, add your Constitution modifier, and regain a number of hit points equal to the total (minimum of 1).</em></li>\n</ul>\n<p><em>Source: XGE, page 74</em></p>",
|
||||
"source": "XGE, page 74",
|
||||
"requirements": "Dwarf"
|
||||
},
|
||||
{
|
||||
"name": "Bountiful Luck",
|
||||
"description": "<p>Your people have extraordinary luck, which you have learned to mystically lend to your companions when you see them falter. You're not sure how you do it; you just wish it, and it happens. Surely a sign of fortune's favor!</p>\n<div> </div>\n<p>When an ally you can see within 30 feet of you rolls a 1 on the <span title=\"Click to roll. SHIFT/CTRL to roll twice.\" data-packed-dice=\"{"type":"dice","rollable":true,"toRoll":"d20"}\">d20</span> for an attack roll, an ability check, or a saving throw, you can use your reaction to let the ally reroll the die. The ally must use the new roll.</p>\n<p>When you use this ability, you can't use your Lucky racial trait before the end of your next turn.</p>",
|
||||
"source": "XGE, page 73",
|
||||
"requirements": "Halfling"
|
||||
},
|
||||
{
|
||||
"name": "Prodigy",
|
||||
"description": "<p><em>Prerequisites: Half-Elf, half-orc, or human</em></p>\n<p><em>You have a knack for learning new things. You gain the following benefits:</em></p>\n<ul>\n<li><em>You gain one skill proficiency of your choice, one tool proficiency of your choice, and fluency in one language of your choice.</em></li>\n<li><em>Choose one skill in which you have proficiency. You gain expertise with that skill, which means your proficiency bonus is doubled for any ability check you make with it. The skill you choose must be one that isn't already benefiting from a feature, such as Expertise, that doubles your proficiency bonus.</em></li>\n</ul>\n<p><em>Source: XGE, page 75</em></p>",
|
||||
"source": "XGE, page 75",
|
||||
"requirements": "Half-Elf, half-orc, or human"
|
||||
},
|
||||
{
|
||||
"name": "Sentinel",
|
||||
"description": "<p><em>You have mastered techniques to take advantage of every drop in any enemy's guard, gaining the following benefits:</em></p>\n<ul>\n<li><em>When you hit a creature with an opportunity attack, the creature's speed becomes 0 for the rest of the turn.</em></li>\n<li><em>Creatures provoke opportunity attacks from you even if they take the Disengage action before leaving your reach.</em></li>\n<li><em>When a creature within 5 feet of you makes an attack against a target other than you (and that target doesn't have this feat), you can use your reaction to make a melee weapon attack against the attacking creature.</em></li>\n</ul>\n<p><em>Source: PHB, page 169</em></p>",
|
||||
"source": "PHB, page 169",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Lucky",
|
||||
"description": "<p>You have inexplicable luck that seems to kick in at just the right moment.</p>\n<p>You have 3 luck points. Whenever you make an attack roll, an ability check, or a saving throw, you can spend one luck point to roll an additional d20. You can choose to spend one of your luck points after you roll the die, but before the outcome is determined. You choose which of the d20s is used for the attack roll, ability check, or saving throw.</p>\n<p>You can also spend one luck point when an attack roll is made against you. Roll a d20, and then choose whether the attack uses the attacker's roll or yours. If more than one creature spends a luck point to influence the outcome of a roll, the points cancel each other out; no additional dice are rolled.</p>\n<p>You regain your expended luck points when you finish a long rest.</p>\n<p> </p>\n<p>Source: PHB, page 167</p>",
|
||||
"source": "PHB, page 167",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Mobile",
|
||||
"description": "<p><em>You are exceptionally speedy and agile. You gain the following benefits:</em></p>\n<ul>\n<li><em>Your speed increases by 10 feet.</em></li>\n<li><em>When you use the Dash action, difficult terrain doesn't cost you extra movement on that turn.</em></li>\n<li><em>When you make a melee attack against a creature, you don't provoke opportunity attacks from that creature for the rest of the turn, whether you hit or not.</em></li>\n</ul>\n<p><em>Source: PHB, page 168</em></p>",
|
||||
"source": "PHB, page 168",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Mounted Combatant",
|
||||
"description": "<p><em>You are a dangerous foe to face while mounted. While you are mounted and aren't incapacitated, you gain the following benefits:</em></p>\n<ul>\n<li><em>You have advantage on melee attack rolls against any unmounted creature that is smaller than your mount.</em></li>\n<li><em>You can force an attack targeted at your mount to target you instead.</em></li>\n<li><em>If your mount is subjected to an effect that allows it to make a Dexterity saving throw to take only half damage, it instead takes no damage if it succeeds on the saving throw, and only half damage if it fails.</em></li>\n</ul>\n<p><em>Source: PHB, page 168</em></p>",
|
||||
"source": "PHB, page 168",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Dragon Fear",
|
||||
"description": "<p>Prerequisites: Dragonborn</p>\n<p>When angered, you radiate menace. You gain the following benefits:</p>\n<p>Increase your Strength, Constitution, or Charisma by 1, to a maximum of 20.</p>\n<p>Instead of exhaling destructive energy, you can expend a use of your Breath Weapon trait to roar, forcing each creature of your choice within 30 feet of you to make a Wisdom saving throw (DC 8 + your proficiency bonus + your Charisma modifier). A target automatically succeeds on the save if it can't hear or see you. On a failed save, a target becomes frightened of you for 1 minute. If the frightened target takes any damage, it can repeat the saving throw, ending the effect on itself on a success.</p>\n<p>Source: XGE, page 74</p>",
|
||||
"source": "XGE, page 74",
|
||||
"requirements": "Dragonborn"
|
||||
},
|
||||
{
|
||||
"name": "Heavily Armored",
|
||||
"description": "<p>Prerequisites: Proficiency with medium armor</p>\n<p>You have trained to master the use of heavy armor, gaining the following benefits:</p>\n<ul>\n<li>Increase your Strength score by 1, to a maximum of 20.</li>\n<li>You gain proficiency with heavy armor.</li>\n</ul>\n<p>Source: PHB, page 167</p>",
|
||||
"source": "PHB, page 167",
|
||||
"requirements": "Proficiency medium armor"
|
||||
},
|
||||
{
|
||||
"name": "Keen Mind",
|
||||
"description": "<p><em>You have a mind that can track time, direction, and detail with uncanny precision. You gain the following benefits:</em></p>\n<ul>\n<li><em>Increase your Intelligence score by 1, to a maximum of 20.</em></li>\n<li><em>You always know which way is north.</em></li>\n<li><em>You always know the number of hours left before the next sunrise or sunset.</em></li>\n<li><em>You can accurately recall anything you have seen or heard within the past month.</em></li>\n</ul>\n<p><em>Source: PHB, page 167</em></p>",
|
||||
"source": "PHB, page 167",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Mage Slayer",
|
||||
"description": "<p><em>You have practiced techniques useful in melee combat against spellcasters, gaining the following benefits:</em></p>\n<ul>\n<li><em>When a creature within 5 feet of you casts a spell, you can use your reaction to make a melee weapon attack against that creature.</em></li>\n<li><em>When you damage a creature that is concentrating on a spell, that creature has disadvantage on the saving throw it makes to maintain its concentration.</em></li>\n<li><em>You have advantage on saving throws against spells cast by creatures within 5 feet of you.</em></li>\n</ul>\n<p><em>Source: PHB, page 168</em></p>",
|
||||
"source": "PHB, page 168",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Moderately Armored",
|
||||
"description": "<p><em>Prerequisites: Proficiency with light armor</em></p>\n<p><em>You have trained to master the use of medium armor and shields, gaining the following benefits:</em></p>\n<ul>\n<li><em>Increase your Strength or Dexterity by 1, to a maximum of 20.</em></li>\n<li><em>You gain proficiency with medium armor and shields.</em></li>\n</ul>\n<p><em>Source: PHB, page 168</em></p>",
|
||||
"source": "PHB, page 168",
|
||||
"requirements": "Proficiency light armor"
|
||||
},
|
||||
{
|
||||
"name": "War Caster",
|
||||
"description": "<p><em>Prerequisites: The ability to cast at least one spell</em></p>\n<p><em>You have practiced casting spells in the midst of combat, learning techniques that grant you the following benefits:</em></p>\n<ul>\n<li><em>You have advantage on Constitution saving throws that you make to maintain your concentration on a spell when you take damage.</em></li>\n<li><em>You can perform the somatic components of spells even when you have weapons or a shield in one or both hands.</em></li>\n<li><em>When a hostile creature's movement provokes an opportunity attack from you, you can use your reaction to cast a spell at the creature, rather than making an opportunity attack. The spell must have a casting time of 1 action and must target only that creature.</em></li>\n</ul>\n<p><em>Source: PHB, page 170</em></p>",
|
||||
"source": "PHB, page 170",
|
||||
"requirements": "Caster"
|
||||
},
|
||||
{
|
||||
"name": "Weapon Master",
|
||||
"description": "<p><em>You have practiced extensively with a variety of weapons, gaining the following benefits:</em></p>\n<ul>\n<li><em>Increase your Strength or Dexterity by 1, to a maximum of 20.</em></li>\n<li><em>You gain proficiency with four simple or martial weapons of your choice. Each one must be a simple or a martial weapon.</em></li>\n</ul>\n<p><em>Source: PHB, page 170</em></p>",
|
||||
"source": "PHB, page 170",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Resilient",
|
||||
"description": "<p><em>Choose one ability score. You gain the following benefits:</em></p>\n<ul>\n<li><em>Increase the chosen ability score by 1, to a maximum of 20.</em></li>\n<li><em>You gain proficiency in saving throws using the chosen ability.</em></li>\n</ul>\n<p><em>Source: PHB, page 168</em></p>",
|
||||
"source": "PHB, page 168",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Healer",
|
||||
"description": "<p>You are an able physician, allowing you to mend wounds quickly and get your allies back in the fight. You gain the following benefits:</p>\n<ul>\n<li>When you use a healer's kit to stabilize a dying creature, that creature also regains 1 hit point.</li>\n<li>As an action, you can spend one use of a healer's kit to tend to a creature and restore 1d6 + 4 hit points to it, plus additional hit points equal to the creature's maximum number of Hit Dice. The creature can't regain hit points from this feat again until it finishes a short or long rest.</li>\n</ul>\n<p>Source: PHB, page 167</p>",
|
||||
"source": "PHB, page 167",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Lightly Armored",
|
||||
"description": "<p><em>You have trained to master the use of light armor, gaining the following benefits:</em></p>\n<ul>\n<li><em>Increase your Strength or Dexterity by 1, to a maximum of 20.</em></li>\n<li><em>You gain proficiency with light armor.</em></li>\n</ul>\n<p><em>Source: PHB, page 167</em></p>",
|
||||
"source": "PHB, page 167",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Observant",
|
||||
"description": "<p><em>Quick to notice details of your environment, you gain the following benefits:</em></p>\n<ul>\n<li><em>Increase your Intelligence or Wisdom by 1, to a maximum of 20.</em></li>\n<li><em>If you can see a creature's mouth while it is speaking a language you understand, you can interpret what it's saying by reading its lips.</em></li>\n<li><em>You have a +5 bonus to your passive Wisdom (Perception) and passive Intelligence (Investigation) scores.</em></li>\n</ul>\n<p><em>Source: PHB, page 168</em></p>",
|
||||
"source": "PHB, page 168",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Martial Adept",
|
||||
"description": "<p><em>You have martial training that allows you to perform special combat maneuvers. You gain the following benefits:</em></p>\n<ul>\n<li><em>You learn two maneuvers of your choice from among those available to the Battle Master archetype in the fighter class. If a maneuver you use requires your target to make a saving throw to resist the maneuver's effects, the saving throw DC equals 8 + your proficiency bonus + your Strength or Dexterity modifier (your choice).</em></li>\n<li><em>You gain one superiority die, which is a d6 (this die is added to any superiority dice you have from another source). This die is used to fuel your maneuvers. A superiority die is expended when you use it. You regain your expended superiority dice when you finish a short or long rest.</em></li>\n</ul>\n<p><em>Source: PHB, page 168</em></p>",
|
||||
"source": "PHB, page 168",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Dragon Hide",
|
||||
"description": "<p><em>Prerequisites: Dragonborn</em></p>\n<p><em>You manifest scales and claws reminiscent of your draconic ancestors. You gain the following benefits:</em></p>\n<ul>\n<li><em>Increase your Strength, Constitution, or Charisma by 1, to a maximum of 20.</em></li>\n<li><em>Your scales harden. While you aren't wearing armor, you can calculate your AC as 13 + your Dexterity modifier. You can use a shield and still gain this benefit.</em></li>\n<li><em>You grow retractable claws from the tips of your fingers. Extending or retracting the claws requires no action. The claws are natural weapons, which you can use to make unarmed strikes. If you hit with them, you deal slashing damage equal to 1d4 + your Strength modifier, instead of the normal bludgeoning damage for an unarmed strike.</em></li>\n</ul>\n<p><em>Source: XGE, page 74</em></p>",
|
||||
"source": "XGE, page 74",
|
||||
"requirements": "Dragonborn"
|
||||
},
|
||||
{
|
||||
"name": "Wood Elf Magic",
|
||||
"description": "<p><em>Prerequisites: Elf (wood)</em></p>\n<p><em>You learn the magic of the primeval woods, which are revered and protected by your people. You learn one druid cantrip of your choice. You also learn the longstrider and pass without trace spells, each of which you can cast once without expending a spell slot. You regain the ability to cast these two spells in this way when you finish a long rest. Wisdom is your spellcasting ability for all three spells.</em></p>\n<p><em>Source: XGE, page 75</em></p>",
|
||||
"source": "XGE, page 75",
|
||||
"requirements": "Elf (wood)"
|
||||
},
|
||||
{
|
||||
"name": "Crossbow Expert",
|
||||
"description": "<p><em>Thanks to extensive practice with the crossbow, you gain the following benefits:</em></p>\n<ul>\n<li><em>You ignore the loading quality of crossbows with which you are proficient.</em></li>\n<li><em>Being within 5 feet of a hostile creature doesn't impose disadvantage on your ranged attack rolls.</em></li>\n<li><em>When you use the Attack action and attack with a one-handed weapon, you can use a bonus action to attack with a hand crossbow you are holding.</em></li>\n</ul>\n<p><em>Source: PHB, page 165</em></p>",
|
||||
"source": "PHB, page 165",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Savage Attacker",
|
||||
"description": "<p><em>Once per turn when you roll damage for a melee weapon attack, you can reroll the weapon's damage dice and use either total.</em></p>\n<p><em>Source: PHB, page 169</em></p>",
|
||||
"source": "PHB, page 169",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Polearm Master",
|
||||
"description": "<p><em>You can keep your enemies at bay with reach weapons. You gain the following benefits:</em></p>\n<ul>\n<li><em>When you take the Attack action and attack with only a glaive, halberd, quarterstaff, or spear, you can use a bonus action to make a melee attack with the opposite end of the weapon; this attack uses the same ability modifier as the primary attack. The weapon's damage die for this attack is a d4, and the attack deals bludgeoning damage.</em></li>\n<li><em>While you are wielding a glaive, halberd, pike, quarterstaff, or spear, other creatures provoke an opportunity attack from you when they enter your reach.</em></li>\n</ul>\n<p><em>Source: PHB, page 168</em></p>",
|
||||
"source": "PHB, page 168",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Revenant Blade",
|
||||
"description": "<p><em>Prerequisites: Elf</em></p>\n<p><em>You are descended from a master of the double-bladed scimitar, and some of that mastery has passed on to you. You gain the following benefits:</em></p>\n<ul>\n<li><em>Increase your Strength or Dexterity by 1, to a maximum of 20.</em></li>\n<li><em>While you are holding a double-bladed scimitar with two hands, you gain a +1 bonus to Armor Class.</em></li>\n<li><em>A double-bladed scimitar has the finesse property when you wield it.</em></li>\n</ul>\n<p><em>Source: ERLW, page 22. Also found in WGE, page 74.</em></p>",
|
||||
"source": "ERLW, page 22",
|
||||
"requirements": "Elf"
|
||||
},
|
||||
{
|
||||
"name": "Spell Sniper",
|
||||
"description": "<p><em>Prerequisites: The ability to cast at least one spell</em></p>\n<p><em>You have learned techniques to enhance your attacks with certain kinds of spells, gaining the following benefits:</em></p>\n<ul>\n<li><em>When you cast a spell that requires you to make an attack roll, the spell's range is doubled.</em></li>\n<li><em>Your ranged spell attacks ignore half cover and three-quarters cover.</em></li>\n<li><em>You learn one cantrip that requires an attack roll. Choose the cantrip from the bard, cleric, druid, sorcerer, warlock, or wizard spell list. Your spellcasting ability for this cantrip depends on the spell list you chose from: Charisma for bard, sorcerer, or warlock; Wisdom for cleric or druid; or Intelligence for wizard.</em></li>\n</ul>\n<p><em>Source: PHB, page 170</em></p>",
|
||||
"source": "PHB, page 170",
|
||||
"requirements": "Caster"
|
||||
},
|
||||
{
|
||||
"name": "Shield Master",
|
||||
"description": "<p><em>You use shields not just for protection but also for offense. You gain the following benefits while you are wielding a shield:</em></p>\n<ul>\n<li><em>If you take the Attack action on your turn, you can use a bonus action to try to shove a creature within 5 feet of you with your shield.</em></li>\n<li><em>If you aren't incapacitated, you can add your shield's AC bonus to any Dexterity saving throw you make against a spell or other harmful effect that targets only you.</em></li>\n<li><em>If you are subjected to an effect that allows you to make a Dexterity saving throw to take only half damage, you can use your reaction to take no damage if you succeed on the saving throw, interposing your shield between yourself and the source of the effect.</em></li>\n</ul>\n<p><em>Source: PHB, page 170</em></p>",
|
||||
"source": "PHB, page 170",
|
||||
"requirements": ""
|
||||
},
|
||||
{
|
||||
"name": "Aberrant Dragonmark",
|
||||
"description": "<p>Prerequisites: No other dragonmark</p>\n<p> </p>\n<table id=\"pagecontent\">\n<tbody>\n<tr>\n<td style=\"width: 399px;\" colspan=\"6\">\n<div>\n<p>You have manifested an aberrant dragonmark. Determine its appearance and the flaw associated with it. You gain the following benefits:</p>\n<div> </div>\n<ul>\n<li>Increase your Constitution score by 1, to a maximum of 20.</li>\n<li>You learn a <a href=\"https://5e.tools/spells.html#blankhash,flstlevel:0=1,flstclass:sorcerer=1\">cantrip of your choice from the sorcerer spell list</a>. In addition, choose a <a href=\"https://5e.tools/spells.html#blankhash,flstlevel:1=1,flstclass:sorcerer=1\">1st-level spell from the sorcerer spell list</a>. You learn that spell and can cast it through your mark. Once you cast it, you must finish a short or long rest before you can cast it again through the mark. Constitution is your spellcasting ability for these spells.</li>\n<li>When you cast the 1st-level spell through your mark, you can expend one of your Hit Dice and roll it. If you roll an even number, you gain a number of temporary hit points equal to the number rolled. If you roll an odd number, one random creature within 30 feet of you (not including you) takes force damage equal to the number rolled. If no other creatures are in range, you take the damage.</li>\n</ul>\n<p>You also develop a random flaw from the Aberrant Dragonmark Flaws table.</p>\n<table style=\"height: 195px; width: 269px;\" width=\"374\"><caption>Aberrant Dragonmark Flaws</caption>\n<thead>\n<tr>\n<th style=\"width: 19px;\" data-rd-isroller=\"true\"><span title=\"Click to roll. SHIFT/CTRL to roll twice.\" data-packed-dice=\"{"type":"dice","rollable":true,"toRoll":"d8"}\">d8</span></th>\n<th style=\"width: 248px;\" data-rd-isroller=\"false\">Flaw</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"width: 17px;\" data-roll-min=\"1\" data-roll-max=\"1\">1</td>\n<td style=\"width: 246px;\">Your mark is a source of constant physical pain.</td>\n</tr>\n<tr>\n<td style=\"width: 17px;\" data-roll-min=\"2\" data-roll-max=\"2\">2</td>\n<td style=\"width: 246px;\">Your mark whispers to you. Its meaning can be unclear.</td>\n</tr>\n<tr>\n<td style=\"width: 17px;\" data-roll-min=\"3\" data-roll-max=\"3\">3</td>\n<td style=\"width: 246px;\">When you're stressed, the mark hisses audibly.</td>\n</tr>\n<tr>\n<td style=\"width: 17px;\" data-roll-min=\"4\" data-roll-max=\"4\">4</td>\n<td style=\"width: 246px;\">The skin around the mark is burned, scaly, or withered.</td>\n</tr>\n<tr>\n<td style=\"width: 17px;\" data-roll-min=\"5\" data-roll-max=\"5\">5</td>\n<td style=\"width: 246px;\">Animals are uneasy around you.</td>\n</tr>\n<tr>\n<td style=\"width: 17px;\" data-roll-min=\"6\" data-roll-max=\"6\">6</td>\n<td style=\"width: 246px;\">You have a mood swing any time you use your mark.</td>\n</tr>\n<tr>\n<td style=\"width: 17px;\" data-roll-min=\"7\" data-roll-max=\"7\">7</td>\n<td style=\"width: 246px; text-align: center;\">Your looks change slightly whenever you use the mark.</td>\n</tr>\n<tr>\n<td style=\"width: 17px;\" data-roll-min=\"8\" data-roll-max=\"8\">8</td>\n<td style=\"width: 246px;\">You have horrific nightmares after you use your mark.</td>\n</tr>\n</tbody>\n</table>\n<div>\n<div>\n<div>Option: Greater Aberrant Powers\n<p>At the DM's option, a character who has the Aberrant Dragonmark feat has a chance of manifesting greater power. Upon reaching 10th level, such a character has a 10 percent chance of gaining an epic boon from among the options in <a href=\"https://5e.tools/book.html#DMG,-1\">chapter 7</a> of the <a href=\"https://5e.tools/book.html#DMG\">Dungeon Master's Guide</a>. If the character fails to gain a boon, they have a 10 percent chance the next time they gain a level.</p>\n<p>If the character gains a boon, the DM chooses it or determines it randomly. The character also permanently loses one of their Hit Dice, and their hit point maximum is reduced by an amount equal to a roll of that die plus their Constitution modifier (minimum reduction of 1). This reduction can't be reversed by any means.</p>\n</div>\n</div>\n</div>\n</div>\n</td>\n</tr>\n<tr>\n<td style=\"width: 399px;\" colspan=\"6\">Source: ERLW, page 52. Also found in WGE, page 112.</td>\n</tr>\n</tbody>\n</table>",
|
||||
"source": "ERLW, page 52",
|
||||
"featType": {
|
||||
"value": "passive",
|
||||
"_deprecated": true,
|
||||
"type": "String",
|
||||
"label": "Feat Type"
|
||||
},
|
||||
"requirements": "No other dragonmark"
|
||||
},
|
||||
{
|
||||
"name": "Alert",
|
||||
"description": "<p>Always on the lookout for danger, you gain the following benefits:</p>\n<ul>\n<li>You gain a +5 bonus to initiative.</li>\n<li>You can't be surprised while you are conscious.</li>\n<li>Other creatures don't gain advantage on attack rolls against you as a result of being unseen by you.</li>\n</ul>\n<p>Source: PHB, page 165</p>",
|
||||
"source": "PHB, page 165",
|
||||
"requirements": "",
|
||||
"flags": {
|
||||
"dynamicitems": {
|
||||
"cursed": {
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,473 +0,0 @@
|
||||
{
|
||||
"gods": [
|
||||
{
|
||||
"name": "The Daghdha, god of weather and crops",
|
||||
"alignment": "CG",
|
||||
"suggested_domains": "Nature, Trickery",
|
||||
"symbol": "Bubbling cauldron or shield",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Arawn, god of life and death",
|
||||
"alignment": "NE",
|
||||
"suggested_domains": "Life, Death",
|
||||
"symbol": "Black star on gray background",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Belenus, god of sun, light, and warmth",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Light",
|
||||
"symbol": "Solar disk and standing stones",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Brigantia, goddess of rivers and livestock",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Life",
|
||||
"symbol": "Footbridge",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Diancecht, god of medicine and healing",
|
||||
"alignment": "LG",
|
||||
"suggested_domains": "Life",
|
||||
"symbol": "Crossed oak and mistletoe branches",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Dunatis, god of mountains and peaks",
|
||||
"alignment": "N",
|
||||
"suggested_domains": "Nature",
|
||||
"symbol": "Red sun-capped mountain peak",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Goibhniu, god of smiths and healing",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Knowledge, Life",
|
||||
"symbol": "Giant mallet over sword",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Lugh, god of arts, travel, and commerce",
|
||||
"alignment": "CN",
|
||||
"suggested_domains": "Knowledge, Life",
|
||||
"symbol": "Pair of long hands",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Manannan mac Lir, god of oceans and sea creatures",
|
||||
"alignment": "LN",
|
||||
"suggested_domains": "Nature, Tempest",
|
||||
"symbol": "Wave of white water on green",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Math Mathonwy, god of magic",
|
||||
"alignment": "NE",
|
||||
"suggested_domains": "Knowledge",
|
||||
"symbol": "Staff",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Morrigan, goddess of battle",
|
||||
"alignment": "CE",
|
||||
"suggested_domains": "War",
|
||||
"symbol": "Two crossed spears",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Nuada, god of war and warriors",
|
||||
"alignment": "N",
|
||||
"suggested_domains": "War",
|
||||
"symbol": "Silver hand on black background",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Oghma, god of speech and writing",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Knowledge",
|
||||
"symbol": "Unfurled scroll",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Silvanus, god of nature and forests",
|
||||
"alignment": "N",
|
||||
"suggested_domains": "Nature",
|
||||
"symbol": "Summer oak tree",
|
||||
"pantheon": "Celtic"
|
||||
},
|
||||
{
|
||||
"name": "Zeus, god of the sky, ruler of the gods",
|
||||
"alignment": "N",
|
||||
"suggested_domains": "Tempest",
|
||||
"symbol": "Fist full of lightning bolts",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Aphrodite, goddess of love and beauty",
|
||||
"alignment": "CG",
|
||||
"suggested_domains": "Light",
|
||||
"symbol": "Sea shell",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Apollo, god of light, music, and healing",
|
||||
"alignment": "CG",
|
||||
"suggested_domains": "Knowledge, Life, Light",
|
||||
"symbol": "Lyre",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Ares, god of war and strife",
|
||||
"alignment": "CE",
|
||||
"suggested_domains": "War",
|
||||
"symbol": "Spear",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Artemis, goddess of hunting and childbirth",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Life, Nature",
|
||||
"symbol": "Bow and arrow on lunar disk",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Athena, goddess of wisdom and civilization",
|
||||
"alignment": "LG",
|
||||
"suggested_domains": "Knowledge, War",
|
||||
"symbol": "Owl",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Demeter, goddess of agriculture",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Life",
|
||||
"symbol": "Mareʼs head",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Dionysus, god of mirth and wine",
|
||||
"alignment": "CN",
|
||||
"suggested_domains": "Life",
|
||||
"symbol": "Thyrsus (staff tipped with pine cone)",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Hades, god of the underworld",
|
||||
"alignment": "LE",
|
||||
"suggested_domains": "Death",
|
||||
"symbol": "Black ram",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Hecate, goddess of magic and the moon",
|
||||
"alignment": "CE",
|
||||
"suggested_domains": "Knowledge, Trickery",
|
||||
"symbol": "Setting moon",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Hephaestus, god of smithing and craft",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Knowledge",
|
||||
"symbol": "Hammer and anvil",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Hera, goddess of marriage and intrigue",
|
||||
"alignment": "CN",
|
||||
"suggested_domains": "Trickery",
|
||||
"symbol": "Fan of peacock feathers",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Hercules, god of strength and adventure",
|
||||
"alignment": "CG",
|
||||
"suggested_domains": "Tempest, War",
|
||||
"symbol": "Lionʼs head",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Hermes, god of travel and commerce",
|
||||
"alignment": "CG",
|
||||
"suggested_domains": "Trickery",
|
||||
"symbol": "Caduceus (winged staff and serpents)",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Hestia, goddess of home and family",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Life",
|
||||
"symbol": "Hearth",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Nike, goddess of victory",
|
||||
"alignment": "LN",
|
||||
"suggested_domains": "War",
|
||||
"symbol": "Winged woman",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Pan, god of nature",
|
||||
"alignment": "CN",
|
||||
"suggested_domains": "Nature",
|
||||
"symbol": "Syrinx (pan pipes)",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Poseidon, god of the sea and earthquakes",
|
||||
"alignment": "CN",
|
||||
"suggested_domains": "Tempest",
|
||||
"symbol": "Trident",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Tyche, goddess of good fortune",
|
||||
"alignment": "N",
|
||||
"suggested_domains": "Trickery",
|
||||
"symbol": "Red pentagram",
|
||||
"pantheon": "Greek"
|
||||
},
|
||||
{
|
||||
"name": "Re-Horakhty, god of the sun, ruler of the god",
|
||||
"alignment": "LG",
|
||||
"suggested_domains": "Life, Light",
|
||||
"symbol": "Solar disk encircled by serpent",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Anubis, god of judgment and deat",
|
||||
"alignment": "LN",
|
||||
"suggested_domains": "Death",
|
||||
"symbol": "Black jackal",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Apep, god of evil, fire, and serpent",
|
||||
"alignment": "NE",
|
||||
"suggested_domains": "Trickery",
|
||||
"symbol": "Flaming snake",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Bast, goddess of cats and vengeanc",
|
||||
"alignment": "CG",
|
||||
"suggested_domains": "War",
|
||||
"symbol": "Cat",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Bes, god of luck and musi",
|
||||
"alignment": "CN",
|
||||
"suggested_domains": "Trickery",
|
||||
"symbol": "Image of the misshapen deity",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Hathor, goddess of love, music, and motherhoo",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Life, Light",
|
||||
"symbol": "Horned cowʼs head with lunar disk",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Imhotep, god of crafts and medicin",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Knowledge",
|
||||
"symbol": "Step pyramid",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Isis, goddess of fertility and magi",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Knowledge, Life",
|
||||
"symbol": "Ankh and star",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Nephthys, goddess of death and grie",
|
||||
"alignment": "CG",
|
||||
"suggested_domains": "Death",
|
||||
"symbol": "Horns around a lunar disk",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Osiris, god of nature and the underworl",
|
||||
"alignment": "LG",
|
||||
"suggested_domains": "Life, Nature",
|
||||
"symbol": "Crook and flail",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Ptah, god of crafts, knowledge, and secret",
|
||||
"alignment": "LN",
|
||||
"suggested_domains": "Knowledge",
|
||||
"symbol": "Bull",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Set, god of darkness and desert storm",
|
||||
"alignment": "CE",
|
||||
"suggested_domains": "Death, Tempest, Trickery",
|
||||
"symbol": "Coiled cobra",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Sobek, god of water and crocodile",
|
||||
"alignment": "LE",
|
||||
"suggested_domains": "Nature, Tempest",
|
||||
"symbol": "Crocodile head with horns and plumes",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Thoth, god of knowledge and wisdo",
|
||||
"alignment": "N",
|
||||
"suggested_domains": "Knowledge",
|
||||
"symbol": "Ibis",
|
||||
"pantheon": "Egyptian"
|
||||
},
|
||||
{
|
||||
"name": "Odin, god of knowledge and war",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Knowledge, War",
|
||||
"symbol": "Watching blue eye",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Aegir, god of the sea and storms",
|
||||
"alignment": "NE",
|
||||
"suggested_domains": "Tempest",
|
||||
"symbol": "Rough ocean waves",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Balder, god of beauty and poetry",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Life, Light",
|
||||
"symbol": "Gem-encrusted silver chalice",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Forseti, god of justice and law",
|
||||
"alignment": "N",
|
||||
"suggested_domains": "Light",
|
||||
"symbol": "Head of a bearded man",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Frey, god of fertility and the sun",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Life, Light",
|
||||
"symbol": "Ice-blue greatsword",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Freya, goddess of fertility and love",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Life",
|
||||
"symbol": "Falcon",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Frigga, goddess of birth and fertility",
|
||||
"alignment": "N",
|
||||
"suggested_domains": "Life, Light",
|
||||
"symbol": "Cat",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Heimdall, god of watchfulness and loyalty",
|
||||
"alignment": "LG",
|
||||
"suggested_domains": "Light, War",
|
||||
"symbol": "Curling musical horn",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Hel, goddess of the underworld",
|
||||
"alignment": "NE",
|
||||
"suggested_domains": "Death",
|
||||
"symbol": "Womanʼs face, rotting on one side",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Hermod, god of luck",
|
||||
"alignment": "CN",
|
||||
"suggested_domains": "Trickery",
|
||||
"symbol": "Winged scroll",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Loki, god of thieves and trickery",
|
||||
"alignment": "CE",
|
||||
"suggested_domains": "Trickery",
|
||||
"symbol": "Flame",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Njord, god of sea and wind",
|
||||
"alignment": "NG",
|
||||
"suggested_domains": "Nature, Tempest",
|
||||
"symbol": "Gold coin",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Odur, god of light and the sun",
|
||||
"alignment": "CG",
|
||||
"suggested_domains": "Light",
|
||||
"symbol": "Solar disk",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Sif, goddess of war",
|
||||
"alignment": "CG",
|
||||
"suggested_domains": "War",
|
||||
"symbol": "Upraised sword",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Skadi, god of earth and mountains",
|
||||
"alignment": "N",
|
||||
"suggested_domains": "Nature",
|
||||
"symbol": "Mountain peak",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Surtur, god of fire giants and war",
|
||||
"alignment": "LE",
|
||||
"suggested_domains": "War",
|
||||
"symbol": "Flaming sword",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Thor, god of storms and thunder",
|
||||
"alignment": "CG",
|
||||
"suggested_domains": "Tempest, War",
|
||||
"symbol": "Hammer",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Thrym, god of frost giants and cold",
|
||||
"alignment": "CE",
|
||||
"suggested_domains": "War",
|
||||
"symbol": "White double-bladed axe",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Tyr, god of courage and strategy",
|
||||
"alignment": "LN",
|
||||
"suggested_domains": "Knowledge, War",
|
||||
"symbol": "Sword",
|
||||
"pantheon": "Norse"
|
||||
},
|
||||
{
|
||||
"name": "Uller, god of hunting and winter",
|
||||
"alignment": "CN",
|
||||
"suggested_domains": "Nature",
|
||||
"symbol": "Longbow",
|
||||
"pantheon": "Norse"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,244 +0,0 @@
|
||||
{
|
||||
"languages": [
|
||||
{
|
||||
"name": "Common",
|
||||
"type": "standard",
|
||||
"script": "Common",
|
||||
"typical_speakers": "Humans",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "Common is the essentially universal language of D&D.",
|
||||
"description": "Common is the essentially universal language of D&D.",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Dwarvish",
|
||||
"type": "standard",
|
||||
"script": "Dwarvish",
|
||||
"typical_speakers": "Dwarves",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "Mainly spoken by Dwarves, this language's simple alphabet is the foundation of many other languages.",
|
||||
"description": "Mainly spoken by Dwarves, this language's simple alphabet is the foundation of many other languages.",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Elvish",
|
||||
"type": "standard",
|
||||
"script": "Elvish",
|
||||
"typical_speakers": "Elves",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "Elvish",
|
||||
"description": "Elvish",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Giant",
|
||||
"type": "standard",
|
||||
"script": "Dwarvish",
|
||||
"typical_speakers": "Giants, ogres",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "Giant",
|
||||
"description": "Giant",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Gnomish",
|
||||
"type": "standard",
|
||||
"script": "Dwarvish",
|
||||
"typical_speakers": "Gnomes",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "Gnomish",
|
||||
"description": "Gnomish",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Goblin",
|
||||
"type": "standard",
|
||||
"script": "Dwarvish",
|
||||
"typical_speakers": "Goblins",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "Goblin",
|
||||
"description": "Goblin",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Halfling",
|
||||
"type": "standard",
|
||||
"script": "Common",
|
||||
"typical_speakers": "Halflings",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "Halfling",
|
||||
"description": "Halfling",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Orc",
|
||||
"type": "standard",
|
||||
"script": "Dwarvish",
|
||||
"typical_speakers": "Orcs",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "Orc",
|
||||
"description": "Orc",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Abyssal",
|
||||
"type": "exotic",
|
||||
"script": "Infernal",
|
||||
"typical_speakers": "Demons",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "Abyssal is spoken by all demons, but its dialects sound vastly different depending on the rank of the demon speaking.",
|
||||
"description": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Celestial",
|
||||
"type": "exotic",
|
||||
"script": "Celestial",
|
||||
"typical_speakers": "Celestials, Angels",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "As the name implies, Celestials speak Celestial. It’s also common for the odd DnD Cleric to pick it up, given its angelic origins.",
|
||||
"description": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Deep Speech",
|
||||
"type": "exotic",
|
||||
"script": "aberrations. rarely written",
|
||||
"typical_speakers": "aberrations, Aboleths, cloakers",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "Aberrations, such as Mind Flayers and Beholders, speak the Deep Speech of the Far Realm. There is no written version of this language, though some species have created their own version as accurately as they can.",
|
||||
"description": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Draconic",
|
||||
"type": "exotic",
|
||||
"script": "Draconic",
|
||||
"typical_speakers": "Dragons, Dragonborn",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "The language of the Dragonborn",
|
||||
"description": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Infernal",
|
||||
"type": "exotic",
|
||||
"script": "Infernal",
|
||||
"typical_speakers": "Devils",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "Devils in the Nine Hells commonly speak and write in Infernal. Clerics of certain DnD alignments may learn this language. Plus, a DnD Warlock in a pact with a devil might find it useful to know.",
|
||||
"description": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Primordial",
|
||||
"type": "exotic",
|
||||
"script": "Dwarvish",
|
||||
"typical_speakers": "Elementals",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"description": "These are Auran, Aquan, Ignan, and Terran. An elemental who speaks Aquan can still communicate with one that speaks Ignan, but they remain distinct. Technically, there are different elemental languages (Ignan, Aquan, Auran, and Terran), but they’re all considered dialects of Primordial—so if you understand one, you understand them all.",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Sylvan",
|
||||
"type": "exotic",
|
||||
"script": "Elvish",
|
||||
"typical_speakers": "Fey creatures, Fairies, Eladrin",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"description": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Undercommon",
|
||||
"type": "exotic",
|
||||
"script": "Elvish",
|
||||
"typical_speakers": "Underdark denizens, Underworld traders, Drow and Duargar",
|
||||
"sound": "",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "It's a common trade language, so many creatures beyond the Underdark make the effort to learn Undercommon. ",
|
||||
"description": "It's a common trade language, so many creatures beyond the Underdark make the effort to learn Undercommon. ",
|
||||
"image": ""
|
||||
}
|
||||
]
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
{
|
||||
"races": [
|
||||
{
|
||||
"name": "Dragonborn",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"languages": "1,12",
|
||||
"size": "Medium",
|
||||
"walking_speed": "30",
|
||||
"climbing_speed": "15",
|
||||
"swimming_speed": "15",
|
||||
"burrowing_speed": "0",
|
||||
"flying_speed": "0",
|
||||
"abilityScores": {
|
||||
"str": 2,
|
||||
"char": 1
|
||||
},
|
||||
"racial_traits": "28,29,30"
|
||||
},
|
||||
{
|
||||
"name": "Dwarf",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"languages": "1,2",
|
||||
"size": "Medium",
|
||||
"walking_speed": "25",
|
||||
"climbing_speed": "12.5",
|
||||
"swimming_speed": "12.5",
|
||||
"burrowing_speed": "0",
|
||||
"flying_speed": "0",
|
||||
"abilityScores": {
|
||||
"con": 2
|
||||
},
|
||||
"racial_traits": "1,6,7,8,9"
|
||||
},
|
||||
{
|
||||
"name": "Elf",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"languages": "1,3",
|
||||
"size": "Medium",
|
||||
"walking_speed": "30",
|
||||
"climbing_speed": "15",
|
||||
"swimming_speed": "15",
|
||||
"burrowing_speed": "0",
|
||||
"flying_speed": "0",
|
||||
"abilityScores": {
|
||||
"dex": 2
|
||||
},
|
||||
"racial_traits": "2,12,13,14"
|
||||
},
|
||||
{
|
||||
"name": "Gnome",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"languages": "1,5",
|
||||
"size": "Small",
|
||||
"walking_speed": "25",
|
||||
"climbing_speed": "12.5",
|
||||
"swimming_speed": "12.5",
|
||||
"burrowing_speed": "0",
|
||||
"flying_speed": "0",
|
||||
"abilityScores": {
|
||||
"int": 2
|
||||
},
|
||||
"racial_traits": "3,31"
|
||||
},
|
||||
{
|
||||
"name": "Half-Elf",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"languages": "1,3,*",
|
||||
"size": "Medium",
|
||||
"walking_speed": "30",
|
||||
"climbing_speed": "15",
|
||||
"swimming_speed": "15",
|
||||
"burrowing_speed": "0",
|
||||
"flying_speed": "0",
|
||||
"abilityScores": {
|
||||
"char": 2,
|
||||
"plusOne": 2
|
||||
},
|
||||
"racial_traits": "13"
|
||||
},
|
||||
{
|
||||
"name": "Half-Orc",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"languages": "1,8",
|
||||
"size": "Medium",
|
||||
"walking_speed": "30",
|
||||
"climbing_speed": "15",
|
||||
"swimming_speed": "15",
|
||||
"burrowing_speed": "0",
|
||||
"flying_speed": "0",
|
||||
"abilityScores": {
|
||||
"dex": 2
|
||||
},
|
||||
"racial_traits": "4,37,38,39"
|
||||
},
|
||||
{
|
||||
"name": "Halfling",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"languages": "1,7",
|
||||
"size": "Small",
|
||||
"walking_speed": "25",
|
||||
"climbing_speed": "12.5",
|
||||
"swimming_speed": "12.5",
|
||||
"burrowing_speed": "0",
|
||||
"flying_speed": "0",
|
||||
"abilityScores": {
|
||||
"str": 2,
|
||||
"char": 1
|
||||
},
|
||||
"racial_traits": "21,22,23"
|
||||
},
|
||||
{
|
||||
"name": "Human",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"languages": "1,*",
|
||||
"size": "Medium",
|
||||
"walking_speed": "30",
|
||||
"climbing_speed": "15",
|
||||
"swimming_speed": "15",
|
||||
"burrowing_speed": "0",
|
||||
"flying_speed": "0",
|
||||
"abilityScores": {
|
||||
"all": 1
|
||||
},
|
||||
"racial_traits": ""
|
||||
},
|
||||
{
|
||||
"name": "Tiefling",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"languages": "1,13",
|
||||
"size": "Medium",
|
||||
"walking_speed": "30",
|
||||
"climbing_speed": "15",
|
||||
"swimming_speed": "15",
|
||||
"burrowing_speed": "0",
|
||||
"flying_speed": "0",
|
||||
"abilityScores": {
|
||||
"int": 2,
|
||||
"char": 2
|
||||
},
|
||||
"racial_traits": "5,40,41"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
{
|
||||
"skills": [
|
||||
{
|
||||
"index": "acrobatics",
|
||||
"name": "Acrobatics",
|
||||
"description": "Your Dexterity (Acrobatics) check covers your attempt to stay on your feet in a tricky situation, such as when you're trying to run across a sheet of ice, balance on a tightrope, or stay upright on a rocking ship's deck. The GM might also call for a Dexterity (Acrobatics) check to see if you can perform acrobatic stunts, including dives, rolls, somersaults, and flips.",
|
||||
"ability_score": "dex"
|
||||
},
|
||||
{
|
||||
"index": "animal-handling",
|
||||
"name": "Animal Handling",
|
||||
"description": "When there is any question whether you can calm down a domesticated animal, keep a mount from getting spooked, or intuit an animal's intentions, the GM might call for a Wisdom (Animal Handling) check. You also make a Wisdom (Animal Handling) check to control your mount when you attempt a risky maneuver.",
|
||||
"ability_score": "wis"
|
||||
},
|
||||
{
|
||||
"index": "arcana",
|
||||
"name": "Arcana",
|
||||
"description": "Your Intelligence (Arcana) check measures your ability to recall lore about spells, magic items, eldritch symbols, magical traditions, the planes of existence, and the inhabitants of those planes.",
|
||||
"ability_score": "int"
|
||||
},
|
||||
{
|
||||
"index": "athletics",
|
||||
"name": "Athletics",
|
||||
"description": "Your Strength (Athletics) check covers difficult situations you encounter while climbing, jumping, or swimming.",
|
||||
"ability_score": "str"
|
||||
},
|
||||
{
|
||||
"index": "deception",
|
||||
"name": "Deception",
|
||||
"description": "Your Charisma (Deception) check determines whether you can convincingly hide the truth, either verbally or through your actions. This deception can encompass everything from misleading others through ambiguity to telling outright lies. Typical situations include trying to fast- talk a guard, con a merchant, earn money through gambling, pass yourself off in a disguise, dull someone's suspicions with false assurances, or maintain a straight face while telling a blatant lie.",
|
||||
"ability_score": "cha"
|
||||
},
|
||||
{
|
||||
"index": "history",
|
||||
"name": "History",
|
||||
"description": "Your Intelligence (History) check measures your ability to recall lore about historical events, legendary people, ancient kingdoms, past disputes, recent wars, and lost civilizations.",
|
||||
"ability_score": "int"
|
||||
},
|
||||
{
|
||||
"index": "insight",
|
||||
"name": "Insight",
|
||||
"description": "Your Wisdom (Insight) check decides whether you can determine the true intentions of a creature, such as when searching out a lie or predicting someone's next move. Doing so involves gleaning clues from body language, speech habits, and changes in mannerisms.",
|
||||
"ability_score": "wis"
|
||||
},
|
||||
{
|
||||
"index": "intimidation",
|
||||
"name": "Intimidation",
|
||||
"description": "When you attempt to influence someone through overt threats, hostile actions, and physical violence, the GM might ask you to make a Charisma (Intimidation) check. Examples include trying to pry information out of a prisoner, convincing street thugs to back down from a confrontation, or using the edge of a broken bottle to convince a sneering vizier to reconsider a decision.",
|
||||
"ability_score": "cha"
|
||||
},
|
||||
{
|
||||
"index": "investigation",
|
||||
"name": "Investigation",
|
||||
"description": "When you look around for clues and make deductions based on those clues, you make an Intelligence (Investigation) check. You might deduce the location of a hidden object, discern from the appearance of a wound what kind of weapon dealt it, or determine the weakest point in a tunnel that could cause it to collapse. Poring through ancient scrolls in search of a hidden fragment of knowledge might also call for an Intelligence (Investigation) check.",
|
||||
"ability_score": "int"
|
||||
},
|
||||
{
|
||||
"index": "medicine",
|
||||
"name": "Medicine",
|
||||
"description": "A Wisdom (Medicine) check lets you try to stabilize a dying companion or diagnose an illness.",
|
||||
"ability_score": "wis"
|
||||
},
|
||||
{
|
||||
"index": "nature",
|
||||
"name": "Nature",
|
||||
"description": "Your Intelligence (Nature) check measures your ability to recall lore about terrain, plants and animals, the weather, and natural cycles.",
|
||||
"ability_score": "int"
|
||||
},
|
||||
{
|
||||
"index": "perception",
|
||||
"name": "Perception",
|
||||
"description": "Your Wisdom (Perception) check lets you spot, hear, or otherwise detect the presence of something. It measures your general awareness of your surroundings and the keenness of your senses. For example, you might try to hear a conversation through a closed door, eavesdrop under an open window, or hear monsters moving stealthily in the forest. Or you might try to spot things that are obscured or easy to miss, whether they are orcs lying in ambush on a road, thugs hiding in the shadows of an alley, or candlelight under a closed secret door.",
|
||||
"ability_score": "wis"
|
||||
},
|
||||
{
|
||||
"index": "performance",
|
||||
"name": "Performance",
|
||||
"description": "Your Charisma (Performance) check determines how well you can delight an audience with music, dance, acting, storytelling, or some other form of entertainment.",
|
||||
"ability_score": "cha"
|
||||
},
|
||||
{
|
||||
"index": "persuasion",
|
||||
"name": "Persuasion",
|
||||
"description": "When you attempt to influence someone or a group of people with tact, social graces, or good nature, the GM might ask you to make a Charisma (Persuasion) check. Typically, you use persuasion when acting in good faith, to foster friendships, make cordial requests, or exhibit proper etiquette. Examples of persuading others include convincing a chamberlain to let your party see the king, negotiating peace between warring tribes, or inspiring a crowd of townsfolk.",
|
||||
"ability_score": "cha"
|
||||
},
|
||||
{
|
||||
"index": "religion",
|
||||
"name": "Religion",
|
||||
"description": "Your Intelligence (Religion) check measures your ability to recall lore about deities, rites and prayers, religious hierarchies, holy symbols, and the practices of secret cults.",
|
||||
"ability_score": "int"
|
||||
},
|
||||
{
|
||||
"index": "sleight-of-hand",
|
||||
"name": "Sleight of Hand",
|
||||
"description": "Whenever you attempt an act of legerdemain or manual trickery, such as planting something on someone else or concealing an object on your person, make a Dexterity (Sleight of Hand) check. The GM might also call for a Dexterity (Sleight of Hand) check to determine whether you can lift a coin purse off another person or slip something out of another person's pocket.",
|
||||
"ability_score": "dex"
|
||||
},
|
||||
{
|
||||
"index": "stealth",
|
||||
"name": "Stealth",
|
||||
"description": "Make a Dexterity (Stealth) check when you attempt to conceal yourself from enemies, slink past guards, slip away without being noticed, or sneak up on someone without being seen or heard.",
|
||||
"ability_score": "dex"
|
||||
},
|
||||
{
|
||||
"index": "survival",
|
||||
"name": "Survival",
|
||||
"description": "The GM might ask you to make a Wisdom (Survival) check to follow tracks, hunt wild game, guide your group through frozen wastelands, identify signs that owlbears live nearby, predict the weather, or avoid quicksand and other natural hazards.",
|
||||
"ability_score": "wis"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": [
|
||||
{
|
||||
"name": "Player's Handbook (5e)",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"shortDescription": "The essential rulebook for Dungeons & Dragons (5th edition)",
|
||||
"description": "The essential rulebook for Dungeons & Dragons (5th edition). Contains all the rules you need to know to play D&D. Step-by-step guide to creating and leveling up characters. Go-to player reference for over 350 spells, equipment, and more. 1 of 3 D&D Core Rulebooks—the Player’s Handbook (rules for playing the game), the Dungeon Master’s Guide (how to run the game), and Monster Manual (creatures to encounter in your game)",
|
||||
"image": "",
|
||||
"type": "Rules",
|
||||
"publish_year": "2014",
|
||||
"amazon_url": "https://www.amazon.com/Players-Handbook-Dungeons-Dragons-Wizards/dp/0786965606?th=1"
|
||||
}
|
||||
]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,455 +0,0 @@
|
||||
{
|
||||
"traits": [
|
||||
{
|
||||
"name": "Dwarven Darkvision",
|
||||
"description": "Accustomed to life underground, you have superior vision in dark and dim conditions. You can see in dim lightwithin 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can’t discern color in darkness, only shades of gray.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Elven Darkvision",
|
||||
"description": "Accustomed to twilit forests and the night sky, you have superior vision in dark and dim conditions. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can’t discern color in darkness, only shades of gray.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Gnomish Darkvision",
|
||||
"description": "Accustomed to life underground, you have superior vision in dark and dim conditions. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can’t discern color in darkness, only shades of gray.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Orcish Darkvision",
|
||||
"description": "Thanks to your orc blood, you have superior vision in dark and dim conditions. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can’t discern color in darkness, only shades of gray.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Tiefling Darkvision",
|
||||
"description": "Thanks to your infernal heritage, you have superior vision in dark and dim conditions. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can’t discern color in darkness, only shades of gray.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Dwarven Resilience",
|
||||
"description": "You have advantage on saving throws against poison, and you have resistance against poison damage.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Dwarven Combat Training",
|
||||
"description": "You have proficiency with the battleaxe, handaxe, light hammer, and warhammer.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Tool Proficiency",
|
||||
"description": "You gain proficiency with the artisan’s tools of your choice: smith’s tools, brewer’s supplies, or mason’s tools.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Stonecunning",
|
||||
"description": "Whenever you make an Intelligence (History) check related to the origin of stonework, you are considered proficient in the History skill and add double your proficiency bonus to the check, instead of your normal proficiency bonus.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Dwarven Toughness",
|
||||
"description": "Your hit point maximum increases by 1, and it increases by 1 every time you gain a level.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Dwarven Armor Training",
|
||||
"description": "You have proficiency with light and medium armor.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Keen Senses",
|
||||
"description": "You have proficiency in the Perception skill.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Fey Ancestry",
|
||||
"description": "You have advantage on saving throws against being charmed, and magic can’t put you to sleep.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Trance",
|
||||
"description": "Elves don't need to sleep. Instead, they meditate deeply, remaining semiconscious, for 4 hours a day. (The Common word for such meditation is \"trance.\") While meditating, you can dream after a fashion; such dreams are actually mental exercises that have become reflexive through years of practice. After resting in this way, you gain the same benefit that a human does from 8 hours of sleep.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Elf Weapon Training",
|
||||
"description": "You have proficiency with the longsword, shortsword, shortbow, and longbow.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Cantrip",
|
||||
"description": "You know one cantrip of your choice from the wizard spell list. Intelligence is your spellcasting ability for it.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Extra Language",
|
||||
"description": "You can speak, read, and write one extra language of your choice.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Elf Weapon Training",
|
||||
"description": "You have proficiency with the longsword, shortsword, shortbow, and longbow.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Fleet of Foot",
|
||||
"description": "Your base walking speed increases to 35 feet.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Mask of the Wild",
|
||||
"description": "You can attempt to hide even when you are only lightly obscured by foliage, heavy rain, falling snow, mist, and other natural phenomena.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Lucky",
|
||||
"description": "When you roll a 1 on the d20 for an attack roll, ability check, or saving throw, you can reroll the die and must use the new roll.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Brave",
|
||||
"description": "You have advantage on saving throws against being frightened.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Halfling Nimbleness",
|
||||
"description": "You can move through the space of any creature that is of a size larger than yours.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Naturally Stealthy",
|
||||
"description": "You can attempt to hide even when you are obscured only by a creature that is at least one size larger than you.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Stout Resilience",
|
||||
"description": "You have advantage on saving throws against poison, and you have resistance against poison damage.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Skills",
|
||||
"description": "You gain proficiency in one skill of your choice.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Feat",
|
||||
"description": "You gain one feat of your choice.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Draconic Ancestry",
|
||||
"description": "You have draconic ancestry. Choose one type of dragon from the Draconic Ancestry table. Your breath weapon and damage resistance are determined by the dragon type, as shown in the table.\n Dragon Damage Type Breath Weapon\n Black Acid 5 by 30 ft. line (Dex. save)\n Blue Lightning 5 by 30 ft. line (Dex. save)\n Brass Fire 5 by 30 ft. line (Dex. save)\n Bronze Lightning 5 by 30 ft. line (Dex. save)\n Copper Acid 5 by 30 ft. line (Dex. save)\n Gold Fire 15 ft. cone (Dex. save)\n Green Poison 15 ft. cone (Con. save)\n Red Fire 15 ft. cone (Dex. save)\n Silver Cold 15 ft. cone (Con. save)\n White Cold 15 ft. cone (Con. save)",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Breath Weapon",
|
||||
"description": "You can use your action to exhale destructive energy. Your draconic ancestry determines the size, shape, and damage type of the exhalation. When you use your breath weapon, each creature in the area of the exhalation must make a saving throw, the type of which is determined by your draconic ancestry. The DC for this saving throw equals 8 + your Constitution modifier + your proficiency bonus. A creature takes 2d6 damage on a failed save, and half as much damage on a successful one. The damage increases to 3d6 at 6th level, 4d6 at 11th level, and 5d6 at 16th level. After you use your breath weapon, you can’t use it again until you complete a short or long rest.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Damage Resistance",
|
||||
"description": "You have resistance to the damage type associated with your draconic ancestry.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Gnome Cunning",
|
||||
"description": "You have advantage on all Intelligence, Wisdom, and Charisma saving throws against magic.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Artificer's Lore",
|
||||
"description": "Whenever you make an Intelligence (History) check related to magic items, alchemical objects, or technological devices, you can add twice your proficiency bonus, instead of any proficiency bonus you normally apply.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Tinker",
|
||||
"description": "You have proficiency with artisan’s tools (tinker’s tools). Using those tools, you can spend 1 hour and 10 gp worth of materials to construct a Tiny clockwork device (AC 5, 1 hp). The device ceases to function after 24 hours (unless you spend 1 hour repairing it to keep the device functioning), or when you use your action to dismantle it; at that time, you can reclaim the materials used to create it. You can have up to three such devices active at a time. When you create a device, choose one of the following options:",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Clockwork Toy",
|
||||
"description": "This toy is a clockwork animal, monster, or person, such as a frog, mouse, bird, dragon, or soldier. When placed on the ground, the toy moves 5 feet across the ground on each of your turns in a random direction. It makes noises as appropriate to the creature it represents.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Fire Starter",
|
||||
"description": "The device produces a miniature flame, which you can use to light a candle, torch, or campfire. Using the device requires your action.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Music Box",
|
||||
"description": "When opened, this music box plays a single song at a moderate volume. The box stops playing when it reaches the song’s end or when it is closed.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Menacing",
|
||||
"description": "You gain proficiency in the Intimidation skill.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Relentless Endurance",
|
||||
"description": "When you are reduced to 0 hit points but not killed outright, you can drop to 1 hit point instead. You can’t use this feature again until you finish a long rest.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Savage Attacks",
|
||||
"description": "When you score a critical hit with a melee weapon attack, you can roll one of the weapon’s damage dice one additional time and add it to the extra damage of the critical hit.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Hellish Resistance",
|
||||
"description": "You have resistance to fire damage.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
},
|
||||
{
|
||||
"name": "Infernal Legacy",
|
||||
"description": "You know the thaumaturgy cantrip. When you reach 3rd level, you can cast the hellish rebuke spell as a 2nd-level spell once with this trait and regain the ability to do so when you finish a long rest. When you reach 5th level, you can cast the darkness spell once with this trait and regain the ability to do so when you finish a long rest. Charisma is your spellcasting ability for these spells.",
|
||||
"createdBy": "0",
|
||||
"createdAt": "{time}",
|
||||
"privacy": "public",
|
||||
"version": "5",
|
||||
"sourcebookID": "1",
|
||||
"shortDescription": "",
|
||||
"image": ""
|
||||
}
|
||||
]
|
||||
}
|
@ -1,297 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/models/characters.php
|
||||
*
|
||||
* This class is used for the manipulation of the dnd_characters database table.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Functions\Date;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Houdini\Classes\Filters;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
|
||||
class Characters extends DatabaseModel {
|
||||
public $tableName = 'dnd_characters';
|
||||
public $databaseMatrix = [
|
||||
// Name
|
||||
[ 'prefix', 'varchar', '128' ],
|
||||
[ 'first_name', 'varchar', '128' ],
|
||||
[ 'middle_name', 'varchar', '128' ],
|
||||
[ 'last_name', 'varchar', '128' ],
|
||||
[ 'suffix', 'varchar', '128' ],
|
||||
|
||||
// General
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'privacy', 'varchar', '16' ],
|
||||
[ 'notes', 'text', '' ], // campaign notes
|
||||
[ 'version', 'varchar', '5' ],
|
||||
[ 'image', 'text', '' ],
|
||||
[ 'avatar', 'text', '' ],
|
||||
|
||||
// allignment
|
||||
[ 'morality', 'varchar', '16' ], // good, neutral, evil
|
||||
[ 'order', 'varchar', '16' ], // lawful, neutral, chaotic
|
||||
|
||||
// Appearance
|
||||
[ 'age', 'int', '4' ],
|
||||
[ 'height', 'varchar', '32' ],
|
||||
[ 'weight', 'varchar', '32' ],
|
||||
[ 'eyes', 'varchar', '32' ],
|
||||
[ 'skin', 'varchar', '32' ],
|
||||
[ 'hair', 'varchar', '32' ],
|
||||
[ 'gender', 'varchar', '32' ],
|
||||
|
||||
// Core
|
||||
[ 'raceID', 'int', '11' ],
|
||||
[ 'classID', 'int', '11' ],
|
||||
[ 'hitpoints', 'int', '5' ],
|
||||
[ 'current_hitpoints', 'int', '5' ],
|
||||
[ 'level', 'int', '4' ],
|
||||
[ 'experience', 'int', '12' ],
|
||||
|
||||
// Skills
|
||||
[ 'strength', 'int', '4' ],
|
||||
[ 'dexterity', 'int', '4' ],
|
||||
[ 'constitution', 'int', '4' ],
|
||||
[ 'charisma', 'int', '4' ],
|
||||
[ 'intelligence', 'int', '4' ],
|
||||
[ 'wisdom', 'int', '4' ],
|
||||
|
||||
// Expository
|
||||
[ 'story', 'text', '' ], // backstory
|
||||
[ 'appearance', 'text', '' ],
|
||||
[ 'allies', 'text', '' ],
|
||||
[ 'enemies', 'text', '' ],
|
||||
[ 'organizations', 'text', '' ],
|
||||
[ 'flaws', 'text', '' ],
|
||||
[ 'bonds', 'text', '' ],
|
||||
[ 'oaths', 'text', '' ],
|
||||
[ 'ideals', 'text', '' ],
|
||||
[ 'creed', 'text', '' ],
|
||||
[ 'motto', 'text', '' ],
|
||||
[ 'traits', 'text', '' ], // personality traits
|
||||
|
||||
// Currency
|
||||
[ 'copper', 'int', '12' ],
|
||||
[ 'silver', 'int', '12' ],
|
||||
[ 'gold', 'int', '12' ],
|
||||
[ 'platinum', 'int', '12' ],
|
||||
[ 'electrum', 'int', '12' ],
|
||||
|
||||
// [ 'armorclass', 'int', '4' ],
|
||||
// [ 'initiative', 'int', '4' ],
|
||||
// [ 'speed', 'int', '4' ],
|
||||
// [ 'proficiency', 'int', '4' ],
|
||||
// [ 'inspiration', 'int', '4' ],
|
||||
// [ 'alignment', 'varchar', '16' ],
|
||||
// [ 'background', 'varchar', '128' ],
|
||||
// [ 'languages', 'text', '' ],
|
||||
// [ 'equipment', 'text', '' ],
|
||||
// [ 'features', 'text', '' ],
|
||||
// [ 'spells', 'text', '' ],
|
||||
// [ 'skills', 'text', '' ],
|
||||
// [ 'saves', 'text', '' ],
|
||||
// [ 'bonuses', 'text', '' ],
|
||||
// [ 'inventory', 'text', '' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function createFromScreenOne( $first_name, $last_name, $privacy, $version, $prefix = '', $middle_name = '', $suffix = '', $avatar = '' ) {
|
||||
$fields = [
|
||||
// required
|
||||
'first_name' => $first_name,
|
||||
'last_name' => $last_name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
// optional
|
||||
'prefix' => $prefix,
|
||||
'middle_name' => $middle_name,
|
||||
'suffix' => $suffix,
|
||||
'avatar' => $avatar,
|
||||
];
|
||||
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'characterCreate' );
|
||||
Debug::error( "Character: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function updateFromScreenTwo( $id, $raceID ) {
|
||||
$fields = [
|
||||
'raceID' => $raceID,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'characterUpdate' );
|
||||
Debug::error( "Character: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function updateFromScreenThree( $id, $classID ) {
|
||||
$fields = [
|
||||
'classID' => $classID,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'characterUpdate' );
|
||||
Debug::error( "Character: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// public function updateFromScreenFour( $id, $name ) {
|
||||
// $fields = [
|
||||
// 'name' => $name,
|
||||
// ];
|
||||
// if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
// new CustomException( 'characterUpdate' );
|
||||
// Debug::error( "Character: $id not updated: $fields" );
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public function updateFromScreenFive( $id, $strength, $dexterity, $constitution, $charisma, $intelligence, $wisdom ) {
|
||||
$fields = [
|
||||
'strength' => $strength,
|
||||
'dexterity' => $dexterity,
|
||||
'constitution' => $constitution,
|
||||
'charisma' => $charisma,
|
||||
'intelligence' => $intelligence,
|
||||
'wisdom' => $wisdom,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'characterUpdate' );
|
||||
Debug::error( "Character: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function updateFromScreenSix( $id, $order, $morality, $story = '', $allies = '', $enemies = '', $organizations = '', $flaws = '', $bonds = '', $ideals = '', $traits = '', $oaths = '', $motto = '', $creed = '' ) {
|
||||
$fields = [
|
||||
'order' => $order,
|
||||
'morality' => $morality,
|
||||
'story' => $story,
|
||||
'allies' => $allies,
|
||||
'enemies' => $enemies,
|
||||
'organizations' => $organizations,
|
||||
'flaws' => $flaws,
|
||||
'bonds' => $bonds,
|
||||
'ideals' => $ideals,
|
||||
'traits' => $traits,
|
||||
'oaths' => $oaths,
|
||||
'motto' => $motto,
|
||||
'creed' => $creed,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'characterUpdate' );
|
||||
Debug::error( "Character: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function updateFromScreenSeven( $id, $age = '', $height = '', $weight = '', $eyes = '', $skin = '', $hair = '', $gender = '', $appearance = '' ) {
|
||||
$fields = [
|
||||
'age' => $age,
|
||||
'height' => $height,
|
||||
'weight' => $weight,
|
||||
'eyes' => $eyes,
|
||||
'skin' => $skin,
|
||||
'hair' => $hair,
|
||||
'gender' => $gender,
|
||||
'appearance' => $appearance,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'characterUpdate' );
|
||||
Debug::error( "Character: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function updateFromScreenEight( $id, $name ) {
|
||||
$fields = [
|
||||
'copper' => $copper,
|
||||
'silver' => $silver,
|
||||
'gold' => $gold,
|
||||
'platinum' => $platinum,
|
||||
'electrum' => $electrum,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'characterUpdate' );
|
||||
Debug::error( "Character: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function create( $name ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'characterCreate' );
|
||||
Debug::error( "Character: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $name ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'characterUpdate' );
|
||||
Debug::error( "Character: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No Characters found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
// inventory() - items
|
||||
// spells() - spells
|
||||
// skills() - skills
|
||||
// saves() - calculate all the various saving throws
|
||||
// bonuses() - calculate the various bonuses such as to initiative and AC etc
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/models/classes.php
|
||||
*
|
||||
* This class is used for the manipulation of the dnd_classes database table.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Models\Sourcebooks as SourcebooksModel;
|
||||
|
||||
class Classes extends DatabaseModel {
|
||||
protected static $sourcebooks;
|
||||
public $tableName = 'dnd_classes';
|
||||
public $databaseMatrix = [
|
||||
// Name
|
||||
[ 'name', 'varchar', '32' ],
|
||||
|
||||
// General
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'privacy', 'varchar', '16' ],
|
||||
[ 'version', 'varchar', '5' ],
|
||||
[ 'sourcebookID', 'int', '11' ],
|
||||
[ 'shortDescription', 'text', '' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'image', 'text', '' ],
|
||||
[ 'avatar', 'text', '' ],
|
||||
|
||||
[ 'classID', 'int', '11' ],
|
||||
// spells()
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$sourcebooks = new SourcebooksModel;
|
||||
}
|
||||
|
||||
public function create( $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'Create' );
|
||||
Debug::error( "Class: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'Update' );
|
||||
Debug::error( "Class: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No Classes found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
$out = [];
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$sourcebook = self::$sourcebooks->findById( $instance->sourcebookID );
|
||||
if ( !empty( $sourcebook ) ) {
|
||||
$instance->sourcebookName = $sourcebook->name;
|
||||
} else {
|
||||
$instance->sourcebookName = 'Unknown';
|
||||
}
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
@ -1,117 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/models/feats.php
|
||||
*
|
||||
* This class is used for the manipulation of the dnd_feats database table.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Models\Sourcebooks as SourcebooksModel;
|
||||
|
||||
class Feats extends DatabaseModel {
|
||||
protected static $sourcebooks;
|
||||
public $tableName = 'dnd_feats';
|
||||
public $databaseMatrix = [
|
||||
// Name
|
||||
[ 'name', 'varchar', '32' ],
|
||||
|
||||
// General
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'privacy', 'varchar', '16' ],
|
||||
[ 'version', 'varchar', '5' ],
|
||||
[ 'sourcebookID', 'int', '11' ],
|
||||
[ 'shortDescription', 'text', '' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'image', 'text', '' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$sourcebooks = new SourcebooksModel;
|
||||
}
|
||||
|
||||
public function create( $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'Create' );
|
||||
Debug::error( "Feat: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'Update' );
|
||||
Debug::error( "Feat: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No Feats found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
$out = [];
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$sourcebook = self::$sourcebooks->findById( $instance->sourcebookID );
|
||||
if ( !empty( $sourcebook ) ) {
|
||||
$instance->sourcebookName = $sourcebook->name;
|
||||
} else {
|
||||
$instance->sourcebookName = 'Unknown';
|
||||
}
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/models/gods.php
|
||||
*
|
||||
* This class is used for the manipulation of the dnd_gods database table.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Models\Sourcebooks as SourcebooksModel;
|
||||
|
||||
class Gods extends DatabaseModel {
|
||||
protected static $sourcebooks;
|
||||
public $tableName = 'dnd_gods';
|
||||
public $databaseMatrix = [
|
||||
// Name
|
||||
[ 'name', 'varchar', '32' ],
|
||||
[ 'pantheon', 'varchar', '32' ],
|
||||
[ 'domains', 'varchar', '32' ],
|
||||
[ 'symbol', 'varchar', '32' ],
|
||||
[ 'morality', 'varchar', '16' ], // good, neutral, evil
|
||||
[ 'order', 'varchar', '16' ], // lawful, neutral, chaotic
|
||||
|
||||
// General
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'privacy', 'varchar', '16' ],
|
||||
[ 'version', 'varchar', '5' ],
|
||||
[ 'sourcebookID', 'int', '11' ],
|
||||
[ 'shortDescription', 'text', '' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'image', 'text', '' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$sourcebooks = new SourcebooksModel;
|
||||
}
|
||||
|
||||
public function create( $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'Create' );
|
||||
Debug::error( "God: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'Update' );
|
||||
Debug::error( "God: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No Gods found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/models/items.php
|
||||
*
|
||||
* This class is used for the manipulation of the dnd_items database table.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Models\Sourcebooks as SourcebooksModel;
|
||||
|
||||
class Items extends DatabaseModel {
|
||||
protected static $sourcebooks;
|
||||
public $tableName = 'dnd_items';
|
||||
public $databaseMatrix = [
|
||||
// Name
|
||||
[ 'name', 'varchar', '32' ],
|
||||
|
||||
// General
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'privacy', 'varchar', '16' ],
|
||||
[ 'version', 'varchar', '5' ],
|
||||
[ 'sourcebookID', 'int', '11' ],
|
||||
[ 'shortDescription', 'text', '' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'image', 'text', '' ],
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// type
|
||||
// Weight
|
||||
// class ( mundane / magical )
|
||||
|
||||
[ 'cost_copper', 'int', '12' ],
|
||||
[ 'cost_silver', 'int', '12' ],
|
||||
[ 'cost_gold', 'int', '12' ],
|
||||
[ 'cost_platinum', 'int', '12' ],
|
||||
[ 'cost_electrum', 'int', '12' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$sourcebooks = new SourcebooksModel;
|
||||
}
|
||||
|
||||
public function create( $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'Create' );
|
||||
Debug::error( "Item: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'Update' );
|
||||
Debug::error( "Item: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No Items found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
$out = [];
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$sourcebook = self::$sourcebooks->findById( $instance->sourcebookID );
|
||||
if ( !empty( $sourcebook ) ) {
|
||||
$instance->sourcebookName = $sourcebook->name;
|
||||
} else {
|
||||
$instance->sourcebookName = 'Unknown';
|
||||
}
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/models/languages.php
|
||||
*
|
||||
* This class is used for the manipulation of the dnd_languages database table.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Models\Sourcebooks as SourcebooksModel;
|
||||
|
||||
class Languages extends DatabaseModel {
|
||||
protected static $sourcebooks;
|
||||
public $tableName = 'dnd_languages';
|
||||
public $databaseMatrix = [
|
||||
// Core
|
||||
[ 'name', 'varchar', '32' ],
|
||||
[ 'type', 'varchar', '32' ], // exotic / standard / other
|
||||
[ 'typical_speakers', 'varchar', '32' ],
|
||||
[ 'script', 'varchar', '32' ],
|
||||
[ 'sound', 'text', '' ],
|
||||
|
||||
// General
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'privacy', 'varchar', '16' ],
|
||||
[ 'version', 'varchar', '5' ],
|
||||
[ 'sourcebookID', 'int', '11' ],
|
||||
[ 'shortDescription', 'text', '' ],
|
||||
[ 'description', 'text', '' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$sourcebooks = new SourcebooksModel;
|
||||
}
|
||||
|
||||
public function create( $name, $privacy, $version, $sourcebookID = '', $type = '', $typical_speakers = '', $script = '', $sound = '', $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'type' => $type,
|
||||
'typical_speakers' => $typical_speakers,
|
||||
'script' => $script,
|
||||
'sound' => $sound,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'shortDescription' => $shortDescription,
|
||||
'description' => $description,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'Create' );
|
||||
Debug::error( "Language: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $name, $privacy, $version, $sourcebookID = '', $type = '', $typical_speakers = '', $script = '', $sound = '', $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'type' => $type,
|
||||
'typical_speakers' => $typical_speakers,
|
||||
'script' => $script,
|
||||
'sound' => $sound,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'shortDescription' => $shortDescription,
|
||||
'description' => $description,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'Update' );
|
||||
Debug::error( "Language: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No Languages found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function paginatedList() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$objects = self::$db->getPaginated( $this->tableName, $whereClause );
|
||||
if ( ! $objects->count() ) {
|
||||
Debug::info( 'No Language found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function simpleList() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $objects->count() ) {
|
||||
Debug::warn( 'No Languages found.' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$objects = $objects->results();
|
||||
$out = [];
|
||||
foreach ( $objects as &$object ) {
|
||||
$out[ $object->name ] = $object->ID;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
$out = [];
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$sourcebook = self::$sourcebooks->findById( $instance->sourcebookID );
|
||||
if ( !empty( $sourcebook ) ) {
|
||||
$instance->sourcebookName = $sourcebook->name;
|
||||
} else {
|
||||
$instance->sourcebookName = 'Unknown';
|
||||
}
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
@ -1,153 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/models/monsters.php
|
||||
*
|
||||
* This class is used for the manipulation of the dnd_monsters database table.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Models\Sourcebooks as SourcebooksModel;
|
||||
|
||||
class Monsters extends DatabaseModel {
|
||||
protected static $sourcebooks;
|
||||
public $tableName = 'dnd_monsters';
|
||||
public $databaseMatrix = [
|
||||
// Name
|
||||
[ 'name', 'varchar', '32' ],
|
||||
|
||||
// General
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'privacy', 'varchar', '16' ],
|
||||
[ 'version', 'varchar', '5' ],
|
||||
[ 'sourcebookID', 'int', '11' ],
|
||||
[ 'shortDescription', 'text', '' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'image', 'text', '' ],
|
||||
[ 'avatar', 'text', '' ],
|
||||
|
||||
// Core
|
||||
[ 'experience', 'int', '12' ],
|
||||
[ 'perception', 'varchar', '4' ],
|
||||
[ 'armor_class', 'varchar', '4' ],
|
||||
[ 'armor_type', 'varchar', '16' ],
|
||||
[ 'alignment', 'varchar', '16' ],
|
||||
[ 'hit_die', 'varchar', '4' ],
|
||||
[ 'hit_die_count', 'int', '4' ],
|
||||
[ 'hit_die_modifier', 'varchar', '4' ],
|
||||
[ 'race', 'varchar', '32' ],
|
||||
[ 'size', 'varchar', '32' ],
|
||||
[ 'type', 'varchar', '32' ],
|
||||
[ 'sub_type', 'varchar', '32' ],
|
||||
[ 'challenge_rating', 'varchar', '32' ],
|
||||
[ 'average_hp', 'int', '5' ],
|
||||
|
||||
// Skills
|
||||
[ 'strength', 'int', '4' ],
|
||||
[ 'dexterity', 'int', '4' ],
|
||||
[ 'constitution', 'int', '4' ],
|
||||
[ 'charisma', 'int', '4' ],
|
||||
[ 'intelligence', 'int', '4' ],
|
||||
[ 'wisdom', 'int', '4' ],
|
||||
|
||||
// Expository
|
||||
[ 'characteristics', 'text', '' ],
|
||||
[ 'special_traits', 'text', '' ],
|
||||
[ 'actions', 'text', '' ],
|
||||
[ 'reactions', 'text', '' ],
|
||||
[ 'bonus_actions', 'text', '' ],
|
||||
[ 'mythic_actions', 'text', '' ],
|
||||
[ 'legendary_actions', 'text', '' ],
|
||||
[ 'lair_actions', 'text', '' ],
|
||||
[ 'languages', 'text', '' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$sourcebooks = new SourcebooksModel;
|
||||
}
|
||||
|
||||
public function create( $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'Create' );
|
||||
Debug::error( "Monster: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'Update' );
|
||||
Debug::error( "Monster: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No Monsters found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
$out = [];
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$sourcebook = self::$sourcebooks->findById( $instance->sourcebookID );
|
||||
if ( !empty( $sourcebook ) ) {
|
||||
$instance->sourcebookName = $sourcebook->name;
|
||||
} else {
|
||||
$instance->sourcebookName = 'Unknown';
|
||||
}
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
@ -1,213 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/models/races.php
|
||||
*
|
||||
* This class is used for the manipulation of the dnd_races database table.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Models\Sourcebooks as SourcebooksModel;
|
||||
|
||||
class Races extends DatabaseModel {
|
||||
protected static $sourcebooks;
|
||||
public $tableName = 'dnd_races';
|
||||
public $databaseMatrix = [
|
||||
// Name
|
||||
[ 'name', 'varchar', '32' ],
|
||||
[ 'languages', 'varchar', '32' ],
|
||||
[ 'racial_traits', 'varchar', '32' ],
|
||||
[ 'size', 'varchar', '16' ],
|
||||
[ 'age', 'text', '' ],
|
||||
[ 'raceID', 'int', '11' ],
|
||||
[ 'suggested_classes', 'text', '' ],
|
||||
[ 'abilityScores', 'text', '' ], // json
|
||||
|
||||
// General
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'privacy', 'varchar', '16' ],
|
||||
[ 'version', 'varchar', '5' ],
|
||||
[ 'sourcebookID', 'int', '11' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'shortDescription', 'text', '' ],
|
||||
[ 'image', 'text', '' ],
|
||||
[ 'avatar', 'text', '' ],
|
||||
|
||||
// Speeds
|
||||
[ 'walking_speed', 'int', '4' ],
|
||||
[ 'climbing_speed', 'int', '4' ],
|
||||
[ 'swimming_speed', 'int', '4' ],
|
||||
[ 'burrowing_speed', 'int', '4' ],
|
||||
[ 'flying_speed', 'int', '4' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$sourcebooks = new SourcebooksModel;
|
||||
}
|
||||
|
||||
public function create( $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'Create' );
|
||||
Debug::error( "Race: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'Update' );
|
||||
Debug::error( "Race: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No Races found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
$out = [];
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$sourcebook = self::$sourcebooks->findById( $instance->sourcebookID );
|
||||
if ( !empty( $sourcebook ) ) {
|
||||
$instance->sourcebookName = $sourcebook->name;
|
||||
} else {
|
||||
$instance->sourcebookName = 'Unknown';
|
||||
}
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Master list with origins 2:
|
||||
// Aarakocra - Elemental Evil Player's Companion, Monsters of the Multiverse
|
||||
// Aasimar - Volo's Guide to Monsters, Monsters of the Multiverse
|
||||
// Autognome - Spelljammer: Adventures in Space
|
||||
// Bugbear - Volo's Guide to Monsters, Eberron: Rising from the Last War, Monsters of the Multiverse
|
||||
// Centaur - Guildmaster’s Guide to Ravnica, Mythic Odysseys of Theros, Monsters of the Multiverse
|
||||
// Cervan - Humblewood Campaign Setting
|
||||
// Changeling - Eberron: Rising from the Last War, Monsters of the Multiverse
|
||||
// Corvum - Humblewood Campaign Setting
|
||||
// Dhampir - Van Richten's Guide to Ravenloft
|
||||
// The Disembodied - Grim Hollow: Player Pack
|
||||
|
||||
|
||||
|
||||
// Fairy - The Wild Beyond the Witchlight, Monsters of the Multiverse
|
||||
// Firbolg - Volo's Guide to Monsters, Monsters of the Multiverse
|
||||
// Gallus - Humblewood Campaign Setting
|
||||
// Genasi - Elemental Evil Player's Companion, Monsters of the Multiverse
|
||||
// Giff - Spelljammer: Adventures in Space
|
||||
// Gith - Mordenkainen’s Tome of Foes, Monsters of the Multiverse (Githyanki, Githzerai)
|
||||
|
||||
// Goblin - Volo's Guide to Monsters, Eberron: Rising from the Last War, Monsters of the Multiverse
|
||||
// Goliath - Elemental Evil Player's Companion, Volo's Guide to Monsters, Monsters of the Multiverse
|
||||
// Grung - One Grung Above
|
||||
// Hadozee - Spelljammer: Adventures in Space
|
||||
|
||||
|
||||
|
||||
// Harengon - The Wild Beyond the Witchlight, Monsters of the Multiverse
|
||||
// Hedge - Humblewood Campaign Setting
|
||||
// Hexblood - Van Richten's Guide to Ravenloft
|
||||
// Hobgoblin - Volo's Guide to Monsters, Eberron: Rising from the Last War, Monsters of the Multiverse
|
||||
|
||||
// Jerbeen - Humblewood Campaign Setting
|
||||
// Kalashtar - Eberron: Rising from the Last War
|
||||
// Kender - Dragonlance: Shadow of the Dragon Queen
|
||||
// Kenku - Volo's Guide to Monsters, Monsters of the Multiverse
|
||||
// Kobold - Volo's Guide to Monsters, Monsters of the Multiverse
|
||||
// Leonin - Mythic Odysseys of Theros
|
||||
// Lizardfolk - Volo's Guide to Monsters, Monsters of the Multiverse
|
||||
// Locathah - Locathah Rising
|
||||
// Loxodon - Guildmaster’s Guide to Ravnica
|
||||
// Luma - Humblewood Campaign Setting
|
||||
// Mapach - Humblewood Campaign Setting
|
||||
// Minotaur - Guildmaster’s Guide to Ravnica, Mythic Odysseys of Theros, Monsters of the Multiverse
|
||||
// Orc - Volo's Guide to Monsters, Eberron: Rising from the Last War, Monsters of the Multiverse
|
||||
// Owlin - Strixhaven: Curriculum of Chaos
|
||||
// Plasmoid - Spelljammer: Adventures in Space
|
||||
// Raptor - Humblewood Campaign Setting
|
||||
// Reborn - Van Richten's Guide to Ravenloft
|
||||
// Satyr - Mythic Odysseys of Theros, Monsters of the Multiverse
|
||||
// Shadar-kai - Mordenkainen’s Tome of Foes, Monsters of the Multiverse
|
||||
// Shifter - Eberron: Rising from the Last War, Monsters of the Multiverse
|
||||
// Simic Hybrid - Guildmaster’s Guide to Ravnica
|
||||
// Strig - Humblewood Campaign Setting
|
||||
// Tabaxi - Volo's Guide to Monsters, Monsters of the Multiverse
|
||||
// Thri-kreen - Spelljammer: Adventures in Space, Monsters of the Multiverse
|
||||
|
||||
// Tortle - The Tortle Package, Monsters of the Multiverse
|
||||
// Triton - Mythic Odysseys of Theros, Monsters of the Multiverse
|
||||
// Vedalken - Guildmaster’s Guide to Ravnica
|
||||
// Verdan - Acquisitions Incorporated
|
||||
// Vulpin - Humblewood Campaign Setting
|
||||
// Warforged - Eberron: Rising from the Last War
|
||||
// Wechselkind - Grim Hollow: Player Pack
|
||||
// Yuan-ti Pureblood - Volo's Guide to Monsters, Monsters of the Multiverse
|
||||
// Custom Lineage - Tasha's Cauldron of Everything
|
||||
// Deep Gnome - Elemental Evil Player's Companion, Mordenkainen’s Tome of Foes, Monsters of the Multiverse
|
||||
// Duergar - Mordenkainen’s Tome of Foes, Monsters of the Multiverse
|
||||
// Eladrin - Mordenkainen’s Tome of Foes, Monsters of the Multiverse
|
||||
// Air Genasi - Elemental Evil Player's Companion, Monsters of the Multiverse
|
||||
// Earth Genasi - Elemental Evil Player's Companion, Monsters of the Multiverse
|
||||
// Fire Genasi - Elemental Evil Player's Companion, Monsters of the Multiverse
|
||||
// Water Genasi - Elemental Evil Player's Companion, Monsters of the Multiverse
|
||||
// Astral Elf - Spelljammer: Adventures in Space
|
||||
// Sea Elf - Mordenkainen’s Tome of Foes, Monsters of the Multiverse
|
||||
// Githyanki - Mordenkainen’s Tome of Foes, Monsters of the Multiverse
|
||||
// Githzerai - Mordenkainen’s Tome of Foes, Monsters of the Multiverse
|
@ -1,117 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/models/skills.php
|
||||
*
|
||||
* This class is used for the manipulation of the dnd_skills database table.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Models\Sourcebooks as SourcebooksModel;
|
||||
|
||||
class Skills extends DatabaseModel {
|
||||
protected static $sourcebooks;
|
||||
public $tableName = 'dnd_skills';
|
||||
public $databaseMatrix = [
|
||||
// Name
|
||||
[ 'name', 'varchar', '32' ],
|
||||
|
||||
// General
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'privacy', 'varchar', '16' ],
|
||||
[ 'version', 'varchar', '5' ],
|
||||
[ 'sourcebookID', 'int', '11' ],
|
||||
[ 'shortDescription', 'text', '' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'image', 'text', '' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$sourcebooks = new SourcebooksModel;
|
||||
}
|
||||
|
||||
public function create( $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'Create' );
|
||||
Debug::error( "Skill: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'Update' );
|
||||
Debug::error( "Skill: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No Skills found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
$out = [];
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$sourcebook = self::$sourcebooks->findById( $instance->sourcebookID );
|
||||
if ( !empty( $sourcebook ) ) {
|
||||
$instance->sourcebookName = $sourcebook->name;
|
||||
} else {
|
||||
$instance->sourcebookName = 'Unknown';
|
||||
}
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/models/sourcebooks.php
|
||||
*
|
||||
* This class is used for the manipulation of the dnd_sourcebooks database table.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
|
||||
class Sourcebooks extends DatabaseModel {
|
||||
public $tableName = 'dnd_sourcebooks';
|
||||
public $databaseMatrix = [
|
||||
// Name
|
||||
[ 'name', 'varchar', '32' ],
|
||||
|
||||
// General
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'privacy', 'varchar', '16' ],
|
||||
[ 'version', 'varchar', '5' ],
|
||||
[ 'shortDescription', 'text', '' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'image', 'text', '' ],
|
||||
|
||||
// Core
|
||||
[ 'type', 'varchar', '5' ],
|
||||
[ 'publish_year', 'int', '4' ],
|
||||
[ 'amazon_url', 'text', '' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function create( $name, $privacy, $version, $type = '', $publishYear = '', $amazonUrl = '', $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'type' => $type,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
'publish_year' => $publishYear,
|
||||
'amazon_url' => $amazonUrl,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'Create' );
|
||||
Debug::error( "SourceBook: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $name, $privacy, $version, $type = '', $publishYear = '', $amazonUrl = '', $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'type' => $type,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
'publish_year' => $publishYear,
|
||||
'amazon_url' => $amazonUrl,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'Update' );
|
||||
Debug::error( "SourceBook: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function paginatedList() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$objects = self::$db->getPaginated( $this->tableName, $whereClause );
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No SourceBooks found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No SourceBooks found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function simpleList() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $objects->count() ) {
|
||||
Debug::warn( 'No Languages found.' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$objects = $objects->results();
|
||||
$out = [];
|
||||
foreach ( $objects as &$object ) {
|
||||
$out[ $object->name ] = $object->ID;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// origins
|
||||
// Player's Handbook / Basic Rules
|
||||
// The main Rulebook for D&D.
|
||||
// Elemental Evil Player's Companion
|
||||
// Volo's Guide to Monsters
|
||||
// Mordenkainen Presents: Monsters of the Multiverse
|
||||
// Eberron: Rising from the Last War
|
||||
// Fizban’s Treasury of Dragons
|
||||
// Guildmaster’s Guide to Ravnica
|
||||
// Locathah Rising
|
||||
// Mordenkainen’s Tome of Foes
|
||||
// Mythic Odysseys of Theros
|
||||
// One Grung Above
|
||||
// The Tortle Package
|
||||
// The Wild Beyond the Witchlight
|
||||
// Dragonlance: Shadow of the Dragon Queen
|
||||
// Spelljammer: Adventures in Space
|
||||
// Strixhaven: Curriculum of Chaos
|
||||
// Van Richten's Guide to Ravenloft
|
||||
// Tasha's Cauldron of Everything
|
||||
// Grim Hollow: Player Pack
|
||||
// Humblewood Campaign Setting
|
||||
// Acquisitions Incorporated
|
||||
// Sword Coast Adventurer's Guide
|
@ -1,140 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/models/spells.php
|
||||
*
|
||||
* This class is used for the manipulation of the dnd_spells database table.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Models\Sourcebooks as SourcebooksModel;
|
||||
|
||||
class Spells extends DatabaseModel {
|
||||
protected static $sourcebooks;
|
||||
public $tableName = 'dnd_spells';
|
||||
public $databaseMatrix = [
|
||||
// level
|
||||
// Name // spell-name
|
||||
[ 'name', 'varchar', '32' ],
|
||||
// casting time
|
||||
// duration
|
||||
// school / magic school
|
||||
[ 'school', 'varchar', '16' ],
|
||||
// comps / components
|
||||
// range
|
||||
// area
|
||||
// attack
|
||||
// save
|
||||
// conc / concentration
|
||||
// source
|
||||
// damage effect
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// General
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'privacy', 'varchar', '16' ],
|
||||
[ 'version', 'varchar', '5' ],
|
||||
[ 'sourcebookID', 'int', '11' ],
|
||||
[ 'shortDescription', 'text', '' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'image', 'text', '' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$sourcebooks = new SourcebooksModel;
|
||||
}
|
||||
|
||||
public function create( $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'Create' );
|
||||
Debug::error( "Spell: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'Update' );
|
||||
Debug::error( "Spell: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No Spells found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
$out = [];
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$sourcebook = self::$sourcebooks->findById( $instance->sourcebookID );
|
||||
if ( !empty( $sourcebook ) ) {
|
||||
$instance->sourcebookName = $sourcebook->name;
|
||||
} else {
|
||||
$instance->sourcebookName = 'Unknown';
|
||||
}
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/models/traits.php
|
||||
*
|
||||
* This class is used for the manipulation of the dnd_racial_traits database table.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Models\Sourcebooks as SourcebooksModel;
|
||||
|
||||
class Traits extends DatabaseModel {
|
||||
protected static $sourcebooks;
|
||||
public $tableName = 'dnd_racial_traits';
|
||||
public $databaseMatrix = [
|
||||
// Core
|
||||
[ 'name', 'varchar', '64' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'shortDescription', 'text', '' ],
|
||||
|
||||
// General
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'privacy', 'varchar', '16' ],
|
||||
[ 'version', 'varchar', '5' ],
|
||||
[ 'sourcebookID', 'int', '11' ],
|
||||
[ 'image', 'text', '' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$sourcebooks = new SourcebooksModel;
|
||||
}
|
||||
|
||||
public function create( $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'Create' );
|
||||
Debug::error( "Traits: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $name, $privacy, $version, $sourcebookID, $description = '', $shortDescription = '' ) {
|
||||
$fields = [
|
||||
'name' => $name,
|
||||
'privacy' => $privacy,
|
||||
'version' => $version,
|
||||
'sourcebookID' => $sourcebookID,
|
||||
'description' => $description,
|
||||
'shortDescription' => $shortDescription,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'Update' );
|
||||
Debug::error( "Traits: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No Traits found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function bySystem( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', '0'];
|
||||
if ( empty( $limit ) ) {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$objects = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$objects->count() ) {
|
||||
Debug::info( 'No Traits found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $objects->results() );
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
$out = [];
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$sourcebook = self::$sourcebooks->findById( $instance->sourcebookID );
|
||||
if ( !empty( $sourcebook ) ) {
|
||||
$instance->sourcebookName = $sourcebook->name;
|
||||
} else {
|
||||
$instance->sourcebookName = 'Unknown';
|
||||
}
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
@ -1,158 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/dnd/plugin.php
|
||||
*
|
||||
* This houses all of the main plugin info and functionality.
|
||||
*
|
||||
* @package TTE Dungeons & Dragons
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@tabletopelite.com>
|
||||
* @link https://TableTopElite.com
|
||||
*/
|
||||
namespace TheTempusProject\Plugins;
|
||||
|
||||
use TheTempusProject\Classes\Plugin;
|
||||
|
||||
class Dnd extends Plugin {
|
||||
public $pluginName = 'TP D&D';
|
||||
public $pluginAuthor = 'JoeyK';
|
||||
public $pluginWebsite = 'https://TheTempusProject.com';
|
||||
public $modelVersion = '1.0';
|
||||
public $pluginVersion = '3.0';
|
||||
public $pluginDescription = 'A simple plugin which adds support for D&D 5e.';
|
||||
public $configName = 'dnd';
|
||||
public $configMatrix = [
|
||||
'enabled' => [
|
||||
'type' => 'radio',
|
||||
'pretty' => 'Enable D&D plugin.',
|
||||
'default' => true,
|
||||
],
|
||||
];
|
||||
public $permissionMatrix = [
|
||||
'canCreateCharacters' => [
|
||||
'pretty' => 'Can use the character creator',
|
||||
'default' => true,
|
||||
],
|
||||
'canCreateClasses' => [
|
||||
'pretty' => 'Can add Classes.',
|
||||
'default' => true,
|
||||
],
|
||||
'canCreateItems' => [
|
||||
'pretty' => 'Can add Items',
|
||||
'default' => true,
|
||||
],
|
||||
'canCreateMonsters' => [
|
||||
'pretty' => 'Can add Monsters',
|
||||
'default' => true,
|
||||
],
|
||||
'canCreateRaces' => [
|
||||
'pretty' => 'Can add Races',
|
||||
'default' => true,
|
||||
],
|
||||
'canCreateSkills' => [
|
||||
'pretty' => 'Can add Skills',
|
||||
'default' => true,
|
||||
],
|
||||
'canCreateSourceBooks' => [
|
||||
'pretty' => 'Can add SourceBooks',
|
||||
'default' => true,
|
||||
],
|
||||
'canCreateSpells' => [
|
||||
'pretty' => 'Can add Spells',
|
||||
'default' => true,
|
||||
],
|
||||
];
|
||||
public $main_links = [
|
||||
[
|
||||
'text' => 'Characters',
|
||||
'url' => '{ROOT_URL}characters/index',
|
||||
],
|
||||
[
|
||||
'text' => 'D&Databases',
|
||||
'url' => [
|
||||
[
|
||||
'text' => 'Spells',
|
||||
'url' => '{ROOT_URL}dndatabase/spells',
|
||||
],
|
||||
[
|
||||
'text' => 'Classes',
|
||||
'url' => '{ROOT_URL}dndatabase/classes',
|
||||
],
|
||||
[
|
||||
'text' => 'Races',
|
||||
'url' => '{ROOT_URL}dndatabase/races',
|
||||
],
|
||||
[
|
||||
'text' => 'Monsters',
|
||||
'url' => '{ROOT_URL}dndatabase/monsters',
|
||||
],
|
||||
[
|
||||
'text' => 'Items',
|
||||
'url' => '{ROOT_URL}dndatabase/items',
|
||||
],
|
||||
[
|
||||
'text' => 'Skills',
|
||||
'url' => '{ROOT_URL}dndatabase/skills',
|
||||
],
|
||||
[
|
||||
'text' => 'SourceBooks',
|
||||
'url' => '{ROOT_URL}dndatabase/sourcebooks',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
public $admin_links = [
|
||||
[
|
||||
'text' => '<i class="fa fa-fw fa-arrows-v"></i> DnD-Database',
|
||||
'url' => [
|
||||
[
|
||||
'text' => '<i class="fa fa-fw fa-database"></i> Classes',
|
||||
'url' => '{ROOT_URL}admin/classes',
|
||||
],
|
||||
[
|
||||
'text' => '<i class="fa fa-fw fa-database"></i> Gods',
|
||||
'url' => '{ROOT_URL}admin/gods',
|
||||
],
|
||||
[
|
||||
'text' => '<i class="fa fa-fw fa-database"></i> Items',
|
||||
'url' => '{ROOT_URL}admin/items',
|
||||
],
|
||||
[
|
||||
'text' => '<i class="fa fa-fw fa-database"></i> Languages',
|
||||
'url' => '{ROOT_URL}admin/languages',
|
||||
],
|
||||
[
|
||||
'text' => '<i class="fa fa-fw fa-database"></i> Monsters',
|
||||
'url' => '{ROOT_URL}admin/monsters',
|
||||
],
|
||||
[
|
||||
'text' => '<i class="fa fa-fw fa-database"></i> Races',
|
||||
'url' => '{ROOT_URL}admin/races',
|
||||
],
|
||||
[
|
||||
'text' => '<i class="fa fa-fw fa-database"></i> Skills',
|
||||
'url' => '{ROOT_URL}admin/skills',
|
||||
],
|
||||
[
|
||||
'text' => '<i class="fa fa-fw fa-database"></i> Source Books',
|
||||
'url' => '{ROOT_URL}admin/sourcebooks',
|
||||
],
|
||||
[
|
||||
'text' => '<i class="fa fa-fw fa-database"></i> Spells',
|
||||
'url' => '{ROOT_URL}admin/spells',
|
||||
],
|
||||
[
|
||||
'text' => '<i class="fa fa-fw fa-database"></i> Traits',
|
||||
'url' => '{ROOT_URL}admin/traits',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
// would be cool to have mmo-style character creator
|
||||
// need a highlight mode with question mark popups that give you more info
|
||||
// allow players to 'use' swap and adjust spells and spell slots
|
||||
// need to highlight aspects that need to be filled out such as adding spells, picking traits or skills etc.
|
||||
|
||||
// need to add a system for importing the jsons i make
|
File diff suppressed because it is too large
Load Diff
@ -1,19 +0,0 @@
|
||||
<legend>Create D&D Class</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,19 +0,0 @@
|
||||
<legend>Edit D&D Class</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name" value="{name}">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,34 +0,0 @@
|
||||
<legend>D&D Classes</legend>
|
||||
{PAGINATION}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 40%">Name</th>
|
||||
<th style="width: 20%">Type</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td>{ID}</td>
|
||||
<td>{name}</td>
|
||||
<td>{type}</td>
|
||||
<td><a href="{ROOT_URL}admin/classes/view/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/classes/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/classes/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}admin/classes/create" class="btn btn-sm btn-primary" role="button">Add</a>
|
@ -1,63 +0,0 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xs-offset-0 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" >
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">D&D Class</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class=" col-md-12 col-lg-12 ">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200">ID:</td>
|
||||
<td align="right">{ID}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td align="right">{name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Privacy</td>
|
||||
<td align="right">{privacy}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td align="right">{version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Created at:</td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created by</b></td>
|
||||
<td align="right"><a href="{ROOT_URL}admin/users/view/{userID}">{createdBy}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Short Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{shortDescription}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{ADMIN}
|
||||
<a href="{ROOT_URL}admin/classes/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}admin/classes/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
{/ADMIN}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,19 +0,0 @@
|
||||
<legend>Create D&D God</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,19 +0,0 @@
|
||||
<legend>Edit D&D God</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name" value="{name}">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,34 +0,0 @@
|
||||
<legend>D&D Gods</legend>
|
||||
{PAGINATION}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 40%">Name</th>
|
||||
<th style="width: 20%">Type</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td>{ID}</td>
|
||||
<td>{name}</td>
|
||||
<td>{type}</td>
|
||||
<td><a href="{ROOT_URL}admin/gods/view/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/gods/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/gods/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}admin/gods/create" class="btn btn-sm btn-primary" role="button">Add</a>
|
@ -1,63 +0,0 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xs-offset-0 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" >
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">D&D God</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class=" col-md-12 col-lg-12 ">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200">ID:</td>
|
||||
<td align="right">{ID}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td align="right">{name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Privacy</td>
|
||||
<td align="right">{privacy}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td align="right">{version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Created at:</td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created by</b></td>
|
||||
<td align="right"><a href="{ROOT_URL}admin/users/view/{userID}">{createdBy}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Short Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{shortDescription}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{ADMIN}
|
||||
<a href="{ROOT_URL}admin/gods/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}admin/gods/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
{/ADMIN}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,19 +0,0 @@
|
||||
<legend>Create D&D Item</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,19 +0,0 @@
|
||||
<legend>Edit D&D Item</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name" value="{name}">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,34 +0,0 @@
|
||||
<legend>D&D Items</legend>
|
||||
{PAGINATION}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 40%">Name</th>
|
||||
<th style="width: 20%">Type</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td>{ID}</td>
|
||||
<td>{name}</td>
|
||||
<td>{type}</td>
|
||||
<td><a href="{ROOT_URL}admin/items/view/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/items/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/items/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}admin/items/create" class="btn btn-sm btn-primary" role="button">Add</a>
|
@ -1,63 +0,0 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xs-offset-0 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" >
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">D&D Item</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class=" col-md-12 col-lg-12 ">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200">ID:</td>
|
||||
<td align="right">{ID}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td align="right">{name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Privacy</td>
|
||||
<td align="right">{privacy}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td align="right">{version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Created at:</td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created by</b></td>
|
||||
<td align="right"><a href="{ROOT_URL}admin/users/view/{userID}">{createdBy}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Short Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{shortDescription}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{ADMIN}
|
||||
<a href="{ROOT_URL}admin/items/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}admin/items/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
{/ADMIN}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,50 +0,0 @@
|
||||
<legend>Create D&D Language</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name">
|
||||
</div>
|
||||
</div>
|
||||
{languageTypeDropdown}
|
||||
<div class="form-group">
|
||||
<label for="typical_speakers" class="col-lg-3 control-label">Typical Speakers</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="typical_speakers" id="typical_speakers">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="script" class="col-lg-3 control-label">Script</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="script" id="script">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="sound" class="col-lg-3 control-label">Sound</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="sound" maxlength="2000" rows="10" cols="50" id="sound"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="shortDescription" class="col-lg-3 control-label">Short Description</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="shortDescription" maxlength="2000" rows="10" cols="50" id="shortDescription"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,50 +0,0 @@
|
||||
<legend>Edit D&D Language</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name" value="{name}">
|
||||
</div>
|
||||
</div>
|
||||
{languageTypeDropdown}
|
||||
<div class="form-group">
|
||||
<label for="typical_speakers" class="col-lg-3 control-label">Typical Speakers</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="typical_speakers" id="typical_speakers" value="{typical_speakers}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="script" class="col-lg-3 control-label">Script</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="script" id="script" value="{script}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="sound" class="col-lg-3 control-label">Sound</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="sound" maxlength="2000" rows="10" cols="50" id="sound">{sound}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="shortDescription" class="col-lg-3 control-label">Short Description</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="shortDescription" maxlength="2000" rows="10" cols="50" id="shortDescription">{shortDescription}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description">{description}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,34 +0,0 @@
|
||||
<legend>D&D Languages</legend>
|
||||
{PAGINATION}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 40%">Name</th>
|
||||
<th style="width: 20%">Type</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td>{ID}</td>
|
||||
<td>{name}</td>
|
||||
<td>{type}</td>
|
||||
<td><a href="{ROOT_URL}admin/languages/view/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/languages/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/languages/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}admin/languages/create" class="btn btn-sm btn-primary" role="button">Add</a>
|
@ -1,83 +0,0 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xs-offset-0 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" >
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">D&D Language</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class=" col-md-12 col-lg-12 ">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200">ID:</td>
|
||||
<td align="right">{ID}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Created at:</td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created by</b></td>
|
||||
<td align="right"><a href="{ROOT_URL}admin/users/view/{userID}">{createdBy}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td align="right">{name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Type</td>
|
||||
<td align="right">{type}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Script</td>
|
||||
<td align="right">{script}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Typical Speaker</td>
|
||||
<td align="right">{typical_speakers}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sounds Like:</td>
|
||||
<td align="right">{sound}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SourceBook Name</td>
|
||||
<td align="right">{sourcebookName}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Privacy</td>
|
||||
<td align="right">{privacy}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td align="right">{version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Short Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{shortDescription}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{ADMIN}
|
||||
<a href="{ROOT_URL}admin/languages/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}admin/languages/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
{/ADMIN}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,19 +0,0 @@
|
||||
<legend>Create D&D Monster</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,19 +0,0 @@
|
||||
<legend>Edit D&D Monster</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name" value="{name}">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,34 +0,0 @@
|
||||
<legend>D&D Monsters</legend>
|
||||
{PAGINATION}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 40%">Name</th>
|
||||
<th style="width: 20%">Type</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td>{ID}</td>
|
||||
<td>{name}</td>
|
||||
<td>{type}</td>
|
||||
<td><a href="{ROOT_URL}admin/monsters/view/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/monsters/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/monsters/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}admin/monsters/create" class="btn btn-sm btn-primary" role="button">Add</a>
|
@ -1,63 +0,0 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xs-offset-0 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" >
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">D&D Monster</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class=" col-md-12 col-lg-12 ">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200">ID:</td>
|
||||
<td align="right">{ID}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td align="right">{name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Privacy</td>
|
||||
<td align="right">{privacy}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td align="right">{version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Created at:</td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created by</b></td>
|
||||
<td align="right"><a href="{ROOT_URL}admin/users/view/{userID}">{createdBy}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Short Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{shortDescription}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{ADMIN}
|
||||
<a href="{ROOT_URL}admin/monsters/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}admin/monsters/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
{/ADMIN}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,19 +0,0 @@
|
||||
<legend>Create D&D Race</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,19 +0,0 @@
|
||||
<legend>Edit D&D Race</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name" value="{name}">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,34 +0,0 @@
|
||||
<legend>D&D Races</legend>
|
||||
{PAGINATION}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 40%">Name</th>
|
||||
<th style="width: 20%">Type</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td>{ID}</td>
|
||||
<td>{name}</td>
|
||||
<td>{type}</td>
|
||||
<td><a href="{ROOT_URL}admin/races/view/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/races/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/races/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}admin/races/create" class="btn btn-sm btn-primary" role="button">Add</a>
|
@ -1,63 +0,0 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xs-offset-0 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" >
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">D&D Race</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class=" col-md-12 col-lg-12 ">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200">ID:</td>
|
||||
<td align="right">{ID}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td align="right">{name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Privacy</td>
|
||||
<td align="right">{privacy}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td align="right">{version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Created at:</td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created by</b></td>
|
||||
<td align="right"><a href="{ROOT_URL}admin/users/view/{userID}">{createdBy}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Short Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{shortDescription}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{ADMIN}
|
||||
<a href="{ROOT_URL}admin/races/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}admin/races/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
{/ADMIN}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,19 +0,0 @@
|
||||
<legend>Create D&D Skill</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,19 +0,0 @@
|
||||
<legend>Edit D&D Skill</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name" value="{name}">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,34 +0,0 @@
|
||||
<legend>D&D Skills</legend>
|
||||
{PAGINATION}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 40%">Name</th>
|
||||
<th style="width: 20%">Type</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td>{ID}</td>
|
||||
<td>{name}</td>
|
||||
<td>{type}</td>
|
||||
<td><a href="{ROOT_URL}admin/skills/view/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/skills/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/skills/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}admin/skills/create" class="btn btn-sm btn-primary" role="button">Add</a>
|
@ -1,63 +0,0 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xs-offset-0 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" >
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">D&D Skill</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class=" col-md-12 col-lg-12 ">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200">ID:</td>
|
||||
<td align="right">{ID}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td align="right">{name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Privacy</td>
|
||||
<td align="right">{privacy}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td align="right">{version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Created at:</td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created by</b></td>
|
||||
<td align="right"><a href="{ROOT_URL}admin/users/view/{userID}">{createdBy}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Short Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{shortDescription}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{ADMIN}
|
||||
<a href="{ROOT_URL}admin/skills/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}admin/skills/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
{/ADMIN}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,48 +0,0 @@
|
||||
<legend>Create D&D SourceBook</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="sourceType" class="col-lg-3 control-label">Type</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="sourceType" id="sourceType">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="year" class="col-lg-3 control-label">Publish Year</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="year" id="year">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="amazonUrl" class="col-lg-3 control-label">Amazon URL</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="amazonUrl" id="amazonUrl">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="shortDescription" class="col-lg-3 control-label">Short Description</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="shortDescription" maxlength="2000" rows="10" cols="50" id="shortDescription"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
{privacyDropdown}
|
||||
{versionDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,48 +0,0 @@
|
||||
<legend>Edit D&D SourceBook</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name" value="{name}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="sourceType" class="col-lg-3 control-label">Type</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="sourceType" id="sourceType" value="{type}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="year" class="col-lg-3 control-label">Publish Year</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="year" id="year" value="{publish_year}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="amazonUrl" class="col-lg-3 control-label">Amazon URL</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="amazonUrl" id="amazonUrl" value="{amazon_url}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description">{description}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="shortDescription" class="col-lg-3 control-label">Short Description</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="shortDescription" maxlength="2000" rows="10" cols="50" id="shortDescription">{shortDescription}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
{privacyDropdown}
|
||||
{versionDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,38 +0,0 @@
|
||||
<legend>D&D Source Books</legend>
|
||||
{PAGINATION}
|
||||
<form action="{ROOT_URL}admin/sourcebooks/delete" method="post">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%">ID</th>
|
||||
<th style="width: 40%">Name</th>
|
||||
<th style="width: 20%">Type</th>
|
||||
<th style="width: 20%">Published</th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td>{ID}</td>
|
||||
<td>{name}</td>
|
||||
<td>{type}</td>
|
||||
<td>{publish_year}</td>
|
||||
<td><a href="{ROOT_URL}admin/sourcebooks/view/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/sourcebooks/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/sourcebooks/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
<a href="{ROOT_URL}admin/sourcebooks/create" class="btn btn-sm btn-primary" role="button">Add</a>
|
@ -1,75 +0,0 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xs-offset-0 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" >
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">D&D SourceBook</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class=" col-md-12 col-lg-12 ">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200">ID:</td>
|
||||
<td align="right">{ID}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td align="right">{name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Privacy</td>
|
||||
<td align="right">{privacy}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td align="right">{version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Type</td>
|
||||
<td align="right">{type}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Publish Year</td>
|
||||
<td align="right">{publish_year}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Amazon URL</td>
|
||||
<td align="right">{amazon_url}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Created at:</td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created by</b></td>
|
||||
<td align="right"><a href="{ROOT_URL}admin/users/view/{userID}">{createdBy}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Short Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{shortDescription}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{ADMIN}
|
||||
<a href="{ROOT_URL}admin/sourcebooks/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}admin/sourcebooks/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
{/ADMIN}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,19 +0,0 @@
|
||||
<legend>Create D&D Spell</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,19 +0,0 @@
|
||||
<legend>Edit D&D Spell</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name" value="{name}">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,34 +0,0 @@
|
||||
<legend>D&D Spells</legend>
|
||||
{PAGINATION}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 40%">Name</th>
|
||||
<th style="width: 20%">Type</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td>{ID}</td>
|
||||
<td>{name}</td>
|
||||
<td>{type}</td>
|
||||
<td><a href="{ROOT_URL}admin/spells/view/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/spells/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/spells/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}admin/spells/create" class="btn btn-sm btn-primary" role="button">Add</a>
|
@ -1,63 +0,0 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xs-offset-0 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" >
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">D&D Spell</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class=" col-md-12 col-lg-12 ">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200">ID:</td>
|
||||
<td align="right">{ID}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td align="right">{name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Privacy</td>
|
||||
<td align="right">{privacy}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td align="right">{version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Created at:</td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created by</b></td>
|
||||
<td align="right"><a href="{ROOT_URL}admin/users/view/{userID}">{createdBy}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Short Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{shortDescription}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{ADMIN}
|
||||
<a href="{ROOT_URL}admin/spells/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}admin/spells/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
{/ADMIN}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,19 +0,0 @@
|
||||
<legend>Create D&D Racial Trait</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,19 +0,0 @@
|
||||
<legend>Edit D&D Trait</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-lg-3 control-label">Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="name" id="name" value="{name}">
|
||||
</div>
|
||||
</div>
|
||||
{sourcebookSelect}
|
||||
{versionDropdown}
|
||||
{privacyDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,34 +0,0 @@
|
||||
<legend>D&D Traits</legend>
|
||||
{PAGINATION}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 40%">Name</th>
|
||||
<th style="width: 20%">Type</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td>{ID}</td>
|
||||
<td>{name}</td>
|
||||
<td>{type}</td>
|
||||
<td><a href="{ROOT_URL}admin/traits/view/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/traits/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/traits/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}admin/traits/create" class="btn btn-sm btn-primary" role="button">Add</a>
|
@ -1,63 +0,0 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xs-offset-0 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" >
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">D&D Trait</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class=" col-md-12 col-lg-12 ">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200">ID:</td>
|
||||
<td align="right">{ID}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td align="right">{name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Privacy</td>
|
||||
<td align="right">{privacy}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td align="right">{version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Created at:</td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created by</b></td>
|
||||
<td align="right"><a href="{ROOT_URL}admin/users/view/{userID}">{createdBy}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Short Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{shortDescription}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{ADMIN}
|
||||
<a href="{ROOT_URL}admin/traits/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}admin/traits/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
{/ADMIN}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,35 +0,0 @@
|
||||
<div class="row" style="margin-top: 30px; margin-bottom: 50px;">
|
||||
<form action="" method="post">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 40%">Name</th>
|
||||
<th style="width: 20%">Race</th>
|
||||
<th style="width: 20%">Class</th>
|
||||
<th style="width: 10%">Level</th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td><a href='{ROOT_URL}dnd/characters/{ID}'>{name}</a></td>
|
||||
<td>{race}</td>
|
||||
<td>{class}</td>
|
||||
<td><a href="{ROOT_URL}dnd/editCharacter/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}dnd/deleteCharacter/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
No Characters
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}dnd/createCharacter" class="btn btn-sm btn-primary" role="button">Create Character</a>
|
||||
</form>
|
||||
</div>
|
@ -1,47 +0,0 @@
|
||||
<legend>Character Creator / Character Sheet Generator</legend>
|
||||
<form action="" method="post" class="form-horizontal" enctype="multipart/form-data">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<label for="avatar" class="col-lg-3 control-label">Avatar</label>
|
||||
<div class="form-group col-lg-3">
|
||||
<input type="file" class="form-control" name="avatar" id="avatar">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="prefix" class="col-lg-3 control-label">Prefix</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="prefix" id="prefix">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="first_name" class="col-lg-3 control-label">First Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="first_name" id="first_name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="middle_name" class="col-lg-3 control-label">Middle Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="middle_name" id="middle_name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="last_name" class="col-lg-3 control-label">Last Name</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="last_name" id="last_name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="suffix" class="col-lg-3 control-label">Suffix</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="suffix" id="suffix">
|
||||
</div>
|
||||
</div>
|
||||
{privacyDropdown}
|
||||
{versionDropdown}
|
||||
{hitpointRollDropdown}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Create</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,12 +0,0 @@
|
||||
<legend>Character Creator - Race Select</legend>
|
||||
<form action="" method="post" class="form-horizontal" enctype="multipart/form-data">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<input type="hidden" name="characterID" value="{characterID}">
|
||||
{raceSelect}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Continue</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user