zischenstand
This commit is contained in:
1
src/modules/combat-enhancements/.gitignore
vendored
Normal file
1
src/modules/combat-enhancements/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules
|
||||
1
src/modules/combat-enhancements/.nvmrc
Normal file
1
src/modules/combat-enhancements/.nvmrc
Normal file
@@ -0,0 +1 @@
|
||||
v16.15.0
|
||||
3
src/modules/combat-enhancements/CHANGELOG.txt
Normal file
3
src/modules/combat-enhancements/CHANGELOG.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
# 1.2.4
|
||||
|
||||
- Added support for Foundry v12
|
||||
35
src/modules/combat-enhancements/README.md
Normal file
35
src/modules/combat-enhancements/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Combat Enhancements
|
||||
|
||||
  
|
||||
|
||||
This small module adds a radial health bar, an editable HP field, and drag/drop re-ordering to the combat tracker.
|
||||
|
||||
## Installation
|
||||
|
||||
Install using the module browser in Foundry or via this manifest URL: [https://gitlab.com/asacolips-projects/foundry-mods/combat-enhancements/raw/master/module.json](https://gitlab.com/asacolips-projects/foundry-mods/combat-enhancements/raw/master/module.json)
|
||||
|
||||
## Usage
|
||||
|
||||
### Radial Health Bars
|
||||
|
||||
The radial health bars will appear automatically if you're a GM user. For players, the health bar will only appear if the user is either the owner of the combatant's token or if the token's bar visibility is set to something other than one of the "owner" options.
|
||||
|
||||
The module will attempt to use the `system.attributes.hp` field on the actor, but this can be overridden by changing the attribute associated with Bar 1 in the token settings.
|
||||
|
||||
### Health Modification
|
||||
|
||||
For GM users, all combatants will have an HP input that lets them modify it using absolute numbers or relative numbers (such as `-10` or `+3`).
|
||||
|
||||
Players will only be able to edit HP if they own the combatant's token.
|
||||
|
||||
### Drag/drop Re-ordering
|
||||
|
||||
The module also includes the ability to rearrange combatants by dragging and dropping them. This is handled by setting the combatant being dragged to a new initiative that's the average of the two combatants it's landing in-between. This means that if you're using dexterity tie-breakers, the tiebreaker will become a number much higher than possible dexterity scores due to the average math.
|
||||
|
||||
If you're not using dexterity tie breakers, the module includes an optional setting to reflow combatant initiative if the combatants have identical initiative. For example, if you drop a combatant on top of another combatant that has an initiative of 18 and the combatant after that one has an 18 as well, the combatants will have new initiatives equal to 20, 19, and 18. If this setting isn't enabled, the combatants won't appear to change since the order is initiative followed by the alphabetical name.
|
||||
|
||||
### End of Turn Target Removal
|
||||
|
||||
When enabled, this will remove all targets from all tokens when the turn/round is updated in the combat tracker. Going backwards, forwards, and ending combat will cause all targets to be removed from all tokens. This is system agnostic. Enabling will cause a refresh of all connected clients.
|
||||
|
||||
#### ***Note! This is in direct conflict with other target removal modules like Midi-QoL. For this reason it is off by default.***
|
||||
12
src/modules/combat-enhancements/es-ES
Normal file
12
src/modules/combat-enhancements/es-ES
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"COMBAT_ENHANCEMENTS.setting.reflow.label": "Activar el reajuste de la iniciativa.",
|
||||
"COMBAT_ENHANCEMENTS.setting.reflow.description": "Si las iniciativas son identicas, ajustar el combatiente siendo arrastrado además del combatiente sobre el que se arrastra.",
|
||||
"COMBAT_ENHANCEMENTS.setting.showHpForType.label": "Mostar los PG para actores del tipo.",
|
||||
"COMBAT_ENHANCEMENTS.setting.showHPForType.description": "Usa esto para mostrar siempre el radial de salud en el registro de combate para un tipo de actor específico, como por ejemplo PJs.",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpField.label": "Activar el campo PG",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpField.description": "Activar un campo de salud editable en el registro de combate para los DM y los propietarios de los actores.",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpRadial.label": "Activar el radial de salud",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpRadial.description": "Activa una barra de progreso radial para mostrar la salud del actor en el registro de combate. La visibilidad queda determinada por los ajustas de la visibilidad de la barra 1 de los tokens (Los DMs siempre podrán ver las barras de salud se esta opción está activa).",
|
||||
"COMBAT_ENHANCEMENTS.setting.removeTargets.label": "Permite eliminar objetivos cada turno.",
|
||||
"COMBAT_ENHANCEMENTS.setting.removeTargets.description": "Permite la eliminación de todos los objetivos y objetivos muertos al final de cada turno. Esto se activa cuando se presiona el botón \"Siguiente giro\"."
|
||||
}
|
||||
67
src/modules/combat-enhancements/gulpfile.js
Normal file
67
src/modules/combat-enhancements/gulpfile.js
Normal file
@@ -0,0 +1,67 @@
|
||||
const gulp = require('gulp');
|
||||
const prefix = require('gulp-autoprefixer');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
const sass = require('gulp-sass')(require('sass'));
|
||||
const yaml = require('gulp-yaml');
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* Compile Sass
|
||||
/* ----------------------------------------- */
|
||||
|
||||
// Small error handler helper function.
|
||||
function handleError(err) {
|
||||
console.log(err.toString());
|
||||
this.emit('end');
|
||||
}
|
||||
|
||||
const SYSTEM_SCSS = ["styles/src/**/*.scss"];
|
||||
function compileScss() {
|
||||
// Configure options for sass output. For example, 'expanded' or 'nested'
|
||||
let options = {
|
||||
outputStyle: 'compressed'
|
||||
};
|
||||
return gulp.src(SYSTEM_SCSS)
|
||||
.pipe(
|
||||
sass(options)
|
||||
.on('error', handleError)
|
||||
)
|
||||
.pipe(prefix({
|
||||
cascade: false
|
||||
}))
|
||||
.pipe(gulp.dest("./styles/dist"))
|
||||
}
|
||||
const cssTask = gulp.series(compileScss);
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* Compile YAML
|
||||
/* ----------------------------------------- */
|
||||
const SYSTEM_YAML = ['./yaml/**/*.yml', './yaml/**/*.yaml'];
|
||||
function compileYaml() {
|
||||
return gulp.src(SYSTEM_YAML)
|
||||
.pipe(yaml({ space: 2 }))
|
||||
.pipe(gulp.dest('./'))
|
||||
}
|
||||
const yamlTask = gulp.series(compileYaml);
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* Watch Updates
|
||||
/* ----------------------------------------- */
|
||||
|
||||
function watchUpdates() {
|
||||
gulp.watch(SYSTEM_SCSS, cssTask);
|
||||
gulp.watch(SYSTEM_YAML, yamlTask);
|
||||
// gulp.watch(SYSTEM_SCRIPTS, scripts);
|
||||
}
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* Export Tasks
|
||||
/* ----------------------------------------- */
|
||||
|
||||
exports.default = gulp.series(
|
||||
compileScss,
|
||||
// compileScripts,
|
||||
watchUpdates
|
||||
);
|
||||
exports.css = cssTask;
|
||||
exports.yaml = yamlTask;
|
||||
// exports.scripts = scripts;
|
||||
15
src/modules/combat-enhancements/lang/en.json
Normal file
15
src/modules/combat-enhancements/lang/en.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"COMBAT_ENHANCEMENTS.setting.reflow.label": "Enable initiative reflow",
|
||||
"COMBAT_ENHANCEMENTS.setting.reflow.description": "If initiatives are identical, adjust the combatant being dragged onto in addition to the combatant being dragged.",
|
||||
"COMBAT_ENHANCEMENTS.setting.showHpForType.label": "Show HP for actor type",
|
||||
"COMBAT_ENHANCEMENTS.setting.showHPForType.description": "Use this to always display the radial HP bar in the combat tracker for a specific actor type, such as characters.",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpField.label": "Enable HP field",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpField.description": "Enable an editable HP field in the combat tracker for GMs and actor owners.",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpRadial.label": "Enable HP radial bar",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpRadial.description": "Enables a radial progress bar for HP on the actor portraits in the combat tracker. Visibility is determined by the Bar 1 visibility settings on tokens (GMs can alway see bars if they're enabled here).",
|
||||
"COMBAT_ENHANCEMENTS.setting.removeTargets.label": "Enable target removal every turn",
|
||||
"COMBAT_ENHANCEMENTS.setting.removeTargets.description": "Enables target removal at the end of each turn. This is done by pressing the button 'Next Turn' on the combat tracker.",
|
||||
"COMBAT_ENHANCEMENTS.setting.hideNonAllyInitiative.label": "Hide non-ally initiative",
|
||||
"COMBAT_ENHANCEMENTS.setting.hideNonAllyInitiative.description": "Hide non-ally initiative from players on FVTT combat tracker",
|
||||
"COMBAT_ENHANCEMENTS.hp.label": "HP"
|
||||
}
|
||||
13
src/modules/combat-enhancements/lang/es.json
Normal file
13
src/modules/combat-enhancements/lang/es.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"COMBAT_ENHANCEMENTS.setting.reflow.label": "Habilitar la reordenación de la iniciativa",
|
||||
"COMBAT_ENHANCEMENTS.setting.reflow.description": "Si las iniciativas son iguales, ajusta tanto el contendiente hacia el que están arrastrando como el contendiente que está siendo arrastrado",
|
||||
"COMBAT_ENHANCEMENTS.setting.showHpForType.label": "Mostrar PV por tipo de actor",
|
||||
"COMBAT_ENHANCEMENTS.setting.showHPForType.description": "Permite que se muestre siempre la barra radial de PVs en el asistente de combate para un tipo de actor en particular, como ,por ejemplo, los personajes",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpField.label": "Habilitar campo de PVs",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpField.description": "Habilita un campo editable con los PVs en el asistente de combate que verán los GM y los propietarios de los actores",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpRadial.label": "Habilitar barra radial de PVs",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpRadial.description": "Habilita en el retrato del actor del asistente de combate una barra radial de progreso con los PV restantes. Quién puede verla está determinado por los ajustes de visibilidad de la barra 1 de los iconos (aunque los GM siempre podrán ver las barras si está opción está habilitada)",
|
||||
"COMBAT_ENHANCEMENTS.setting.removeTargets.label": "Habilitar borrado de objetivos en cada turno",
|
||||
"COMBAT_ENHANCEMENTS.setting.removeTargets.description": "Habilita que se borren los objetivos marcados en cada turno. Sucederá al hacer clic en el botón 'Turno siguiente' del asistente de combate",
|
||||
"COMBAT_ENHANCEMENTS.hp.label": "PV"
|
||||
}
|
||||
12
src/modules/combat-enhancements/lang/ja.json
Normal file
12
src/modules/combat-enhancements/lang/ja.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"COMBAT_ENHANCEMENTS.setting.reflow.label": "イニシアチブの再調整を有効にする",
|
||||
"COMBAT_ENHANCEMENTS.setting.reflow.description": "ドラッグ&ドロップによってイニシアチブ順を並び替えたとき、ドラッグしたキャラクターのみならず、ほか戦闘参加者のイニシアチブ値も調整するようになります。無効にした場合、イニシアチブに敏捷力を表示せず、かつイニシアチブが同一の戦闘参加者が複数ある場合に並び替えが反映されないことがあります。",
|
||||
"COMBAT_ENHANCEMENTS.setting.showHpForType.label": "HPを常に表示するアクタータイプ",
|
||||
"COMBAT_ENHANCEMENTS.setting.showHPForType.description": "指定したアクタータイプでは、イニシアチブ表で常にHPバーが表示されるようになります。",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpField.label": "HP入力欄を有効にする",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpField.description": "GMやアクター所有者が編集できるHP入力欄をイニシアチブ表に表示します。",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpRadial.label": "環状のHPバーを表示する",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpRadial.description": "イニシアチブ表に環状のHPバーを表示します。ここで表示されるのは,トークン設定のバー1に設定した属性値です(有効の場合、GMは常にバーを見ることができます)。",
|
||||
"COMBAT_ENHANCEMENTS.setting.removeTargets.label": "ターゲットを毎ターン外す",
|
||||
"COMBAT_ENHANCEMENTS.setting.removeTargets.description": "各ターン終了時に、現在のターゲットを外します。これはイニシアチブ表の「次のターン」ボタンを押すことで行われます。"
|
||||
}
|
||||
10
src/modules/combat-enhancements/lang/pt-BR.json
Normal file
10
src/modules/combat-enhancements/lang/pt-BR.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"COMBAT_ENHANCEMENTS.setting.reflow.label": "Ativar reordenador de Iniciativa",
|
||||
"COMBAT_ENHANCEMENTS.setting.reflow.description": "Se as iniciativas forem idênticas, ajuste o combatente arrastando as posições.",
|
||||
"COMBAT_ENHANCEMENTS.setting.showHpForType.label": "Exibe PV para cada tipo de ator",
|
||||
"COMBAT_ENHANCEMENTS.setting.showHPForType.description": "Use para sempre exibir a barra circular de PV no rastreador de combate para um tipo de ator específico, como personagens.",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpField.label": "Ativar campo PV",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpField.description": "Ative um campo editável de PV no rastreador de combate para MJs e proprietários de atores.",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpRadial.label": "Ativar barra circular de PV",
|
||||
"COMBAT_ENHANCEMENTS.setting.enableHpRadial.description": "Permite uma barra de progresso circular para a PV nos retratos de atores no rastreador de combate. A visibilidade é determinada pelas configurações de visibilidade da Barra 1 nos tokens"
|
||||
}
|
||||
49
src/modules/combat-enhancements/module.json
Normal file
49
src/modules/combat-enhancements/module.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"id": "combat-enhancements",
|
||||
"title": "Combat Enhancements",
|
||||
"description": "Adds health tracking and drag/drop re-ordering to the combat tracker.",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Asacolips",
|
||||
"discord": "asacolips"
|
||||
}
|
||||
],
|
||||
"version": "1.2.4",
|
||||
"minimumCoreVersion": "10",
|
||||
"compatibility": {
|
||||
"minimum": "10",
|
||||
"verified": "12.328",
|
||||
"maximum": "12"
|
||||
},
|
||||
"esmodules": [
|
||||
"module/combat-enhancements.js"
|
||||
],
|
||||
"styles": [
|
||||
"styles/dist/combat-enhancements.css"
|
||||
],
|
||||
"languages": [
|
||||
{
|
||||
"lang": "en",
|
||||
"name": "English",
|
||||
"path": "lang/en.json"
|
||||
},
|
||||
{
|
||||
"lang": "pt-BR",
|
||||
"name": "Português (Brasil)",
|
||||
"path": "lang/pt-BR.json"
|
||||
},
|
||||
{
|
||||
"lang": "es",
|
||||
"name": "Español",
|
||||
"path": "lang/es.json"
|
||||
},
|
||||
{
|
||||
"lang": "ja",
|
||||
"name": "日本語",
|
||||
"path": "lang/ja.json"
|
||||
}
|
||||
],
|
||||
"url": "https://gitlab.com/asacolips-projects/foundry-mods/combat-enhancements",
|
||||
"manifest": "https://gitlab.com/asacolips-projects/foundry-mods/combat-enhancements/raw/master/module.json",
|
||||
"download": "https://gitlab.com/asacolips-projects/foundry-mods/combat-enhancements/-/archive/1.2.4/combat-enhancements-master.zip"
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { CombatSidebarCe } from './combat.js';
|
||||
import { CeUtility } from './utility.js';
|
||||
|
||||
Hooks.once('init', async function() {
|
||||
CeUtility.registerHelpers();
|
||||
|
||||
// TODO: Determine a good way to localize this.
|
||||
let types = game?.release?.generation >= 12 ? Object.keys(game.system.template.Actor) : game.system.template.Actor.types;
|
||||
let choices = {
|
||||
'': '—'
|
||||
};
|
||||
for (let type of types) {
|
||||
choices[type] = type;
|
||||
}
|
||||
|
||||
game.settings.register('combat-enhancements', 'showHpForType', {
|
||||
name: game.i18n.localize('COMBAT_ENHANCEMENTS.setting.showHpForType.label'),
|
||||
scope: 'world',
|
||||
config: true,
|
||||
default: null,
|
||||
type: String,
|
||||
choices: choices,
|
||||
});
|
||||
|
||||
game.settings.register('combat-enhancements', 'enableInitReflow', {
|
||||
name: game.i18n.localize('COMBAT_ENHANCEMENTS.setting.reflow.label'),
|
||||
hint: game.i18n.localize('COMBAT_ENHANCEMENTS.setting.reflow.description'),
|
||||
scope: 'world',
|
||||
config: true,
|
||||
default: false,
|
||||
type: Boolean,
|
||||
});
|
||||
|
||||
game.settings.register('combat-enhancements', 'enableHpField', {
|
||||
name: game.i18n.localize('COMBAT_ENHANCEMENTS.setting.enableHpField.label'),
|
||||
hint: game.i18n.localize('COMBAT_ENHANCEMENTS.setting.enableHpField.description'),
|
||||
scope: 'world',
|
||||
config: true,
|
||||
default: true,
|
||||
type: Boolean,
|
||||
});
|
||||
|
||||
game.settings.register('combat-enhancements', 'enableHpRadial', {
|
||||
name: game.i18n.localize('COMBAT_ENHANCEMENTS.setting.enableHpRadial.label'),
|
||||
hint: game.i18n.localize('COMBAT_ENHANCEMENTS.setting.enableHpRadial.description'),
|
||||
scope: 'world',
|
||||
config: true,
|
||||
default: true,
|
||||
type: Boolean,
|
||||
});
|
||||
|
||||
game.settings.register('combat-enhancements', 'removeTargets', {
|
||||
name: game.i18n.localize('COMBAT_ENHANCEMENTS.setting.removeTargets.label'),
|
||||
hint: game.i18n.localize('COMBAT_ENHANCEMENTS.setting.removeTargets.description'),
|
||||
scope: 'world',
|
||||
config: true,
|
||||
default: false,
|
||||
type: Boolean,
|
||||
onChange: () => location.reload(),
|
||||
});
|
||||
|
||||
game.settings.register('combat-enhancements', 'hideNonAllyInitiative', {
|
||||
name: game.i18n.localize('COMBAT_ENHANCEMENTS.setting.hideNonAllyInitiative.label'),
|
||||
hint: game.i18n.localize('COMBAT_ENHANCEMENTS.setting.hideNonAllyInitiative.description'),
|
||||
scope: 'world',
|
||||
config: true,
|
||||
default: false,
|
||||
type: Boolean,
|
||||
});
|
||||
|
||||
let combatSidebar = new CombatSidebarCe();
|
||||
combatSidebar.startup();
|
||||
});
|
||||
448
src/modules/combat-enhancements/module/combat.js
Normal file
448
src/modules/combat-enhancements/module/combat.js
Normal file
@@ -0,0 +1,448 @@
|
||||
import { CeUtility } from "./utility.js";
|
||||
import { untargetDeadTokens, untargetAllTokens } from './removeTarget.js';
|
||||
|
||||
/**
|
||||
* Helper class to handle rendering the custom combat tracker.
|
||||
*/
|
||||
export class CombatSidebarCe {
|
||||
// This must be called in the `init` hook in order for the other hooks to
|
||||
// fire correctly.
|
||||
startup() {
|
||||
// CONFIG.debug.hooks = true;
|
||||
const removeTarget = game.settings.get('combat-enhancements', 'removeTargets');
|
||||
|
||||
Hooks.on('updateCombat', (...args) => {
|
||||
if (!removeTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
untargetDeadTokens();
|
||||
untargetAllTokens(args);
|
||||
});
|
||||
|
||||
Hooks.on('deleteCombat', (...args) => {
|
||||
if (!removeTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
untargetDeadTokens();
|
||||
untargetAllTokens(args);
|
||||
});
|
||||
|
||||
Hooks.on('ready', () => {
|
||||
// Add an event listener for input fields. This is currently only
|
||||
// used for updating HP on actors.
|
||||
$('body').on('change', '.ce-modify-hp', (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
// Get the incput and actor element.
|
||||
const dataset = event.currentTarget.dataset;
|
||||
let $input = $(event.currentTarget);
|
||||
let $actorRow = $input.parents('.directory-item.actor-elem');
|
||||
|
||||
// If there isn't an actor element, don't proceed.
|
||||
if (!$actorRow.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!game.combat) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve the combatant for this actor, or exit if not valid.
|
||||
const combatant = game.combat.combatants.find(c => c.id == $actorRow.data('combatant-id'));
|
||||
if (!combatant) {
|
||||
return;
|
||||
}
|
||||
|
||||
const actor = combatant.actor;
|
||||
|
||||
// Check for bad numbers, otherwise convert into a Number type.
|
||||
let value = $input.val();
|
||||
let inputValue = getProperty(actor, $input.attr('name'));
|
||||
if (dataset.dtype == 'Number') {
|
||||
value = Number(value);
|
||||
if (Number.isNaN(value)) {
|
||||
$input.val(inputValue);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare update data for the actor.
|
||||
let updateData = {};
|
||||
// If this started with a "+" or "-", handle it as a relative change.
|
||||
let operation = $input.val().match(/^\+|\-/g);
|
||||
console.log($input.attr('name'));
|
||||
if (operation) {
|
||||
updateData[$input.attr('name')] = Number(inputValue) + value;
|
||||
}
|
||||
// Otherwise, set it absolutely.
|
||||
else {
|
||||
updateData[$input.attr('name')] = value;
|
||||
}
|
||||
|
||||
// Update the actor.
|
||||
actor.update(updateData);
|
||||
return;
|
||||
});
|
||||
|
||||
// Drag handler for the combat tracker.
|
||||
if (game.user.isGM) {
|
||||
$('body')
|
||||
// Initiate the drag event.
|
||||
.on('dragstart', '#combat-tracker .directory-item.actor-elem', (event) => {
|
||||
// Set the drag data for later usage.
|
||||
let dragData = event.currentTarget.dataset;
|
||||
event.originalEvent.dataTransfer.setData('text/plain', JSON.stringify(dragData));
|
||||
|
||||
// Store the combatant type for reference. We have to do this
|
||||
// because dragover doesn't have access to the drag data, so we
|
||||
// store it as a new type entry that can be split later.
|
||||
let newCombatant = game.combat.combatants.find(c => c.id == dragData.combatantId);
|
||||
event.originalEvent.dataTransfer.setData(`newtype--${dragData.actorType}`, '');
|
||||
|
||||
// Set the drag image.
|
||||
let dragIcon = $(event.currentTarget).find('.ce-image-wrapper')[0];
|
||||
event.originalEvent.dataTransfer.setDragImage(dragIcon, 25, 25);
|
||||
})
|
||||
// Add a class on hover, if the actor types match.
|
||||
.on('dragover', '#combat-tracker .directory-item.actor-elem', (event) => {
|
||||
// Get the drop target.
|
||||
let $self = $(event.originalEvent.target);
|
||||
let $dropTarget = $self.parents('.directory-item');
|
||||
|
||||
// Exit early if we don't need to make any changes.
|
||||
if ($dropTarget.hasClass('drop-hover')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$dropTarget.data('combatant-id')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the hover class.
|
||||
$dropTarget.addClass('drop-hover');
|
||||
return false;
|
||||
})
|
||||
// Remove the class on drag leave.
|
||||
.on('dragleave', '#combat-tracker .directory-item.actor-elem', (event) => {
|
||||
// Get the drop target and remove any hover classes on it when
|
||||
// the mouse leaves it.
|
||||
let $self = $(event.originalEvent.target);
|
||||
let $dropTarget = $self.parents('.directory-item');
|
||||
$dropTarget.removeClass('drop-hover');
|
||||
return false;
|
||||
})
|
||||
// Update initiative on drop.
|
||||
.on('drop', '#combat-tracker .directory-item.actor-elem', async (event) => {
|
||||
// Retrieve the default encounter.
|
||||
let combat = game.combat;
|
||||
|
||||
if (combat === null || combat === undefined) {
|
||||
// When dragging a token from the actors tab this drop event fire but we aren't in combat.
|
||||
// This catches all instances of drop events when not in combat.
|
||||
return;
|
||||
}
|
||||
|
||||
// Retreive the drop target, remove any hover classes.
|
||||
let $self = $(event.originalEvent.target);
|
||||
let $dropTarget = $self.parents('.directory-item');
|
||||
$dropTarget.removeClass('drop-hover');
|
||||
|
||||
// Attempt to retrieve and parse the data transfer from the drag.
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(event.originalEvent.dataTransfer.getData('text/plain'));
|
||||
// if (data.type !== "Item") return;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Retrieve the combatant being dropped.
|
||||
let newCombatant = combat.combatants.find(c => c.id == data.combatantId);
|
||||
|
||||
// Retrieve the combatants grouped by type.
|
||||
let combatants = this.getCombatantsData(false);
|
||||
// Retrieve the combatant being dropped onto.
|
||||
let originalCombatant = combatants.find(c => {
|
||||
return c.id == $dropTarget.data('combatant-id');
|
||||
});
|
||||
|
||||
// Exit early if there's no target.
|
||||
if (!originalCombatant?.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
let nextCombatantElem = $(`.combatant[data-combatant-id="${originalCombatant.id}"] + .combatant`);
|
||||
let nextCombatantId = nextCombatantElem.length > 0 ? nextCombatantElem.data('combatant-id') : null;
|
||||
let nextCombatant = null;
|
||||
if (nextCombatantId) {
|
||||
nextCombatant = combatants.find(c => c.id == nextCombatantId);
|
||||
}
|
||||
|
||||
if (nextCombatant && nextCombatant.id == newCombatant.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the initiative equal to the drop target's initiative.
|
||||
let oldInit = [
|
||||
originalCombatant ? Number(originalCombatant.initiative) : 0,
|
||||
nextCombatant ? Number(nextCombatant.initiative) : Number(originalCombatant.initiative) - 1,
|
||||
];
|
||||
|
||||
// If the initiative was valid, we need to update the initiative
|
||||
// for every combatant to reset their numbers.
|
||||
if (oldInit !== null) {
|
||||
// Set the initiative of the actor being draged to the drop
|
||||
// target's -1. This will later be adjusted increments of 10.
|
||||
// let updatedCombatant = combatants.find(c => c.id == newCombatant.id);
|
||||
let initiative = (oldInit[0] + oldInit[1]) / 2;
|
||||
let updateOld = false;
|
||||
|
||||
// Handle identical initiative.
|
||||
if (game.settings.get('combat-enhancements', 'enableInitReflow')) {
|
||||
if (oldInit[0] == oldInit[1] && oldInit[0] % 1 == 0) {
|
||||
oldInit[0] += 2;
|
||||
initiative = (oldInit[1] + 1);
|
||||
updateOld = true;
|
||||
}
|
||||
}
|
||||
|
||||
let updates = [{
|
||||
_id: newCombatant.id,
|
||||
initiative: initiative
|
||||
}];
|
||||
|
||||
if (updateOld) {
|
||||
updates.push({
|
||||
_id: originalCombatant.id,
|
||||
initiative: oldInit[0]
|
||||
});
|
||||
}
|
||||
|
||||
// If there are updates, update the combatants at once.
|
||||
if (updates) {
|
||||
await combat.updateEmbeddedDocuments('Combatant', updates, {});
|
||||
ui.combat.render();
|
||||
}
|
||||
}
|
||||
}); // end of html.find('.directory-item.actor-elem')
|
||||
}
|
||||
});
|
||||
|
||||
// Re-render combat when actors are modified.
|
||||
Hooks.on('updateActor', (actor, data, options, id) => {
|
||||
if (game.combat === null || game.combat === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
let inCombat = game.combat.combatants.find(c => c?.actor?.id == actor?.id);
|
||||
if (inCombat) {
|
||||
ui.combat.render();
|
||||
}
|
||||
});
|
||||
|
||||
Hooks.on('updateToken', (token, data, options, id) => {
|
||||
if ((data.actorData || data.flags?.barbrawl) && game.combat) {
|
||||
let inCombat = game.combat.combatants.find(c => c.tokenId == token.id);
|
||||
if (inCombat) {
|
||||
ui.combat.render();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// // TODO: Replace this hack that triggers an extra render.
|
||||
// Hooks.on('renderSidebar', (app, html, options) => {
|
||||
// ui.combat.render();
|
||||
// });
|
||||
|
||||
// When the combat tracker is rendered, we need to completely replace
|
||||
// its HTML with a custom version.
|
||||
Hooks.on('renderCombatTracker', async (app, html, options) => {
|
||||
// If there's as combat, we can proceed.
|
||||
if (game.combat) {
|
||||
// Retrieve a list of the combatants grouped by actor type and sorted
|
||||
// by their initiative count.
|
||||
let combatants = this.getCombatantsData();
|
||||
|
||||
combatants.forEach(c => {
|
||||
// Add class to trigger drag events.
|
||||
let $combatant = html.find(`.combatant[data-combatant-id="${c.id}"]`);
|
||||
$combatant.addClass('actor-elem');
|
||||
|
||||
// Add svg circle.
|
||||
// console.log(c);
|
||||
// console.log(CeUtility.getProgressCircleHtml(c.healthSvg))
|
||||
|
||||
$combatant.find('.token-image').wrap('<div class="ce-image-wrapper">');
|
||||
$combatant.append($('<span class="ce-drop-indicator"></span>'));
|
||||
|
||||
// Display the health SVG if it should be visible.
|
||||
if (c.displayHealth) {
|
||||
$combatant.find('.ce-image-wrapper').append(CeUtility.getProgressCircleHtml(c.healthSvg));
|
||||
}
|
||||
|
||||
if (c.editable) {
|
||||
// Display the HP input/div.
|
||||
let $healthInput = null;
|
||||
if (c.editable) {
|
||||
$healthInput = $(`<div class="ce-modify-hp-wrapper">${game.i18n.localize("COMBAT_ENHANCEMENTS.hp.label")} <input onclick="this.select();" class="ce-modify-hp" type="text" name="system.${c.combatAttr}.value" value="${getProperty(c.actor.system, c.combatAttr + '.value')}" data-dtype="Number"></div>`);
|
||||
}
|
||||
// else {
|
||||
// $healthInput = $(`<div class="ce-modify-hp-wrapper">HP ${getProperty(c.actor.system, c.combatAttr + '.value')}</div>`);
|
||||
// }
|
||||
|
||||
if ($healthInput) {
|
||||
$combatant.find('.combatant-controls').append($healthInput);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Drag handler for the combat tracker.
|
||||
if (game.user.isGM) {
|
||||
html.find('.directory-item.actor-elem').attr('draggable', true).addClass('draggable');
|
||||
}
|
||||
|
||||
// If the hide initiative setting is true, hide non-friendly combatant's init number.
|
||||
if (game.settings.get('combat-enhancements', 'hideNonAllyInitiative')) {
|
||||
// Only do this for players and not GMs.
|
||||
if (!game.user.isGM) {
|
||||
const combatants = html.find('.combatant');
|
||||
combatants.each((i, el) => {
|
||||
const initDiv = el.getElementsByClassName('token-initiative')[0];
|
||||
// Initiative was found, check to see if we should remove it.
|
||||
if (initDiv) {
|
||||
const combatant = game.combat.combatants.get(el.dataset.combatantId);
|
||||
const token = combatant.token;
|
||||
// If the token isn't friendly, hide their initiative.
|
||||
if (token.disposition < 1) {
|
||||
console.log(token.name);
|
||||
initDiv.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of combatants for the current combat.
|
||||
*
|
||||
* Combatants will be sorted into groups by actor type. Set the
|
||||
* updateInitiative argument to true to reassign init numbers.
|
||||
* @param {Boolean} updateInitiative
|
||||
*/
|
||||
getCombatantsData(updateInitiative = false) {
|
||||
// If there isn't a combat, exit and return an empty array.
|
||||
if (!game.combat) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let currentInitiative = 0;
|
||||
// Reduce the combatants array into a new object with keys based on
|
||||
// the actor types.
|
||||
let combatants = game.combat.combatants.filter(combatant => {
|
||||
// Append valid actors to the appropriate group.
|
||||
if (combatant.actor) {
|
||||
// Initialize the group if it doesn't exist.
|
||||
let group = combatant.actor.type;
|
||||
let alwaysOnType = game.settings.get('combat-enhancements', 'showHpForType');
|
||||
let editableHp = game.settings.get('combat-enhancements', 'enableHpField');
|
||||
let displayHealthRadials = game.settings.get('combat-enhancements', 'enableHpRadial');
|
||||
|
||||
// Retrieve the health bars mode from the token's resource settings.
|
||||
let displayBarsMode = Object.entries(CONST.TOKEN_DISPLAY_MODES).find(i => i[1] == combatant.token.displayBars)[0];
|
||||
// Assume player characters should always show their health bar.
|
||||
let displayHealth = alwaysOnType && group == alwaysOnType ? true : false;
|
||||
|
||||
// Determine the combat attribute.
|
||||
if (combatant?.actor?.system?.attributes?.hp?.value) {
|
||||
combatant.combatAttr = 'attributes.hp';
|
||||
}
|
||||
|
||||
if (combatant.token.bar1.attribute) {
|
||||
combatant.combatAttr = combatant.token.bar1.attribute;
|
||||
}
|
||||
|
||||
// If this is a group other than character (such as NPC), we need to
|
||||
// evaluate whether or not this player can see its health bar.
|
||||
if (!alwaysOnType || group != alwaysOnType) {
|
||||
// If the mode is one of the owner options, only the token owner or
|
||||
// the GM should be able to see it.
|
||||
if (displayBarsMode.includes("OWNER")) {
|
||||
if (combatant.isOwner || game.user.isGM) {
|
||||
displayHealth = true;
|
||||
}
|
||||
}
|
||||
// For other modes, always show it.
|
||||
else if (displayBarsMode != "NONE") {
|
||||
displayHealth = true;
|
||||
}
|
||||
// If it's set to the none mode, hide it from players, but allow
|
||||
// the GM to see it.
|
||||
else {
|
||||
displayHealth = game.user.isGM ? true : false;
|
||||
}
|
||||
|
||||
// If the updateInitiative flag was set to true, recalculate the
|
||||
// initiative for each actor while we're looping through them.
|
||||
if (updateInitiative) {
|
||||
combatant.initiative = currentInitiative;
|
||||
currentInitiative = currentInitiative + 10;
|
||||
}
|
||||
}
|
||||
|
||||
// Set a property based on the health mode earlier.
|
||||
combatant.displayHealth = displayHealthRadials ? displayHealth : false;
|
||||
// Set a property for whether or not this is editable. This controls
|
||||
// whether editabel fields like HP will be shown as an input or a div
|
||||
// in the combat tracker HTML template.
|
||||
combatant.editable = editableHp && (combatant.isOwner || game.user.isGM);
|
||||
|
||||
|
||||
// If the Bar Brawl module is enabled, let it handle the bar's value and visibility.
|
||||
let currentHealth, maxHealth;
|
||||
if (game.modules.get("barbrawl")?.active) {
|
||||
// Fetch the bar's validated source data.
|
||||
let barData = window.BarBrawlApi?.getBar(combatant.token, "bar1");
|
||||
if (displayHealth && barData && window.BarBrawlApi?.isBarVisible) {
|
||||
// Make sure that the bar should be visible for the current user.
|
||||
displayHealth = window.BarBrawlApi.isBarVisible(combatant.token.object, barData, true);
|
||||
}
|
||||
if (barData && window.BarBrawlApi?.getActualBarValue) {
|
||||
// Fetch the value that should actually be displayed on the bar.
|
||||
const barValue = window.BarBrawlApi.getActualBarValue(combatant.token, barData);
|
||||
currentHealth = barValue.value;
|
||||
maxHealth = barValue.max;
|
||||
}
|
||||
}
|
||||
// Otherwise, retrieve the current and max health bar data.
|
||||
else {
|
||||
if (currentHealth === undefined) {
|
||||
let resource = combatant.token.getBarAttribute(null, { alternative: combatant.combatAttr });
|
||||
if (resource && resource.type === "bar") {
|
||||
currentHealth = resource.value;
|
||||
maxHealth = resource.max;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Build the radial progress circle settings for the template.
|
||||
combatant.healthSvg = CeUtility.getProgressCircle({
|
||||
current: currentHealth,
|
||||
max: maxHealth,
|
||||
radius: 16
|
||||
});
|
||||
|
||||
// Return true to include combatant in filter
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Return the list of combatants
|
||||
return combatants
|
||||
}
|
||||
}
|
||||
19
src/modules/combat-enhancements/module/removeTarget.js
Normal file
19
src/modules/combat-enhancements/module/removeTarget.js
Normal file
@@ -0,0 +1,19 @@
|
||||
export function untargetDeadTokens() {
|
||||
game.user.targets.forEach((t) => {
|
||||
if (t.actor?.system.attributes.hp.value <= 0) {
|
||||
t.setTarget(false, { releaseOthers: false });
|
||||
game.user.targets.delete(t);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function untargetAllTokens(...args) {
|
||||
const params = args[0];
|
||||
const combat = params[0] ?? game.combat;
|
||||
if (game.user.targets) {
|
||||
game.user.targets.forEach((t) => {
|
||||
t.setTarget(false, { releaseOthers: false });
|
||||
});
|
||||
game.user.targets.clear();
|
||||
}
|
||||
}
|
||||
44
src/modules/combat-enhancements/module/utility.js
Normal file
44
src/modules/combat-enhancements/module/utility.js
Normal file
@@ -0,0 +1,44 @@
|
||||
export class CeUtility {
|
||||
static registerHelpers() {
|
||||
Handlebars.registerHelper('progressCircle', function(data) {
|
||||
return CeUtility.getProgressCircleHtml(data);
|
||||
});
|
||||
}
|
||||
|
||||
static getProgressCircleHtml(data) {
|
||||
return `<svg class="progress-ring progress-ring--${data.class}" viewBox="0 0 ${data.diameter} ${data.diameter}" width="${data.diameter}" height="${data.diameter}">
|
||||
<circle
|
||||
class="progress-ring__circle"
|
||||
stroke-width="${data.strokeWidth}"
|
||||
stroke-dasharray="${data.circumference}"
|
||||
stroke-dashoffset="${data.offset}"
|
||||
stroke="${data.color}"
|
||||
fill="transparent"
|
||||
r="${data.radius}"
|
||||
cx="${data.position}"
|
||||
cy="${data.position}"
|
||||
/>
|
||||
</svg>`;
|
||||
}
|
||||
|
||||
static getProgressCircle({ current = 100, max = 100, radius = 16 }) {
|
||||
let circumference = radius * 2 * Math.PI;
|
||||
let percent = current < max ? current / max : 1;
|
||||
let percentNumber = percent * 100;
|
||||
let offset = circumference - (percent * circumference);
|
||||
let strokeWidth = 4;
|
||||
let diameter = (radius * 2) + strokeWidth;
|
||||
let colorClass = Math.round((percent * 100) / 10) * 10;
|
||||
|
||||
return {
|
||||
radius: radius,
|
||||
diameter: diameter,
|
||||
strokeWidth: strokeWidth,
|
||||
circumference: circumference,
|
||||
offset: offset,
|
||||
position: diameter / 2,
|
||||
color: 'red',
|
||||
class: colorClass,
|
||||
};
|
||||
}
|
||||
}
|
||||
27
src/modules/combat-enhancements/package.json
Normal file
27
src/modules/combat-enhancements/package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "combat-enhancements",
|
||||
"version": "1.0.0",
|
||||
"description": "Adds health tracking and drag/drop reordering.",
|
||||
"scripts": {
|
||||
"build": "gulp yaml & gulp css",
|
||||
"compile": "gulp css",
|
||||
"watch": "gulp",
|
||||
"gulp": "gulp",
|
||||
"yaml": "gulp yaml"
|
||||
},
|
||||
"browserslist": [
|
||||
"last 3 versions"
|
||||
],
|
||||
"author": "Asacolips",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-autoprefixer": "^8.0.0",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-sass": "^5.1.0",
|
||||
"gulp-sourcemaps": "^3.0.0",
|
||||
"gulp-yaml": "^2.0.4",
|
||||
"sass": "^1.52.1"
|
||||
}
|
||||
}
|
||||
1
src/modules/combat-enhancements/styles/dist/combat-enhancements.css
vendored
Normal file
1
src/modules/combat-enhancements/styles/dist/combat-enhancements.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.combatant{position:relative;height:60px}.combatant .ce-drop-indicator{content:"";display:block;position:absolute;bottom:0;left:0;right:0;margin:auto;height:5px;width:0px;background:rgba(255,255,255,.75);-webkit-transition:all ease-in-out .25s;-o-transition:all ease-in-out .25s;transition:all ease-in-out .25s;pointer-events:none}.combatant .token-resource{padding-right:6px;line-height:75px;height:100%;color:#bfbfbf}.combatant .token-initiative{padding-top:14px}.combatant .ce-image-wrapper{position:relative;width:48px;height:48px;-webkit-box-flex:0;-ms-flex:0 0 48px;flex:0 0 48px;border-radius:50%;overflow:hidden}.combatant .ce-image-wrapper .progress-ring{position:absolute;top:0;left:0;width:100%;height:100%;-webkit-box-shadow:inset 0 0 3px 5px rgba(0,0,0,.65);box-shadow:inset 0 0 3px 5px rgba(0,0,0,.65);border-radius:50%}.combatant .ce-image-wrapper .progress-ring--100 circle,.combatant .ce-image-wrapper .progress-ring--90 circle{stroke:#41c179}.combatant .ce-image-wrapper .progress-ring--80 circle,.combatant .ce-image-wrapper .progress-ring--70 circle{stroke:#f7d601}.combatant .ce-image-wrapper .progress-ring--60 circle,.combatant .ce-image-wrapper .progress-ring--50 circle,.combatant .ce-image-wrapper .progress-ring--40 circle{stroke:#f78c01}.combatant .ce-image-wrapper .progress-ring--30 circle,.combatant .ce-image-wrapper .progress-ring--20 circle,.combatant .ce-image-wrapper .progress-ring--10 circle,.combatant .ce-image-wrapper .progress-ring--0 circle{stroke:#ca0000}.combatant .ce-modify-hp-wrapper{font-size:12px;-ms-flex-wrap:nowrap;flex-wrap:nowrap;white-space:nowrap}.combatant .ce-modify-hp{color:#fff;width:45px;text-align:center}.combatant .ce-modify-hp:hover,.combatant .ce-modify-hp:active,.combatant .ce-modify-hp:focus{-webkit-box-shadow:none;box-shadow:none;background:rgba(255,255,255,.25)}.drop-hover .ce-drop-indicator{width:100%}
|
||||
@@ -0,0 +1,112 @@
|
||||
$c-white: #fff;
|
||||
$c-black: #000;
|
||||
$c-green: #41c179;
|
||||
$c-yellow: #f7d601;
|
||||
$c-orange: #f78c01;
|
||||
$c-red: #ca0000;
|
||||
|
||||
.combatant {
|
||||
position: relative;
|
||||
height: 60px;
|
||||
|
||||
.ce-drop-indicator {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
height: 5px;
|
||||
width: 0px;
|
||||
background: rgba(#fff, 0.75);
|
||||
transition: all ease-in-out 0.25s;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.token-resource {
|
||||
padding-right: 6px;
|
||||
line-height: 75px;
|
||||
height: 100%;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
|
||||
.token-initiative {
|
||||
padding-top: 14px;
|
||||
}
|
||||
|
||||
.ce-image-wrapper {
|
||||
position: relative;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
flex: 0 0 48px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
|
||||
.progress-ring {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-shadow: inset 0 0 3px 5px rgba(0, 0, 0, 0.65);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.progress-ring--100,
|
||||
.progress-ring--90 {
|
||||
circle {
|
||||
stroke: $c-green;
|
||||
}
|
||||
}
|
||||
|
||||
.progress-ring--80,
|
||||
.progress-ring--70 {
|
||||
circle {
|
||||
stroke: $c-yellow;
|
||||
}
|
||||
}
|
||||
|
||||
.progress-ring--60,
|
||||
.progress-ring--50,
|
||||
.progress-ring--40 {
|
||||
circle {
|
||||
stroke: $c-orange;
|
||||
}
|
||||
}
|
||||
|
||||
.progress-ring--30,
|
||||
.progress-ring--20,
|
||||
.progress-ring--10,
|
||||
.progress-ring--0 {
|
||||
circle {
|
||||
stroke: $c-red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ce-modify-hp-wrapper {
|
||||
font-size: 12px;
|
||||
flex-wrap: nowrap;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ce-modify-hp {
|
||||
color: $c-white;
|
||||
width: 45px;
|
||||
text-align: center;
|
||||
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
background: rgba($c-white, 0.25);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.drop-hover {
|
||||
.ce-drop-indicator {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
13
src/modules/combat-enhancements/yaml/lang/en.yaml
Normal file
13
src/modules/combat-enhancements/yaml/lang/en.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
COMBAT_ENHANCEMENTS.setting.reflow.label: Enable initiative reflow
|
||||
COMBAT_ENHANCEMENTS.setting.reflow.description: If initiatives are identical, adjust the combatant being dragged onto in addition to the combatant being dragged.
|
||||
COMBAT_ENHANCEMENTS.setting.showHpForType.label: Show HP for actor type
|
||||
COMBAT_ENHANCEMENTS.setting.showHPForType.description: Use this to always display the radial HP bar in the combat tracker for a specific actor type, such as characters.
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpField.label: Enable HP field
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpField.description: Enable an editable HP field in the combat tracker for GMs and actor owners.
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpRadial.label: Enable HP radial bar
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpRadial.description: Enables a radial progress bar for HP on the actor portraits in the combat tracker. Visibility is determined by the Bar 1 visibility settings on tokens (GMs can alway see bars if they're enabled here).
|
||||
COMBAT_ENHANCEMENTS.setting.removeTargets.label: Enable target removal every turn
|
||||
COMBAT_ENHANCEMENTS.setting.removeTargets.description: Enables target removal at the end of each turn. This is done by pressing the button 'Next Turn' on the combat tracker.
|
||||
COMBAT_ENHANCEMENTS.setting.hideNonAllyInitiative.label: Hide non-ally initiative
|
||||
COMBAT_ENHANCEMENTS.setting.hideNonAllyInitiative.description: Hide non-ally initiative from players on FVTT combat tracker
|
||||
COMBAT_ENHANCEMENTS.hp.label: HP
|
||||
13
src/modules/combat-enhancements/yaml/lang/es.yaml
Normal file
13
src/modules/combat-enhancements/yaml/lang/es.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
# I18N.LANGUAGE: Español
|
||||
# I18N.MAINTAINERS: "@Viriato139ac#0342"
|
||||
COMBAT_ENHANCEMENTS.setting.reflow.label: Habilitar la reordenación de la iniciativa
|
||||
COMBAT_ENHANCEMENTS.setting.reflow.description: Si las iniciativas son iguales, ajusta tanto el contendiente hacia el que están arrastrando como el contendiente que está siendo arrastrado
|
||||
COMBAT_ENHANCEMENTS.setting.showHpForType.label: Mostrar PV por tipo de actor
|
||||
COMBAT_ENHANCEMENTS.setting.showHPForType.description: Permite que se muestre siempre la barra radial de PVs en el asistente de combate para un tipo de actor en particular, como ,por ejemplo, los personajes
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpField.label: Habilitar campo de PVs
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpField.description: Habilita un campo editable con los PVs en el asistente de combate que verán los GM y los propietarios de los actores
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpRadial.label: Habilitar barra radial de PVs
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpRadial.description: Habilita en el retrato del actor del asistente de combate una barra radial de progreso con los PV restantes. Quién puede verla está determinado por los ajustes de visibilidad de la barra 1 de los iconos (aunque los GM siempre podrán ver las barras si está opción está habilitada)
|
||||
COMBAT_ENHANCEMENTS.setting.removeTargets.label: Habilitar borrado de objetivos en cada turno
|
||||
COMBAT_ENHANCEMENTS.setting.removeTargets.description: Habilita que se borren los objetivos marcados en cada turno. Sucederá al hacer clic en el botón 'Turno siguiente' del asistente de combate
|
||||
COMBAT_ENHANCEMENTS.hp.label: PV
|
||||
10
src/modules/combat-enhancements/yaml/lang/ja.yaml
Normal file
10
src/modules/combat-enhancements/yaml/lang/ja.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
COMBAT_ENHANCEMENTS.setting.reflow.label: イニシアチブの再調整を有効にする
|
||||
COMBAT_ENHANCEMENTS.setting.reflow.description: ドラッグ&ドロップによってイニシアチブ順を並び替えたとき、ドラッグしたキャラクターのみならず、ほか戦闘参加者のイニシアチブ値も調整するようになります。無効にした場合、イニシアチブに敏捷力を表示せず、かつイニシアチブが同一の戦闘参加者が複数ある場合に並び替えが反映されないことがあります。
|
||||
COMBAT_ENHANCEMENTS.setting.showHpForType.label: HPを常に表示するアクタータイプ
|
||||
COMBAT_ENHANCEMENTS.setting.showHPForType.description: 指定したアクタータイプでは、イニシアチブ表で常にHPバーが表示されるようになります。
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpField.label: HP入力欄を有効にする
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpField.description: GMやアクター所有者が編集できるHP入力欄をイニシアチブ表に表示します。
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpRadial.label: 環状のHPバーを表示する
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpRadial.description: イニシアチブ表に環状のHPバーを表示します。ここで表示されるのは,トークン設定のバー1に設定した属性値です(有効の場合、GMは常にバーを見ることができます)。
|
||||
COMBAT_ENHANCEMENTS.setting.removeTargets.label: ターゲットを毎ターン外す
|
||||
COMBAT_ENHANCEMENTS.setting.removeTargets.description: 各ターン終了時に、現在のターゲットを外します。これはイニシアチブ表の「次のターン」ボタンを押すことで行われます。
|
||||
8
src/modules/combat-enhancements/yaml/lang/pt-BR.yaml
Normal file
8
src/modules/combat-enhancements/yaml/lang/pt-BR.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
COMBAT_ENHANCEMENTS.setting.reflow.label: Ativar reordenador de Iniciativa
|
||||
COMBAT_ENHANCEMENTS.setting.reflow.description: Se as iniciativas forem idênticas, ajuste o combatente arrastando as posições.
|
||||
COMBAT_ENHANCEMENTS.setting.showHpForType.label: Exibe PV para cada tipo de ator
|
||||
COMBAT_ENHANCEMENTS.setting.showHPForType.description: Use para sempre exibir a barra circular de PV no rastreador de combate para um tipo de ator específico, como personagens.
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpField.label: Ativar campo PV
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpField.description: Ative um campo editável de PV no rastreador de combate para MJs e proprietários de atores.
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpRadial.label: Ativar barra circular de PV
|
||||
COMBAT_ENHANCEMENTS.setting.enableHpRadial.description: Permite uma barra de progresso circular para a PV nos retratos de atores no rastreador de combate. A visibilidade é determinada pelas configurações de visibilidade da Barra 1 nos tokens
|
||||
32
src/modules/combat-enhancements/yaml/module.yaml
Normal file
32
src/modules/combat-enhancements/yaml/module.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
id: combat-enhancements
|
||||
title: Combat Enhancements
|
||||
description: Adds health tracking and drag/drop re-ordering to the combat tracker.
|
||||
authors:
|
||||
- name: Asacolips
|
||||
discord: asacolips
|
||||
version: "1.2.4"
|
||||
minimumCoreVersion: "10"
|
||||
compatibility:
|
||||
minimum: "10"
|
||||
verified: "12.328"
|
||||
maximum: "12"
|
||||
esmodules:
|
||||
- module/combat-enhancements.js
|
||||
styles:
|
||||
- styles/dist/combat-enhancements.css
|
||||
languages:
|
||||
- lang: en
|
||||
name: English
|
||||
path: lang/en.json
|
||||
- lang: pt-BR
|
||||
name: Português (Brasil)
|
||||
path: lang/pt-BR.json
|
||||
- lang: es
|
||||
name: Español
|
||||
path: lang/es.json
|
||||
- lang: ja
|
||||
name: 日本語
|
||||
path: lang/ja.json
|
||||
url: https://gitlab.com/asacolips-projects/foundry-mods/combat-enhancements
|
||||
manifest: https://gitlab.com/asacolips-projects/foundry-mods/combat-enhancements/raw/master/module.json
|
||||
download: https://gitlab.com/asacolips-projects/foundry-mods/combat-enhancements/-/archive/1.2.4/combat-enhancements-master.zip
|
||||
Reference in New Issue
Block a user