ENH: Attack rolls !
parent
e1319b6215
commit
7106f138d9
|
@ -167,5 +167,8 @@
|
||||||
"OSE.exploration.ft.long": "Find Room Trap",
|
"OSE.exploration.ft.long": "Find Room Trap",
|
||||||
"OSE.exploration.ft.short": "Find Trap",
|
"OSE.exploration.ft.short": "Find Trap",
|
||||||
|
|
||||||
"OSE.messages.getExperience": "{name} gained {value} experience points!"
|
"OSE.messages.GetExperience": "{name} gained {value} experience points!",
|
||||||
|
"OSE.messages.AttackSuccess": "<b>Hits AC {result}!</b> ({bonus})",
|
||||||
|
"OSE.messages.AttackFailure": "<b>Attack fails</b> ({bonus})",
|
||||||
|
"OSE.messages.InflictsDamage": "Inflicts damage!"
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@ export class OseActor extends Actor {
|
||||||
|
|
||||||
// Compute modifiers from actor scores
|
// Compute modifiers from actor scores
|
||||||
this.computeModifiers();
|
this.computeModifiers();
|
||||||
|
this.computeAttack();
|
||||||
|
|
||||||
// Determine Initiative
|
// Determine Initiative
|
||||||
if (game.settings.get("ose", "individualInit")) {
|
if (game.settings.get("ose", "individualInit")) {
|
||||||
|
@ -37,7 +38,7 @@ export class OseActor extends Actor {
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
const speaker = ChatMessage.getSpeaker({ actor: this });
|
const speaker = ChatMessage.getSpeaker({ actor: this });
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
content: game.i18n.format("OSE.messages.getExperience", {
|
content: game.i18n.format("OSE.messages.GetExperience", {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
value: modified,
|
value: modified,
|
||||||
}),
|
}),
|
||||||
|
@ -51,7 +52,6 @@ export class OseActor extends Actor {
|
||||||
|
|
||||||
rollHP(options = {}) {
|
rollHP(options = {}) {
|
||||||
let roll = new Roll(this.data.data.hp.hd).roll();
|
let roll = new Roll(this.data.data.hp.hd).roll();
|
||||||
console.log(roll);
|
|
||||||
return this.update({
|
return this.update({
|
||||||
data: {
|
data: {
|
||||||
hp: {
|
hp: {
|
||||||
|
@ -177,8 +177,8 @@ export class OseActor extends Actor {
|
||||||
...this.data,
|
...this.data,
|
||||||
...{
|
...{
|
||||||
rollData: {
|
rollData: {
|
||||||
type: "Exploration",
|
type: "Below",
|
||||||
stat: expl,
|
target: this.data.data.exploration[expl],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -236,22 +236,40 @@ export class OseActor extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
rollAttack(attData, options = {}) {
|
rollAttack(attData, options = {}) {
|
||||||
const rollParts = ["1d20"];
|
|
||||||
const data = this.data.data;
|
const data = this.data.data;
|
||||||
|
|
||||||
if (attData.type == "missile") {
|
const rollParts = ["1d20"];
|
||||||
rollParts.push(
|
const dmgParts = [];
|
||||||
data.scores.dex.mod.toString(),
|
|
||||||
data.thac0.mod.missile.toString()
|
if (!attData.dmg || !game.settings.get("ose", "variableWeaponDamage")) {
|
||||||
);
|
dmgParts.push("1d6");
|
||||||
} else if (attData.type == "melee") {
|
} else {
|
||||||
rollParts.push(
|
dmgParts.push(attData.dmg);
|
||||||
data.scores.str.mod.toString(),
|
|
||||||
data.thac0.mod.melee.toString()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (game.settings.get("ose", "ascendingAC")) {
|
|
||||||
rollParts.push(this.data.data.thac0.bba.toString());
|
|
||||||
|
let ascending = game.settings.get("ose", "ascendingAC");
|
||||||
|
if (ascending) {
|
||||||
|
rollParts.push(data.thac0.bba.toString());
|
||||||
|
if (attData.type == "missile") {
|
||||||
|
rollParts.push(
|
||||||
|
data.scores.dex.mod.toString(),
|
||||||
|
data.thac0.mod.missile.toString()
|
||||||
|
);
|
||||||
|
} else if (attData.type == "melee") {
|
||||||
|
rollParts.push(
|
||||||
|
data.scores.str.mod.toString(),
|
||||||
|
data.thac0.mod.melee.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let thac0 = 0;
|
||||||
|
if (attData.type == "melee") {
|
||||||
|
dmgParts.push(data.scores.str.mod);
|
||||||
|
thac0 = data.thac0.melee;
|
||||||
|
} else if (attData.type == "missile") {
|
||||||
|
thac0 = data.thac0.missile;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rollData = {
|
const rollData = {
|
||||||
|
@ -259,12 +277,15 @@ export class OseActor extends Actor {
|
||||||
...{
|
...{
|
||||||
rollData: {
|
rollData: {
|
||||||
type: "Attack",
|
type: "Attack",
|
||||||
stat: attData.type,
|
thac0: thac0,
|
||||||
scores: data.scores,
|
weapon: {
|
||||||
|
parts: dmgParts,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let skip = options.event && options.event.ctrlKey;
|
let skip = options.event && options.event.ctrlKey;
|
||||||
|
|
||||||
// Roll and return
|
// Roll and return
|
||||||
return OseDice.Roll({
|
return OseDice.Roll({
|
||||||
event: options.event,
|
event: options.event,
|
||||||
|
@ -274,8 +295,6 @@ export class OseActor extends Actor {
|
||||||
speaker: ChatMessage.getSpeaker({ actor: this }),
|
speaker: ChatMessage.getSpeaker({ actor: this }),
|
||||||
flavor: `${attData.label} - ${game.i18n.localize("OSE.Attack")}`,
|
flavor: `${attData.label} - ${game.i18n.localize("OSE.Attack")}`,
|
||||||
title: `${attData.label} - ${game.i18n.localize("OSE.Attack")}`,
|
title: `${attData.label} - ${game.i18n.localize("OSE.Attack")}`,
|
||||||
}).then(() => {
|
|
||||||
this.rollDamage(attData, {});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,4 +353,21 @@ export class OseActor extends Actor {
|
||||||
data.scores.dex.init = OseActor._cappedMod(this.data.data.scores.dex.value);
|
data.scores.dex.init = OseActor._cappedMod(this.data.data.scores.dex.value);
|
||||||
data.scores.cha.npc = OseActor._cappedMod(this.data.data.scores.cha.value);
|
data.scores.cha.npc = OseActor._cappedMod(this.data.data.scores.cha.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
computeAttack() {
|
||||||
|
const data = this.data.data;
|
||||||
|
let ascending = game.settings.get("ose", "ascendingAC");
|
||||||
|
data.thac0.missile = ascending ? data.thac0.bba : data.thac0.value;
|
||||||
|
data.thac0.melee = ascending ? data.thac0.bba : data.thac0.value;
|
||||||
|
if (this.data.type != "character") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ascending) {
|
||||||
|
data.thac0.missile += data.scores.dex.mod + data.thac0.mod.missile;
|
||||||
|
data.thac0.melee += data.scores.str.mod + data.thac0.mod.melee;
|
||||||
|
} else {
|
||||||
|
data.thac0.missile -= data.scores.dex.mod - data.thac0.mod.missile;
|
||||||
|
data.thac0.melee -= data.scores.str.mod - data.thac0.mod.melee;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,75 +3,27 @@ export class OseDice {
|
||||||
let result = {
|
let result = {
|
||||||
isSuccess: false,
|
isSuccess: false,
|
||||||
isFailure: false,
|
isFailure: false,
|
||||||
target: "",
|
target: data.rollData.target,
|
||||||
};
|
};
|
||||||
// ATTACKS
|
|
||||||
let die = roll.parts[0].total;
|
let die = roll.parts[0].total;
|
||||||
if (data.rollData.type == "Attack") {
|
if (data.rollData.type == "Above") {
|
||||||
if (game.settings.get("ose", "ascendingAC")) {
|
|
||||||
let bba = data.data.thac0.bba;
|
|
||||||
if (data.rollData.stat == "melee") {
|
|
||||||
bba += data.data.thac0.mod.melee + data.rollData.scores.str.mod;
|
|
||||||
} else if (data.rollData.stat == "missile") {
|
|
||||||
bba += data.data.thac0.mod.missile + data.rollData.scores.dex.mod;
|
|
||||||
}
|
|
||||||
result.target = bba;
|
|
||||||
if (die == 1) {
|
|
||||||
result.isFailure = true;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result.isSuccess = true;
|
|
||||||
} else {
|
|
||||||
// B/X Historic THAC0 Calculation
|
|
||||||
let thac = data.data.thac0.value;
|
|
||||||
if (data.rollData.stat == "melee") {
|
|
||||||
thac -= data.data.thac0.mod.melee + data.rollData.scores.str.mod;
|
|
||||||
} else if (data.rollData.stat == "missile") {
|
|
||||||
thac -= data.data.thac0.mod.missile + data.rollData.scores.dex.mod;
|
|
||||||
}
|
|
||||||
result.target = thac;
|
|
||||||
if (thac - roll.total > 9) {
|
|
||||||
result.isFailure = true;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result.details = `<div class='roll-result'><b>Hits AC ${Math.clamped(
|
|
||||||
thac - roll.total,
|
|
||||||
-3,
|
|
||||||
9
|
|
||||||
)}</b> (${thac})</div>`;
|
|
||||||
}
|
|
||||||
} else if (data.rollData.type == "Above") {
|
|
||||||
// SAVING THROWS
|
// SAVING THROWS
|
||||||
let sv = data.rollData.target;
|
if (roll.total >= result.target) {
|
||||||
result.target = sv;
|
|
||||||
if (roll.total >= sv) {
|
|
||||||
result.isSuccess = true;
|
result.isSuccess = true;
|
||||||
} else {
|
} else {
|
||||||
result.isFailure = true;
|
result.isFailure = true;
|
||||||
}
|
}
|
||||||
} else if (data.rollData.type == "Below") {
|
} else if (data.rollData.type == "Below") {
|
||||||
// Morale
|
// MORALE, EXPLORATION
|
||||||
let m = data.rollData.target;
|
if (roll.total <= result.target) {
|
||||||
result.target = m;
|
|
||||||
if (roll.total <= m) {
|
|
||||||
result.isSuccess = true;
|
result.isSuccess = true;
|
||||||
} else {
|
} else {
|
||||||
result.isFailure = true;
|
result.isFailure = true;
|
||||||
}
|
}
|
||||||
} else if (data.rollData.type == "Check") {
|
} else if (data.rollData.type == "Check") {
|
||||||
// SCORE CHECKS
|
// SCORE CHECKS (1s and 20s)
|
||||||
let sc = data.rollData.target;
|
if (die == 1 || (roll.total <= result.target && die < 20)) {
|
||||||
result.target = sc;
|
|
||||||
if (die == 1 || (roll.total <= sc && die < 20)) {
|
|
||||||
result.isSuccess = true;
|
|
||||||
} else {
|
|
||||||
result.isFailure = true;
|
|
||||||
}
|
|
||||||
} else if (data.rollData.type == "Exploration") {
|
|
||||||
// EXPLORATION CHECKS
|
|
||||||
let sc = data.data.exploration[data.rollData.stat];
|
|
||||||
result.target = sc;
|
|
||||||
if (roll.total <= sc) {
|
|
||||||
result.isSuccess = true;
|
result.isSuccess = true;
|
||||||
} else {
|
} else {
|
||||||
result.isFailure = true;
|
result.isFailure = true;
|
||||||
|
@ -88,7 +40,7 @@ export class OseDice {
|
||||||
speaker = null,
|
speaker = null,
|
||||||
form = null,
|
form = null,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
const template = "systems/ose/templates/chat/roll-attack.html";
|
const template = "systems/ose/templates/chat/roll-result.html";
|
||||||
|
|
||||||
let chatData = {
|
let chatData = {
|
||||||
user: game.user._id,
|
user: game.user._id,
|
||||||
|
@ -142,6 +94,110 @@ export class OseDice {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static digestAttackResult(data, roll) {
|
||||||
|
let result = {
|
||||||
|
isSuccess: false,
|
||||||
|
isFailure: false,
|
||||||
|
target: "",
|
||||||
|
};
|
||||||
|
result.target = data.rollData.thac0;
|
||||||
|
if (game.settings.get("ose", "ascendingAC")) {
|
||||||
|
result.details = game.i18n.format('OSE.messages.AttackSuccess', {result: roll.total, bonus: result.target});
|
||||||
|
result.isSuccess = true;
|
||||||
|
} else {
|
||||||
|
// B/X Historic THAC0 Calculation
|
||||||
|
if (result.target - roll.total > 9) {
|
||||||
|
result.details = game.i18n.format('OSE.messages.AttackFailure', {bonus: result.target});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.isSuccess = true;
|
||||||
|
let value = Math.clamped(result.target - roll.total, -3, 9);
|
||||||
|
result.details = game.i18n.format('OSE.messages.AttackSuccess', {result: value, bonus: result.target});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async sendAttackRoll({
|
||||||
|
parts = [],
|
||||||
|
data = {},
|
||||||
|
title = null,
|
||||||
|
flavor = null,
|
||||||
|
speaker = null,
|
||||||
|
form = null,
|
||||||
|
} = {}) {
|
||||||
|
const template = "systems/ose/templates/chat/roll-attack.html";
|
||||||
|
|
||||||
|
let chatData = {
|
||||||
|
user: game.user._id,
|
||||||
|
speaker: speaker,
|
||||||
|
};
|
||||||
|
|
||||||
|
let templateData = {
|
||||||
|
title: title,
|
||||||
|
flavor: flavor,
|
||||||
|
data: data,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Optionally include a situational bonus
|
||||||
|
if (form !== null) data["bonus"] = form.bonus.value;
|
||||||
|
if (data["bonus"]) parts.push(data["bonus"]);
|
||||||
|
|
||||||
|
const roll = new Roll(parts.join("+"), data).roll();
|
||||||
|
const dmgRoll = new Roll(data.rollData.weapon.parts.join("+"), data).roll();
|
||||||
|
|
||||||
|
// Convert the roll to a chat message and return the roll
|
||||||
|
let rollMode = game.settings.get("core", "rollMode");
|
||||||
|
rollMode = form ? form.rollMode.value : rollMode;
|
||||||
|
|
||||||
|
templateData.result = OseDice.digestAttackResult(data, roll);
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
roll.render().then((r) => {
|
||||||
|
templateData.rollOSE = r;
|
||||||
|
dmgRoll.render().then((dr) => {
|
||||||
|
templateData.rollDamage = dr;
|
||||||
|
renderTemplate(template, templateData).then((content) => {
|
||||||
|
chatData.content = content;
|
||||||
|
// 2 Step Dice So Nice
|
||||||
|
if (game.dice3d) {
|
||||||
|
game.dice3d
|
||||||
|
.showForRoll(
|
||||||
|
roll,
|
||||||
|
game.user,
|
||||||
|
true,
|
||||||
|
chatData.whisper,
|
||||||
|
chatData.blind
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
if (templateData.result.isSuccess) {
|
||||||
|
game.dice3d
|
||||||
|
.showForRoll(
|
||||||
|
dmgRoll,
|
||||||
|
game.user,
|
||||||
|
true,
|
||||||
|
chatData.whisper,
|
||||||
|
chatData.blind
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
ChatMessage.create(chatData);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ChatMessage.create(chatData);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
chatData.sound = CONFIG.sounds.dice;
|
||||||
|
ChatMessage.create(chatData);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static async Roll({
|
static async Roll({
|
||||||
parts = [],
|
parts = [],
|
||||||
data = {},
|
data = {},
|
||||||
|
@ -164,37 +220,40 @@ export class OseDice {
|
||||||
rollModes: CONFIG.Dice.rollModes,
|
rollModes: CONFIG.Dice.rollModes,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let rollData = {
|
||||||
|
parts: parts,
|
||||||
|
data: data,
|
||||||
|
title: title,
|
||||||
|
flavor: flavor,
|
||||||
|
speaker: speaker,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (skipDialog) {
|
||||||
|
return data.rollData.type === "Attack"
|
||||||
|
? OseDice.sendAttackRoll(rollData)
|
||||||
|
: OseDice.sendRoll(rollData);
|
||||||
|
}
|
||||||
|
|
||||||
let buttons = {
|
let buttons = {
|
||||||
ok: {
|
ok: {
|
||||||
label: game.i18n.localize("OSE.Roll"),
|
label: game.i18n.localize("OSE.Roll"),
|
||||||
icon: '<i class="fas fa-dice-d20"></i>',
|
icon: '<i class="fas fa-dice-d20"></i>',
|
||||||
callback: (html) => {
|
callback: (html) => {
|
||||||
roll = OseDice.sendRoll({
|
rolled = true;
|
||||||
parts: parts,
|
rollData.form = html[0].children[0];
|
||||||
data: data,
|
roll =
|
||||||
title: title,
|
data.rollData.type === "Attack"
|
||||||
flavor: flavor,
|
? OseDice.sendAttackRoll(rollData)
|
||||||
speaker: speaker,
|
: OseDice.sendRoll(rollData);
|
||||||
form: html[0].children[0],
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
cancel: {
|
cancel: {
|
||||||
icon: '<i class="fas fa-times"></i>',
|
icon: '<i class="fas fa-times"></i>',
|
||||||
label: game.i18n.localize("OSE.Cancel"),
|
label: game.i18n.localize("OSE.Cancel"),
|
||||||
|
callback: (html) => {},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (skipDialog) {
|
|
||||||
return OseDice.sendRoll({
|
|
||||||
parts,
|
|
||||||
data,
|
|
||||||
title,
|
|
||||||
flavor,
|
|
||||||
speaker,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const html = await renderTemplate(template, dialogData);
|
const html = await renderTemplate(template, dialogData);
|
||||||
let roll;
|
let roll;
|
||||||
|
|
||||||
|
|
|
@ -156,12 +156,12 @@
|
||||||
{{#if config.ascendingAC}}
|
{{#if config.ascendingAC}}
|
||||||
<div class="attribute-value"
|
<div class="attribute-value"
|
||||||
title="{{localize 'OSE.AB'}}({{data.thac0.bba}}) + {{localize 'OSE.scores.str.long'}}({{data.scores.str.mod}}) + {{localize 'OSE.Modifier'}}({{data.thac0.mod.melee}})">
|
title="{{localize 'OSE.AB'}}({{data.thac0.bba}}) + {{localize 'OSE.scores.str.long'}}({{data.scores.str.mod}}) + {{localize 'OSE.Modifier'}}({{data.thac0.mod.melee}})">
|
||||||
{{add data.thac0.mod.melee (add data.scores.str.mod data.thac0.bba)}}
|
{{data.thac0.melee}}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="attribute-value"
|
<div class="attribute-value"
|
||||||
title="{{localize 'OSE.Thac0'}}({{data.thac0.value}}) - {{localize 'OSE.scores.str.long'}}({{data.scores.str.mod}}) - {{localize 'OSE.Modifier'}}({{data.thac0.mod.melee}})">
|
title="{{localize 'OSE.Thac0'}}({{data.thac0.value}}) - {{localize 'OSE.scores.str.long'}}({{data.scores.str.mod}}) - {{localize 'OSE.Modifier'}}({{data.thac0.mod.melee}})">
|
||||||
{{subtract data.thac0.mod.melee (subtract data.scores.str.mod data.thac0.value)}}
|
{{data.thac0.melee}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -196,12 +196,12 @@
|
||||||
{{#if config.ascendingAC}}
|
{{#if config.ascendingAC}}
|
||||||
<div class="attribute-value"
|
<div class="attribute-value"
|
||||||
title="{{localize 'OSE.AB'}}({{data.thac0.bba}}) + {{localize 'OSE.scores.dex.long'}}({{data.scores.dex.mod}}) + {{localize 'OSE.Modifier'}}({{data.thac0.mod.missile}})">
|
title="{{localize 'OSE.AB'}}({{data.thac0.bba}}) + {{localize 'OSE.scores.dex.long'}}({{data.scores.dex.mod}}) + {{localize 'OSE.Modifier'}}({{data.thac0.mod.missile}})">
|
||||||
{{add data.thac0.mod.missile (add data.scores.dex.mod data.thac0.bba)}}
|
{{data.thac0.missile}}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="attribute-value"
|
<div class="attribute-value"
|
||||||
title="{{localize 'OSE.Thac0'}}({{data.thac0.value}}) - {{localize 'OSE.scores.dex.long'}}({{data.scores.dex.mod}}) - {{localize 'OSE.Modifier'}}({{data.thac0.mod.missile}})">
|
title="{{localize 'OSE.Thac0'}}({{data.thac0.value}}) - {{localize 'OSE.scores.dex.long'}}({{data.scores.dex.mod}}) - {{localize 'OSE.Modifier'}}({{data.thac0.mod.missile}})">
|
||||||
{{subtract data.thac0.mod.missile (subtract data.scores.dex.mod data.thac0.value)}}
|
{{data.thac0.missile}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
<section class="ose chat-message">
|
<section class="ose chat-message">
|
||||||
<div class="ose chat-block">
|
<div class="ose chat-block">
|
||||||
<h2 class="chat-title">{{title}}</h2>
|
<h2 class="chat-title">{{title}}</h2>
|
||||||
{{#if result.details}}<div class="chat-details">{{{result.details}}}</div>{{/if}}
|
<div class="chat-details">
|
||||||
{{#if result.isFailure}}<div class='roll-result roll-fail'><b>{{localize 'OSE.Failure'}}</b> ({{result.target}})</div>{{/if}}
|
<div class="roll-result">{{{result.details}}}</div>
|
||||||
{{#if result.isSuccess}}<div class='roll-result roll-success'><b>{{localize 'OSE.Success'}}</b> ({{result.target}})</div>{{/if}}
|
</div>
|
||||||
{{#if rollOSE}}<div>{{{rollOSE}}}</div>{{/if}}
|
{{#if rollOSE}}<div>{{{rollOSE}}}</div>{{/if}}
|
||||||
|
{{#if result.isSuccess}}
|
||||||
|
<div class="chat-details">
|
||||||
|
<div class="roll-result"><b>{{localize 'OSE.messages.InflictsDamage'}}</b></div>
|
||||||
|
</div>
|
||||||
|
<div>{{{rollDamage}}}</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<section class="ose chat-message">
|
||||||
|
<div class="ose chat-block">
|
||||||
|
<h2 class="chat-title">{{title}}</h2>
|
||||||
|
{{#if result.details}}<div class="chat-details">{{{result.details}}}</div>{{/if}}
|
||||||
|
{{#if result.isFailure}}<div class='roll-result roll-fail'><b>{{localize 'OSE.Failure'}}</b> ({{result.target}})
|
||||||
|
</div>{{/if}}
|
||||||
|
{{#if result.isSuccess}}<div class='roll-result roll-success'><b>{{localize 'OSE.Success'}}</b>
|
||||||
|
({{result.target}})</div>{{/if}}
|
||||||
|
{{#if rollOSE}}<div>{{{rollOSE}}}</div>{{/if}}
|
||||||
|
</div>
|
||||||
|
</section>
|
Loading…
Reference in New Issue