forked from GitHub-Mirrors/foundry-sw5e
commit
770f1650d3
22 changed files with 617 additions and 49 deletions
|
@ -660,6 +660,7 @@
|
|||
"SW5E.SheetClassCharacter": "Default Character Sheet",
|
||||
"SW5E.SheetClassCharacterOld": "Old Character Sheet",
|
||||
"SW5E.SheetClassNPC": "Default NPC Sheet",
|
||||
"SW5E.SheetClassNPCOld": "Old NPC Sheet",
|
||||
"SW5E.SheetClassVehicle": "Default Vehicle Sheet",
|
||||
"SW5E.SheetClassItem": "Default Item Sheet",
|
||||
|
||||
|
@ -770,7 +771,7 @@
|
|||
"SW5E.SpeciesDescription": "Description",
|
||||
"SW5E.SpeciesTraits": "Species Traits",
|
||||
"SW5E.StealthDisadvantage": "Stealth Disadvantage",
|
||||
"SW5E.SubclassName": "Subclass Name",
|
||||
"SW5E.ArchetypeName": "Archetype Name",
|
||||
"SW5E.Supply": "Supply",
|
||||
"SW5E.Target": "Target",
|
||||
"SW5E.TargetAlly": "Ally",
|
||||
|
|
|
@ -421,7 +421,7 @@
|
|||
}
|
||||
.item-name {
|
||||
padding-left: 5px;
|
||||
.modesto();
|
||||
//.modesto();
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,11 @@
|
|||
grid-column-start: 1;
|
||||
grid-row-start: 1;
|
||||
grid-row-end: 4;
|
||||
box-sizing: border-box;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
h1.character-name {
|
||||
|
@ -93,6 +98,11 @@
|
|||
.charlevel {
|
||||
.russoOne(17px);
|
||||
text-align: right;
|
||||
input {
|
||||
display: inline-block;
|
||||
width: 42px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.experience {
|
||||
|
@ -932,6 +942,9 @@
|
|||
&>.panel {
|
||||
grid-template-rows: 32px 24px 24px auto;
|
||||
}
|
||||
h3.power-dc {
|
||||
line-height: 24px;
|
||||
}
|
||||
.powercasting-ability {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr 1fr;
|
||||
|
@ -991,4 +1004,56 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
&.npc {
|
||||
.swalt-sheet {
|
||||
header {
|
||||
h1.character-name {
|
||||
align-self: auto;
|
||||
}
|
||||
.npc-size {
|
||||
.russoOne(18px);
|
||||
line-height: 28px;
|
||||
}
|
||||
.attributes {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
footer {
|
||||
&.proficiency {
|
||||
margin-top: 0;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
&.hit-points {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nav.sheet-navigation {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
.tab.attributes {
|
||||
.traits-resources {
|
||||
display: block;
|
||||
|
||||
.counter {
|
||||
display: flex;
|
||||
.counter-value {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
// section.traits {
|
||||
// display:block;
|
||||
// }
|
||||
}
|
||||
}
|
||||
.tab.powerbook {
|
||||
input.powercasting-level {
|
||||
width: 48px;
|
||||
}
|
||||
}
|
||||
.tab.biography.active {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -404,4 +404,13 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
&.npc {
|
||||
.swalt-sheet {
|
||||
header {
|
||||
.experience {
|
||||
color: @actorProficiencyTextColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -142,14 +142,14 @@ export default class Actor5e extends Actor {
|
|||
/**
|
||||
* Return the features which a character is awarded for each class level
|
||||
* @param {string} className The class name being added
|
||||
* @param {string} subclassName The subclass of the class being added, if any
|
||||
* @param {string} archetypeName The archetype of the class being added, if any
|
||||
* @param {number} level The number of levels in the added class
|
||||
* @param {number} priorLevel The previous level of the added class
|
||||
* @return {Promise<Item5e[]>} Array of Item5e entities
|
||||
*/
|
||||
static async getClassFeatures({className="", subclassName="", level=1, priorLevel=0}={}) {
|
||||
static async getClassFeatures({className="", archetypeName="", level=1, priorLevel=0}={}) {
|
||||
className = className.toLowerCase();
|
||||
subclassName = subclassName.slugify();
|
||||
archetypeName = archetypeName.slugify();
|
||||
|
||||
// Get the configuration of features which may be added
|
||||
const clsConfig = CONFIG.SW5E.classFeatures[className];
|
||||
|
@ -162,8 +162,8 @@ export default class Actor5e extends Actor {
|
|||
if ( (l <= level) && (l > priorLevel) ) ids = ids.concat(f);
|
||||
}
|
||||
|
||||
// Acquire subclass features
|
||||
const subConfig = clsConfig.subclasses[subclassName] || {};
|
||||
// Acquire archetype features
|
||||
const subConfig = clsConfig.archetypes[archetypeName] || {};
|
||||
for ( let [l, f] of Object.entries(subConfig.features || {}) ) {
|
||||
l = parseInt(l);
|
||||
if ( (l <= level) && (l > priorLevel) ) ids = ids.concat(f);
|
||||
|
@ -207,7 +207,7 @@ export default class Actor5e extends Actor {
|
|||
const updateData = expandObject(u);
|
||||
const config = {
|
||||
className: updateData.name || item.data.name,
|
||||
subclassName: updateData.data.subclass || item.data.data.subclass,
|
||||
archetypeName: updateData.data.archetype || item.data.data.archetype,
|
||||
level: getProperty(updateData, "data.levels"),
|
||||
priorLevel: item ? item.data.data.levels : 0
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ export default class Actor5e extends Actor {
|
|||
// Get and create features for an increased class level
|
||||
let changed = false;
|
||||
if ( config.level && (config.level > config.priorLevel)) changed = true;
|
||||
if ( config.subclassName !== item.data.data.subclass ) changed = true;
|
||||
if ( config.archetypeName !== item.data.data.archetype ) changed = true;
|
||||
|
||||
// Get features to create
|
||||
if ( changed ) {
|
||||
|
@ -549,7 +549,7 @@ export default class Actor5e extends Actor {
|
|||
async createOwnedItem(itemData, options) {
|
||||
|
||||
// Assume NPCs are always proficient with weapons and always have powers prepared
|
||||
if ( !this.isPC ) {
|
||||
if ( !this.hasPlayerOwner ) {
|
||||
let t = itemData.type;
|
||||
let initial = {};
|
||||
if ( t === "weapon" ) initial["data.proficient"] = true;
|
||||
|
|
|
@ -516,7 +516,7 @@ async function addFavorites(app, html, data) {
|
|||
|
||||
if (app.options.editable) {
|
||||
favtabHtml.find('.item-image').click(ev => app._onItemRoll(ev));
|
||||
let handler = ev => app._onDragItemStart(ev);
|
||||
let handler = ev => app._onDragStart(ev);
|
||||
favtabHtml.find('.item').each((i, li) => {
|
||||
if (li.classList.contains("inventory-header")) return;
|
||||
li.setAttribute("draggable", true);
|
||||
|
@ -566,7 +566,14 @@ async function addFavorites(app, html, data) {
|
|||
});
|
||||
}
|
||||
tabContainer.append(favtabHtml);
|
||||
|
||||
// if(app.options.editable) {
|
||||
// let handler = ev => app._onDragItemStart(ev);
|
||||
// tabContainer.find('.item').each((i, li) => {
|
||||
// if (li.classList.contains("inventory-header")) return;
|
||||
// li.setAttribute("draggable", true);
|
||||
// li.addEventListener("dragstart", handler, false);
|
||||
// });
|
||||
//}
|
||||
// try {
|
||||
// if (game.modules.get("betterrolls5e") && game.modules.get("betterrolls5e").active) BetterRolls.addItemContent(app.object, favtabHtml, ".item .item-name h4", ".item-properties", ".item > .rollable div");
|
||||
// }
|
||||
|
|
137
module/actor/sheets/newSheet/npc.js
Normal file
137
module/actor/sheets/newSheet/npc.js
Normal file
|
@ -0,0 +1,137 @@
|
|||
import ActorSheet5e from "../base.js";
|
||||
|
||||
/**
|
||||
* An Actor sheet for NPC type characters in the SW5E system.
|
||||
* Extends the base ActorSheet5e class.
|
||||
* @extends {ActorSheet5e}
|
||||
*/
|
||||
export default class ActorSheet5eNPCNew extends ActorSheet5e {
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
if ( !game.user.isGM && this.actor.limited ) return "systems/sw5e/templates/actors/newActor/limited-sheet.html";
|
||||
return `systems/sw5e/templates/actors/newActor/npc-sheet.html`;
|
||||
}
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
return mergeObject(super.defaultOptions, {
|
||||
classes: ["sw5e", "sheet", "actor", "npc"],
|
||||
width: 600,
|
||||
width: 800,
|
||||
tabs: [{
|
||||
navSelector: ".root-tabs",
|
||||
contentSelector: ".sheet-body",
|
||||
initial: "attributes"
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Organize Owned Items for rendering the NPC sheet
|
||||
* @private
|
||||
*/
|
||||
_prepareItems(data) {
|
||||
|
||||
// Categorize Items as Features and Powers
|
||||
const features = {
|
||||
weapons: { label: game.i18n.localize("SW5E.AttackPl"), items: [] , hasActions: true, dataset: {type: "weapon", "weapon-type": "natural"} },
|
||||
actions: { label: game.i18n.localize("SW5E.ActionPl"), items: [] , hasActions: true, dataset: {type: "feat", "activation.type": "action"} },
|
||||
passive: { label: game.i18n.localize("SW5E.Features"), items: [], dataset: {type: "feat"} },
|
||||
equipment: { label: game.i18n.localize("SW5E.Inventory"), items: [], dataset: {type: "loot"}}
|
||||
};
|
||||
|
||||
// Start by classifying items into groups for rendering
|
||||
let [powers, other] = data.items.reduce((arr, item) => {
|
||||
item.img = item.img || DEFAULT_TOKEN;
|
||||
item.isStack = Number.isNumeric(item.data.quantity) && (item.data.quantity !== 1);
|
||||
item.hasUses = item.data.uses && (item.data.uses.max > 0);
|
||||
item.isOnCooldown = item.data.recharge && !!item.data.recharge.value && (item.data.recharge.charged === false);
|
||||
item.isDepleted = item.isOnCooldown && (item.data.uses.per && (item.data.uses.value > 0));
|
||||
item.hasTarget = !!item.data.target && !(["none",""].includes(item.data.target.type));
|
||||
if ( item.type === "power" ) arr[0].push(item);
|
||||
else arr[1].push(item);
|
||||
return arr;
|
||||
}, [[], []]);
|
||||
|
||||
// Apply item filters
|
||||
powers = this._filterItems(powers, this._filters.powerbook);
|
||||
other = this._filterItems(other, this._filters.features);
|
||||
|
||||
// Organize Powerbook
|
||||
const powerbook = this._preparePowerbook(data, powers);
|
||||
|
||||
// Organize Features
|
||||
for ( let item of other ) {
|
||||
if ( item.type === "weapon" ) features.weapons.items.push(item);
|
||||
else if ( item.type === "feat" ) {
|
||||
if ( item.data.activation.type ) features.actions.items.push(item);
|
||||
else features.passive.items.push(item);
|
||||
}
|
||||
else features.equipment.items.push(item);
|
||||
}
|
||||
|
||||
// Assign and return
|
||||
data.features = Object.values(features);
|
||||
data.powerbook = powerbook;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/** @override */
|
||||
getData() {
|
||||
const data = super.getData();
|
||||
|
||||
// Challenge Rating
|
||||
const cr = parseFloat(data.data.details.cr || 0);
|
||||
const crLabels = {0: "0", 0.125: "1/8", 0.25: "1/4", 0.5: "1/2"};
|
||||
data.labels["cr"] = cr >= 1 ? String(cr) : crLabels[cr] || 1;
|
||||
return data;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Object Updates */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/** @override */
|
||||
_updateObject(event, formData) {
|
||||
|
||||
// Format NPC Challenge Rating
|
||||
const crs = {"1/8": 0.125, "1/4": 0.25, "1/2": 0.5};
|
||||
let crv = "data.details.cr";
|
||||
let cr = formData[crv];
|
||||
cr = crs[cr] || parseFloat(cr);
|
||||
if ( cr ) formData[crv] = cr < 1 ? cr : parseInt(cr);
|
||||
|
||||
// Parent ActorSheet update steps
|
||||
super._updateObject(event, formData);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Event Listeners and Handlers */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/** @override */
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
html.find(".health .rollable").click(this._onRollHealthFormula.bind(this));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Handle rolling NPC health values using the provided formula
|
||||
* @param {Event} event The original click event
|
||||
* @private
|
||||
*/
|
||||
_onRollHealthFormula(event) {
|
||||
event.preventDefault();
|
||||
const formula = this.actor.data.data.attributes.hp.formula;
|
||||
if ( !formula ) return;
|
||||
const hp = new Roll(formula).roll().total;
|
||||
AudioHelper.play({src: CONFIG.sounds.dice});
|
||||
this.actor.update({"data.attributes.hp.value": hp, "data.attributes.hp.max": hp});
|
||||
}
|
||||
}
|
|
@ -285,7 +285,7 @@ export default class ActorSheet5eCharacter extends ActorSheet5e {
|
|||
if ( !hasClass || addLevel ) {
|
||||
const features = await Actor5e.getClassFeatures({
|
||||
className: itemData.name,
|
||||
subclassName: itemData.data.subclass,
|
||||
archetypeName: itemData.data.archetype,
|
||||
level: itemData.levels,
|
||||
priorLevel: priorLevel
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* A specialized form used to select from a checklist of attributes, traits, or properties
|
||||
* @extends {FormApplication}
|
||||
* @implements {FormApplication}
|
||||
*/
|
||||
export default class TraitSelector extends FormApplication {
|
||||
|
||||
|
@ -36,7 +36,7 @@ export default class TraitSelector extends FormApplication {
|
|||
getData() {
|
||||
|
||||
// Get current values
|
||||
let attr = getProperty(this.object.data, this.attribute) || {};
|
||||
let attr = getProperty(this.object._data, this.attribute) || {};
|
||||
attr.value = attr.value || [];
|
||||
|
||||
// Populate choices
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -767,3 +767,6 @@ body.dark-theme .sw5e.sheet.actor .swalt-sheet .tab.notes section > input {
|
|||
color: #E81111;
|
||||
border-bottom: 2px solid #0d99cc;
|
||||
}
|
||||
body.dark-theme .sw5e.sheet.actor.npc .swalt-sheet header .experience {
|
||||
color: #4f4f4f;
|
||||
}
|
||||
|
|
|
@ -745,6 +745,11 @@ input[type="reset"]:disabled {
|
|||
grid-column-start: 1;
|
||||
grid-row-start: 1;
|
||||
grid-row-end: 4;
|
||||
box-sizing: border-box;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
.sw5e.sheet.actor .swalt-sheet header h1.character-name {
|
||||
grid-row: 1;
|
||||
|
@ -783,6 +788,11 @@ input[type="reset"]:disabled {
|
|||
letter-spacing: 0.5px;
|
||||
text-align: right;
|
||||
}
|
||||
.sw5e.sheet.actor .swalt-sheet header .level-experience .charlevel input {
|
||||
display: inline-block;
|
||||
width: 42px;
|
||||
height: auto;
|
||||
}
|
||||
.sw5e.sheet.actor .swalt-sheet header .level-experience .experience {
|
||||
font-family: 'Russo One';
|
||||
font-size: 17px;
|
||||
|
@ -1507,6 +1517,9 @@ input[type="reset"]:disabled {
|
|||
.sw5e.sheet.actor .swalt-sheet .tab.powerbook > .panel {
|
||||
grid-template-rows: 32px 24px 24px auto;
|
||||
}
|
||||
.sw5e.sheet.actor .swalt-sheet .tab.powerbook h3.power-dc {
|
||||
line-height: 24px;
|
||||
}
|
||||
.sw5e.sheet.actor .swalt-sheet .tab.powerbook .powercasting-ability {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr 1fr;
|
||||
|
@ -1567,6 +1580,45 @@ input[type="reset"]:disabled {
|
|||
.sw5e.sheet.actor .swalt-sheet.limited .tab.biography {
|
||||
grid-template-columns: 100%;
|
||||
}
|
||||
.sw5e.sheet.actor.npc .swalt-sheet header h1.character-name {
|
||||
align-self: auto;
|
||||
}
|
||||
.sw5e.sheet.actor.npc .swalt-sheet header .npc-size {
|
||||
font-family: 'Russo One';
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.5px;
|
||||
line-height: 28px;
|
||||
}
|
||||
.sw5e.sheet.actor.npc .swalt-sheet header .attributes {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
.sw5e.sheet.actor.npc .swalt-sheet header .attributes footer.proficiency {
|
||||
margin-top: 0;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
.sw5e.sheet.actor.npc .swalt-sheet header .attributes footer.hit-points {
|
||||
display: block;
|
||||
}
|
||||
.sw5e.sheet.actor.npc .swalt-sheet nav.sheet-navigation {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
.sw5e.sheet.actor.npc .swalt-sheet .tab.attributes .traits-resources {
|
||||
display: block;
|
||||
}
|
||||
.sw5e.sheet.actor.npc .swalt-sheet .tab.attributes .traits-resources .counter {
|
||||
display: flex;
|
||||
}
|
||||
.sw5e.sheet.actor.npc .swalt-sheet .tab.attributes .traits-resources .counter .counter-value {
|
||||
margin-left: auto;
|
||||
}
|
||||
.sw5e.sheet.actor.npc .swalt-sheet .tab.powerbook input.powercasting-level {
|
||||
width: 48px;
|
||||
}
|
||||
.sw5e.sheet.actor.npc .swalt-sheet .tab.biography.active {
|
||||
display: block;
|
||||
}
|
||||
@keyframes pause-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
|
|
|
@ -767,3 +767,6 @@ body.light-theme .sw5e.sheet.actor .swalt-sheet .tab.notes section > input {
|
|||
color: #c40f0f;
|
||||
border-bottom: 2px solid #0d99cc;
|
||||
}
|
||||
body.light-theme .sw5e.sheet.actor.npc .swalt-sheet header .experience {
|
||||
color: #4f4f4f;
|
||||
}
|
||||
|
|
37
sw5e.css
37
sw5e.css
|
@ -461,9 +461,7 @@
|
|||
}
|
||||
.sw5e.sheet .items-list .items-header .item-name {
|
||||
padding-left: 5px;
|
||||
font-family: 'Russo One';
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
}
|
||||
.sw5e.sheet .items-list .item-name {
|
||||
flex: 2;
|
||||
|
@ -1060,9 +1058,7 @@
|
|||
overflow-y: auto;
|
||||
}
|
||||
.sw5e.sheet.item {
|
||||
min-height: 400px;
|
||||
max-height: 95%;
|
||||
min-width: 480px;
|
||||
min-height: 420px;
|
||||
/* ----------------------------------------- */
|
||||
/* Sheet Header */
|
||||
/* ----------------------------------------- */
|
||||
|
@ -1083,7 +1079,7 @@
|
|||
border: 2px solid #000;
|
||||
}
|
||||
.sw5e.sheet.item .sheet-header .item-subtitle {
|
||||
flex: 0 0 100px;
|
||||
flex: 0 0 80px;
|
||||
height: 60px;
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
|
@ -1538,3 +1534,30 @@
|
|||
max-width: 40px;
|
||||
text-align: right;
|
||||
}
|
||||
input[type="number"] {
|
||||
width: calc(100% - 2px);
|
||||
min-width: 20px;
|
||||
height: 26px;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
padding: 1px 3px;
|
||||
margin: 0;
|
||||
color: #191813;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
text-align: inherit;
|
||||
line-height: inherit;
|
||||
border: 1px solid #7a7971;
|
||||
border-radius: 3px;
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
input[type="number"]:focus {
|
||||
box-shadow: 0 0 5px red;
|
||||
}
|
||||
input[type="number"]::-webkit-inner-spin-button,
|
||||
input[type="number"]::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
|
9
sw5e.js
9
sw5e.js
|
@ -26,6 +26,7 @@ import ActorSheet5eCharacter from "./module/actor/sheets/oldSheets/character.js"
|
|||
import ActorSheet5eNPC from "./module/actor/sheets/oldSheets/npc.js";
|
||||
import ActorSheet5eVehicle from "./module/actor/sheets/oldSheets/vehicle.js";
|
||||
import ActorSheet5eCharacterNew from "./module/actor/sheets/newSheet/character.js";
|
||||
import ActorSheet5eNPCNew from "./module/actor/sheets/newSheet/npc.js";
|
||||
import ItemSheet5e from "./module/item/sheet.js";
|
||||
import ShortRestDialog from "./module/apps/short-rest.js";
|
||||
import TraitSelector from "./module/apps/trait-selector.js";
|
||||
|
@ -52,6 +53,7 @@ Hooks.once("init", function() {
|
|||
ActorSheet5eCharacter,
|
||||
ActorSheet5eCharacterNew,
|
||||
ActorSheet5eNPC,
|
||||
ActorSheet5eNPCNew,
|
||||
ActorSheet5eVehicle,
|
||||
ItemSheet5e,
|
||||
ShortRestDialog,
|
||||
|
@ -101,11 +103,16 @@ Hooks.once("init", function() {
|
|||
makeDefault: false,
|
||||
label: "SW5E.SheetClassCharacterOld"
|
||||
});
|
||||
Actors.registerSheet("sw5e", ActorSheet5eNPC, {
|
||||
Actors.registerSheet("sw5e", ActorSheet5eNPCNew, {
|
||||
types: ["npc"],
|
||||
makeDefault: true,
|
||||
label: "SW5E.SheetClassNPC"
|
||||
});
|
||||
Actors.registerSheet("sw5e", ActorSheet5eNPC, {
|
||||
types: ["npc"],
|
||||
makeDefault: false,
|
||||
label: "SW5E.SheetClassNPCOld"
|
||||
});
|
||||
Actors.registerSheet('sw5e', ActorSheet5eVehicle, {
|
||||
types: ['vehicle'],
|
||||
makeDefault: true,
|
||||
|
|
|
@ -591,7 +591,7 @@
|
|||
"templates": ["classDescription"],
|
||||
"className": "",
|
||||
"levels": 1,
|
||||
"subclass": "",
|
||||
"archetype": "",
|
||||
"hitDice": "d6",
|
||||
"hitDiceUsed": 0,
|
||||
"skills": {
|
||||
|
|
189
templates/actors/newActor/npc-sheet.html
Normal file
189
templates/actors/newActor/npc-sheet.html
Normal file
|
@ -0,0 +1,189 @@
|
|||
<form class="{{cssClass}} swalt-sheet" autocomplete="off">
|
||||
|
||||
{{!-- NPC Sheet Header --}}
|
||||
<header class="panel">
|
||||
<img class="profile" src="{{actor.img}}" title="{{actor.name}}" data-edit="img" />
|
||||
<h1 class="character-name">
|
||||
<input name="name" type="text" value="{{actor.name}}" placeholder="{{ localize 'SW5E.Name' }}" />
|
||||
</h1>
|
||||
<div class="level-experience">
|
||||
<div class="charlevel">
|
||||
{{ localize "SW5E.AbbreviationCR" }}
|
||||
<input name="data.details.cr" type="text" value="{{labels.cr}}" placeholder="1" />
|
||||
</div>
|
||||
|
||||
<div class="experience">
|
||||
<span class="max">{{data.details.xp.value}} XP</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="summary">
|
||||
<span class="npc-size">{{lookup config.actorSizes data.traits.size}}</span>
|
||||
<input type="text" name="data.details.alignment" value="{{data.details.alignment}}"
|
||||
placeholder="{{ localize 'SW5E.Alignment' }}" />
|
||||
<input type="text" name="data.details.type" value="{{data.details.type}}"
|
||||
placeholder="{{ localize 'SW5E.Type' }}" />
|
||||
<input type="text" name="data.details.source" value="{{data.details.source}}"
|
||||
placeholder="{{ localize 'SW5E.Source' }}" />
|
||||
</div>
|
||||
<div class="attributes">
|
||||
{{!-- ARMOR CLASS --}}
|
||||
<section>
|
||||
<h1>{{ localize "SW5E.ArmorClass" }}</h1>
|
||||
<div class="attribute-value">
|
||||
<input class="ac-display" name="data.attributes.ac.value" type="text"
|
||||
value="{{data.attributes.ac.value}}" data-dtype="Number" placeholder="10" />
|
||||
</div>
|
||||
<footer class="attribute-footer proficiency">
|
||||
{{ localize "SW5E.Proficiency" }}
|
||||
{{numberFormat data.attributes.prof decimals=0 sign=true}}
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
{{!-- HIT POINTS --}}
|
||||
<section>
|
||||
<h1>Hit Points</h1>
|
||||
<div class="attribute-value multiple">
|
||||
<input name="data.attributes.hp.value" type="text" value="{{data.attributes.hp.value}}"
|
||||
data-dtype="Number" placeholder="10" class="value-number" />
|
||||
<span class="value-separator">/</span>
|
||||
<input name="data.attributes.hp.max" type="text" value="{{data.attributes.hp.max}}"
|
||||
data-dtype="Number" placeholder="10" class="value-number" />
|
||||
</div>
|
||||
<footer class="attribute-footer hit-points">
|
||||
<input name="data.attributes.hp.formula" class="hpformula" type="text"
|
||||
placeholder="{{ localize 'SW5E.HealthFormula' }}" value="{{data.attributes.hp.formula}}" />
|
||||
</footer>
|
||||
</section>
|
||||
<section>
|
||||
<h1>{{ localize "SW5E.Speed" }}</h1>
|
||||
<div class="attribute-value">
|
||||
<input name="data.attributes.speed.value" type="text" value="{{data.attributes.speed.value}}"
|
||||
placeholder="0" />
|
||||
</div>
|
||||
<footer class="attribute-footer speed">
|
||||
<input type="text" class="speed" name="data.attributes.speed.special"
|
||||
value="{{data.attributes.speed.special}}" placeholder="{{ localize 'SW5E.SpeedSpecial' }}" />
|
||||
</footer>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</header>
|
||||
|
||||
{{!-- NPC Sheet Navigation --}}
|
||||
<nav class="sheet-navigation root-tabs" data-group="primary">
|
||||
<button class="item active" data-tab="attributes">{{ localize "SW5E.Attributes" }}</button>
|
||||
<button class="item" data-tab="features">{{ localize "SW5E.Features" }}</button>
|
||||
<button class="item" data-tab="powerbook">{{ localize "SW5E.Powerbook" }}</button>
|
||||
<button class="item" data-tab="biography">{{ localize "SW5E.Biography" }}</button>
|
||||
</nav>
|
||||
|
||||
{{!-- NPC Sheet Body --}}
|
||||
<section class="sheet-body">
|
||||
<section class="tab attributes core" data-group="primary" data-tab="attributes">
|
||||
<section class="panel abilities">
|
||||
{{!-- Ability Scores --}}
|
||||
<section class="scores">
|
||||
<h1>Ability Scores</h1>
|
||||
<ol>
|
||||
{{#each data.abilities as |ability id|}}
|
||||
<li class="ability {{#if ability.proficient}}proficient{{/if}}" data-ability="{{id}}">
|
||||
<h2 class="ability-name rollable">{{ability.label}}</h4>
|
||||
<input class="ability-score" name="data.abilities.{{id}}.value" type="text"
|
||||
value="{{ability.value}}" data-dtype="Number" placeholder="10" />
|
||||
<div class="ability-modifiers">
|
||||
<span class="ability-mod"
|
||||
title="Modifier">{{numberFormat ability.mod decimals=0 sign=true}}</span>
|
||||
<input type="hidden" name="data.abilities.{{id}}.proficient"
|
||||
value="{{ability.proficient}}" data-dtype="Number" />
|
||||
<button class="proficiency-toggle ability-proficiency"
|
||||
title="Proficiency">{{{ability.icon}}}</button>
|
||||
<span class="ability-save"
|
||||
title="Saving Throw">{{numberFormat ability.save decimals=0 sign=true}}</span>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
</section>
|
||||
{{!-- Skills --}}
|
||||
<section class="skills">
|
||||
<h1>Skills</h1>
|
||||
<ol>
|
||||
{{#each data.skills as |skill s|}}
|
||||
<li class="skill {{#if skill.value}}proficient{{/if}}" data-skill="{{s}}">
|
||||
<input type="hidden" name="data.skills.{{s}}.value" value="{{skill.value}}"
|
||||
data-dtype="Number" />
|
||||
<button class="proficiency-toggle skill-proficiency"
|
||||
title="{{skill.hover}}">{{{skill.icon}}}</button>
|
||||
<span class="skill-name rollable">{{skill.label}}</span>
|
||||
<span class="skill-ability">{{skill.ability}}</span>
|
||||
<span class="skill-mod">{{numberFormat skill.total decimals=0 sign=true}}</span>
|
||||
{{!-- <input class="skill-bonus" name="data.skills.{{s}}.bonus" type="text" value="{{numberFormat skill.bonus decimals=0 sign=true}}" data-dtype="Number" placeholder="0" title="Misc. Modifier"/> --}}
|
||||
{{!-- <span class="skill-passive">({{skill.passive}})</span> --}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
</section>
|
||||
</section>
|
||||
<section class="panel traits-resources">
|
||||
{{!-- Legendary Actions --}}
|
||||
<div class="counters">
|
||||
<div class="counter legendary">
|
||||
<strong>{{ localize "SW5E.LegAct" }}</strong>
|
||||
<div class="counter-value">
|
||||
<input name="data.resources.legact.value" type="number"
|
||||
value="{{data.resources.legact.value}}" placeholder="0" />
|
||||
<span class="sep">/</span>
|
||||
<input name="data.resources.legact.max" type="number" value="{{data.resources.legact.max}}"
|
||||
placeholder="0" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="counter legendary">
|
||||
<strong>{{ localize "SW5E.LegRes" }}</strong>
|
||||
<div class="counter-value">
|
||||
<input name="data.resources.legres.value" type="number"
|
||||
value="{{data.resources.legres.value}}" placeholder="0" />
|
||||
<span class="sep">/</span>
|
||||
<input name="data.resources.legres.max" type="number" value="{{data.resources.legres.max}}"
|
||||
placeholder="0" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="counter lair">
|
||||
<strong>{{ localize "SW5E.LairAct" }}</strong>
|
||||
<div class="counter-value">
|
||||
<input name="data.resources.lair.value" type="checkbox"
|
||||
value="{{data.resources.lair.value}}" data-dtype="Boolean"
|
||||
{{checked data.resources.lair.value}} />
|
||||
<input name="data.resources.lair.initiative" type="number"
|
||||
value="{{data.resources.lair.initiative}}" placeholder="20" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="core-traits">
|
||||
{{> "systems/sw5e/templates/actors/newActor/parts/swalt-traits.html"}}
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
{{!-- Features Tab --}}
|
||||
<div class="tab features flexcol" data-group="primary" data-tab="features">
|
||||
{{> "systems/sw5e/templates/actors/newActor/parts/swalt-features.html" sections=features}}
|
||||
</div>
|
||||
|
||||
{{!-- Powerbook Tab --}}
|
||||
<div class="tab powerbook flexcol" data-group="primary" data-tab="powerbook">
|
||||
{{> "systems/sw5e/templates/actors/newActor/parts/swalt-powerbook.html"}}
|
||||
</div>
|
||||
|
||||
{{!-- Biography Tab --}}
|
||||
<div class="tab biography flexcol" data-group="primary" data-tab="biography">
|
||||
<div class="panel">
|
||||
<section>
|
||||
<h1>Biography</h1>
|
||||
{{editor content=data.details.biography.value target="data.details.biography.value" button=true owner=owner editable=editable}}
|
||||
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
{{else if section.isClass}}
|
||||
<div class="item-detail player-class">
|
||||
{{item.data.subclass}}
|
||||
{{item.data.archetype}}
|
||||
</div>
|
||||
<div class="item-detail player-class-levels">
|
||||
Level {{item.data.levels}}
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
<ol class="group-items">
|
||||
<ol class="group-items item-list">
|
||||
{{#each section.items as |item iid|}}
|
||||
<li class="item group-grid-inventory" data-item-id="{{item._id}}">
|
||||
<div class="item-name rollable">
|
||||
|
|
|
@ -96,7 +96,7 @@
|
|||
|
||||
{{else if section.isClass}}
|
||||
<div class="item-detail player-class">
|
||||
{{item.data.subclass}}
|
||||
{{item.data.archetype}}
|
||||
</div>
|
||||
<div class="item-detail item-action">
|
||||
Level {{item.data.levels}}
|
||||
|
|
|
@ -53,11 +53,11 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Subclass Name --}}
|
||||
{{!-- Archetype Name --}}
|
||||
<div class="form-group">
|
||||
<label>{{ localize "SW5E.SubclassName" }}</label>
|
||||
<label>{{ localize "SW5E.ArchetypeName" }}</label>
|
||||
<div class="form-fields">
|
||||
<input type="text" name="data.subclass" value="{{data.subclass}}"/>
|
||||
<input type="text" name="data.archetype" value="{{data.archetype}}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue