Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89d9d71395 | ||
|
|
1e298ed809 | ||
|
|
4ffaebf52b | ||
|
|
de7691c4dc | ||
|
|
c87b25fbaf | ||
|
|
6ce51ed8cf | ||
|
|
df852f17d1 | ||
|
|
8916600bf6 | ||
|
|
0189f62734 |
@@ -19,6 +19,9 @@ foundry
|
||||
# Ancien dossier SCSS (archivé)
|
||||
scss_old/
|
||||
|
||||
# Outils d'audit local
|
||||
.swival/
|
||||
|
||||
# Fichiers CSS générés
|
||||
css/vermine2047.*.css
|
||||
!css/vermine2047.css
|
||||
|
||||
+10
-3
@@ -31,7 +31,7 @@
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.char-name-value {
|
||||
font-size: 1.5rem;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
input:not([type="radio"]):not([type="checkbox"]) {
|
||||
font-size: 1rem;
|
||||
@@ -291,7 +291,7 @@
|
||||
|
||||
.chooseTotem {
|
||||
font-family: "DistressBlack", sans-serif;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.8rem;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
@@ -377,7 +377,7 @@
|
||||
}
|
||||
|
||||
.char-vermine2047 {
|
||||
font-size: 1.5rem;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,6 +409,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
// ── Onglet Histoire : doubler la hauteur des zones Notes et Relations ──
|
||||
.tab.stories {
|
||||
prose-mirror.editor {
|
||||
min-height: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
nav.tabs[data-group="sheet"] {
|
||||
display: inline-flex;
|
||||
justify-content: space-around;
|
||||
|
||||
+18
-3
@@ -20,16 +20,25 @@
|
||||
|
||||
div.minor-totems {
|
||||
position: relative;
|
||||
height: 8.5rem;
|
||||
background-color: rgba(146, 156, 111, 0.5215686275);
|
||||
|
||||
h3 {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
h5 {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
top: 2.6rem;
|
||||
margin: 0;
|
||||
z-index: 1;
|
||||
|
||||
img {
|
||||
max-width: 2rem;
|
||||
position: absolute;
|
||||
bottom: -2rem;
|
||||
top: 1.4rem;
|
||||
bottom: auto;
|
||||
}
|
||||
|
||||
&.human, &.adapted {
|
||||
@@ -53,6 +62,12 @@
|
||||
}
|
||||
|
||||
.totem-dice {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
|
||||
.human-dice,
|
||||
.adapted-dice {
|
||||
display: flex;
|
||||
@@ -90,7 +105,7 @@
|
||||
|
||||
.adapted {
|
||||
right: 0;
|
||||
img { right: 0; }
|
||||
img { right: 0; left: auto; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,6 +230,17 @@ export default class VermineBaseActorSheet extends HandlebarsApplicationMixin(fo
|
||||
const id = target.closest("[data-item-id]")?.dataset?.itemId
|
||||
if (!id) return
|
||||
const item = this.document.items.get(id)
|
||||
if (!item) return
|
||||
if (item.type === "weapon" && this.document.system.abilities && this.document.system.skills) {
|
||||
const { default: RollDialog } = await import("../../system/dialogs/rollDialog.mjs")
|
||||
const dialog = await RollDialog.create({
|
||||
actorId: this.document.id,
|
||||
rolltype: "skill",
|
||||
label: item.system.skill
|
||||
})
|
||||
if (dialog) dialog.render(true)
|
||||
return
|
||||
}
|
||||
item?.roll()
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ export class VermineBaseItemSheet extends HandlebarsApplicationMixin(foundry.app
|
||||
// ── Rendu ───────────────────────────────────────────────────────────
|
||||
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options);
|
||||
this.#dragDrop.forEach(d => d.bind(this.element))
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ export default class VermineItem extends Item {
|
||||
*/
|
||||
getRollData() {
|
||||
// If present, return the actor's roll data.
|
||||
if (!this.actor) return null;
|
||||
if (!this.actor) return this.system;
|
||||
const rollData = this.actor.getRollData();
|
||||
// Grab the item's system data as well.
|
||||
rollData.item = foundry.utils.deepClone(this.system);
|
||||
|
||||
@@ -14,6 +14,7 @@ export default class VermineWeaponData extends foundry.abstract.TypeDataModel {
|
||||
const reqInt = { required: true, nullable: false, integer: true }
|
||||
return {
|
||||
...baseItemSchema(),
|
||||
skill: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
min_range: new fields.NumberField({ ...reqInt, initial: 0, min: 0 }),
|
||||
max_range: new fields.NumberField({ ...reqInt, initial: 0, min: 0 }),
|
||||
damage: new fields.SchemaField({
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api
|
||||
|
||||
export class TotemPicker extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
|
||||
constructor(linkEl, actor) {
|
||||
@@ -24,9 +26,9 @@ export class TotemPicker extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
return { config: CONFIG.VERMINE };
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
html.querySelectorAll('.totem').forEach(el => {
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options);
|
||||
this.element.querySelectorAll('.totem').forEach(el => {
|
||||
el.addEventListener('click', event => {
|
||||
const link = event.target.closest('a');
|
||||
if (!link?.dataset.totem) return;
|
||||
@@ -80,9 +82,9 @@ export class ActorPicker extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
};
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
html.querySelectorAll('.actor').forEach(el => {
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options);
|
||||
this.element.querySelectorAll('.actor').forEach(el => {
|
||||
el.addEventListener('click', async event => {
|
||||
const div = event.target.closest('div');
|
||||
const actorId = div?.dataset.actorId;
|
||||
@@ -148,15 +150,15 @@ export class TraitSelector extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
};
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
this._validateTraits(html);
|
||||
html.querySelectorAll('input').forEach(el => {
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options);
|
||||
this._validateTraits(this.element);
|
||||
this.element.querySelectorAll('input').forEach(el => {
|
||||
el.addEventListener('change', ev => this._onChangeInput(ev));
|
||||
});
|
||||
}
|
||||
|
||||
async _validateTraits(html) {
|
||||
_validateTraits(html) {
|
||||
const checks = html.querySelectorAll("input.trait-selector");
|
||||
for (const inp of checks) {
|
||||
if (this.targetItem.system.traits[inp.dataset.trait]) {
|
||||
@@ -165,7 +167,6 @@ export class TraitSelector extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
}
|
||||
}
|
||||
}
|
||||
await this.render(true);
|
||||
}
|
||||
|
||||
async _onChangeInput(ev) {
|
||||
|
||||
@@ -121,7 +121,8 @@ export default class RollDialog extends HandlebarsApplicationMixin(foundry.appli
|
||||
const specChecked = this.#el.querySelector("#usingSpecialization")?.checked;
|
||||
const helped = this.#el.querySelector("#helped")?.checked;
|
||||
const tools = this.#el.querySelector("input[name='usingTools']:checked")?.value !== "0";
|
||||
const bonuses = (specChecked ? 1 : 0) + (helped ? 1 : 0) + (tools ? 1 : 0);
|
||||
const group = parseInt(this.#el.querySelector("#group")?.value, 10) || 0;
|
||||
const bonuses = (specChecked ? 1 : 0) + (helped ? 1 : 0) + (tools ? 1 : 0) + group;
|
||||
return (abilVal + sc + skillPool + bonuses) || 0;
|
||||
}
|
||||
|
||||
@@ -212,10 +213,6 @@ export default class RollDialog extends HandlebarsApplicationMixin(foundry.appli
|
||||
b += parseInt(this.#getSelfCtrl()?.value, 10) || 0;
|
||||
const tools = this.#el.querySelector("input[name='usingTools']:checked");
|
||||
if (tools && tools.value !== "0") b += 1;
|
||||
const human = this.#el.querySelector("#human-totem");
|
||||
if (human?.checked) b += parseInt(this.#actor?.system?.adaptation?.totems?.human?.value, 10) || 0;
|
||||
const adapted = this.#el.querySelector("#adapted-totem");
|
||||
if (adapted?.checked) b += parseInt(this.#actor?.system?.adaptation?.totems?.adapted?.value, 10) || 0;
|
||||
if (this.hasSpecialtySelected()) b += 1;
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ export function prepareActiveEffectCategories(effects) {
|
||||
|
||||
// Iterate over active effects, classifying them into categories
|
||||
for ( let e of effects ) {
|
||||
e._getSourceName(); // Trigger a lookup for the source name
|
||||
if ( e.disabled ) categories.inactive.effects.push(e);
|
||||
else if ( e.isTemporary ) categories.temporary.effects.push(e);
|
||||
else categories.passive.effects.push(e);
|
||||
|
||||
+64
-15
@@ -184,10 +184,9 @@ export class VermineCombat extends Combat {
|
||||
// encounter check
|
||||
}
|
||||
|
||||
async rollInitiative(ids, formula = undefined, messageOptions = {}) {
|
||||
async rollInitiative(ids, {formula=null, updateTurn=true, messageMode, messageOptions={}}={}) {
|
||||
// roll initiative
|
||||
return super.rollInitiative(ids, formula, messageOptions)
|
||||
|
||||
return super.rollInitiative(ids, {formula, updateTurn, messageMode, messageOptions});
|
||||
}
|
||||
|
||||
nextRound() {
|
||||
@@ -224,24 +223,74 @@ export class VermineCombat extends Combat {
|
||||
|
||||
export class VermineCombatTracker extends foundry.applications.sidebar.tabs.CombatTracker {
|
||||
|
||||
get template() {
|
||||
return "systems/vermine2047/templates/combat-tracker.hbs";
|
||||
}
|
||||
|
||||
async getData(options) {
|
||||
const context = await super.getData(options);
|
||||
|
||||
if (!context.hasCombat) {
|
||||
return context;
|
||||
/** @override */
|
||||
static PARTS = {
|
||||
main: {
|
||||
template: "systems/vermine2047/templates/combat-tracker.hbs",
|
||||
root: true
|
||||
}
|
||||
};
|
||||
|
||||
/** @override */
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
context.user = game.user;
|
||||
|
||||
const combat = this.viewed;
|
||||
const hasCombat = combat !== null;
|
||||
const combats = this.combats;
|
||||
const currentIdx = combats.indexOf(combat);
|
||||
const isPlayerTurn = combat?.combatant?.players?.includes(game.user);
|
||||
const canControl = combat?.turn && combat.turn.between(1, combat.turns.length - 2)
|
||||
? combat.canUserModify(game.user, "update", { turn: 0 })
|
||||
: combat?.canUserModify(game.user, "update", { round: 0 });
|
||||
|
||||
Object.assign(context, {
|
||||
combat,
|
||||
hasCombat,
|
||||
combatCount: combats.length,
|
||||
currentIndex: currentIdx + 1,
|
||||
previousId: combats[currentIdx - 1]?.id,
|
||||
nextId: combats[currentIdx + 1]?.id,
|
||||
round: combat?.round,
|
||||
control: isPlayerTurn && canControl,
|
||||
linked: combat?.scene !== null,
|
||||
cssClass: combats.length > 7 ? "cycle" : combats.length ? "tabbed" : "",
|
||||
cssId: "combat",
|
||||
tabName: "combat",
|
||||
labels: {
|
||||
scope: game.i18n.localize(`COMBAT.${combat?.scene ? "Linked" : "Unlinked"}`)
|
||||
},
|
||||
turns: []
|
||||
});
|
||||
|
||||
if ( combat ) {
|
||||
for ( const [i, combatant] of combat.turns.entries() ) {
|
||||
if ( !combatant.visible ) continue;
|
||||
context.turns.push(await this._prepareTurnContext(combat, combatant, i));
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
html.querySelectorAll("[data-attitude]").forEach(el => {
|
||||
/** @override */
|
||||
async _prepareTurnContext(combat, combatant, index) {
|
||||
const turn = await super._prepareTurnContext(combat, combatant, index);
|
||||
const actor = combatant.actor;
|
||||
turn.attitude = combatant.getFlag("world", "attitude") || "active";
|
||||
turn.isPlayer = actor?.hasPlayerOwner ?? false;
|
||||
turn.isNpc = !!actor && !actor.hasPlayerOwner;
|
||||
turn.owner = combatant.isOwner;
|
||||
turn.defeated = combatant.isDefeated;
|
||||
turn.hasRolled = combatant.initiative !== null;
|
||||
turn.hasResource = combatant.resource !== null && combatant.resource !== undefined;
|
||||
turn.effects = (turn.effects?.icons ?? []).map(e => e.img);
|
||||
return turn;
|
||||
}
|
||||
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options);
|
||||
this.element.querySelectorAll("[data-attitude]").forEach(el => {
|
||||
el.addEventListener("click", this._setStatut.bind(this));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -388,4 +388,15 @@ export const registerHandlebarsHelpers = function () {
|
||||
Handlebars.registerHelper("setVar", function (varName, varValue, options) {
|
||||
options.data.root[varName] = varValue;
|
||||
});
|
||||
|
||||
// assign local variables in the current context (used by roll-message.hbs)
|
||||
Handlebars.registerHelper("set", function (options) {
|
||||
const ctx = (this && typeof this === "object") ? this : options.contexts?.[0];
|
||||
if ( ctx && typeof ctx === "object" ) {
|
||||
for ( const [key, value] of Object.entries(options.hash) ) {
|
||||
ctx[key] = value;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
});
|
||||
}
|
||||
@@ -69,8 +69,8 @@ export const registerHooks = function () {
|
||||
});
|
||||
|
||||
// changement de la pause
|
||||
Hooks.on("renderPause", async function () {
|
||||
const pauseEl = document.getElementById("pause");
|
||||
Hooks.on("renderGamePause", async function (app, element) {
|
||||
const pauseEl = element ?? document.getElementById("pause");
|
||||
if (!pauseEl || pauseEl.className !== "paused") return;
|
||||
pauseEl.querySelectorAll("img").forEach(img => {
|
||||
img.src = 'systems/vermine2047/assets/images/ui/vermine_pause.webp';
|
||||
@@ -94,17 +94,17 @@ export const registerHooks = function () {
|
||||
});
|
||||
|
||||
Hooks.on('getSceneControlButtons', async (controls) => {
|
||||
const tokenControls = controls.token;
|
||||
const tokenControls = controls.tokens;
|
||||
if (tokenControls && tokenControls.tools) {
|
||||
tokenControls.tools.push({
|
||||
tokenControls.tools['dice-roller'] = {
|
||||
name: 'Dice Roller',
|
||||
title: game.i18n.localize("VERMINE.RollTool"),
|
||||
icon: 'fas fa-dice-d10',
|
||||
button: true,
|
||||
onClick() {
|
||||
onChange() {
|
||||
RollDialog.create().then(d => d.render(true));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+8
-76
@@ -49,22 +49,13 @@ export class VermineUtils {
|
||||
totemBonus = this._calculateTotemDomainBonuses(skillCategory, actor);
|
||||
}
|
||||
|
||||
// Apply auto-successes and auto-thresholds
|
||||
let autoSuccesses = 0;
|
||||
// Apply automatic successes from skill mastery
|
||||
let adjustedDifficulty = difficulty;
|
||||
|
||||
if (skillLevel !== null && skillLevel !== undefined) {
|
||||
autoSuccesses = this._calculateAutoSuccesses(skillLevel, hasSpecialty);
|
||||
const autoThreshold = this._getAutoThreshold(skillLevel);
|
||||
if (autoThreshold !== null) {
|
||||
adjustedDifficulty = autoThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle human totem
|
||||
if (totems.human) {
|
||||
NoD--;
|
||||
const humanDifficulty = skillLevel !== null ? Math.max(adjustedDifficulty, difficulty) : adjustedDifficulty;
|
||||
const humanDifficulty = adjustedDifficulty;
|
||||
const humanFormula = `(1D10cs>=${humanDifficulty}[human_${safeUserName}]*2)`;
|
||||
|
||||
// Apply domain bonus/malus
|
||||
@@ -78,7 +69,7 @@ export class VermineUtils {
|
||||
// Handle adapted totem
|
||||
if (totems.adapted) {
|
||||
NoD--;
|
||||
const adaptedDifficulty = skillLevel !== null ? Math.max(adjustedDifficulty, difficulty) : adjustedDifficulty;
|
||||
const adaptedDifficulty = adjustedDifficulty;
|
||||
const adaptedFormula = `(1D10cs>=${adaptedDifficulty}[adapted_${safeUserName}]*2)`;
|
||||
|
||||
// Apply domain bonus/malus
|
||||
@@ -105,8 +96,8 @@ export class VermineUtils {
|
||||
}
|
||||
}
|
||||
|
||||
// Apply handicap (wounds/maluses reduce dice pool)
|
||||
NoD = Math.max(1, NoD - handicap)
|
||||
// Ensure the dice pool cannot go below zero
|
||||
NoD = Math.max(0, NoD)
|
||||
|
||||
// Build base formula
|
||||
const baseFormula = `${NoD}d10cs>=${adjustedDifficulty}[regular_${safeUserName}]`;
|
||||
@@ -126,7 +117,6 @@ export class VermineUtils {
|
||||
skillCategory: skillCategory,
|
||||
skillLevel: skillLevel,
|
||||
hasSpecialty: hasSpecialty,
|
||||
autoSuccesses: autoSuccesses,
|
||||
totemBonuses: { ...totemBonus },
|
||||
baseNoD: NoD,
|
||||
rerolls: Reroll,
|
||||
@@ -152,7 +142,8 @@ export class VermineUtils {
|
||||
skillCategory,
|
||||
keepTotem,
|
||||
skillLevel,
|
||||
hasSpecialty
|
||||
hasSpecialty,
|
||||
handicap
|
||||
});
|
||||
|
||||
return roll;
|
||||
@@ -205,63 +196,6 @@ export class VermineUtils {
|
||||
return bonuses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates automatic successes based on skill mastery level.
|
||||
* @param {number} skillLevel - Skill level (0-5)
|
||||
* @param {boolean} [hasSpecialty=false] - Whether a specialty is used
|
||||
* @returns {number} Number of automatic successes
|
||||
*/
|
||||
static _calculateAutoSuccesses(skillLevel, hasSpecialty = false) {
|
||||
// According to Vermine2047 rules, automatic successes are based on mastery level:
|
||||
// Level 0 (Incompetent): 0 automatic successes
|
||||
// Level 1 (Beginner): 0 automatic successes
|
||||
// Level 2 (Proficient): 1 automatic success if specialty is used
|
||||
// Level 3 (Expert): 1 automatic success
|
||||
// Level 4 (Master): 1 automatic success + 1 if specialty is used
|
||||
// Level 5 (Legend): 2 automatic successes
|
||||
|
||||
if (!skillLevel) return 0;
|
||||
|
||||
let autoSuccesses = 0;
|
||||
|
||||
switch (skillLevel) {
|
||||
case 2: // Compétent
|
||||
if (hasSpecialty) autoSuccesses = 1;
|
||||
break;
|
||||
case 3: // Expert
|
||||
autoSuccesses = 1;
|
||||
break;
|
||||
case 4: // Maître
|
||||
autoSuccesses = 1;
|
||||
if (hasSpecialty) autoSuccesses += 1;
|
||||
break;
|
||||
case 5: // Légende
|
||||
autoSuccesses = 2;
|
||||
break;
|
||||
default:
|
||||
autoSuccesses = 0;
|
||||
}
|
||||
|
||||
return autoSuccesses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the automatic threshold if the skill is not mastered.
|
||||
* @param {number} skillLevel - Skill level
|
||||
* @returns {number|null} Automatic threshold or null if skill is mastered
|
||||
*/
|
||||
static _getAutoThreshold(skillLevel) {
|
||||
// If the skill is not mastered (level 0 or 1), use a default threshold
|
||||
// Level 0 (Incompetent): threshold = 9 (very hard)
|
||||
// Level 1 (Beginner): threshold = 7 (hard)
|
||||
// Level >= 2: null (use normal threshold)
|
||||
|
||||
if (skillLevel === 0) return 9; // Very hard
|
||||
if (skillLevel === 1) return 7; // Hard
|
||||
|
||||
return null; // Utiliser le seuil normal
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles reroll events on dice in chat messages.
|
||||
* @param {Object} message - The chat message containing the reroll event
|
||||
@@ -471,11 +405,9 @@ export class VermineUtils {
|
||||
const chatData = {
|
||||
user: game.user?._id,
|
||||
speaker: ChatMessage.getSpeaker(),
|
||||
content: content,
|
||||
roll: roll
|
||||
content: content
|
||||
};
|
||||
const msg = await ChatMessage.create(chatData);
|
||||
await msg.setFlag('world', 'roll', roll);
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ Hooks.once('init', async function () {
|
||||
|
||||
// Register sheet application classes (ApplicationV2)
|
||||
// Unregister core sheets
|
||||
foundry.applications.sheets.ActorSheetV2?.unregisterSheet?.("core", "Actor", {
|
||||
foundry.documents.collections.Actors.unregisterSheet("core", foundry.applications.sheets.ActorSheetV2, {
|
||||
types: ["character", "npc", "group", "creature"]
|
||||
})
|
||||
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1?.sheets?.ItemSheet)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
{{!-- Logo --}}
|
||||
<img class="logo mx-auto" src="systems/vermine2047/assets/images/ui/logo.webp"
|
||||
width="200" alt="logo Vermine" />
|
||||
width="150" alt="logo Vermine" />
|
||||
|
||||
{{!-- Sidebar: Profile Image + Totem Dice --}}
|
||||
<div class="image-wrapper">
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</a>
|
||||
{{/if}}
|
||||
<a class="combat-button combat-control" data-tooltip="COMBAT.Delete"
|
||||
data-control="endCombat" {{#unless
|
||||
data-action="endCombat" {{#unless
|
||||
combatCount}}disabled{{/unless}}>
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
@@ -33,12 +33,12 @@
|
||||
<div class="encounter-controls flexrow {{#if hasCombat}}combat{{/if}}">
|
||||
{{#if user.isGM}}
|
||||
<a class="combat-button combat-control"
|
||||
data-tooltip="COMBAT.RollAll" data-control="rollAll" {{#unless
|
||||
data-tooltip="COMBAT.RollAll" data-action="rollAll" {{#unless
|
||||
turns}}disabled{{/unless}}>
|
||||
<i class="fas fa-users"></i>
|
||||
</a>
|
||||
<a class="combat-button combat-control"
|
||||
data-tooltip="COMBAT.RollNPC" data-control="rollNPC" {{#unless
|
||||
data-tooltip="COMBAT.RollNPC" data-action="rollNPC" {{#unless
|
||||
turns}}disabled{{/unless}}>
|
||||
<i class="fas fa-users-cog"></i>
|
||||
</a>
|
||||
@@ -58,18 +58,18 @@
|
||||
|
||||
{{#if user.isGM}}
|
||||
<a class="combat-button combat-control"
|
||||
data-tooltip="COMBAT.InitiativeReset" data-control="resetAll"
|
||||
data-tooltip="COMBAT.InitiativeReset" data-action="resetAll"
|
||||
{{#unless hasCombat}}disabled{{/unless}}>
|
||||
<i class="fas fa-undo"></i>
|
||||
</a>
|
||||
<a class="combat-button combat-control"
|
||||
data-tooltip="{{labels.scope}}"
|
||||
data-control="toggleSceneLink" {{#unless
|
||||
data-action="toggleSceneLink" {{#unless
|
||||
hasCombat}}disabled{{/unless}}>
|
||||
<i class="fas fa-{{#unless linked}}un{{/unless}}link"></i>
|
||||
</a>
|
||||
<a class="combat-button combat-settings"
|
||||
data-tooltip="COMBAT.Settings" data-control="trackerSettings">
|
||||
data-tooltip="COMBAT.Settings" data-action="trackerSettings">
|
||||
<i class="fas fa-cog"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
@@ -90,20 +90,20 @@
|
||||
<a
|
||||
class="combatant-control {{#if turn.hidden}}active{{/if}}"
|
||||
data-tooltip="COMBAT.ToggleVis"
|
||||
data-control="toggleHidden">
|
||||
data-action="toggleHidden">
|
||||
<i class="fas fa-eye-slash"></i>
|
||||
</a>
|
||||
<a
|
||||
class="combatant-control {{#if turn.defeated}}active{{/if}}"
|
||||
data-tooltip="COMBAT.ToggleDead"
|
||||
data-control="toggleDefeated">
|
||||
data-action="toggleDefeated">
|
||||
<i class="fas fa-skull"></i>
|
||||
</a>
|
||||
|
||||
{{#if turn.canPing}}
|
||||
<a class="combatant-control"
|
||||
data-tooltip="COMBAT.PingCombatant"
|
||||
data-control="alertPingCombatant">
|
||||
data-action="pingCombatant">
|
||||
<i class="fa-solid fa-bullseye-arrow"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
@@ -158,7 +158,7 @@
|
||||
{{else if this.owner}}
|
||||
<a class="combatant-control roll"
|
||||
data-tooltip="COMBAT.InitiativeRoll"
|
||||
data-control="rollInitiative"></a>
|
||||
data-action="rollInitiative"></a>
|
||||
{{/if}}
|
||||
</div>
|
||||
</li>
|
||||
@@ -171,30 +171,30 @@
|
||||
{{#if user.isGM}}
|
||||
{{#if round}}
|
||||
<a class="combat-control" data-tooltip="COMBAT.RoundPrev"
|
||||
data-control="previousRound"><i
|
||||
data-action="previousRound"><i
|
||||
class="fas fa-step-backward"></i></a>
|
||||
<a class="combat-control" data-tooltip="COMBAT.TurnPrev"
|
||||
data-control="previousTurn"><i
|
||||
data-action="previousTurn"><i
|
||||
class="fas fa-arrow-left"></i></a>
|
||||
<a class="combat-control center" data-control="endCombat">{{localize
|
||||
<a class="combat-control center" data-action="endCombat">{{localize
|
||||
'COMBAT.End'}}</a>
|
||||
<a class="combat-control" data-tooltip="COMBAT.TurnNext"
|
||||
data-control="nextTurn"><i class="fas fa-arrow-right"></i></a>
|
||||
data-action="nextTurn"><i class="fas fa-arrow-right"></i></a>
|
||||
<a class="combat-control" data-tooltip="COMBAT.RoundNext"
|
||||
data-control="nextRound"><i class="fas fa-step-forward"></i></a>
|
||||
data-action="nextRound"><i class="fas fa-step-forward"></i></a>
|
||||
{{else}}
|
||||
<a class="combat-control center"
|
||||
data-control="startCombat">{{localize
|
||||
data-action="startCombat">{{localize
|
||||
'COMBAT.Begin'}}</a>
|
||||
{{/if}}
|
||||
{{else if control}}
|
||||
<a class="combat-control" data-tooltip="COMBAT.TurnPrev"
|
||||
data-control="previousTurn"><i
|
||||
data-action="previousTurn"><i
|
||||
class="fas fa-arrow-left"></i></a>
|
||||
<a class="combat-control center" data-control="nextTurn">{{localize
|
||||
<a class="combat-control center" data-action="nextTurn">{{localize
|
||||
'COMBAT.TurnEnd'}}</a>
|
||||
<a class="combat-control" data-tooltip="COMBAT.TurnNext"
|
||||
data-control="nextTurn"><i class="fas fa-arrow-right"></i></a>
|
||||
data-action="nextTurn"><i class="fas fa-arrow-right"></i></a>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</nav>
|
||||
|
||||
@@ -280,7 +280,7 @@
|
||||
class="totem-checkbox"
|
||||
/>
|
||||
<span class="totem-label">{{localize 'TOTEMS.human.name'}}</span>
|
||||
<small>(+{{@root.actor.system.adaptation.totems.human.value}}D)</small>
|
||||
<small>({{@root.actor.system.adaptation.totems.human.value}}D)</small>
|
||||
</label>
|
||||
<label class="totem-option">
|
||||
<input
|
||||
@@ -292,7 +292,7 @@
|
||||
class="totem-checkbox"
|
||||
/>
|
||||
<span class="totem-label">{{localize 'TOTEMS.adapted.name'}}</span>
|
||||
<small>(+{{@root.actor.system.adaptation.totems.adapted.value}}D)</small>
|
||||
<small>({{@root.actor.system.adaptation.totems.adapted.value}}D)</small>
|
||||
</label>
|
||||
</div>
|
||||
<small class="totem-hint">{{localize 'VERMINE.totem_hint'}}</small>
|
||||
@@ -309,7 +309,7 @@
|
||||
value="1"
|
||||
/>
|
||||
<span class="totem-label">{{localize 'TOTEMS.human.name'}}</span>
|
||||
<small>(+{{@root.actor.system.adaptation.totems.human.value}}D)</small>
|
||||
<small>({{@root.actor.system.adaptation.totems.human.value}}D)</small>
|
||||
</label>
|
||||
</div>
|
||||
{{/ifgt}}
|
||||
@@ -326,7 +326,7 @@
|
||||
value="1"
|
||||
/>
|
||||
<span class="totem-label">{{localize 'TOTEMS.adapted.name'}}</span>
|
||||
<small>(+{{@root.actor.system.adaptation.totems.adapted.value}}D)</small>
|
||||
<small>({{@root.actor.system.adaptation.totems.adapted.value}}D)</small>
|
||||
</label>
|
||||
</div>
|
||||
{{/ifgt}}
|
||||
|
||||
@@ -3,6 +3,29 @@
|
||||
|
||||
|
||||
<section class="sheet-body">
|
||||
<div class="flexrow">
|
||||
<label class="resource-label" for="system.skill">{{ localize 'VERMINE.skill_title'}}</label>
|
||||
<select
|
||||
name="system.skill"
|
||||
class="skill-select"
|
||||
>
|
||||
{{#each @root.config.skillCategories as |skillCategory sckey|}}
|
||||
<optgroup label="{{ smarttlk 'SKILLS_CATEGORIES' sckey 'name' }}">
|
||||
{{#each @root.config.skills as |skill key|}}
|
||||
{{#ife skill.category sckey}}
|
||||
<option
|
||||
value="{{key}}"
|
||||
{{#ife key @root.system.skill}}
|
||||
selected
|
||||
{{/ife}}
|
||||
>{{ smarttlk 'SKILLS' key 'name' }}</option>
|
||||
{{/ife}}
|
||||
{{/each}}
|
||||
</optgroup>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{{> "systems/vermine2047/templates/item/partials/traits.hbs"}}
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
</div>
|
||||
<div class="flexcol">
|
||||
<h4>{{localize "VERMINE.success_required"}}:</h4>
|
||||
<span id="required">{{param.handicap}}</span>
|
||||
<span id="required">{{math_add 1 param.handicap}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user