feat: add interactive combat roll modifier slider snappable UI and visual ticks
This commit is contained in:
@@ -2338,6 +2338,26 @@ p {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* Skill picker scroll list — thin scrollbar, no overflow on the dialog */
|
||||
.macro-popup-dialog .sla-skill-scroll-list {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #aaa #e6e6e6;
|
||||
}
|
||||
.macro-popup-dialog .sla-skill-scroll-list::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
.macro-popup-dialog .sla-skill-scroll-list::-webkit-scrollbar-track {
|
||||
background: #e6e6e6;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.macro-popup-dialog .sla-skill-scroll-list::-webkit-scrollbar-thumb {
|
||||
background: #aaa;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.macro-popup-dialog .sla-skill-scroll-list::-webkit-scrollbar-thumb:hover {
|
||||
background: #888;
|
||||
}
|
||||
|
||||
.mosh .sla-panel {
|
||||
margin-bottom: 14px;
|
||||
padding: 12px;
|
||||
|
||||
@@ -826,7 +826,7 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
var item;
|
||||
item = foundry.utils.duplicate(this.actor.getEmbeddedDocument("Item", li.dataset.itemId));
|
||||
|
||||
this.actor.rollCheck(null, null, null, item.name, item.system.bonus, null);
|
||||
this.actor.rollCheck(null, null, null, item.name, item.system.bonus, null, null, { promptModifier: true });
|
||||
});
|
||||
|
||||
html.find('.sla-ebb-skill-roll').click(ev => {
|
||||
@@ -858,7 +858,7 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
//const item = duplicate(this.actor.getEmbeddedDocument("Item", li.dataset.itemId));
|
||||
var item;
|
||||
item = foundry.utils.duplicate(this.actor.getEmbeddedDocument("Item", li.dataset.itemId));
|
||||
this.actor.rollWeaponAttack(item);
|
||||
this.actor.rollWeaponAttack(item, { promptModifier: true });
|
||||
});
|
||||
|
||||
// Rollable Damage
|
||||
|
||||
+166
-27
@@ -4,6 +4,21 @@ import { SLADrugSystem } from "../sla-drug-system.js";
|
||||
import { SLA_SPECIES_BALANCE_VERSION, getSlaSpeciesStatAdjustments } from "../sla-species-balance.js";
|
||||
import { buildSlaTraumaResponseText } from "../sla-trauma.js";
|
||||
|
||||
// Global event delegation to handle interactive range slider value updates
|
||||
// in a way that is fully compatible with Foundry VTT's HTML sanitization.
|
||||
if (typeof document !== "undefined") {
|
||||
document.addEventListener("input", (event) => {
|
||||
const target = event.target;
|
||||
if (target && target.tagName === "INPUT" && target.name === "rollModifier") {
|
||||
const value = Number(target.value) || 0;
|
||||
const label = target.closest(".resource")?.querySelector(".slider-value");
|
||||
if (label) {
|
||||
label.innerText = (value >= 0 ? "+" : "") + value;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const SLA_AMMO_TYPES = {
|
||||
STD: { label: "Standard", multiplier: 1, damageBonus: "", woundEffect: "", summary: "Standard ammunition." },
|
||||
AP: { label: "AP", multiplier: 2, damageBonus: "-1", woundEffect: "Gunshot [-]", summary: "Armour-piercing ammunition. Treat target armour as halved and reduce damage by 1." },
|
||||
@@ -1770,11 +1785,21 @@ export class MothershipActor extends Actor {
|
||||
//wrap skill list in a scrollable container so long lists don't push buttons off-screen
|
||||
const scrollableSkillList = `<div class="sla-skill-scroll-list" style="max-height: 340px; overflow-y: auto; padding-right: 4px; margin-bottom: 4px;">${skillList}</div>`;
|
||||
//create final dialog data
|
||||
const showModifier = !foundry.utils.hasProperty(context.attackContext ?? {}, "rollModifier");
|
||||
const modifierHtml = showModifier ? `
|
||||
<div class="resource" style="margin-top: 15px; margin-bottom: 10px; border-top: 1px dashed rgba(255,255,255,0.15); padding-top: 10px; padding-left: 10px; padding-right: 10px;">
|
||||
<label class="resource-label" style="display: flex; justify-content: space-between; font-weight: bold; margin-bottom: 8px;">
|
||||
<span>Roll Modifier</span>
|
||||
<span class="slider-value" style="font-weight: bold; color: #cc2828;">0</span>
|
||||
</label>
|
||||
<input type="range" name="rollModifier" min="-30" max="30" step="10" value="0" style="width: 100%; cursor: pointer; accent-color: #cc2828;" oninput="this.previousElementSibling.querySelector('.slider-value').innerText = (this.value >= 0 ? '+' : '') + this.value">
|
||||
</div>
|
||||
` : "";
|
||||
const dialogData = {
|
||||
window: {title: dlgTitle},
|
||||
classes: ["macro-popup-dialog"],
|
||||
position: {width: 600},
|
||||
content: skillHeader + scrollableSkillList + buttonDesc,
|
||||
content: skillHeader + scrollableSkillList + modifierHtml + buttonDesc,
|
||||
buttons: []
|
||||
};
|
||||
//add adv/normal/dis buttons if we need a rollString
|
||||
@@ -1788,8 +1813,9 @@ export class MothershipActor extends Actor {
|
||||
rollString = `1d100 [+]`;
|
||||
skill = button.form.querySelector("input[name='skill']:checked")?.getAttribute("id");
|
||||
skillValue = button.form.querySelector("input[name='skill']:checked")?.getAttribute("value");
|
||||
resolve([rollString, skill, skillValue]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}`);
|
||||
const rollModifier = showModifier ? (Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0) : (Number(context.attackContext?.rollModifier ?? 0) || 0);
|
||||
resolve([rollString, skill, skillValue, rollModifier]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-angle-double-up`
|
||||
},
|
||||
@@ -1800,8 +1826,9 @@ export class MothershipActor extends Actor {
|
||||
rollString = `1d100`;
|
||||
skill = button.form.querySelector("input[name='skill']:checked")?.getAttribute("id");
|
||||
skillValue = button.form.querySelector("input[name='skill']:checked")?.getAttribute("value");
|
||||
resolve([rollString, skill, skillValue]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}`);
|
||||
const rollModifier = showModifier ? (Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0) : (Number(context.attackContext?.rollModifier ?? 0) || 0);
|
||||
resolve([rollString, skill, skillValue, rollModifier]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-minus`
|
||||
},
|
||||
@@ -1812,8 +1839,9 @@ export class MothershipActor extends Actor {
|
||||
rollString = `1d100 [-]`;
|
||||
skill = button.form.querySelector("input[name='skill']:checked")?.getAttribute("id");
|
||||
skillValue = button.form.querySelector("input[name='skill']:checked")?.getAttribute("value");
|
||||
resolve([rollString, skill, skillValue]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}`);
|
||||
const rollModifier = showModifier ? (Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0) : (Number(context.attackContext?.rollModifier ?? 0) || 0);
|
||||
resolve([rollString, skill, skillValue, rollModifier]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-angle-double-down`
|
||||
}
|
||||
@@ -1827,8 +1855,9 @@ export class MothershipActor extends Actor {
|
||||
callback: (event, button, dialog) => {
|
||||
skill = button.form.querySelector("input[name='skill']:checked")?.getAttribute("id");
|
||||
skillValue = button.form.querySelector("input[name='skill']:checked")?.getAttribute("value");
|
||||
resolve([rollString, skill, skillValue]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}`);
|
||||
const rollModifier = showModifier ? (Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0) : (Number(context.attackContext?.rollModifier ?? 0) || 0);
|
||||
resolve([rollString, skill, skillValue, rollModifier]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-chevron-circle-right`
|
||||
}
|
||||
@@ -1849,19 +1878,29 @@ export class MothershipActor extends Actor {
|
||||
let dieAdv = die + ` [+]`;
|
||||
let dieDis = die + ` [-]`;
|
||||
//create final dialog data
|
||||
const modifierHtml = `
|
||||
<div class="resource" style="margin-top: 15px; margin-bottom: 10px; border-top: 1px dashed rgba(255,255,255,0.15); padding-top: 10px; padding-left: 10px; padding-right: 10px;">
|
||||
<label class="resource-label" style="display: flex; justify-content: space-between; font-weight: bold; margin-bottom: 8px;">
|
||||
<span>Roll Modifier</span>
|
||||
<span class="slider-value" style="font-weight: bold; color: #cc2828;">0</span>
|
||||
</label>
|
||||
<input type="range" name="rollModifier" min="-30" max="30" step="10" value="0" style="width: 100%; cursor: pointer; accent-color: #cc2828;" oninput="this.previousElementSibling.querySelector('.slider-value').innerText = (this.value >= 0 ? '+' : '') + this.value">
|
||||
</div>
|
||||
`;
|
||||
const dialogData = {
|
||||
window: {title: dlgTitle},
|
||||
classes: ["macro-popup-dialog"],
|
||||
position: {width: 600},
|
||||
content: `<div class="macro_prompt">` + game.i18n.localize("Mosh.SelectYourRollType") + `:</div>`,
|
||||
content: `<form style="padding: 5px 10px;"><div class="macro_prompt" style="margin-bottom:10px;">` + game.i18n.localize("Mosh.SelectYourRollType") + `:</div>` + modifierHtml + `</form>`,
|
||||
buttons: [
|
||||
{
|
||||
label: game.i18n.localize("Mosh.Advantage"),
|
||||
action: `action_advantage`,
|
||||
callback: (event, button, dialog) => {
|
||||
rollString = dieAdv;
|
||||
resolve([rollString]);
|
||||
slaDebug(`User left the chooseAdvantage dialog with: rollString:${rollString}`);
|
||||
const rollModifier = Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0;
|
||||
resolve([rollString, rollModifier]);
|
||||
slaDebug(`User left the chooseAdvantage dialog with: rollString:${rollString}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-angle-double-up`
|
||||
},
|
||||
@@ -1870,8 +1909,9 @@ export class MothershipActor extends Actor {
|
||||
action: `action_normal`,
|
||||
callback: (event, button, dialog) => {
|
||||
rollString = die;
|
||||
resolve([rollString]);
|
||||
slaDebug(`User left the chooseAdvantage dialog with: rollString:${rollString}`);
|
||||
const rollModifier = Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0;
|
||||
resolve([rollString, rollModifier]);
|
||||
slaDebug(`User left the chooseAdvantage dialog with: rollString:${rollString}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-minus`
|
||||
},
|
||||
@@ -1880,8 +1920,9 @@ export class MothershipActor extends Actor {
|
||||
action: `action_disadvantage`,
|
||||
callback: (event, button, dialog) => {
|
||||
rollString = dieDis;
|
||||
resolve([rollString]);
|
||||
slaDebug(`User left the chooseAdvantage dialog with: rollString:${rollString}`);
|
||||
const rollModifier = Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0;
|
||||
resolve([rollString, rollModifier]);
|
||||
slaDebug(`User left the chooseAdvantage dialog with: rollString:${rollString}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-angle-double-down`
|
||||
}
|
||||
@@ -2474,6 +2515,9 @@ export class MothershipActor extends Actor {
|
||||
rollString = chosenSkills[0];
|
||||
skill = chosenSkills[1];
|
||||
skillValue = chosenSkills[2];
|
||||
if (chosenSkills[3] !== undefined) {
|
||||
attackContext.rollModifier = chosenSkills[3];
|
||||
}
|
||||
}
|
||||
//if rollString is STILL blank, redirect player to choose the roll
|
||||
if (!rollString) {
|
||||
@@ -2481,6 +2525,9 @@ export class MothershipActor extends Actor {
|
||||
let chosenRollType = await this.chooseAdvantage(this.system.stats[attribute].rollLabel, '1d100');
|
||||
//set variables
|
||||
rollString = chosenRollType[0];
|
||||
if (chosenRollType[1] !== undefined) {
|
||||
attackContext.rollModifier = chosenRollType[1];
|
||||
}
|
||||
}
|
||||
//if this is a weapon roll
|
||||
if (weapon) {
|
||||
@@ -2635,6 +2682,18 @@ export class MothershipActor extends Actor {
|
||||
} else {
|
||||
rollTarget = rollTargetOverride;
|
||||
}
|
||||
const modifier = Number(attackContext?.rollModifier ?? 0) || 0;
|
||||
if (modifier) {
|
||||
rollTarget += modifier;
|
||||
if (effectiveRollBreakdown) {
|
||||
effectiveRollBreakdown.parts.push({
|
||||
label: "Roll Modifier",
|
||||
value: modifier
|
||||
});
|
||||
effectiveRollBreakdown.total += modifier;
|
||||
effectiveRollBreakdown.formulaText += ` ${modifier >= 0 ? "+" : ""}${modifier}`;
|
||||
}
|
||||
}
|
||||
rollTarget = this.clampSlaRollTarget(rollTarget, rollString);
|
||||
if (effectiveRollBreakdown && (String(rollString ?? "").includes("1d100"))) {
|
||||
effectiveRollBreakdown = {
|
||||
@@ -4005,10 +4064,58 @@ export class MothershipActor extends Actor {
|
||||
return { total, parts };
|
||||
}
|
||||
|
||||
async chooseWeaponAttackOptions(weapon) {
|
||||
async promptRollModifier(title = "Roll Modifier") {
|
||||
return new Promise((resolve) => {
|
||||
const dialogData = {
|
||||
window: { title },
|
||||
content: `
|
||||
<form style="padding: 5px 10px;">
|
||||
<div class="resource" style="margin-bottom: 15px;">
|
||||
<label class="resource-label" style="display: flex; justify-content: space-between; font-weight: bold; margin-bottom: 8px;">
|
||||
<span>Modifier Value</span>
|
||||
<span class="slider-value" style="font-weight: bold; color: #cc2828;">0</span>
|
||||
</label>
|
||||
<input type="range" name="rollModifier" min="-30" max="30" step="10" value="0" style="width: 100%; cursor: pointer; accent-color: #cc2828;">
|
||||
<div class="slider-ticks" style="display: flex; justify-content: space-between; margin-top: 5px; font-size: 0.85em; color: rgba(255,255,255,0.6); padding: 0 8px;">
|
||||
<span>-30</span>
|
||||
<span>-20</span>
|
||||
<span>-10</span>
|
||||
<span style="color: #cc2828; font-weight: bold;">0</span>
|
||||
<span>+10</span>
|
||||
<span>+20</span>
|
||||
<span>+30</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
`,
|
||||
buttons: [
|
||||
{
|
||||
label: "Roll",
|
||||
action: "roll",
|
||||
icon: "fas fa-dice-d20",
|
||||
callback: (_event, button) => {
|
||||
const modifier = Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0;
|
||||
resolve(modifier);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Cancel",
|
||||
action: "cancel",
|
||||
icon: "fas fa-times",
|
||||
callback: () => resolve(null)
|
||||
}
|
||||
],
|
||||
close: () => resolve(null)
|
||||
};
|
||||
new foundry.applications.api.DialogV2(dialogData).render({ force: true });
|
||||
});
|
||||
}
|
||||
|
||||
async chooseWeaponAttackOptions(weapon, attackContext = {}) {
|
||||
const fireModes = this.getWeaponFireModes(weapon);
|
||||
const activeFireMode = this.getActiveWeaponFireMode(weapon);
|
||||
const ammoChoices = this.getWeaponAmmoChoices(weapon);
|
||||
const showModifier = Boolean(attackContext?.promptModifier);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const fireOptions = fireModes.map((mode) => `
|
||||
@@ -4018,20 +4125,40 @@ export class MothershipActor extends Actor {
|
||||
<option value="${choice.tag}" ${choice.selected ? "selected" : ""}>${choice.label}</option>
|
||||
`).join("");
|
||||
|
||||
const modifierHtml = showModifier ? `
|
||||
<div class="resource" style="margin-top: 15px; margin-bottom: 10px; border-top: 1px dashed rgba(255,255,255,0.15); padding-top: 10px;">
|
||||
<label class="resource-label" style="display: flex; justify-content: space-between; font-weight: bold; margin-bottom: 8px;">
|
||||
<span>Roll Modifier</span>
|
||||
<span class="slider-value" style="font-weight: bold; color: #cc2828;">0</span>
|
||||
</label>
|
||||
<input type="range" name="rollModifier" min="-30" max="30" step="10" value="0" style="width: 100%; cursor: pointer; accent-color: #cc2828;">
|
||||
<div class="slider-ticks" style="display: flex; justify-content: space-between; margin-top: 5px; font-size: 0.85em; color: rgba(255,255,255,0.6); padding: 0 8px;">
|
||||
<span>-30</span>
|
||||
<span>-20</span>
|
||||
<span>-10</span>
|
||||
<span style="color: #cc2828; font-weight: bold;">0</span>
|
||||
<span>+10</span>
|
||||
<span>+20</span>
|
||||
<span>+30</span>
|
||||
</div>
|
||||
</div>
|
||||
` : "";
|
||||
|
||||
const dialogData = {
|
||||
window: {
|
||||
title: `${weapon.name} Attack Setup`
|
||||
},
|
||||
content: `
|
||||
<form>
|
||||
<form style="padding: 5px 10px;">
|
||||
<div class="resource" style="margin-bottom: 10px;">
|
||||
<label class="resource-label">Fire Mode</label>
|
||||
<select name="fireMode">${fireOptions}</select>
|
||||
<label class="resource-label" style="font-weight: bold; margin-bottom: 5px; display: block;">Fire Mode</label>
|
||||
<select name="fireMode" style="width: 100%;">${fireOptions}</select>
|
||||
</div>
|
||||
<div class="resource" style="margin-bottom: 10px;">
|
||||
<label class="resource-label">Ammo Type</label>
|
||||
<select name="ammoTag">${ammoOptions}</select>
|
||||
<label class="resource-label" style="font-weight: bold; margin-bottom: 5px; display: block;">Ammo Type</label>
|
||||
<select name="ammoTag" style="width: 100%;">${ammoOptions}</select>
|
||||
</div>
|
||||
${modifierHtml}
|
||||
</form>
|
||||
`,
|
||||
buttons: [
|
||||
@@ -4043,10 +4170,12 @@ export class MothershipActor extends Actor {
|
||||
const fireLabel = button.form.querySelector("select[name='fireMode']")?.value ?? activeFireMode.label;
|
||||
const fireMode = fireModes.find((mode) => mode.label === fireLabel) ?? activeFireMode;
|
||||
const ammoTag = button.form.querySelector("select[name='ammoTag']")?.value ?? ammoChoices[0]?.tag ?? "STD";
|
||||
const rollModifier = showModifier ? (Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0) : 0;
|
||||
resolve({
|
||||
fireMode: fireMode.label,
|
||||
shotsPerFire: fireMode.shots,
|
||||
ammoTag
|
||||
ammoTag,
|
||||
rollModifier
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -4063,10 +4192,20 @@ export class MothershipActor extends Actor {
|
||||
});
|
||||
}
|
||||
|
||||
async rollWeaponAttack(weapon) {
|
||||
const attackContext = weapon?.system?.useAmmo ? await this.chooseWeaponAttackOptions(weapon) : {};
|
||||
if (weapon?.system?.useAmmo && !attackContext) return;
|
||||
return this.rollCheck(null, 'low', 'combat', null, null, weapon, null, attackContext ?? {});
|
||||
async rollWeaponAttack(weapon, attackContext = {}) {
|
||||
let context = { ...attackContext };
|
||||
if (weapon?.system?.useAmmo) {
|
||||
const ammoContext = await this.chooseWeaponAttackOptions(weapon, context);
|
||||
if (!ammoContext) return null;
|
||||
context = { ...context, ...ammoContext };
|
||||
} else {
|
||||
if (context.promptModifier) {
|
||||
const rollMod = await this.promptRollModifier(`${weapon.name} Attack Roll`);
|
||||
if (rollMod === null) return null;
|
||||
context.rollModifier = rollMod;
|
||||
}
|
||||
}
|
||||
return this.rollCheck(null, 'low', 'combat', null, null, weapon, null, context);
|
||||
}
|
||||
|
||||
async cycleWeaponFireMode(itemId, direction = 1) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
MANIFEST-000075
|
||||
MANIFEST-000085
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/14-21:44:03.701190 170dcb000 Recovering log #73
|
||||
2026/04/14-21:44:03.701635 170dcb000 Delete type=3 #71
|
||||
2026/04/14-21:44:03.701777 170dcb000 Delete type=0 #73
|
||||
2026/05/19-23:19:40.611150 173b87000 Recovering log #84
|
||||
2026/05/19-23:19:40.611608 173b87000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.611656 173b87000 Delete type=0 #84
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
2026/04/14-14:29:42.528096 1725ef000 Recovering log #70
|
||||
2026/04/14-14:29:42.528525 1725ef000 Delete type=0 #70
|
||||
2026/04/14-14:29:42.528564 1725ef000 Delete type=3 #69
|
||||
2026/04/14-21:41:04.230515 172707000 Level-0 table #74: started
|
||||
2026/04/14-21:41:04.230654 172707000 Level-0 table #74: 0 bytes OK
|
||||
2026/04/14-21:41:04.230837 172707000 Delete type=0 #72
|
||||
2026/04/14-21:41:04.231926 172707000 Manual compaction at level-0 from '!items!1r6ruvSdxn2bHHIk' @ 72057594037927935 : 1 .. '!items!zbKI2RCl5h3vowoy' @ 0 : 0; will stop at (end)
|
||||
2026/04/16-22:16:27.606022 16eb7b000 Recovering log #82
|
||||
2026/04/16-22:16:27.612707 16eb7b000 Delete type=3 #81
|
||||
2026/04/16-22:16:27.612921 16eb7b000 Delete type=0 #82
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000075
|
||||
MANIFEST-000085
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/14-21:44:03.703209 171de3000 Recovering log #73
|
||||
2026/04/14-21:44:03.703506 171de3000 Delete type=3 #71
|
||||
2026/04/14-21:44:03.703538 171de3000 Delete type=0 #73
|
||||
2026/05/19-23:19:40.613309 172363000 Recovering log #84
|
||||
2026/05/19-23:19:40.613576 172363000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.613610 172363000 Delete type=0 #84
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
2026/04/14-14:29:42.530946 171de3000 Recovering log #70
|
||||
2026/04/14-14:29:42.531303 171de3000 Delete type=0 #70
|
||||
2026/04/14-14:29:42.531327 171de3000 Delete type=3 #69
|
||||
2026/04/14-21:41:04.231427 172707000 Level-0 table #74: started
|
||||
2026/04/14-21:41:04.231573 172707000 Level-0 table #74: 0 bytes OK
|
||||
2026/04/14-21:41:04.231822 172707000 Delete type=0 #72
|
||||
2026/04/14-21:41:04.231960 172707000 Manual compaction at level-0 from '!items!0ZAwhewvLBwX3opf' @ 72057594037927935 : 1 .. '!items!z0avrplKe6M0RcXk' @ 0 : 0; will stop at (end)
|
||||
2026/04/16-22:16:27.615553 16f387000 Recovering log #82
|
||||
2026/04/16-22:16:27.616188 16f387000 Delete type=3 #81
|
||||
2026/04/16-22:16:27.616243 16f387000 Delete type=0 #82
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000075
|
||||
MANIFEST-000085
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/14-21:44:03.705381 1725ef000 Recovering log #73
|
||||
2026/04/14-21:44:03.705808 1725ef000 Delete type=3 #71
|
||||
2026/04/14-21:44:03.705977 1725ef000 Delete type=0 #73
|
||||
2026/05/19-23:19:40.614698 172b6f000 Recovering log #84
|
||||
2026/05/19-23:19:40.614916 172b6f000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.614942 172b6f000 Delete type=0 #84
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
2026/04/14-14:29:42.533049 170dcb000 Recovering log #70
|
||||
2026/04/14-14:29:42.533339 170dcb000 Delete type=0 #70
|
||||
2026/04/14-14:29:42.533362 170dcb000 Delete type=3 #69
|
||||
2026/04/14-21:41:04.229609 172707000 Level-0 table #74: started
|
||||
2026/04/14-21:41:04.229909 172707000 Level-0 table #74: 0 bytes OK
|
||||
2026/04/14-21:41:04.230444 172707000 Delete type=0 #72
|
||||
2026/04/14-21:41:04.231906 172707000 Manual compaction at level-0 from '!items!1HNvL7XEUcMQbLps' @ 72057594037927935 : 1 .. '!items!zRzb3Laiuw4ac6p0' @ 0 : 0; will stop at (end)
|
||||
2026/04/16-22:16:27.618035 16fb93000 Recovering log #82
|
||||
2026/04/16-22:16:27.618455 16fb93000 Delete type=3 #81
|
||||
2026/04/16-22:16:27.618488 16fb93000 Delete type=0 #82
|
||||
|
||||
BIN
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000075
|
||||
MANIFEST-000085
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/14-21:44:03.707592 170dcb000 Recovering log #73
|
||||
2026/04/14-21:44:03.708035 170dcb000 Delete type=3 #71
|
||||
2026/04/14-21:44:03.708118 170dcb000 Delete type=0 #73
|
||||
2026/05/19-23:19:40.615928 17337b000 Recovering log #84
|
||||
2026/05/19-23:19:40.616184 17337b000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.616214 17337b000 Delete type=0 #84
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
2026/04/14-14:29:42.534696 1725ef000 Recovering log #70
|
||||
2026/04/14-14:29:42.534932 1725ef000 Delete type=0 #70
|
||||
2026/04/14-14:29:42.534950 1725ef000 Delete type=3 #69
|
||||
2026/04/14-21:41:04.230890 172707000 Level-0 table #74: started
|
||||
2026/04/14-21:41:04.231026 172707000 Level-0 table #74: 0 bytes OK
|
||||
2026/04/14-21:41:04.231365 172707000 Delete type=0 #72
|
||||
2026/04/14-21:41:04.231944 172707000 Manual compaction at level-0 from '!macros!2xRvRAixuocjCm40' @ 72057594037927935 : 1 .. '!macros!ilBclUmPwcd7aNQK' @ 0 : 0; will stop at (end)
|
||||
2026/04/16-22:16:27.619986 16e36f000 Recovering log #82
|
||||
2026/04/16-22:16:27.620339 16e36f000 Delete type=3 #81
|
||||
2026/04/16-22:16:27.620370 16e36f000 Delete type=0 #82
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000075
|
||||
MANIFEST-000085
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/14-21:44:03.709360 171de3000 Recovering log #73
|
||||
2026/04/14-21:44:03.709675 171de3000 Delete type=3 #71
|
||||
2026/04/14-21:44:03.709706 171de3000 Delete type=0 #73
|
||||
2026/05/19-23:19:40.617145 17337b000 Recovering log #84
|
||||
2026/05/19-23:19:40.617442 17337b000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.617486 17337b000 Delete type=0 #84
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
2026/04/14-14:29:42.536078 171de3000 Recovering log #70
|
||||
2026/04/14-14:29:42.536336 171de3000 Delete type=0 #70
|
||||
2026/04/14-14:29:42.536359 171de3000 Delete type=3 #69
|
||||
2026/04/14-21:41:04.232630 172707000 Level-0 table #74: started
|
||||
2026/04/14-21:41:04.232740 172707000 Level-0 table #74: 0 bytes OK
|
||||
2026/04/14-21:41:04.232976 172707000 Delete type=0 #72
|
||||
2026/04/14-21:41:04.234457 172707000 Manual compaction at level-0 from '!macros!2u4a5gEogtLd3XQz' @ 72057594037927935 : 1 .. '!macros!trU0DtBJvJCPddsQ' @ 0 : 0; will stop at (end)
|
||||
2026/04/16-22:16:27.621457 16e36f000 Recovering log #82
|
||||
2026/04/16-22:16:27.621716 16e36f000 Delete type=3 #81
|
||||
2026/04/16-22:16:27.621743 16e36f000 Delete type=0 #82
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000075
|
||||
MANIFEST-000085
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/14-21:44:03.710794 170dcb000 Recovering log #73
|
||||
2026/04/14-21:44:03.711256 170dcb000 Delete type=3 #71
|
||||
2026/04/14-21:44:03.711288 170dcb000 Delete type=0 #73
|
||||
2026/05/19-23:19:40.618390 17337b000 Recovering log #84
|
||||
2026/05/19-23:19:40.618663 17337b000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.618694 17337b000 Delete type=0 #84
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
2026/04/14-14:29:42.537344 1715d7000 Recovering log #70
|
||||
2026/04/14-14:29:42.537597 1715d7000 Delete type=0 #70
|
||||
2026/04/14-14:29:42.537618 1715d7000 Delete type=3 #69
|
||||
2026/04/14-21:41:04.232083 172707000 Level-0 table #74: started
|
||||
2026/04/14-21:41:04.232272 172707000 Level-0 table #74: 0 bytes OK
|
||||
2026/04/14-21:41:04.232554 172707000 Delete type=0 #72
|
||||
2026/04/14-21:41:04.234426 172707000 Manual compaction at level-0 from '!macros!0Yw4QWSAeOuUzRqB' @ 72057594037927935 : 1 .. '!macros!z5V92LyXHjfMxnRQ' @ 0 : 0; will stop at (end)
|
||||
2026/04/16-22:16:27.622897 16e36f000 Recovering log #82
|
||||
2026/04/16-22:16:27.623174 16e36f000 Delete type=3 #81
|
||||
2026/04/16-22:16:27.623240 16e36f000 Delete type=0 #82
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000077
|
||||
MANIFEST-000087
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/14-21:44:03.713901 1725ef000 Recovering log #75
|
||||
2026/04/14-21:44:03.714351 1725ef000 Delete type=0 #75
|
||||
2026/04/14-21:44:03.714384 1725ef000 Delete type=3 #73
|
||||
2026/05/19-23:19:40.619688 17337b000 Recovering log #86
|
||||
2026/05/19-23:19:40.620003 17337b000 Delete type=3 #85
|
||||
2026/05/19-23:19:40.620026 17337b000 Delete type=0 #86
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
2026/04/14-14:29:42.538470 1725ef000 Recovering log #72
|
||||
2026/04/14-14:29:42.538719 1725ef000 Delete type=3 #71
|
||||
2026/04/14-14:29:42.538747 1725ef000 Delete type=0 #72
|
||||
2026/04/14-21:41:04.233774 172707000 Level-0 table #76: started
|
||||
2026/04/14-21:41:04.233930 172707000 Level-0 table #76: 0 bytes OK
|
||||
2026/04/14-21:41:04.234304 172707000 Delete type=0 #74
|
||||
2026/04/14-21:41:04.234513 172707000 Manual compaction at level-0 from '!macros!06NSvDYTtmkeUtLq' @ 72057594037927935 : 1 .. '!macros!zLRsweb35Lw0NMev' @ 0 : 0; will stop at (end)
|
||||
2026/04/16-22:16:27.624570 16e36f000 Recovering log #84
|
||||
2026/04/16-22:16:27.625146 16e36f000 Delete type=3 #83
|
||||
2026/04/16-22:16:27.625212 16e36f000 Delete type=0 #84
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000075
|
||||
MANIFEST-000085
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/14-21:44:03.716230 1715d7000 Recovering log #73
|
||||
2026/04/14-21:44:03.716588 1715d7000 Delete type=3 #71
|
||||
2026/04/14-21:44:03.716645 1715d7000 Delete type=0 #73
|
||||
2026/05/19-23:19:40.621197 17337b000 Recovering log #84
|
||||
2026/05/19-23:19:40.621497 17337b000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.621534 17337b000 Delete type=0 #84
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
2026/04/14-14:29:42.540072 170dcb000 Recovering log #70
|
||||
2026/04/14-14:29:42.540350 170dcb000 Delete type=0 #70
|
||||
2026/04/14-14:29:42.540376 170dcb000 Delete type=3 #69
|
||||
2026/04/14-21:41:04.233064 172707000 Level-0 table #74: started
|
||||
2026/04/14-21:41:04.233246 172707000 Level-0 table #74: 0 bytes OK
|
||||
2026/04/14-21:41:04.233613 172707000 Delete type=0 #72
|
||||
2026/04/14-21:41:04.234486 172707000 Manual compaction at level-0 from '!tables!1vCm4ElRPotQXgNB' @ 72057594037927935 : 1 .. '!tables.results!kqKpQAXyLTEEyz6Z.xdwwswzfoPuVifvw' @ 0 : 0; will stop at (end)
|
||||
2026/04/16-22:16:27.626995 16e36f000 Recovering log #82
|
||||
2026/04/16-22:16:27.627395 16e36f000 Delete type=3 #81
|
||||
2026/04/16-22:16:27.627527 16e36f000 Delete type=0 #82
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000075
|
||||
MANIFEST-000085
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/14-21:44:03.718522 170dcb000 Recovering log #73
|
||||
2026/04/14-21:44:03.718938 170dcb000 Delete type=3 #71
|
||||
2026/04/14-21:44:03.718979 170dcb000 Delete type=0 #73
|
||||
2026/05/19-23:19:40.622748 173b87000 Recovering log #84
|
||||
2026/05/19-23:19:40.622969 173b87000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.622990 173b87000 Delete type=0 #84
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
2026/04/14-14:29:42.542090 1715d7000 Recovering log #70
|
||||
2026/04/14-14:29:42.542385 1715d7000 Delete type=0 #70
|
||||
2026/04/14-14:29:42.542403 1715d7000 Delete type=3 #69
|
||||
2026/04/14-21:41:04.234643 172707000 Level-0 table #74: started
|
||||
2026/04/14-21:41:04.234976 172707000 Level-0 table #74: 0 bytes OK
|
||||
2026/04/14-21:41:04.235710 172707000 Delete type=0 #72
|
||||
2026/04/14-21:41:04.240761 172707000 Manual compaction at level-0 from '!tables!31YibfjueXuZdNLb' @ 72057594037927935 : 1 .. '!tables.results!ypcoikqHLhnc9tNs.zJkYrssfrdWBSeRm' @ 0 : 0; will stop at (end)
|
||||
2026/04/16-22:16:27.629071 16fb93000 Recovering log #82
|
||||
2026/04/16-22:16:27.629605 16fb93000 Delete type=3 #81
|
||||
2026/04/16-22:16:27.629821 16fb93000 Delete type=0 #82
|
||||
|
||||
Binary file not shown.
@@ -70,6 +70,13 @@
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#unless isSlaEbbSkill}}
|
||||
{{#if rollBreakdown}}
|
||||
<div class="sla-chat-section sla-chat-section-meta" style="margin-top: 5px; border-top: 1px dashed rgba(255,255,255,0.15); padding-top: 5px;">
|
||||
<div class="body"><strong>Target Number:</strong> {{#each rollBreakdown.parts as |part index|}}{{#if index}} + {{/if}}{{part.label}} {{part.value}}{{/each}} = <strong>{{rollBreakdown.total}}</strong></div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
|
||||
{{#if (compare 'str' specialRoll '===' 'damage')}}
|
||||
|
||||
Reference in New Issue
Block a user