Merge branch 'development' into 'master'

Development

See merge request mesfoliesludiques/foundryvtt-ose!1
master
U~man 2020-06-28 18:30:45 +00:00
commit b40858aba1
19 changed files with 552 additions and 162 deletions

View File

@ -1 +1,9 @@
### Old School Essentials System for Foundry VTT
# Old School Essentials System for Foundry VTT
## License
Old-School Essentials is a trademark of Necrotic Gnome.
This Foundry VTT system requires Old-School Essentials Core Rules and does not contain any copyrighted material.
## Contributions
This system is currently under heavy development.
Feel free to grab a TO DO issue from the gitlab board. You can then do a merge request on the `development` branch.

View File

@ -1,6 +1,7 @@
{
"OSE.Edit": "Edit",
"OSE.Delete": "Delete",
"OSE.Add": "Add",
"OSE.Name": "Name",
"OSE.Class": "Class",
@ -8,6 +9,10 @@
"OSE.Alignment": "Alignment",
"OSE.Level": "Level",
"OSE.Experience": "Experience",
"OSE.Treasure": "Treasure type",
"OSE.Size": "Size",
"OSE.Morale": "Morale",
"OSE.Appearing": "NA",
"OSE.scores.str.long": "Strength",
"OSE.scores.str.short": "STR",
@ -23,18 +28,31 @@
"OSE.scores.cha.short": "CHA",
"OSE.saves.death.short": "D",
"OSE.saves.death.long": "Death",
"OSE.saves.wands.short": "W",
"OSE.saves.wands.long": "Wands",
"OSE.saves.paralysis.short": "P",
"OSE.saves.paralysis.long": "Paralysis",
"OSE.saves.breath.short": "B",
"OSE.saves.breath.long": "Breath",
"OSE.saves.spells.short": "S",
"OSE.saves.spells.long": "Spells",
"OSE.Health": "Hit Points",
"OSE.HealthShort": "HP",
"OSE.HitDice": "Hit Dice",
"OSE.HitDiceShort": "HD",
"OSE.Movement": "Movement",
"OSE.MovementShort": "MOV",
"OSE.SpecialMovement": "Special Movement",
"OSE.ArmorClass": "Armor Class",
"OSE.ArmorClassShort": "AC",
"OSE.SpellDC": "DC",
"OSE.Thac0": "THAC0",
"OSE.Initiative": "Initiative",
"OSE.InitiativeShort": "INIT",
"OSE.Attacks": "Attacks Usable per Round",
"OSE.AttacksShort": "ATT",
"OSE.category.attributes": "Attributes",
@ -42,5 +60,6 @@
"OSE.category.spells": "Spells",
"OSE.category.notes": "Notes",
"OSE.panel.abilities": "Abilities"
"OSE.panel.abilities": "Abilities",
"OSE.panel.equipment": "Equipment"
}

View File

@ -1,2 +1,65 @@
{
"OSE.Edit": "Modifier",
"OSE.Delete": "Supprimer",
"OSE.Add": "Ajouter",
"OSE.Name": "Nom",
"OSE.Class": "Classe",
"OSE.Title": "Titre",
"OSE.Alignment": "Alignement",
"OSE.Level": "Niveau",
"OSE.Experience": "Expérience",
"OSE.Treasure": "Butin",
"OSE.Size": "Taille",
"OSE.Morale": "Moral",
"OSE.Appearing": "NA",
"OSE.scores.str.long": "Force",
"OSE.scores.str.short": "FOR",
"OSE.scores.wis.long": "Sagesse",
"OSE.scores.wis.short": "SAG",
"OSE.scores.int.long": "Intelligence",
"OSE.scores.int.short": "INT",
"OSE.scores.dex.long": "Dextérité",
"OSE.scores.dex.short": "DEX",
"OSE.scores.con.long": "Constitution",
"OSE.scores.con.short": "CON",
"OSE.scores.cha.long": "Charisme",
"OSE.scores.cha.short": "CHA",
"OSE.saves.death.short": "D",
"OSE.saves.death.long": "Mort",
"OSE.saves.wands.short": "W",
"OSE.saves.wands.long": "Baguettes",
"OSE.saves.paralysis.short": "P",
"OSE.saves.paralysis.long": "Paralysie",
"OSE.saves.breath.short": "B",
"OSE.saves.breath.long": "Souffle",
"OSE.saves.spells.short": "S",
"OSE.saves.spells.long": "Sorts",
"OSE.Health": "Points de Vie",
"OSE.HealthShort": "PV",
"OSE.HitDice": "Dés de Vie",
"OSE.HitDiceShort": "DV",
"OSE.Movement": "Mouvement",
"OSE.MovementShort": "MOUV",
"OSE.SpecialMovement": "Mouvement Spécial",
"OSE.ArmorClass": "Classe d'Armure",
"OSE.ArmorClassShort": "CA",
"OSE.SpellDC": "DF",
"OSE.Thac0": "THAC0",
"OSE.Initiative": "Initiative",
"OSE.InitiativeShort": "INIT",
"OSE.Attacks": "Attaques par Round",
"OSE.AttacksShort": "ATT",
"OSE.category.attributes": "Attributs",
"OSE.category.inventory": "Inventaire",
"OSE.category.spells": "Sorts",
"OSE.category.notes": "Notes",
"OSE.panel.abilities": "Aptitudes",
"OSE.panel.equipment": "Equipement"
}

View File

@ -33,6 +33,20 @@ export class OseActorSheetCharacter extends ActorSheet {
/* -------------------------------------------- */
// Override to set resizable initial size
async _renderInner(...args) {
const html = await super._renderInner(...args);
this.form = html[0];
// Resize resizable classes
let resizable = html.find('.resizable');
resizable.each((_, el) => {
let heightDelta = this.position.height - (this.options.height);
el.style.height = `${heightDelta + parseInt(el.dataset.baseSize)}px`;
});
return html;
}
/**
* Prepare data for rendering the Actor sheet
* The prepared data object contains both the actor data as well as additional sheet options
@ -94,12 +108,6 @@ export class OseActorSheetCharacter extends ActorSheet {
li.toggleClass("expanded");
}
_onRollAttribute(event) {
event.preventDefault();
let attribute = event.currentTarget.dataset.attribute;
this.actor.rollAttribute(attribute, { event: event });
}
/**
* Activate event listeners using the prepared sheet HTML
* @param html {HTML} The prepared HTML object ready to be rendered into the DOM
@ -141,4 +149,14 @@ export class OseActorSheetCharacter extends ActorSheet {
// Handle default listeners last so system listeners are triggered first
super.activateListeners(html);
}
async _onResize(event) {
super._onResize(event);
let html = $(event.path);
let resizable = html.find('.resizable');
resizable.each((_, el) => {
let heightDelta = this.position.height - (this.options.height);
el.style.height = `${heightDelta + parseInt(el.dataset.baseSize)}px`;
});
}
}

View File

@ -17,65 +17,4 @@ export class OseActor extends Actor {
/* -------------------------------------------- */
/* Rolls */
/* -------------------------------------------- */
rollAttribute(attributeId, options = {}) {
const label = CONFIG.MAJI.attributes[attributeId];
const abl = this.data.data.attributes[attributeId];
let parts = [];
if (abl.value <= 4) {
parts.push("2d4");
} else if (abl.value <= 7) {
parts.push("2d6");
} else {
parts.push("2d8");
}
let rollMode = game.settings.get("core", "rollMode");
let roll = new Roll(parts.join(" + "), {}).roll();
roll.toMessage(
{
speaker: ChatMessage.getSpeaker({ actor: this }),
flavor: `${label} Attribute Test`,
},
{ rollMode }
);
return roll;
}
rollInit(monsterId, options = {}) {
let monster = game.actors.get(monsterId);
let speed = monster.data.data.attributes.speed.value + monster.data.data.attributes.speed.mod;
if (!game.combats.active) return;
let combatant = game.combats.active.getCombatant(this.actor);
console.log(combatant);
}
static async applyDamage(roll, options = {}) {
let value = Math.floor(parseFloat(roll.find(".dice-total").text()));
const promises = [];
for (let t of canvas.tokens.controlled) {
let a = t.actor,
hp = a.data.data.hp;
let delta = 0;
if (a.data.type == "monster") {
if (options.vulnerable) {
delta -= value + a.data.data.affinity.value;
} else if (options.resistant) {
delta -= Math.max(0, value - a.data.data.resistance.value);
} else if (options.healing) {
delta += value;
} else {
delta -= value;
}
} else {
delta -= options.healing ? -value : value;
}
promises.push(
t.actor.update({
"data.hp.value": Math.clamped(hp.value + delta, 0, hp.max),
})
);
}
return Promise.all(promises);
}
}

View File

@ -18,14 +18,14 @@ export class OseActorSheetMonster extends ActorSheet {
return mergeObject(super.defaultOptions, {
classes: ["ose", "sheet", "monster", "actor"],
template: "systems/ose/templates/actors/monster-sheet.html",
width: 520,
height: 580,
resizable: false,
width: 450,
height: 560,
resizable: true,
tabs: [
{
navSelector: ".tabs",
contentSelector: ".sheet-body",
initial: "notes",
initial: "attributes",
},
],
});
@ -33,16 +33,36 @@ export class OseActorSheetMonster extends ActorSheet {
/* -------------------------------------------- */
// Override to set resizable initial size
async _renderInner(...args) {
const html = await super._renderInner(...args);
this.form = html[0];
// Resize resizable classes
let resizable = html.find('.resizable');
if (resizable.length == 0) {
return;
}
resizable.each((_, el) => {
let heightDelta = this.position.height - (this.options.height);
el.style.height = `${heightDelta + parseInt(el.dataset.baseSize)}px`;
});
return html;
}
/**
* Prepare data for rendering the Actor sheet
* The prepared data object contains both the actor data as well as additional sheet options
*/
getData() {
const data = super.getData();
data.config = CONFIG.OSE;
// Prepare owned items
this._prepareItems(data);
// DEBUG
return data;
}
@ -51,31 +71,40 @@ export class OseActorSheetMonster extends ActorSheet {
* @private
*/
_prepareItems(data) {
// Partition items by category
let [inventory, abilities, spells] = data.items.reduce(
(arr, item) => {
// Classify items into types
if (item.type === "item") arr[0].push(item);
if (item.type === "ability") arr[1].push(item);
else if (item.type === "spell") arr[2].push(item);
return arr;
},
[[], [], [], []]
);
// Assign and return
data.inventory = inventory;
data.spells = spells;
data.abilities = abilities;
}
_onItemSummary(event) {
event.preventDefault();
let li = $(event.currentTarget).parents(".item-entry"),
expanded = !li.children(".collapsible").hasClass("collapsed");
li = $(li);
let ol = li.children(".collapsible");
let icon = li.find("i.fas");
// Collapse the Playlist
if (expanded) {
ol.slideUp(200, () => {
ol.addClass("collapsed");
icon.removeClass("fa-angle-up").addClass("fa-angle-down");
});
}
// Expand the Playlist
else {
ol.slideDown(200, () => {
ol.removeClass("collapsed");
icon.removeClass("fa-angle-down").addClass("fa-angle-up");
});
let li = $(event.currentTarget).parents(".item"),
item = this.actor.getOwnedItem(li.data("item-id")),
description = TextEditor.enrichHTML(item.data.data.description);
// Toggle summary
if ( li.hasClass("expanded") ) {
let summary = li.parents('.item-entry').children(".item-summary");
summary.slideUp(200, () => summary.remove());
} else {
let div = $(`<div class="item-summary">${description}</div>`);
li.parents('.item-entry').append(div.hide());
div.slideDown(200);
}
li.toggleClass("expanded");
}
/* -------------------------------------------- */
@ -122,4 +151,14 @@ export class OseActorSheetMonster extends ActorSheet {
// Handle default listeners last so system listeners are triggered first
super.activateListeners(html);
}
async _onResize(event) {
super._onResize(event);
let html = $(event.path);
let resizable = html.find('.resizable');
resizable.each((_, el) => {
let heightDelta = this.position.height - (this.options.height);
el.style.height = `${heightDelta + parseInt(el.dataset.baseSize)}px`;
});
}
}

View File

@ -8,6 +8,31 @@
padding: 0;
}
.panel {
border: 1px solid $colorDark;
.panel-title {
color: whitesmoke;
background: $colorDark;
line-height: 14px;
height: 20px;
text-align: center;
margin: 0;
padding: 4px;
display: flex;
h4 {
flex: 1;
}
.item-controls {
font-size: 12px;
flex: 0 0 18px;
}
}
.panel-content {
margin: 0;
padding: 0;
}
}
/* Header Summary Details */
.header-details {
h1 {
@ -75,6 +100,7 @@
.attribute-name {
color: whitesmoke;
padding: 2px;
margin: 0;
background: $colorDark;
text-align: center;
}
@ -85,6 +111,22 @@
}
}
}
.attribute-group {
.attributes {
.attribute {
display: flex;
flex-direction: row;
.attribute-name {
width: 40px;
margin: 0;
line-height: 28px;
}
}
}
}
.editor {
height: 300px;
}
.inventory {
.item-entry {
padding: 0;
@ -93,10 +135,13 @@
.item {
.item-image {
flex: 0 0 24px;
height: 24px;
background-size: cover;
}
.item-name {
line-height: 24px;
height: 24px;
overflow: hidden;
h4 {
text-indent: 4px;
margin: 0;
@ -123,13 +168,13 @@
}
}
}
&:nth-child(odd) {
background: rgba(0, 0, 0, 0.1);
}
}
.item-summary {
font-size: 12px;
padding: 4px;
padding: 0 4px;
}
&:nth-child(odd) {
background: rgba(0, 0, 0, 0.1);
}
}
}

View File

@ -18,40 +18,8 @@
/* Sheet Body */
/* ----------------------------------------- */
.sheet-body {
.attribute-group {
.attributes {
.attribute {
display: flex;
flex-direction: row;
.attribute-name {
width: 40px;
margin: 0;
line-height: 28px;
}
}
}
}
.editor {
height: 300px;
}
}
.panel {
border: 1px solid $colorDark;
.panel-title {
color: whitesmoke;
background: $colorDark;
line-height: 14px;
height: 20px;
text-align: center;
margin: 0;
padding: 4px;
}
.panel-content {
margin: 0;
padding: 0;
}
}
.abilities {
.panel-content {

View File

@ -33,4 +33,8 @@
a:hover {
text-shadow: none;
}
.resizable {
overflow: auto;
}
}

View File

@ -0,0 +1,21 @@
.ose.actor.monster {
min-height: 565px;
min-width: 460px;
.sheet-body {
.editor {
height: 300px;
}
}
.abilities {
.panel-content {
height: 230px;
overflow: auto;
}
}
.attribute-row {
padding: 2px;
.abilities {
margin: 2px;
}
}
}

View File

@ -2,7 +2,7 @@
"name": "ose",
"title": "Old-School Essentials",
"description": "Play OSR modules with Old-School Essentials on Foundry VTT",
"version": 0.1,
"version": 0.2,
"minimumCoreVersion": "0.6.2",
"compatibleCoreVersion": "0.6.4",
"templateVersion": 2,

View File

@ -74,7 +74,7 @@
"value": 0,
"mod": 0
},
"thaco": {
"thac0": {
"value": 19,
"mod": 0
},
@ -101,6 +101,8 @@
"alignment": "",
"xp": 0,
"treasure": "",
"size": "",
"appearing": "",
"morale": 0
},
"saves": {
@ -110,7 +112,7 @@
"B": 10,
"S": 10
},
"thaco": {
"thac0": {
"value": 19,
"mod": 0
},
@ -123,9 +125,35 @@
"value": 0,
"mod": 0
},
"attacks": {
"value": 1
},
"movement": {
"base": 0,
"encounter": 0
},
"spells": {
"dc": 0,
"lvl1": {
"value": 0,
"max": 0
},
"lvl2": {
"value": 0,
"max": 0
},
"lvl3": {
"value": 0,
"max": 0
},
"lvl4": {
"value": 0,
"max": 0
},
"lvl5": {
"value": 0,
"max": 0
}
}
}
},

View File

@ -22,11 +22,7 @@
{{! Sheet Body }}
<section class="sheet-body">
{{! Attributes Tab }}
<div
class="tab"
data-group="primary"
data-tab="attributes"
>
<div class="tab" data-group="primary" data-tab="attributes">
{{> "systems/ose/templates/actors/partials/character-attributes-tab.html"}}
</div>
<div class="tab" data-group="primary" data-tab="inventory">
@ -40,4 +36,4 @@
button=true owner=owner editable=editable}}
</div>
</section>
</form>
</form>

View File

@ -0,0 +1,33 @@
<form class="{{cssClass}}" autocomplete="off">
{{! Sheet Header }}
<header class="sheet-header flexrow">
{{> "systems/ose/templates/actors/partials/monster-header.html"}}
</header>
{{! Sheet Tab Navigation }}
<nav class="sheet-tabs tabs flexrow" data-group="primary">
<a class="item" data-tab="attributes">
{{localize "OSE.category.attributes"}}
</a>
<a class="item" data-tab="spells">
{{localize "OSE.category.spells"}}
</a>
<a class="item" data-tab="notes">
{{localize "OSE.category.notes"}}
</a>
</nav>
{{! Sheet Body }}
<section class="sheet-body">
{{! Attributes Tab }}
<div class="tab" data-group="primary" data-tab="attributes">
{{> "systems/ose/templates/actors/partials/monster-attributes-tab.html"}}
</div>
<div class="tab" data-group="primary" data-tab="spells">
{{> "systems/ose/templates/actors/partials/character-spells-tab.html"}}
</div>
<div class="tab" data-group="primary" data-tab="notes">
{{editor content=data.details.biography target="data.details.biography"
button=true owner=owner editable=editable}}
</div>
</section>
</form>

View File

@ -1,7 +1,7 @@
<section class="flexrow">
<ul class="attributes flexrow">
<li class="attribute health">
<h4 class="attribute-name box-title">{{ localize "OSE.Health" }}</h4>
<h4 class="attribute-name box-title">{{ localize "OSE.HealthShort" }}</h4>
<div class="attribute-value multiple">
<input name="data.hp.value" type="text" value="{{data.hp.value}}" data-dtype="Number"
placeholder="10" />
@ -10,21 +10,28 @@
</div>
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.ArmorClass" }}</h4>
<h4 class="attribute-name box-title">{{ localize "OSE.ArmorClassShort" }}</h4>
<div class="attribute-value">
<input name="data.ac.value" type="text" value="{{data.ac.value}}" data-dtype="Number"
placeholder="10" data-dtype="Number" />
</div>
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.Initiative" }}</h4>
<h4 class="attribute-name box-title">{{ localize "OSE.Thac0" }}</h4>
<div class="attribute-value">
<input name="data.thac0.value" type="text" value="{{data.thac0.value}}" placeholder="0"
data-dtype="Number" />
</div>
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.InitiativeShort" }}</h4>
<div class="attribute-value">
<input name="data.initiative.value" type="text" value="{{data.initiative.value}}"
placeholder="0" data-dtype="Number" />
</div>
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.Movement" }}</h4>
<h4 class="attribute-name box-title">{{ localize "OSE.MovementShort" }}</h4>
<div class="attribute-value">
<input name="data.movement.value" type="text" value="{{data.movement.value}}"
placeholder="0" data-dtype="Number" />
@ -37,41 +44,48 @@
<div class="attribute-group">
<ul class="attributes">
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.scores.str.short" }}</h4>
<h4 class="attribute-name box-title" title="{{ localize 'OSE.scores.str.long' }}">{{ localize "OSE.scores.str.short" }}</h4>
<div class="attribute-value">
<input name="data.scores.str.value" type="text" value="{{data.scores.str.value}}" placeholder="0" data-dtype="Number"/>
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.scores.int.short" }}</h4>
<h4 class="attribute-name box-title" title="{{ localize 'OSE.scores.int.long' }}">{{ localize "OSE.scores.int.short" }}</h4>
<div class="attribute-value">
<input name="data.scores.int.value" type="text" value="{{data.scores.int.value}}" placeholder="0" data-dtype="Number"/>
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.scores.wis.short" }}</h4>
<h4 class="attribute-name box-title" title="{{ localize 'OSE.scores.wis.long' }}">{{ localize "OSE.scores.wis.short" }}</h4>
<div class="attribute-value">
<input name="data.scores.wis.value" type="text" value="{{data.scores.wis.value}}" placeholder="0" data-dtype="Number"/>
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.scores.dex.short" }}</h4>
<h4 class="attribute-name box-title" title="{{ localize 'OSE.scores.dex.long' }}">{{ localize "OSE.scores.dex.short" }}</h4>
<div class="attribute-value">
<input name="data.scores.dex.value" type="text" value="{{data.scores.dex.value}}" placeholder="0" data-dtype="Number"/>
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.scores.con.short" }}</h4>
<h4 class="attribute-name box-title" title="{{ localize 'OSE.scores.con.long' }}">{{ localize "OSE.scores.con.short" }}</h4>
<div class="attribute-value">
<input name="data.scores.con.value" type="text" value="{{data.scores.con.value}}" placeholder="0" data-dtype="Number"/>
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.scores.cha.short" }}</h4>
<h4 class="attribute-name box-title" title="{{ localize 'OSE.scores.cha.long' }}">{{ localize "OSE.scores.cha.short" }}</h4>
<div class="attribute-value">
<input name="data.scores.cha.value" type="text" value="{{data.scores.cha.value}}" placeholder="0" data-dtype="Number"/>
</li>
</ul>
</div>
{{!-- Skills and abilities --}}
<div class="flex3 panel abilities">
<h4 class="panel-title">{{localize 'OSE.panel.abilities'}}</h4>
<ul class="panel-content inventory">
<div class="flex3 panel abilities resizable" data-base-size="250">
<div class="panel-title">
<h4>{{localize 'OSE.panel.abilities'}}</h4>
<div class="item-controls">
{{#if owner}}
<a class="item-control item-create" title='{{localize "OSE.Add"}}' data-type="ability"><i class="fas fa-plus"></i></a>
{{/if}}
</div>
</div>
<ul class="panel-content inventory resizable" data-base-size="225">
<div class="">
{{#each abilities as |item|}}
<li class="item-entry">
@ -100,27 +114,31 @@
<div class="attribute-group">
<ul class="attributes">
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.saves.death.short" }}</h4>
<h4 class="attribute-name box-title" title="{{ localize 'OSE.saves.death.long' }}">{{ localize "OSE.saves.death.short" }}</h4>
<div class="attribute-value">
<input name="data.saves.d.value" type="text" value="{{data.saves.d.value}}" placeholder="0" data-dtype="Number"/>
<input name="data.saves.d.value" type="text" value="{{data.saves.d.value}}" placeholder="0"
data-dtype="Number" />
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.saves.wands.short" }}</h4>
<h4 class="attribute-name box-title" title="{{ localize 'OSE.saves.wands.long' }}">{{ localize "OSE.saves.wands.short" }}</h4>
<div class="attribute-value">
<input name="data.saves.w.value" type="text" value="{{data.saves.w.value}}" placeholder="0" data-dtype="Number" />
<input name="data.saves.w.value" type="text" value="{{data.saves.w.value}}" placeholder="0"
data-dtype="Number" />
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.saves.paralysis.short" }}</h4>
<h4 class="attribute-name box-title" title="{{ localize 'OSE.saves.paralysis.long' }}">{{ localize "OSE.saves.paralysis.short" }}</h4>
<div class="attribute-value">
<input name="data.saves.p.value" type="text" value="{{data.saves.p.value}}" placeholder="0" data-dtype="Number" />
<input name="data.saves.p.value" type="text" value="{{data.saves.p.value}}" placeholder="0"
data-dtype="Number" />
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.saves.breath.short" }}</h4>
<h4 class="attribute-name box-title" title="{{ localize 'OSE.saves.breath.long' }}">{{ localize "OSE.saves.breath.short" }}</h4>
<div class="attribute-value">
<input name="data.saves.b.value" type="text" value="{{data.saves.b.value}}" placeholder="0" data-dtype="Number" />
<input name="data.saves.b.value" type="text" value="{{data.saves.b.value}}" placeholder="0"
data-dtype="Number" />
</li>
<li class="attribute">
<h4 class="attribute-name box-title">{{ localize "OSE.saves.spells.short" }}</h4>
<h4 class="attribute-name box-title" title="{{ localize 'OSE.saves.spells.long' }}">{{ localize "OSE.saves.spells.short" }}</h4>
<div class="attribute-value">
<input name="data.saves.s.value" type="text" value="{{data.saves.s.value}}" placeholder="0" />
</li>

View File

@ -1,4 +1,4 @@
<section class="inventory">
<section class="inventory resizable" data-base-size="320">
<div class="">
{{#each inventory as |item|}}
<li class="item-entry">

View File

@ -57,8 +57,13 @@
<section class="panel inventory">
<div class="panel-title">
<h4>{{localize 'OSE.category.spells'}}</h4>
<div class="item-controls">
{{#if owner}}
<a class="item-control item-create" title='{{localize "OSE.Add"}}' data-type="spell"><i class="fas fa-plus"></i></a>
{{/if}}
</div>
</div>
<div class="panel-content">
<div class="panel-content resizable" data-base-size="230">
{{#each spells as |item|}}
<li class="item-entry">
<div class="item flexrow" data-item-id="{{item._id}}">

View File

@ -0,0 +1,146 @@
<section class="flexrow">
<ul class="attributes flexrow">
<li class="attribute health">
<h4 class="attribute-name box-title" title="{{localize 'OSE.Health'}}">{{ localize "OSE.HealthShort" }}</h4>
<div class="attribute-value multiple">
<input name="data.hp.value" type="text" value="{{data.hp.value}}" data-dtype="Number"
placeholder="10" />
<span class="sep"> / </span>
<input name="data.hp.max" type="text" value="{{data.hp.max}}" data-dtype="Number" placeholder="10" />
</div>
</li>
<li class="attribute">
<h4 class="attribute-name box-title" title="{{localize 'OSE.ArmorClass'}}">{{ localize "OSE.ArmorClassShort" }}</h4>
<div class="attribute-value">
<input name="data.ac.value" type="text" value="{{data.ac.value}}" data-dtype="Number" placeholder="10"
data-dtype="Number" />
</div>
</li>
<li class="attribute">
<h4 class="attribute-name box-title" title="{{localize 'OSE.Thac0'}}">{{ localize "OSE.Thac0" }}</h4>
<div class="attribute-value">
<input name="data.thac0.value" type="text" value="{{data.thac0.value}}" placeholder="0"
data-dtype="Number" />
</div>
</li>
<li class="attribute">
<h4 class="attribute-name box-title" title="{{localize 'OSE.Attacks'}}">{{ localize "OSE.AttacksShort" }}</h4>
<div class="attribute-value">
<input name="data.att.value" type="text" value="{{data.att.value}}" placeholder="0"
data-dtype="Number" />
</div>
</li>
<li class="attribute">
<h4 class="attribute-name box-title" title="{{localize 'OSE.Movement'}}">{{ localize "OSE.MovementShort" }}</h4>
<div class="attribute-value">
<input name="data.movement.value" type="text" value="{{data.movement.value}}" placeholder="0"
data-dtype="Number" />
</div>
</li>
</section>
<section class="flexrow attribute-row">
{{!-- Skills and abilities --}}
<div class="flex3 panel abilities">
<div class="panel-title">
<h4>{{localize 'OSE.panel.abilities'}}</h4>
<div class="item-controls">
{{#if owner}}
<a class="item-control item-create" title='{{localize "OSE.Add"}}' data-type="ability"><i class="fas fa-plus"></i></a>
{{/if}}
</div>
</div>
<ul class="panel-content inventory resizable" data-base-size="220">
<div class="">
{{#each abilities as |item|}}
<li class="item-entry">
<div class="item flexrow" data-item-id="{{item._id}}">
<div class="item-name flexrow">
<div class="item-image" style="background-image: url({{item.img}})"></div>
<h4 title="{{item.name}}">
{{item.name~}}
</h4>
</div>
<div class="item-controls">
{{#if ../owner}}
<a class="item-control item-edit" title='{{localize "Ose.Edit"}}'><i
class="fas fa-edit"></i></a>
<a class="item-control item-delete" title='{{localize "Ose.Delete"}}'><i
class="fas fa-trash"></i></a>
{{/if}}
</div>
</div>
</li>
{{/each}}
</div>
</ul>
</div>
{{!-- Equipment --}}
<div class="flex3 panel abilities">
<div class="panel-title">
<h4>{{localize 'OSE.panel.equipment'}}</h4>
<div class="item-controls">
{{#if owner}}
<a class="item-control item-create" title='{{localize "OSE.Add"}}' data-type="item"><i class="fas fa-plus"></i></a>
{{/if}}
</div>
</div>
<ul class="panel-content inventory resizable" data-base-size="220">
<div class="">
{{#each inventory as |item|}}
<li class="item-entry">
<div class="item flexrow" data-item-id="{{item._id}}">
<div class="item-name flexrow">
<div class="item-image" style="background-image: url({{item.img}})"></div>
<h4 title="{{item.name}}">
{{item.name~}}
</h4>
</div>
<div class="item-controls">
{{#if ../owner}}
<a class="item-control item-edit" title='{{localize "Ose.Edit"}}'><i
class="fas fa-edit"></i></a>
<a class="item-control item-delete" title='{{localize "Ose.Delete"}}'><i
class="fas fa-trash"></i></a>
{{/if}}
</div>
</div>
</li>
{{/each}}
</div>
</ul>
</div>
{{!-- Saving throws --}}
<div class="attribute-group">
<ul class="attributes">
<li class="attribute">
<h4 class="attribute-name box-title" title="{{ localize 'OSE.saves.death.long' }}">{{ localize "OSE.saves.death.short" }}</h4>
<div class="attribute-value">
<input name="data.saves.d.value" type="text" value="{{data.saves.d.value}}" placeholder="0"
data-dtype="Number" />
</li>
<li class="attribute">
<h4 class="attribute-name box-title" title="{{ localize 'OSE.saves.wands.long' }}">{{ localize "OSE.saves.wands.short" }}</h4>
<div class="attribute-value">
<input name="data.saves.w.value" type="text" value="{{data.saves.w.value}}" placeholder="0"
data-dtype="Number" />
</li>
<li class="attribute">
<h4 class="attribute-name box-title" title="{{ localize 'OSE.saves.paralysis.long' }}">{{ localize "OSE.saves.paralysis.short" }}</h4>
<div class="attribute-value">
<input name="data.saves.p.value" type="text" value="{{data.saves.p.value}}" placeholder="0"
data-dtype="Number" />
</li>
<li class="attribute">
<h4 class="attribute-name box-title" title="{{ localize 'OSE.saves.breath.long' }}">{{ localize "OSE.saves.breath.short" }}</h4>
<div class="attribute-value">
<input name="data.saves.b.value" type="text" value="{{data.saves.b.value}}" placeholder="0"
data-dtype="Number" />
</li>
<li class="attribute">
<h4 class="attribute-name box-title" title="{{ localize 'OSE.saves.spells.long' }}">{{ localize "OSE.saves.spells.short" }}</h4>
<div class="attribute-value">
<input name="data.saves.s.value" type="text" value="{{data.saves.s.value}}" placeholder="0" />
</li>
</ul>
</div>
</section>

View File

@ -0,0 +1,40 @@
<img class="profile-img" src="{{actor.img}}" data-edit="img" title="{{actor.name}}" />
<section class="header-details flexrow">
<h1 class="charname">
<input name="name" type="text" value="{{actor.name}}" placeholder="{{localize 'OSE.Name'}}" />
</h1>
<ul class="summary flexrow">
<li class="flex2">
<input type="text" name="data.details.alignment" value="{{data.details.alignment}}"
placeholder="{{ localize 'OSE.Alignment' }}" />
<label>{{localize 'OSE.Alignment'}}</label>
</li>
<li class="flex2">
<input type="text" name="data.details.treasure" value="{{data.details.treasure}}"
placeholder="{{ localize 'OSE.Treasure' }}" />
<label>{{localize 'OSE.Treasure'}}</label>
</li>
<li>
<input type="text" name="data.details.appearing" value="{{data.details.appearing}}"
placeholder="{{ localize 'OSE.Appearing' }}" />
<label>{{localize 'OSE.Appearing'}}</label>
</li>
</ul>
<ul class="summary flexrow">
<li class="flex2">
<input type="text" name="data.details.size" value="{{data.details.size}}"
placeholder="{{ localize 'OSE.Size' }}" />
<label>{{localize 'OSE.Size'}}</label>
</li>
<li class="flex2">
<input type="text" name="data.details.xp" value="{{data.details.xp}}"
placeholder="{{ localize 'OSE.Experience' }}" />
<label>{{localize 'OSE.Experience'}}</label>
</li>
<li>
<input type="text" name="data.details.morale" value="{{data.details.morale}}"
placeholder="{{ localize 'OSE.Morale' }}" />
<label>{{localize 'OSE.Morale'}}</label>
</li>
</ul>
</section>