Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96896ba92f | ||
|
|
6557ef82ad | ||
|
|
17c64ec0de |
+180
-13
@@ -4775,11 +4775,21 @@ p {
|
||||
.mosh.sla-chat-shell .sla-chat-section-danger.sla-severity-minor {
|
||||
background: linear-gradient(180deg, rgba(92, 57, 18, 0.96), rgba(55, 34, 12, 0.96));
|
||||
border-color: rgba(255, 190, 74, 0.5);
|
||||
color: #ffeacc;
|
||||
}
|
||||
|
||||
.mosh.sla-chat-shell .sla-chat-section-danger.sla-severity-minor strong {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.mosh.sla-chat-shell .sla-chat-section-danger.sla-severity-severe {
|
||||
background: linear-gradient(180deg, rgba(90, 18, 26, 0.97), rgba(52, 10, 15, 0.97));
|
||||
border-color: rgba(255, 91, 91, 0.52);
|
||||
color: #ffdada;
|
||||
}
|
||||
|
||||
.mosh.sla-chat-shell .sla-chat-section-danger.sla-severity-severe strong {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.mosh.sla-chat-shell .sla-chat-section-danger.sla-severity-critical {
|
||||
@@ -4788,6 +4798,11 @@ p {
|
||||
linear-gradient(180deg, rgba(102, 8, 28, 0.98), rgba(45, 8, 21, 0.98));
|
||||
border-color: rgba(204, 237, 255, 0.84);
|
||||
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.06), 0 0 14px rgba(162, 231, 255, 0.08);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.mosh.sla-chat-shell .sla-chat-section-danger.sla-severity-critical strong {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.mosh.sla-chat-shell .sla-chat-section-target {
|
||||
@@ -4983,26 +4998,25 @@ p {
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.mosh .sla-severity-minor,
|
||||
.mosh .sla-chat-severity-pill.sla-severity-minor {
|
||||
background: linear-gradient(180deg, rgba(255, 216, 140, 0.32), rgba(255, 189, 79, 0.18));
|
||||
border-color: rgba(224, 152, 24, 0.42);
|
||||
color: #9b5b00;
|
||||
background: linear-gradient(180deg, #ffc866 0%, #ff9d00 100%);
|
||||
border-color: #ffbe4a;
|
||||
color: #1a1000 !important;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.mosh .sla-severity-severe,
|
||||
.mosh .sla-chat-severity-pill.sla-severity-severe {
|
||||
background: linear-gradient(180deg, rgba(255, 145, 145, 0.24), rgba(233, 63, 63, 0.14));
|
||||
border-color: rgba(179, 27, 27, 0.34);
|
||||
color: #9e1717;
|
||||
background: linear-gradient(180deg, #ff8080 0%, #cc0000 100%);
|
||||
border-color: #ff5b5b;
|
||||
color: #ffffff !important;
|
||||
text-shadow: 0 1px 1px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.mosh .sla-severity-critical,
|
||||
.mosh .sla-chat-severity-pill.sla-severity-critical {
|
||||
background: linear-gradient(180deg, rgba(232, 247, 255, 0.94), rgba(196, 233, 255, 0.82));
|
||||
border-color: rgba(84, 145, 199, 0.42);
|
||||
color: #611120;
|
||||
box-shadow: 0 0 14px rgba(126, 196, 245, 0.16);
|
||||
background: linear-gradient(180deg, #9ae6ff 0%, #0099ff 100%);
|
||||
border-color: #54a5d6;
|
||||
color: #001a33 !important;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.mosh .sla-chat-section-target {
|
||||
@@ -5473,3 +5487,156 @@ p {
|
||||
border-radius: 3px;
|
||||
background: rgba(139, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
SLA Industries — Sidebar Tabs and Scene Controls Modern Overhaul
|
||||
============================================================================= */
|
||||
|
||||
/* ── Scene Controls (Left Panel) ────────────────────────────────────────── */
|
||||
#controls {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
#controls ol.main-controls,
|
||||
#controls ol.sub-controls {
|
||||
pointer-events: auto !important;
|
||||
background: rgba(10, 12, 16, 0.88) !important;
|
||||
border: 1px solid rgba(0, 229, 255, 0.2) !important;
|
||||
border-radius: 10px !important;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.65), 0 0 14px rgba(0, 229, 255, 0.08) !important;
|
||||
backdrop-filter: blur(12px) !important;
|
||||
padding: 5px !important;
|
||||
gap: 5px !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
|
||||
#controls li.scene-control,
|
||||
#controls li.control-tool {
|
||||
position: relative !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.06) !important;
|
||||
background: rgba(255, 255, 255, 0.02) !important;
|
||||
color: #8fa4b8 !important; /* Premium muted steel-blue */
|
||||
border-radius: 8px !important;
|
||||
width: 36px !important;
|
||||
height: 36px !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
transition: all 0.22s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||
cursor: pointer !important;
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02) !important;
|
||||
}
|
||||
|
||||
/* Hover State */
|
||||
#controls li.scene-control:hover,
|
||||
#controls li.control-tool:hover {
|
||||
color: #00e5ff !important; /* Vibrant Neon Cyan */
|
||||
background: rgba(0, 229, 255, 0.1) !important;
|
||||
border-color: rgba(0, 229, 255, 0.5) !important;
|
||||
box-shadow: 0 0 14px rgba(0, 229, 255, 0.35), inset 0 1px 0 rgba(0, 229, 255, 0.15) !important;
|
||||
transform: translateY(-1px) scale(1.04) !important;
|
||||
}
|
||||
|
||||
/* Active State */
|
||||
#controls li.scene-control.active,
|
||||
#controls li.control-tool.active {
|
||||
color: #00e5ff !important;
|
||||
background: rgba(0, 229, 255, 0.16) !important;
|
||||
border-color: #00e5ff !important;
|
||||
box-shadow: 0 0 20px rgba(0, 229, 255, 0.5), inset 0 1px 0 rgba(0, 229, 255, 0.25) !important;
|
||||
}
|
||||
|
||||
/* Active side indicator bar */
|
||||
#controls li.scene-control.active::before,
|
||||
#controls li.control-tool.active::before {
|
||||
content: "" !important;
|
||||
position: absolute !important;
|
||||
left: -2px !important;
|
||||
top: 15% !important;
|
||||
height: 70% !important;
|
||||
width: 2px !important;
|
||||
background: #00e5ff !important;
|
||||
box-shadow: 0 0 8px #00e5ff, 0 0 15px #00e5ff !important;
|
||||
border-radius: 2px !important;
|
||||
}
|
||||
|
||||
/* Sub-controls offset container glow adjustment */
|
||||
#controls ol.sub-controls {
|
||||
border-color: rgba(0, 229, 255, 0.14) !important;
|
||||
background: rgba(14, 18, 24, 0.82) !important;
|
||||
}
|
||||
|
||||
|
||||
/* ── Right Sidebar Tabs (Navigation Panel) ─────────────────────────────── */
|
||||
#sidebar-tabs {
|
||||
background: rgba(10, 12, 16, 0.88) !important;
|
||||
border-bottom: 2px solid rgba(0, 229, 255, 0.25) !important;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.05) !important;
|
||||
backdrop-filter: blur(12px) !important;
|
||||
border-radius: 8px 8px 0 0 !important;
|
||||
padding: 3px 5px !important;
|
||||
gap: 4px !important;
|
||||
display: flex !important;
|
||||
margin: 0 !important;
|
||||
border-top: none !important;
|
||||
}
|
||||
|
||||
#sidebar-tabs button[data-tab],
|
||||
#sidebar-tabs [data-tab].icon,
|
||||
#sidebar-tabs .item {
|
||||
position: relative !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.06) !important;
|
||||
background: rgba(255, 255, 255, 0.02) !important;
|
||||
color: #8fa4b8 !important;
|
||||
border-radius: 6px !important;
|
||||
margin: 2px 0 !important;
|
||||
height: 32px !important;
|
||||
transition: all 0.22s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||
cursor: pointer !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02) !important;
|
||||
flex: 1 !important;
|
||||
}
|
||||
|
||||
/* Hover State */
|
||||
#sidebar-tabs button[data-tab]:hover,
|
||||
#sidebar-tabs [data-tab].icon:hover,
|
||||
#sidebar-tabs .item:hover {
|
||||
color: #00e5ff !important;
|
||||
background: rgba(0, 229, 255, 0.1) !important;
|
||||
border-color: rgba(0, 229, 255, 0.5) !important;
|
||||
box-shadow: 0 0 14px rgba(0, 229, 255, 0.35), inset 0 1px 0 rgba(0, 229, 255, 0.15) !important;
|
||||
transform: translateY(-1px) scale(1.04) !important;
|
||||
}
|
||||
|
||||
/* Active State */
|
||||
#sidebar-tabs button[data-tab].active,
|
||||
#sidebar-tabs [data-tab].icon.active,
|
||||
#sidebar-tabs .item.active {
|
||||
color: #00e5ff !important;
|
||||
background: rgba(0, 229, 255, 0.16) !important;
|
||||
border-color: #00e5ff !important;
|
||||
box-shadow: 0 0 18px rgba(0, 229, 255, 0.45), inset 0 1px 0 rgba(0, 229, 255, 0.25) !important;
|
||||
}
|
||||
|
||||
/* Glowing bottom line indicator on active tabs */
|
||||
#sidebar-tabs button[data-tab].active::after,
|
||||
#sidebar-tabs [data-tab].icon.active::after,
|
||||
#sidebar-tabs .item.active::after {
|
||||
content: "" !important;
|
||||
position: absolute !important;
|
||||
bottom: -3px !important;
|
||||
left: 15% !important;
|
||||
width: 70% !important;
|
||||
height: 2px !important;
|
||||
background: #00e5ff !important;
|
||||
box-shadow: 0 0 8px #00e5ff, 0 0 15px #00e5ff !important;
|
||||
border-radius: 2px !important;
|
||||
}
|
||||
|
||||
|
||||
+27
-7
@@ -2031,19 +2031,29 @@ export class MothershipActor extends Actor {
|
||||
if (rawFormula === "Str/10") {
|
||||
rawFormula = `floor((${this.system.stats.strength.value} + ${(Number(this.system.stats.strength.mod) || 0)}) / 10)`;
|
||||
}
|
||||
const mult = Number(weapon?.system?.sla?.damageMultiplier ?? weapon?.system?.damageMultiplier ?? 1) || 1;
|
||||
if (mult > 1) {
|
||||
if (/^\d+d\d+/i.test(rawFormula)) {
|
||||
rawFormula = rawFormula.replace(/^(\d+)(d\d+)/i, (match, dice, rest) => {
|
||||
return `${Number(dice) * mult}${rest}`;
|
||||
});
|
||||
} else {
|
||||
rawFormula = `(${rawFormula}) * ${mult}`;
|
||||
}
|
||||
}
|
||||
const critDamageMode = game.settings.get('sla-mothership', 'critDamage');
|
||||
|
||||
if (isCritical) {
|
||||
if (critDamageMode === 'advantage') {
|
||||
rawFormula = `{${parsedDamageString},${parsedDamageString}}kh`;
|
||||
rawFormula = `{${rawFormula},${rawFormula}}kh`;
|
||||
} else if (critDamageMode === 'doubleDamage') {
|
||||
rawFormula = `(${parsedDamageString}) * 2`;
|
||||
rawFormula = `(${rawFormula}) * 2`;
|
||||
} else if (critDamageMode === 'doubleDice') {
|
||||
rawFormula = `${parsedDamageString} + ${parsedDamageString}`;
|
||||
rawFormula = `${rawFormula} + ${rawFormula}`;
|
||||
} else if (critDamageMode === 'maxDamage') {
|
||||
rawFormula = parsedDamageString.replaceAll('d', ' * ');
|
||||
rawFormula = rawFormula.replaceAll('d', ' * ');
|
||||
} else if (critDamageMode === 'weaponValue') {
|
||||
rawFormula = `${parsedDamageString} + ${weapon?.system?.critDmg || 0}`;
|
||||
rawFormula = `${rawFormula} + ${weapon?.system?.critDmg || 0}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2587,7 +2597,15 @@ export class MothershipActor extends Actor {
|
||||
//if this is a damage roll
|
||||
if (specialRoll === 'damage') {
|
||||
//parse the roll string
|
||||
let damageRollString = weapon.system.damage
|
||||
let damageRollString = weapon.system.damage;
|
||||
if (weapon && !overrideDamagaRollString) {
|
||||
const mult = Number(weapon.system?.sla?.damageMultiplier ?? weapon.system?.damageMultiplier ?? 1) || 1;
|
||||
if (mult > 1) {
|
||||
damageRollString = damageRollString.replace(/^(\d+)(d\d+)/i, (match, dice, rest) => {
|
||||
return `${Number(dice) * mult}${rest}`;
|
||||
});
|
||||
}
|
||||
}
|
||||
if(overrideDamagaRollString){
|
||||
damageRollString = overrideDamagaRollString;
|
||||
}
|
||||
@@ -2606,8 +2624,10 @@ export class MothershipActor extends Actor {
|
||||
}
|
||||
//prepare flavortext
|
||||
if (weapon.system.damage === "Str/10" && this.type === 'character') {
|
||||
const mult = Number(weapon.system?.sla?.damageMultiplier ?? weapon.system?.damageMultiplier ?? 1) || 1;
|
||||
const multStr = mult > 1 ? `${mult} * ` : '';
|
||||
//determine the damage string
|
||||
flavorText = 'You strike your target for <strong>[[floor((' + this.system.stats.strength.value + ' + ' + (Number(this.system.stats.strength.mod) || 0) + ')/10)]] damage</strong>.';
|
||||
flavorText = 'You strike your target for <strong>[[' + multStr + 'floor((' + this.system.stats.strength.value + ' + ' + (Number(this.system.stats.strength.mod) || 0) + ')/10)]] damage</strong>.';
|
||||
} else {
|
||||
flavorText = 'You inflict [[' + parsedDamageString + '[' + dsnTheme + ']' + critMod + ']] points of damage.';
|
||||
}
|
||||
|
||||
+142
-1
@@ -152,8 +152,26 @@ Hooks.once('init', async function () {
|
||||
// character generator creates many items in rapid succession (each createItem
|
||||
// hook call would otherwise race to delete the same Ebb items concurrently).
|
||||
const _pendingEbbEnforcement = new Map();
|
||||
Hooks.on("createItem", (item) => {
|
||||
Hooks.on("createItem", async (item, options, userId) => {
|
||||
// ── Unarmed Combat Auto-Skill Drop ──
|
||||
const actor = item.parent;
|
||||
if (actor && actor.documentName === "Actor" && item.type === "weapon" && String(item.name).trim().toLowerCase() === "unarmed combat") {
|
||||
const hasSkill = actor.items.some(i => i.type === "skill" && String(i.name).trim().toLowerCase() === "unarmed combat");
|
||||
if (!hasSkill) {
|
||||
await actor.createEmbeddedDocuments("Item", [{
|
||||
name: "Unarmed Combat",
|
||||
type: "skill",
|
||||
img: "icons/svg/fist.svg",
|
||||
system: {
|
||||
rank: "Trained",
|
||||
bonus: 10,
|
||||
sla: { category: "combat", skillFamily: "", source: "Unarmed Item Drop" }
|
||||
}
|
||||
}]);
|
||||
ui.notifications.info(`Added 'Unarmed Combat' skill to ${actor.name}.`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!actor || actor.type !== "character" || typeof actor.enforceSlaEbbEligibility !== "function") return;
|
||||
if (actor.isSlaEbbUser?.()) return;
|
||||
if (_pendingEbbEnforcement.has(actor.id)) clearTimeout(_pendingEbbEnforcement.get(actor.id));
|
||||
@@ -358,6 +376,129 @@ Hooks.on("renderChatMessageHTML", (app, html) => {
|
||||
await actor.rollSlaWoundEffect(effectKey, modifier);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Critical Hit? Button Handler ──
|
||||
root.querySelectorAll(".sla-crit-hit-btn").forEach((button) => {
|
||||
button.addEventListener("click", async (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const actorId = button.dataset.actorId;
|
||||
const itemId = button.dataset.itemId;
|
||||
const actor = actorId ? game.actors?.get(actorId) : null;
|
||||
if (!actor) {
|
||||
ui.notifications.warn("The actor for this critical hit could not be found.");
|
||||
return;
|
||||
}
|
||||
|
||||
const weapon = itemId ? actor.items.get(itemId) : null;
|
||||
|
||||
// Determine wound setting key based on weapon and damage type
|
||||
let settingKey = 'table1eWoundBluntForce';
|
||||
let tableLabel = 'Blunt Force';
|
||||
|
||||
if (weapon) {
|
||||
const name = String(weapon.name ?? "").toLowerCase();
|
||||
const damageType = String(weapon.system?.sla?.damageType ?? "").toLowerCase();
|
||||
|
||||
if (damageType.includes("blunt") || damageType.includes("impact")) {
|
||||
settingKey = 'table1eWoundBluntForce';
|
||||
tableLabel = 'Blunt Force';
|
||||
} else if (damageType.includes("penetrating") || damageType.includes("pierce") || damageType.includes("stab") || damageType.includes("bullet") || damageType.includes("shot")) {
|
||||
settingKey = 'table1eWoundGunshot';
|
||||
tableLabel = 'Gunshot';
|
||||
} else if (damageType.includes("slash") || damageType.includes("rend") || damageType.includes("bleed") || damageType.includes("cut")) {
|
||||
settingKey = 'table1eWoundBleeding';
|
||||
tableLabel = 'Bleeding';
|
||||
} else if (damageType.includes("fire") || damageType.includes("explos") || damageType.includes("acid") || damageType.includes("burn")) {
|
||||
settingKey = 'table1eWoundFireExplosives';
|
||||
tableLabel = 'Fire & Explosives';
|
||||
} else if (name.includes("pistol") || name.includes("smg") || name.includes("rifle") || name.includes("shotgun") || name.includes("blunderbuss") || name.includes("gun") || name.includes("harpoon") || name.includes("bullet") || name.includes("projectile") || name.includes("crossbow")) {
|
||||
settingKey = 'table1eWoundGunshot';
|
||||
tableLabel = 'Gunshot';
|
||||
} else if (name.includes("machete") || name.includes("cleaver") || name.includes("whip") || name.includes("blade") || name.includes("knife") || name.includes("sword") || name.includes("claws") || name.includes("bite") || name.includes("razor") || name.includes("teeth")) {
|
||||
settingKey = 'table1eWoundBleeding';
|
||||
tableLabel = 'Bleeding';
|
||||
} else if (name.includes("club") || name.includes("pipe") || name.includes("hammer") || name.includes("prod") || name.includes("unarmed") || name.includes("fist") || name.includes("strike") || name.includes("blunt") || name.includes("brawl") || name.includes("cuff")) {
|
||||
settingKey = 'table1eWoundBluntForce';
|
||||
tableLabel = 'Blunt Force';
|
||||
} else if (name.includes("bomb") || name.includes("acid") || name.includes("spit") || name.includes("fire") || name.includes("flame") || name.includes("grenade") || name.includes("explosive")) {
|
||||
settingKey = 'table1eWoundFireExplosives';
|
||||
tableLabel = 'Fire & Explosives';
|
||||
}
|
||||
}
|
||||
|
||||
const tableId = game.settings.get('sla-mothership', settingKey);
|
||||
if (!tableId) {
|
||||
ui.notifications.warn(`No wound table is configured for ${tableLabel}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Resolve the table
|
||||
let resolved = game.tables.get(tableId) || game.tables.getName(tableId);
|
||||
if (!resolved) {
|
||||
for (const pack of game.packs) {
|
||||
if (pack.metadata.type === "RollTable") {
|
||||
const index = await pack.getIndex();
|
||||
const entry = index.find(e => e.id === tableId || e.name === tableId || e.name === `${tableLabel} Wound` || e.name === tableLabel.replace(/&/g, "and"));
|
||||
if (entry) {
|
||||
resolved = await pack.getDocument(entry._id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!resolved) {
|
||||
ui.notifications.warn(`The ${tableLabel} wound table could not be found.`);
|
||||
return;
|
||||
}
|
||||
|
||||
await actor.rollTable(resolved.uuid ?? resolved.id ?? tableId, resolved.formula ?? "1d10", "low", true, false, null, null);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Critical Success Option Button Handler ──
|
||||
root.querySelectorAll(".sla-crit-option-btn").forEach((button) => {
|
||||
button.addEventListener("click", async (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const actorId = button.dataset.actorId;
|
||||
const optionText = button.dataset.optionText;
|
||||
const actor = actorId ? game.actors?.get(actorId) : null;
|
||||
const actorName = actor ? actor.name : "An operative";
|
||||
|
||||
const chatContent = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/sla-mothership/templates/chat/sla-critical-selection.html',
|
||||
{
|
||||
actorName: actorName,
|
||||
img: actor?.img ?? 'icons/svg/mystery-man.svg',
|
||||
optionText: optionText
|
||||
}
|
||||
);
|
||||
|
||||
await ChatMessage.create({
|
||||
user: game.user.id,
|
||||
content: chatContent,
|
||||
speaker: ChatMessage.getSpeaker({ actor: actor })
|
||||
});
|
||||
|
||||
// Disable all options in the card
|
||||
const container = button.closest(".sla-crit-success-options");
|
||||
if (container) {
|
||||
container.querySelectorAll(".sla-crit-option-btn").forEach(btn => {
|
||||
btn.disabled = true;
|
||||
btn.style.opacity = 0.6;
|
||||
btn.style.cursor = "default";
|
||||
if (btn === button) {
|
||||
btn.style.background = "#0f300f";
|
||||
btn.style.border = "1px solid #1ebd1e";
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//add custom damage dice for MOSH
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"id": "sla-mothership",
|
||||
"title": "SLA Mothership",
|
||||
"description": "An SLA Industries conversion built on the unofficial Mothership system for Foundry VTT, preserving Mothership's core mechanics while adding SLA flux, Ebb, BPN, and equipment support.",
|
||||
"version": "0.6.4",
|
||||
"version": "0.6.9",
|
||||
"esmodules": [
|
||||
"module/mosh.js"
|
||||
],
|
||||
|
||||
@@ -81,6 +81,11 @@
|
||||
|
||||
{{#if (compare 'str' specialRoll '===' 'damage')}}
|
||||
<div class="sla-chat-section sla-chat-section-damage">{{{flavorText}}}</div>
|
||||
<div class="sla-chat-section sla-chat-section-crit-btn" style="margin-top: 6px;">
|
||||
<button class="sla-crit-hit-btn" data-actor-id="{{actor._id}}" data-item-id="{{weapon._id}}" style="background: linear-gradient(185deg, #a80000 0%, #5c0000 100%); color: #ffffff; border: 1px solid #ff4444; border-radius: 4px; padding: 6px 12px; cursor: pointer; font-family: 'Barlow Condensed', sans-serif; font-size: 11pt; font-weight: bold; width: 100%; text-shadow: 0 1px 2px #000; box-shadow: 0 0 6px rgba(255, 0, 0, 0.4); transition: all 0.2s ease;">
|
||||
<i class="fas fa-skull-crossbones"></i> CRITICAL HIT?
|
||||
</button>
|
||||
</div>
|
||||
{{#if needsDesc}}
|
||||
<div class="sla-chat-divider">Description</div>
|
||||
<div class="description sla-chat-section">
|
||||
@@ -96,14 +101,24 @@
|
||||
{{else}}
|
||||
{{#if parsedRollResult.success}}
|
||||
{{#if flavorText}}<div class="sla-chat-section sla-chat-section-success">{{{flavorText}}}</div>{{/if}}
|
||||
{{#if weapon}}
|
||||
<div class="sla-chat-section sla-chat-section-crit-btn" style="margin-top: 6px; margin-bottom: 6px;">
|
||||
<button class="sla-crit-hit-btn" data-actor-id="{{actor._id}}" data-item-id="{{weapon._id}}" style="background: linear-gradient(185deg, #a80000 0%, #5c0000 100%); color: #ffffff; border: 1px solid #ff4444; border-radius: 4px; padding: 6px 12px; cursor: pointer; font-family: 'Barlow Condensed', sans-serif; font-size: 11pt; font-weight: bold; width: 100%; text-shadow: 0 1px 2px #000; box-shadow: 0 0 6px rgba(255, 0, 0, 0.4); transition: all 0.2s ease;">
|
||||
<i class="fas fa-skull-crossbones"></i> CRITICAL HIT?
|
||||
</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if criticalSuccessOptions.length}}
|
||||
<div class="sla-chat-section sla-chat-section-success">
|
||||
<div class="sla-chat-section-title">Critical Success Options</div>
|
||||
<ol class="sla-chat-list">
|
||||
<div class="sla-chat-section-title"><i class="fas fa-crown"></i> Critical Success Options</div>
|
||||
<div class="sla-crit-success-options" style="margin-top: 5px;">
|
||||
{{#each criticalSuccessOptions as |option|}}
|
||||
<li>{{option}}</li>
|
||||
<button class="sla-crit-option-btn" data-actor-id="{{../actor._id}}" data-option-text="{{option}}" style="background: linear-gradient(180deg, #1f421f 0%, #0c260c 100%); color: #bdf2bd; border: 1px solid #3fa63f; border-radius: 4px; padding: 6px 10px; margin-bottom: 6px; cursor: pointer; font-family: 'Barlow Condensed', sans-serif; font-size: 10.5pt; text-align: left; width: 100%; transition: all 0.2s ease; display: flex; align-items: flex-start; gap: 6px; text-shadow: 0 1px 2px #000;">
|
||||
<i class="fas fa-chevron-right" style="margin-top: 3px; font-size: 8pt; color: #2ebd2e;"></i>
|
||||
<span>{{option}}</span>
|
||||
</button>
|
||||
{{/each}}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if weapon}}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<div class="mosh sla-chat-shell sla-chat-shell-check sla-chat-shell-success" style="border-left: 4px solid #2ebd2e; padding-left: 8px;">
|
||||
<div class="rollcontainer">
|
||||
<div class="sla-chat-hero" style="background: rgba(46, 189, 46, 0.15); display: flex; align-items: center; padding: 6px; border-radius: 4px 4px 0 0;">
|
||||
<div class="sla-chat-hero-main" style="flex-grow: 1;">
|
||||
<div class="sla-chat-kicker-row">
|
||||
<div class="sla-chat-kicker" style="color: #85e085; font-size: 8pt; font-weight: bold; letter-spacing: 0.1em;">TACTICAL DECISION</div>
|
||||
</div>
|
||||
<div class="rollweaponh1 sla-chat-hero-title" style="font-size: 14pt; margin: 0; color: #ffffff;">{{{actorName}}}</div>
|
||||
</div>
|
||||
<div class="sla-chat-hero-media" style="width: 32px; height: 32px; border-radius: 4px; overflow: hidden; margin-left: 8px; flex-shrink: 0; border: 1px solid #2ebd2e;">
|
||||
<img class="roll-image" src="{{{img}}}" style="width: 100%; height: 100%; object-fit: cover;" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="sla-chat-section sla-chat-section-success" style="padding: 10px; background: rgba(0,0,0,0.3); border-radius: 0 0 4px 4px; font-family: 'Cormorant Garamond', serif; font-size: 13pt; line-height: 1.3;">
|
||||
<i class="fas fa-check-circle" style="color: #2ebd2e; margin-right: 4px;"></i> <strong>Combat Critical Choice:</strong>
|
||||
<div style="margin-top: 6px; color: #e0fde0; font-style: italic;">"{{{optionText}}}"</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user