Added roll dialog and exceptional rolls

pull/2/head
Erebus 2020-12-01 04:12:47 +01:00
parent 86192d0a3e
commit bec12184da
9 changed files with 275 additions and 13 deletions

View File

@ -62,6 +62,14 @@
"ROLL.SUCCESS": "Success", "ROLL.SUCCESS": "Success",
"ROLL.FAILURE": "Failure", "ROLL.FAILURE": "Failure",
"ROLL.TITLE": "Roll dice",
"BUTTON.ROLL": "Roll",
"BUTTON.CANCEL": "Cancel",
"ROLL.CLOSED": "Closed",
"ROLL.OPENED": "Opened",
"MENU.SHOWROLLDIALOG": "Show diceroller dialog",
"ROLL.OPENCLOSE": "Open / Close",
"ROLL.EXCEPTIONAL": "Exceptional",
"SKILL.TYPE": "Type", "SKILL.TYPE": "Type",
"SKILL.BASE": "Basic", "SKILL.BASE": "Basic",

View File

@ -64,6 +64,15 @@
"ROLL.SUCCESS": "Lyckat", "ROLL.SUCCESS": "Lyckat",
"ROLL.FAILURE": "Misslyckat", "ROLL.FAILURE": "Misslyckat",
"ROLL.TITLE": "Slå tärningar",
"BUTTON.ROLL": "Slå",
"BUTTON.CANCEL": "Avbryt",
"ROLL.CLOSED": "Stängd",
"ROLL.OPENED": "Öppnad",
"MENU.SHOWROLLDIALOG": "Visa tärningsdialog",
"ROLL.OPENCLOSE": "Öppna / Stäng",
"ROLL.EXCEPTIONAL": "Exceptionelt",
"SKILL.TYPE": "Typ", "SKILL.TYPE": "Typ",
"SKILL.BASE": "Grundfärdigheter", "SKILL.BASE": "Grundfärdigheter",
"SKILL.ADVENTURE": "Äventyrsfärdigheter", "SKILL.ADVENTURE": "Äventyrsfärdigheter",

View File

@ -139,6 +139,64 @@ export class ActorSheetKH extends ActorSheet {
}, },
]); ]);
new ContextMenu(html, "div.item-weapon", [
{
name: game.i18n.localize("MENU.SHOWROLLDIALOG"),
icon: '<i class="far dice"></i>',
callback: (li) => {
let itemId = li.data("itemId");
let _item = this.actor.items.find((element) => element._id == itemId);
let skillName = _item.name
let skillValue = _item.data.data.value
let showValue = false
if(this.actor.data.type === "character") {
showValue = true
}
this.khRoller.rollSkillDialogInChat(skillName, skillValue, showValue, this.actor)
},
},
{
name: game.i18n.localize("MENU.SENTTOCHAT"),
icon: '<i class="far fa-comment"></i>',
callback: (li) => {
let itemId = li.data("itemId");
this._itemDetailsToChat(itemId);
},
},
]);
new ContextMenu(html, "li.item-skill", [
{
name: game.i18n.localize("MENU.SHOWROLLDIALOG"),
icon: '<i class="far dice"></i>',
callback: (li) => {
let itemId = li.data("itemId");
let _item = this.actor.items.find((element) => element._id == itemId);
let skillName = _item.name
let skillValue = _item.data.data.value
let showValue = false
if(this.actor.data.type === "character") {
showValue = true
}
this.khRoller.rollSkillDialogInChat(skillName, skillValue, showValue, this.actor)
},
},
{
name: game.i18n.localize("MENU.SENTTOCHAT"),
icon: '<i class="far fa-comment"></i>',
callback: (li) => {
let itemId = li.data("itemId");
this._itemDetailsToChat(itemId);
},
},
]);
html.find(".feature").click(async (ev) => { html.find(".feature").click(async (ev) => {
const featureName = $(ev.currentTarget).data("feature"); const featureName = $(ev.currentTarget).data("feature");
const featureValue = this.actor.data.data.feature[featureName].value; const featureValue = this.actor.data.data.feature[featureName].value;
@ -209,7 +267,7 @@ export class ActorSheetKH extends ActorSheet {
/* Roll skill */ /* Roll skill */
html.find(".roll-skill").click((ev) => { html.find(".roll-skill").click((ev) => {
const li = $(ev.currentTarget).parents(".item"); const li = $(ev.currentTarget).parents(".item-skill");
let itemId = li.data("itemId"); let itemId = li.data("itemId");
let _item = this.actor.items.find((element) => element._id == itemId); let _item = this.actor.items.find((element) => element._id == itemId);
@ -226,7 +284,7 @@ export class ActorSheetKH extends ActorSheet {
/* Roll weapon skill */ /* Roll weapon skill */
html.find(".roll-weapon-skill").click((ev) => { html.find(".roll-weapon-skill").click((ev) => {
const li = $(ev.currentTarget).parents(".item"); const li = $(ev.currentTarget).parents(".item-weapon");
let itemId = li.data("itemId"); let itemId = li.data("itemId");
let weapon = this.actor.getOwnedItem(itemId); let weapon = this.actor.getOwnedItem(itemId);

View File

@ -84,7 +84,7 @@ export default class KHDiceRoller {
}); });
} }
async rollSkillInChat(skillName, skillValue, showValue, speaker) { async rollSkillInChat(skillName, skillValue, showValue, speaker, openclosed) {
const roll = new Roll(`1d100`); const roll = new Roll(`1d100`);
let res = roll.roll(); let res = roll.roll();
@ -95,12 +95,34 @@ export default class KHDiceRoller {
computedName += " (" + skillValue + ")" computedName += " (" + skillValue + ")"
} }
if(openclosed === undefined) {
openclosed = 0
}
let rollData = { let rollData = {
name: computedName, name: computedName,
res: res res: res
}; };
if(skillValue > 0) { if(skillValue > 0) {
let oneRes = Math.floor((res.total / 1) % 10);
let tenRes = Math.floor((res.total / 10) % 10);
if(openclosed < 0) {
rollData.closed = Math.abs(openclosed)
}
if(openclosed > 0) {
rollData.opened = Math.abs(openclosed)
}
if(openclosed < 0 && oneRes !== 0 && Math.abs(openclosed) >= oneRes) {
// roll is closed
rollData.failure = true
} else if(openclosed > 0 && oneRes !== 0 && Math.abs(openclosed) >= oneRes){
// roll is opened
rollData.success = true
} else {
if (res.total <= skillValue) { if (res.total <= skillValue) {
rollData.success = true rollData.success = true
} else { } else {
@ -108,6 +130,11 @@ export default class KHDiceRoller {
} }
} }
if(oneRes === tenRes) {
rollData.excetional = true
}
}
const html = await renderTemplate("systems/kopparhavet/templates/dice/roll.html", rollData); const html = await renderTemplate("systems/kopparhavet/templates/dice/roll.html", rollData);
await roll.toMessage({ await roll.toMessage({
@ -121,4 +148,101 @@ export default class KHDiceRoller {
}, },
}); });
} }
async rollSkillDialogInChat(skillName, skillValue, showValue, speaker, startopen) {
const id = randomID();
if(startopen === undefined) {
startopen = 0
}
const content = await renderTemplate("systems/kopparhavet/templates/roll-dialog.html", {
id,
startopen,
skillName,
skillValue,
});
await new Dialog({
title: game.i18n.localize("ROLL.TITLE"),
content,
buttons: {
one: {
icon: '<i class="fas fa-check"></i>',
label: game.i18n.localize("BUTTON.ROLL"),
callback: async () => {
const container = document.getElementById(id);
let openclosed = container.querySelector('[name="openclosed"]').value
const roll = new Roll(`1d100`);
let res = roll.roll();
let computedName = skillName
if(showValue) {
computedName += " (" + skillValue + ")"
}
let rollData = {
name: computedName,
res: res
};
// Evaluate result only if we have a positive skillvalue
if(skillValue > 0) {
let oneRes = Math.floor((res.total / 1) % 10);
let tenRes = Math.floor((res.total / 10) % 10);
if(openclosed < 0) {
rollData.closed = Math.abs(openclosed)
}
if(openclosed > 0) {
rollData.opened = Math.abs(openclosed)
}
if(openclosed < 0 && oneRes !== 0 && Math.abs(openclosed) >= oneRes) {
// roll is closed
rollData.failure = true
} else if(openclosed > 0 && oneRes !== 0 && Math.abs(openclosed) >= oneRes){
// roll is opened
rollData.success = true
} else {
if (res.total <= skillValue) {
rollData.success = true
} else {
rollData.failure = true
}
}
if(oneRes === tenRes) {
rollData.excetional = true
}
}
const html = await renderTemplate("systems/kopparhavet/templates/dice/roll.html", rollData);
await roll.toMessage({
create: true,
content: html,
user: game.user._id,
speaker: {
actor: speaker._id,
token: speaker.token,
alias: speaker.name,
},
});
},
},
two: {
icon: '<i class="fas fa-times"></i>',
label: game.i18n.localize("BUTTON.CANCEL"),
},
},
},
{
classes: ["dialog", "kopparhavet"],
}).render(true);
}
} }

View File

@ -4,6 +4,16 @@
<div class="roll"> <div class="roll">
<div class="dice-roll"> <div class="dice-roll">
{{#if closed}}
<div>
{{localize "ROLL.CLOSED"}}: {{closed}}
</div>
{{/if}}
{{#if opened}}
<div>
{{localize "ROLL.OPENED"}}: {{opened}}
</div>
{{/if}}
<div class="dice-result"> <div class="dice-result">
{{#if showFormula}} {{#if showFormula}}
<div class="dice-formula-kh">{{res.formula}}</div> <div class="dice-formula-kh">{{res.formula}}</div>
@ -14,12 +24,12 @@
</div> </div>
{{#if success}} {{#if success}}
<div style="text-align: center; width: 100%; font-weight: bold; color: limegreen;"> <div style="text-align: center; width: 100%; font-weight: bold; color: limegreen;">
{{localize "ROLL.SUCCESS"}} {{#if excetional}}{{localize "ROLL.EXCEPTIONAL"}}{{/if}} {{localize "ROLL.SUCCESS"}}
</div> </div>
{{/if}} {{/if}}
{{#if failure}} {{#if failure}}
<div style="text-align: center; width: 100%; font-weight: bold; color: darkred;"> <div style="text-align: center; width: 100%; font-weight: bold; color: darkred;">
{{localize "ROLL.FAILURE"}} {{#if excetional}}{{localize "ROLL.EXCEPTIONAL"}}{{/if}} {{localize "ROLL.FAILURE"}}
</div> </div>
{{/if}} {{/if}}
</div> </div>

View File

@ -20,7 +20,7 @@
</li> </li>
<ul class="items-list"> <ul class="items-list">
{{#each actor.weapons as |item id|}} {{#each actor.weapons as |item id|}}
<li class="item flexrow" data-item-id="{{item._id}}" data-ability="{{item.data.skill.value}}"> <li class="item-weapon flexrow" data-item-id="{{item._id}}" data-ability="{{item.data.skill.value}}">
<div class="item-name">{{item.name}}</div> <div class="item-name">{{item.name}}</div>
<div> <div>
{{#if item.data.equipable.equipped}} {{#if item.data.equipable.equipped}}

View File

@ -5,7 +5,7 @@
<ul class="items-list"> <ul class="items-list">
{{#each actor.skills as |skill key|}} {{#each actor.skills as |skill key|}}
{{#if skill.hasAdventure}} {{#if skill.hasAdventure}}
<li class="item flexrow" data-item-id="{{skill._id}}"> <li class="item-skill flexrow" data-item-id="{{skill._id}}">
<div class="item-name roll-skill rollable" style="flex-grow: 8;">{{skill.name}}</div> <div class="item-name roll-skill rollable" style="flex-grow: 8;">{{skill.name}}</div>
<div class="item-value" style="flex: none;"><input class="skill-value" type="number" value="{{skill.data.value}}" min="0" data-item-id="{{skill._id}}" data-dtype="Number" /></div> <div class="item-value" style="flex: none;"><input class="skill-value" type="number" value="{{skill.data.value}}" min="0" data-item-id="{{skill._id}}" data-dtype="Number" /></div>
<div style="align-self: flex-end"> <div style="align-self: flex-end">
@ -25,7 +25,7 @@
<ul class="items-list"> <ul class="items-list">
{{#each actor.skills as |skill key|}} {{#each actor.skills as |skill key|}}
{{#if skill.hasCombat}} {{#if skill.hasCombat}}
<li class="item flexrow" data-item-id="{{skill._id}}"> <li class="item-skill flexrow" data-item-id="{{skill._id}}">
<div class="item-name roll-skill rollable" style="flex-grow: 8;">{{skill.name}}</div> <div class="item-name roll-skill rollable" style="flex-grow: 8;">{{skill.name}}</div>
<div class="item-value" style="flex: none;"><input class="skill-value" type="number" value="{{skill.data.value}}" min="0" data-item-id="{{skill._id}}" data-dtype="Number" /></div> <div class="item-value" style="flex: none;"><input class="skill-value" type="number" value="{{skill.data.value}}" min="0" data-item-id="{{skill._id}}" data-dtype="Number" /></div>
<div style="align-self: flex-end"> <div style="align-self: flex-end">

View File

@ -5,7 +5,7 @@
<ul class="items-list"> <ul class="items-list">
{{#each actor.skills as |skill key|}} {{#each actor.skills as |skill key|}}
{{#if skill.hasBase}} {{#if skill.hasBase}}
<li class="item flexrow" data-item-id="{{skill._id}}"> <li class="item-skill flexrow" data-item-id="{{skill._id}}">
<div class="item-name roll-skill rollable" style="flex-grow: 8;">{{skill.name}}</div> <div class="item-name roll-skill rollable" style="flex-grow: 8;">{{skill.name}}</div>
<div class="item-value" style="flex: none;"><input class="skill-value" type="number" value="{{skill.data.value}}" min="0" data-item-id="{{skill._id}}" data-dtype="Number" /></div> <div class="item-value" style="flex: none;"><input class="skill-value" type="number" value="{{skill.data.value}}" min="0" data-item-id="{{skill._id}}" data-dtype="Number" /></div>
<div style="align-self: flex-end"> <div style="align-self: flex-end">
@ -25,7 +25,7 @@
<ul class="items-list"> <ul class="items-list">
{{#each actor.skills as |skill key|}} {{#each actor.skills as |skill key|}}
{{#if skill.hasAdventure}} {{#if skill.hasAdventure}}
<li class="item flexrow" data-item-id="{{skill._id}}"> <li class="item-skill flexrow" data-item-id="{{skill._id}}">
<div class="item-name roll-skill rollable" style="flex-grow: 8;">{{skill.name}}</div> <div class="item-name roll-skill rollable" style="flex-grow: 8;">{{skill.name}}</div>
<div class="item-value" style="flex: none;"><input class="skill-value" type="number" value="{{skill.data.value}}" min="0" data-item-id="{{skill._id}}" data-dtype="Number" /></div> <div class="item-value" style="flex: none;"><input class="skill-value" type="number" value="{{skill.data.value}}" min="0" data-item-id="{{skill._id}}" data-dtype="Number" /></div>
<div style="align-self: flex-end"> <div style="align-self: flex-end">
@ -45,7 +45,7 @@
<ul class="items-list"> <ul class="items-list">
{{#each actor.skills as |skill key|}} {{#each actor.skills as |skill key|}}
{{#if skill.hasCombat}} {{#if skill.hasCombat}}
<li class="item flexrow" data-item-id="{{skill._id}}"> <li class="item-skill flexrow" data-item-id="{{skill._id}}">
<div class="item-name roll-skill rollable" style="flex-grow: 8;">{{skill.name}}</div> <div class="item-name roll-skill rollable" style="flex-grow: 8;">{{skill.name}}</div>
<div class="item-value" style="flex: none;"><input class="skill-value" type="number" value="{{skill.data.value}}" min="0" data-item-id="{{skill._id}}" data-dtype="Number" /></div> <div class="item-value" style="flex: none;"><input class="skill-value" type="number" value="{{skill.data.value}}" min="0" data-item-id="{{skill._id}}" data-dtype="Number" /></div>
<div style="align-self: flex-end"> <div style="align-self: flex-end">

View File

@ -0,0 +1,53 @@
<div id="{{id}}" class="roll-dialog">
<h1 style="text-align: center;">{{skillName}} {{skillValue}}</h1>
<label>{{localize "ROLL.OPENCLOSE"}}</label>
<input type="button" name="openclosed" min="0" value="{{startopen}}" style="margin-bottom: 10px; min-height: 26px; min-width: 30px;" />
<label name="notopenedorclosed" style="display: inline-block;">&nbsp;</label>
<label name="closed" style="display: none;">{{localize "ROLL.CLOSED"}}</label>
<label name="opened" style="display: none;">{{localize "ROLL.OPENED"}}</label>
</div>
<script>
(function() {
const scope = document.getElementById("{{{id}}}");
const input = scope.querySelector(`[name="openclosed"`);
const closed = scope.querySelector(`[name="closed"`);
const opened = scope.querySelector(`[name="opened"`);
const none = scope.querySelector(`[name="notopenedorclosed"`);
input.addEventListener("click", (event) => {
event.target.value++;
if(event.target.value > 0) {
closed.style.display = "none"
none.style.display = "none"
opened.style.display = "inline-block"
} else if(event.target.value < 0) {
opened.style.display = "none"
none.style.display = "none"
closed.style.display = "inline-block"
} else {
opened.style.display = "none"
closed.style.display = "none"
none.style.display = "inline-block"
}
});
input.addEventListener("contextmenu", (event) => {
event.target.value--;
if(event.target.value > 0) {
closed.style.display = "none"
none.style.display = "none"
opened.style.display = "inline-block"
} else if(event.target.value < 0) {
opened.style.display = "none"
none.style.display = "none"
closed.style.display = "inline-block"
} else {
opened.style.display = "none"
closed.style.display = "none"
none.style.display = "inline-block"
}
});
})();
</script>