diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 9fdcbca..1000e8f 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -77,3 +77,22 @@ jobs:
asset_content_type: application/gzip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Commit and Push Updated module.json to deploy branch
+ run: |
+ git config --local user.email "action@github.com"
+ git config --local user.name "GitHub Action"
+ git add module.json
+ git commit -m "Update version in module.json"
+ git push origin deploy
+
+ - name: Create Pull Request to push new version back to master
+ uses: repo-sync/pull-request@v2
+ with:
+ source_branch: "deploy"
+ destination_branch: "master"
+ pr_title: "Deploy to Master"
+ pr_body: "Auto PR to update version number."
+ pr_label: "automerge"
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/Old Module.txt b/Old Module.txt
index 9489a0c..ab1e766 100644
--- a/Old Module.txt
+++ b/Old Module.txt
@@ -1,7 +1,6 @@
This file is just holding old module.json information for later.
"dnd5e",
"dnd5eJP",
- "pf1",
"pf2e",
"D35E",
"sw5e",
@@ -26,14 +25,7 @@ This file is just holding old module.json information for later.
"id": "dnd5eJP",
"type": "system"
},
- {
- "id": "pf1",
- "type": "system",
- "manifest": "https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/releases/v0.82.1/downloads/system.json",
- "compatibility": {
- "verified": "0.82.1"
- }
- },
+ ,
{
"id": "pf2e",
"type": "system",
diff --git a/css/pf1.css b/css/pf1.css
new file mode 100644
index 0000000..f41577f
--- /dev/null
+++ b/css/pf1.css
@@ -0,0 +1,7 @@
+/* WARNING: When mentioning any changes, all CSS must be prefixed with .game.system-pf1 in this file. If you need to edit Ceus-wide CSS, please edit ceus.css. */
+/* Pathfinder 1 Specific CSS */
+.game.system-pf1 .ceus.ceus-result header,
+.game.system-pf1 .ceus.ceus-result .result-body .result-total,
+.game.system-pf1 .ceus.ceus-result .result-body .result-breakdown {
+ background-color: rgba(255,255,255,0.3);
+}
\ No newline at end of file
diff --git a/module.json b/module.json
index 7de78b3..94b1e19 100644
--- a/module.json
+++ b/module.json
@@ -3,7 +3,7 @@
"name": "Ceus",
"title": "Ceus - Ask For Rolls",
"description": "Want your players to roll in a specific way? Ceus asks players for specific rolls, preventing them from spending time looking for rolls.",
- "version": "0.80",
+ "version": "0.81",
"author": "KaKaRoTo, iotech, Limping Ninja, Rughalt, Calego, VTT Lair, Imper1um",
"authors": [{
"name": "Imper1um",
@@ -14,7 +14,8 @@
],
"scripts": [],
"styles": [
- "/css/ceus.css"
+ "/css/ceus.css",
+ "/css/pf1.css"
],
"minimumCoreVersion": "11",
"compatibleCoreVersion": "11",
@@ -29,10 +30,19 @@
}
],
"systems": [
+ "pf1",
"sf1e"
],
"relationships": {
"systems": [
+ {
+ "id": "pf1",
+ "type": "system",
+ "manifest": "https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/releases/v0.82.1/downloads/system.json",
+ "compatibility": {
+ "verified": "0.82.1"
+ }
+ },
{
"id": "sfrpg",
"type": "system",
@@ -46,7 +56,7 @@
"socket": true,
"url": "https://github.com/Imper1um/foundry-ceus/",
"manifest": "https://github.com/Imper1um/foundry-ceus/releases/latest/download/module.json",
- "download": "https://github.com/Imper1um/foundry-ceus/releases/download/v3.00/module.zip",
+ "download": "https://github.com/Imper1um/foundry-ceus/releases/download/0.81/module.zip",
"changelog": "https://github.com/Imper1um/foundry-ceus/releases",
"bugs": "https://github.com/Imper1um/foundry-ceus/issues"
}
\ No newline at end of file
diff --git a/src/ceus.js b/src/ceus.js
index 5018943..b33d55e 100644
--- a/src/ceus.js
+++ b/src/ceus.js
@@ -5,7 +5,6 @@ import { ceus_SocketEngine } from "./ceus_SocketEngine.js";
import { ceus_SettingsEngine } from "./ceus_SettingsEngine.js";
import { ceus_ResultsWindow } from "./ceus_ResultsWindow.js";
import { ceus_LogEngine } from "./ceus_LogEngine.js";
-import { CeusRequestor } from "./requestor.js";
export class Ceus {
@@ -34,7 +33,7 @@ export class Ceus {
}
async onChatMessage(app, html, data) {
- Ceus.log.Trace("onChatMessage", {app, html, data});
+ if (Ceus.current && Ceus.current.settingsEngine) { Ceus.log.Trace("onChatMessage", {app, html, data}); } //Avoids conflicts when starting up.
if (game.user.isGM) { return; }
if (html.hasClass("sensitive") && html.hasClass("ceus")) {
html.find('.result-total').text('???');
@@ -87,31 +86,10 @@ export class Ceus {
}
}
- onThemeChange(enabled) {
- $(".ceus.ceus-requestor,.ceus.ceus-roller").toggleClass("ceus-parchment", enabled);
- if (!this.requestor) { return; }
- if (enabled) {
- this.requestor.options.classes.push("ceus-parchment");
- } else {
- this.requestor.options.classes = this.requestor.options.classes.filter(c => c !== "ceus-parchment");
- }
- // Resize to fit the new theme
- if (this.requestor.element.length) {
- this.requestor.setPosition({ width: "auto", height: "auto" });
- }
- }
-
requestRoll() {
- if (this.providerEngine.currentRollProvider.rollProviderType() === 'legacy') {
- if (this.requestor === undefined) {
- this.requestor = new CeusRequestor();
- }
- this.requestor.render(true);
- } else if (this.providerEngine.currentRollProvider.rollProviderType() === 'refactor') {
- const requestwindow = new ceus_RequestWindow();
- this.requestWindows.push(requestwindow);
- requestwindow.render(true);
- }
+ const requestwindow = new ceus_RequestWindow();
+ this.requestWindows.push(requestwindow);
+ requestwindow.render(true);
}
async registerHandlebarsHelpers() {
@@ -212,80 +190,4 @@ export class Ceus {
static requestRoll(data) {
if (!game.user.isGM) { return; }
}
-
- /*async onReady() {
- this.providerEngine.onReady();
- this.socketEngine.onReady();
-
-
-
- if (game.settings.get('ceus', 'deselectOnRequestorRender')) {
- Hooks.on("renderCeusRequestor", () => {
- canvas.tokens.releaseAll();
- });
- }
-
-
- Hooks.on('renderChatMessage', this.hideBlind);
- }*/
-
- /*
- results() {
- if (this.results === undefined) {
- this.results = new Array();
- }
- return this.results;
- }
- addResults(newResults) {
- const r = results();
- r.push(newResults);
- this.results = r;
- }
- getResults(id) {
- return results.find(r => r.id == id);
- }
-
-
-
-
-
- async hideBlind(app, html, msg) {
- if (msg.message.flags && msg.message.flags.ceus) {
- if (msg.message.flags.ceus.blind && !game.user.isGM) {
- msg.content = '
');
- html[0].innerHTML = html[0].innerHTML.substring(0, idx);
- html[0].innerHTML += `
${msg.content}
`;
- }
- }
- }
-
- fromUuid(uuid) {
- let parts = uuid.split(".");
- let doc;
-
- if (parts.length === 1) return game.actors.get(uuid);
- // Compendium Documents
- if (parts[0] === "Compendium") {
- return undefined;
- }
-
- // World Documents
- else {
- const [docName, docId] = parts.slice(0, 2);
- parts = parts.slice(2);
- const collection = CONFIG[docName].collection.instance;
- doc = collection.get(docId);
- }
-
- // Embedded Documents
- while (parts.length > 1) {
- const [embeddedName, embeddedId] = parts.slice(0, 2);
- doc = doc.getEmbeddedDocument(embeddedName, embeddedId);
- parts = parts.slice(2);
- }
- if (doc.actor) doc = doc.actor;
- return doc || undefined;
- } */
}
\ No newline at end of file
diff --git a/src/ceus_LogEngine.js b/src/ceus_LogEngine.js
index df752ca..b53abc9 100644
--- a/src/ceus_LogEngine.js
+++ b/src/ceus_LogEngine.js
@@ -22,6 +22,7 @@ export class ceus_LogEngine {
}
Error(module, message, error = null, system = null) {
+ if (!Ceus.current.settingsEngine || !Ceus.current.settingsEngine.isInitialized) { return; }
if (system == null) { system = this.system; }
if (typeof message !== "string") { message = JSON.stringify(message); }
const logLevel = Ceus.current.settingsEngine.LogLevel;
@@ -41,6 +42,7 @@ export class ceus_LogEngine {
}
Warn(module, message, error = null, system = null) {
+ if (!Ceus.current.settingsEngine || !Ceus.current.settingsEngine.isInitialized) { return; }
if (system == null) { system = this.system; }
if (typeof message !== "string") { message = JSON.stringify(message); }
const logLevel = Ceus.current.settingsEngine.LogLevel;
@@ -60,6 +62,7 @@ export class ceus_LogEngine {
}
Info(module, message, error = null, system = null) {
+ if (!Ceus.current.settingsEngine || !Ceus.current.settingsEngine.isInitialized) { return; }
if (system == null) { system = this.system; }
if (typeof message !== "string") { message = JSON.stringify(message); }
const logLevel = Ceus.current.settingsEngine.LogLevel;
@@ -79,6 +82,7 @@ export class ceus_LogEngine {
}
Debug(module, message, error = null, system = null) {
+ if (!Ceus.current.settingsEngine || !Ceus.current.settingsEngine.isInitialized) { return; }
if (system == null) { system = this.system; }
if (typeof message !== "string") { message = JSON.stringify(message); }
const logLevel = Ceus.current.settingsEngine.LogLevel;
@@ -98,6 +102,7 @@ export class ceus_LogEngine {
}
Trace(module, message, error = null, system = null) {
+ if (!Ceus.current.settingsEngine || !Ceus.current.settingsEngine.isInitialized) { return; }
if (system == null) { system = this.system; }
if (typeof message !== "string") { message = JSON.stringify(message); }
const logLevel = Ceus.current.settingsEngine.LogLevel;
diff --git a/src/ceus_ProviderEngine.js b/src/ceus_ProviderEngine.js
index 8ef1b38..d0f359b 100644
--- a/src/ceus_ProviderEngine.js
+++ b/src/ceus_ProviderEngine.js
@@ -1,3 +1,5 @@
+import { ceus_RollProvider_pf1 } from "./ceus_RollProvider_pf1.js";
+import { ceus_RollProvider_sf1e } from "./ceus_RollProvider_sf1e.js";
/*import { ceus_RollProvider_pf2e } from "./ceus_RollProvider_pf2e.js";
import { ceus_RollProvider_cof } from "./ceus_RollProvider_cof.js";
import { ceus_RollProvider_coc } from "./ceus_RollProvider_coc.js";
@@ -8,13 +10,13 @@ import { ceus_RollProvider_dnd5eJP } from "./ceus_RollProvider_dnd5eJP.js";
import { ceus_RollProvider_dnd35 } from "./ceus_RollProvider_dnd35.js";
import { ceus_RollProvider_ffd20 } from "./ceus_RollProvider_ffd20.js";
import { ceus_RollProvider_ose } from "./ceus_RollProvider_ose.js";
-import { ceus_RollProvider_pf1 } from "./ceus_RollProvider_pf1.js";*/
-import { ceus_RollProvider_sf1e } from "./ceus_RollProvider_sf1e.js";
-//import { ceus_RollProvider_sw5e } from "./ceus_RollProvider_sw5e.js";
+import { ceus_RollProvider_sw5e } from "./ceus_RollProvider_sw5e.js";*/
export class ceus_ProviderEngine {
constructor() {
this.externalRollProviders = [
+ new ceus_RollProvider_pf1(),
+ new ceus_RollProvider_sf1e()
/*new ceus_RollProvider_cd(),
new ceus_RollProvider_coc(),
new ceus_RollProvider_cof(),
@@ -24,9 +26,7 @@ export class ceus_ProviderEngine {
new ceus_RollProvider_dnd35(),
new ceus_RollProvider_ffd20(),
new ceus_RollProvider_ose(),
- new ceus_RollProvider_pf1(),
- new ceus_RollProvider_pf2e(),*/
- new ceus_RollProvider_sf1e()/*,
+ new ceus_RollProvider_pf2e(),
new ceus_RollProvider_sw5e()*/
];
}
diff --git a/src/ceus_RollProvider_pf1.js b/src/ceus_RollProvider_pf1.js
index 0addbc2..7299876 100644
--- a/src/ceus_RollProvider_pf1.js
+++ b/src/ceus_RollProvider_pf1.js
@@ -1,50 +1,420 @@
-import { ceus_RollProvider } from "./ceus_RollProvider.js";
+import { ceus_RefactorRollProvider } from "./ceus_RefactorRollProvider.js";
+import { CeusRoller } from "./roller.js";
+import { Ceus } from "./ceus.js";
+import { ceus_Result } from "./ceus_Result.js";
+import { ceus_LogEngine } from "./ceus_LogEngine.js";
-export class ceus_RollProvider_pf1 extends ceus_RollProvider {
+/**
+ * RollProvider for Pathfinder (1st Edition) (pf1)
+ *
+ * systemIdentifier: pf1
+ * trained: enabled
+ * results: enabled
+ * advantage/disadvantage: disabled
+ * DC: enabled
+ * rollMode: enabled
+ */
+export class ceus_RollProvider_pf1 extends ceus_RefactorRollProvider {
+ constructor() {
+ super();
+ }
+
+ static get log() {
+ if (!ceus_RollProvider_pf1._log) {
+ ceus_RollProvider_pf1._log = new ceus_LogEngine("pf1");
+ }
+ return ceus_RollProvider_pf1._log;
+ }
systemIdentifiers() {
return 'pf1';
}
- abilities() {
- return CONFIG.PF1.abilities;
+ trainedOptions() {
+ return [ "HideUntrained", "PreventUntrained", "AllowUntrained" ];
}
-
- abilityAbbreviations() {
- return CONFIG.PF1.abilitiesShort;
+
+ rollTrainedOptions(rollType, id) {
+ switch (rollType) {
+ case CeusRoller.rollTypes().INITIATIVE:
+ case CeusRoller.rollTypes().ABILITY:
+ case CeusRoller.rollTypes().PERCEPTION:
+ case CeusRoller.rollTypes().SAVE:
+ return [ "AllowUntrained" ];
+ }
+
+ return this.trainedOptions();
}
-
- abilityRollMethod() {
- return 'rollAbility';
+
+ isActorTrained(actor, rollType, id) {
+ if (rollType != CeusRoller.rollTypes().SKILL) {
+ return true;
+ }
+ var skill = actor.system.skills[id];
+ if (!skill) {
+ const availableSkillRoll = this.getAvailableSkillRolls().find(s => s.id === id);
+ if (availableSkillRoll) {
+ skill = actor.system.skills[availableSkillRoll.skillId];
+ }
+ }
+ if (!skill) { return false; }
+ return skill.rank > 0;
}
-
- advantageRollEvent() {
- return new ceus_RollEvent(false, true, false);
+
+ getActorRollBonus(actor, rollType, id) {
+ switch (rollType) {
+ case CeusRoller.rollTypes().SKILL:
+ var skill = actor.system.skills[id];
+ if (!skill) {
+ const availableSkillRoll = this.getAvailableSkillRolls().find(s => s.id === id);
+ if (availableSkillRoll) {
+ skill = actor.system.skills[availableSkillRoll.skillId];
+ }
+ }
+ if (!skill) { return null; }
+ return skill.mod;
+ case CeusRoller.rollTypes().INITIATIVE:
+ return actor.system.attributes.init.value;
+ case CeusRoller.rollTypes().PERCEPTION:
+ return actor.system.skills.per.mod;
+ case CeusRoller.rollTypes().ABILITY:
+ var ability = actor.system.abilities[id];
+ if (!ability) {
+ const availableAbilityRoll = this.getAvailableAbilityRolls().find(a => a.id === id);
+ if (availableAbilityRoll) {
+ ability = actor.system.abilities[availableAbilityRoll.abilityId];
+ }
+ }
+ if (!ability) { return null; }
+ return ability.mod;
+ case CeusRoller.rollTypes().SAVE:
+ var save = actor.system.attributes.savingThrows[id];
+ if (!save) {
+ const availableSaveRoll = this.getAvailableSaveRolls().find(a => a.id === id);
+ if (availableSaveRoll) {
+ save = actor.system.attributes.savingThrows[availableSaveRoll.saveId];
+ }
+ }
+ if (!save) { return null; }
+ return save.value;
+ }
+ return null;
}
-
- disadvantageRollEvent() {
- return new ceus_RollEvent(false, false, true);
+
+ isPlayer(actor) {
+ return actor.type === "character";
}
-
- normalRollEvent() {
- return new ceus_RollEvent(false, false, false);
+
+ canActorSeeRoll(actor, rollType, id, trainedOption) {
+ var train = this.isActorTrained(actor, rollType, id);
+ switch (trainedOption) {
+ case "HideUntrained":
+ return train;
+ }
+ return true;
}
-
- saveRollMethod() {
- return 'rollSavingThrow';
+
+ canActorRoll(actor, rollType, id, trainedOption) {
+ var train = this.isActorTrained(actor, rollType, id);
+ switch (trainedOption) {
+ case "HideUntrained":
+ case "PreventUntrained":
+ return train;
+ }
+ return true;
}
-
- saves() {
- return CONFIG.PF1.savingThrows;
+
+ getInitiativeContexts() {
+ const initiativeContexts = new Array();
+ for (const combat of game.combats) {
+ initiativeContexts.push({"id":combat._id, "name":`${combat.combatants.size} on ${combat.scene.name}`});
+ }
+ ceus_RollProvider_pf1.log.Trace("getInitiativeContexts", initiativeContexts);
+ return initiativeContexts;
}
-
- skills() {
- return CONFIG.PF1.skills;
+
+ getAvailableRolls() {
+ return [
+ {
+ id: "Special",
+ name: "PF1.WeaponPropSpecial",
+ type: "category",
+ rolls: [
+ { id: "Initiative", name: "PF1.Initiative", type: "roll", rollType: CeusRoller.rollTypes().INITIATIVE, method: this.rollInitiative, contexts: this.getInitiativeContexts, canCritSuccess: false, canCritFail: false },
+ { id: "Perception", name: "PF1.SkillPer", type: "roll", rollType:CeusRoller.rollTypes().PERCEPTION, method: this.rollPerception, canCritSuccess: false, canCritFail: false }
+ ]
+ },
+ {
+ id: "Abilities",
+ name: "PF1.Ability",
+ type: "category",
+ rolls: this.getAvailableAbilityRolls()
+ },
+ {
+ id: "Saves",
+ name: "PF1.Save",
+ type: "category",
+ rolls: this.getAvailableSaveRolls()
+ },
+ {
+ id: "Skills",
+ name: "PF1.Skills",
+ type: "category",
+ rolls: this.getAvailableSkillRolls()
+ },
+ ];
}
-
- skillRollMethod() {
- return 'rollSkill';
+
+ getAvailableAbilityRolls() {
+ const abilities = CONFIG.PF1.abilities;
+ return Object.keys(abilities).map(key => {
+ const capitalizedKey = key.charAt(0).toUpperCase() + key.slice(1);
+ return {
+ id: `Ability${capitalizedKey}`,
+ name: `PF1.Ability${capitalizedKey}`,
+ type: "roll",
+ rollType: CeusRoller.rollTypes().ABILITY,
+ method: this.rollAbility,
+ abilityId: key,
+ canCritSuccess: true,
+ canCritFail: true
+ };
+ });
}
-
- specialRolls() {
- return {'initiative': true, 'deathsave': false, 'perception': false};
+
+ getAvailableSaveRolls() {
+ const saves = CONFIG.PF1.savingThrows;
+ return Object.keys(saves).map(key => {
+ const saveName = saves[key];
+ const capitalizedKey = key.charAt(0).toUpperCase() + key.slice(1);
+ return {
+ id: `${saveName}Save`,
+ name: `PF1.SavingThrow${capitalizedKey}`,
+ type: "roll",
+ rollType: CeusRoller.rollTypes().SAVE,
+ method: this.rollSave,
+ saveId: key,
+ canCritSuccess: true,
+ canCritFail: true
+ };
+ });
+ }
+
+ getAvailableSkillRolls() {
+ const abilities = CONFIG.PF1.skills;
+ return Object.keys(abilities).map(key => {
+ const capitalizedKey = (key.charAt(0).toUpperCase() + key.slice(1)).substring(0, 3);
+ var translatedKey = capitalizedKey;
+ if (capitalizedKey.startsWith("K")) {
+ //Knowledge skills are different. The second letter is capitalized.
+ translatedKey = key.charAt(0).toUpperCase() + key.charAt(1).toUpperCase() + key.slice(2);
+ } else if (capitalizedKey == "Umd") {
+ //UMD is UMD.
+ translatedKey = "UMD";
+ }
+
+ return {
+ id: `Skill${capitalizedKey}`,
+ name: `PF1.Skill${translatedKey}`,
+ type: "roll",
+ rollType: CeusRoller.rollTypes().SKILL,
+ method: this.rollSkill,
+ skillId: key,
+ canCritSuccess: false,
+ canCritFail: translatedKey == "UMD" ? true : false //UMD can Crit Fail
+ };
+ });
+ }
+
+ baseRollOptions() {
+ return {
+ chatMessage: false
+ };
+ }
+
+ async rollSkill(requestOptions, actor, requestItem) {
+ ceus_RollProvider_pf1.log.Trace("rollSkill", {requestOptions, actor, requestItem});
+ const rp = Ceus.current.providerEngine.currentRollProvider;
+ const skillRoll = rp.getAvailableRolls().find(r => r.id === "Skills").rolls.find(r => r.id === requestItem.rollId);
+ const skillId = skillRoll.skillId;
+ const skill = actor.system.skills[skillRoll.skillId];
+ const rollOptions = rp.baseRollOptions();
+ var completeRoll;
+ switch (requestItem.trainedOption) {
+ case "HideUntrained":
+ if (skill.isTrainedOnly && skill.ranks < 1) {
+ return new ceus_Result(
+ requestOptions.requestId,
+ actor._id,
+ requestItem.id,
+ game.data.userId,
+ null,
+ false,
+ null,
+ null
+ );
+ }
+ completeRoll = await actor.rollSkill(skillId, rollOptions);
+ break;
+ case "PreventUntrained":
+ if (skill.isTrainedOnly && skill.ranks < 1) {
+ completeRoll = await actor.rollSkill(skillId, rollOptions);
+ } else {
+ completeRoll = await actor.rollSkill(skillId, rollOptions);
+ }
+ break;
+ default:
+ completeRoll = await actor.rollSkill(skillId, rollOptions);
+ break;
+
+ }
+ return rp.buildResult(requestOptions, actor, requestItem, completeRoll);
+ }
+
+ async rollPerception(requestOptions, actor, requestItem) {
+ ceus_RollProvider_pf1.log.Trace("rollPerception", {requestOptions, actor, requestItem});
+ const rp = Ceus.current.providerEngine.currentRollProvider;
+ const skill = actor.system.skills["per"];
+ const skillId = "per";
+ const completeRoll = await actor.rollSkill(skillId, skill, rp.baseRollOptions());
+ return rp.buildResult(requestOptions, actor, requestItem, completeRoll);
+ }
+
+ async rollSave(requestOptions, actor, requestItem) {
+ ceus_RollProvider_pf1.log.Trace("rollSave", {requestOptions, actor, requestItem});
+ const rp = Ceus.current.providerEngine.currentRollProvider;
+ const saveRoll = rp.getAvailableRolls().find(r => r.id === "Saves").rolls.find(r => r.id === requestItem.rollId);
+ const completeRoll = await actor.rollSavingThrow(saveRoll.saveId, rp.baseRollOptions());
+ return rp.buildResult(requestOptions, actor, requestItem, completeRoll);
+ }
+
+ async rollAbility(requestOptions, actor, requestItem) {
+ ceus_RollProvider_pf1.log.Trace("rollAbility", {requestOptions, actor, requestItem});
+ const rp = Ceus.current.providerEngine.currentRollProvider;
+ const abilityRoll = rp.getAvailableRolls().find(r => r.id === "Abilities").rolls.find(r => r.id === requestItem.rollId);
+ const completeRoll = await actor.rollAbilityTest(abilityRoll.abilityId, rp.baseRollOptions());
+ return rp.buildResult(requestOptions, actor, requestItem, completeRoll);
+ }
+
+ async rollInitiative(requestOptions, actor, requestItem) {
+ ceus_RollProvider_pf1.log.Trace("rollInitiative", {requestOptions, actor, requestItem});
+ const rp = Ceus.current.providerEngine.currentRollProvider;
+ const combat = game.combats.get(requestOptions.contextId);
+ if (!combat) { return; }
+ var rollOptions = {formula: null, updateTurn: true, messageOptions: {}, requireMode: null, requireRollState: null};
+ switch (requestOptions.rollPrivacy) {
+ case "public":
+ rollOptions.rollMode = "publicroll";
+ break;
+ case "blind":
+ rollOptions.rollMode = "blindroll";
+ break;
+ case "gm":
+ rollOptions.rollMode = "gmroll";
+ break;
+ case "self":
+ rollOptions.rollMode = "selfroll";
+ break;
+ }
+ //Roll Privacy can't be enforced for Initiative.
+ const newCombat = await combat.rollInitiative(actor._id, rollOptions);
+ const newTurn = newCombat.turns.find(t => t.actorId === actor._id);
+ if (!newTurn) { return; }
+ const result = new ceus_Result(
+ requestOptions.id,
+ requestOptions.resultId,
+ actor._id,
+ requestItem.id,
+ game.data.userId,
+ newTurn.resource,
+ true,
+ true,
+ null);
+ return result;
+ }
+
+ buildResult(requestOptions, actor, requestItem, roll) {
+ ceus_RollProvider_pf1.log.Trace("buildResult", {requestOptions, actor, requestItem, roll});
+ let rollType;
+ if (roll.button === "advantage") {
+ rollType = "advantage";
+ } else if (roll.button === "disadvantage") {
+ rollType = "disadvantage";
+ } else {
+ rollType = "normal";
+ }
+ var isCritSuccess = false;
+ var isCritFail = false;
+ const finalRoll = typeof roll.rolls[0] === 'string' ? JSON.parse(roll.rolls[0]) : roll.rolls[0]; //I don't know why it does this.
+ for (const term of finalRoll.terms) {
+ if (!term.faces || term.faces !== 20) { continue; }
+ if (term.results[0].result === 20 && requestItem.canCritSuccess) { isCritSuccess = true; }
+ if (term.results[0].result === 1 && requestItem.canCritFail) { isCritFail = true; }
+ }
+ var isPass = null;
+ if (requestItem.dc) {
+ isPass = requestItem.dc <= finalRoll.total;
+ if (isCritSuccess) { isPass = true; }
+ if (isCritFail) { isPass = false; }
+ }
+
+ return new ceus_Result(
+ requestOptions.id,
+ requestOptions.resultId,
+ actor._id,
+ requestItem.rollId,
+ game.data.userId,
+ finalRoll.total,
+ true,
+ isPass,
+ rollType,
+ finalRoll.formula,
+ isCritFail,
+ isCritSuccess
+ );
+ }
+
+ resultsEnabled() {
+ return true;
+ }
+
+ canActionAdvantage(rollType, id) {
+ return false; //Advantage/Disadvantage can't base be passed into the Pathfinder 1e roll system. You can't force it (at least through PF1)
+ }
+
+ canActionDisadvantage(rollType, id) {
+ return false;
+ }
+
+ permitAdvantageDisadvantage() {
+ return false;
+ }
+ needsContext(requestOptions) {
+ if (requestOptions.requestItems.some(ri => ri.id == "Initiative")) {
+ return true;
+ }
+ return false;
+ }
+ getContextList(requestOptions) {
+ if (requestOptions.requestItems.some(ri => ri.id == "Initiative")) {
+ return this.getInitiativeContexts();
+ }
+ return null;
+ }
+ permitDC() {
+ return true;
+ }
+ allowDC(rollType, id) {
+ if (rollType == CeusRoller.rollTypes().INITIATIVE) {
+ return false;
+ }
+ return true;
+ }
+ permitSetRollPrivacy() {
+ return true;
+ }
+ permitRequireRollPrivacy() {
+ return true;
+ }
+ displayRequiredByMod() {
+ return true;
}
}
\ No newline at end of file
diff --git a/src/ceus_RollProvider_sf1e.js b/src/ceus_RollProvider_sf1e.js
index 6d35fff..eb201bd 100644
--- a/src/ceus_RollProvider_sf1e.js
+++ b/src/ceus_RollProvider_sf1e.js
@@ -212,7 +212,7 @@ export class ceus_RollProvider_sf1e extends ceus_RefactorRollProvider {
const rp = Ceus.current.providerEngine.currentRollProvider;
const saveRoll = rp.getAvailableRolls().find(r => r.id === "Saves").rolls.find(r => r.id === requestItem.rollId);
const completeRoll = await actor.rollSave(saveRoll.saveId, rp.baseRollOptions());
- return this.buildResult(requestOptions, actor, requestItem, completeRoll);
+ return rp.buildResult(requestOptions, actor, requestItem, completeRoll);
}
async rollAbility(requestOptions, actor, requestItem) {
diff --git a/src/ceus_SettingsEngine.js b/src/ceus_SettingsEngine.js
index a9bbfdb..4478d9b 100644
--- a/src/ceus_SettingsEngine.js
+++ b/src/ceus_SettingsEngine.js
@@ -50,11 +50,13 @@ export class ceus_SettingsEngine {
config: setting.config,
type: setting.type,
default: setting.default,
- onChange: setting.onChange
+ onChange: setting.onChange,
+ choices: setting.choices
});
}
console.log("Ceus | Game settings ready.");
+ this.isInitialized = true;
}
get LogLevel() {
diff --git a/src/ceus_SocketEngine.js b/src/ceus_SocketEngine.js
index e14c992..d3b344e 100644
--- a/src/ceus_SocketEngine.js
+++ b/src/ceus_SocketEngine.js
@@ -99,22 +99,28 @@ export class ceus_SocketEngine {
async pushRefactorRequest(request) {
ceus_SocketEngine.log.Trace("pushRefactorRequest", request);
- await game.socket.emit('module.ceus', {type: 'refactor', request});
+ const data = {type: 'refactor', request};
+ await game.socket.emit('module.ceus', data);
+ await this.onRefactorRequest(data.request);
ui.notifications.info(game.i18n.localize("Ceus.Requestor.Sent"));
}
async pushCancelResponse(request, userid) {
ceus_SocketEngine.log.Trace("pushCancelResponse", {request, userid});
- await game.socket.emit('module.ceus', {type: 'cancel', request: {
+ const data = {type: 'cancel', request: {
userid,
request
- }});
+ }};
+ await game.socket.emit('module.ceus', data);
+ await this.onRequestCancel(data.request);
}
async pushCompleteResponse(request, userid, response) {
ceus_SocketEngine.log.Trace("onRefactorRequest", {request,userid,response});
- await game.socket.emit('module.ceus', {type: 'complete', request: {
+ const data = {type: 'complete', request: {
userid,
request,
response
- }});
+ }};
+ await game.socket.emit('module.ceus', data);
+ await this.onRequestComplete(data.request);
}
}
\ No newline at end of file
diff --git a/src/ceus_RollProvider.js b/src/old code/ceus_RollProvider.js
similarity index 100%
rename from src/ceus_RollProvider.js
rename to src/old code/ceus_RollProvider.js
diff --git a/src/ceus_RollProvider_cd.js b/src/old code/ceus_RollProvider_cd.js
similarity index 100%
rename from src/ceus_RollProvider_cd.js
rename to src/old code/ceus_RollProvider_cd.js
diff --git a/src/ceus_RollProvider_coc.js b/src/old code/ceus_RollProvider_coc.js
similarity index 100%
rename from src/ceus_RollProvider_coc.js
rename to src/old code/ceus_RollProvider_coc.js
diff --git a/src/ceus_RollProvider_cof.js b/src/old code/ceus_RollProvider_cof.js
similarity index 100%
rename from src/ceus_RollProvider_cof.js
rename to src/old code/ceus_RollProvider_cof.js
diff --git a/src/ceus_RollProvider_degenesis.js b/src/old code/ceus_RollProvider_degenesis.js
similarity index 100%
rename from src/ceus_RollProvider_degenesis.js
rename to src/old code/ceus_RollProvider_degenesis.js
diff --git a/src/ceus_RollProvider_demonlord.js b/src/old code/ceus_RollProvider_demonlord.js
similarity index 100%
rename from src/ceus_RollProvider_demonlord.js
rename to src/old code/ceus_RollProvider_demonlord.js
diff --git a/src/ceus_RollProvider_dnd35.js b/src/old code/ceus_RollProvider_dnd35.js
similarity index 100%
rename from src/ceus_RollProvider_dnd35.js
rename to src/old code/ceus_RollProvider_dnd35.js
diff --git a/src/ceus_RollProvider_dnd5e.js b/src/old code/ceus_RollProvider_dnd5e.js
similarity index 100%
rename from src/ceus_RollProvider_dnd5e.js
rename to src/old code/ceus_RollProvider_dnd5e.js
diff --git a/src/ceus_RollProvider_dnd5eJP.js b/src/old code/ceus_RollProvider_dnd5eJP.js
similarity index 100%
rename from src/ceus_RollProvider_dnd5eJP.js
rename to src/old code/ceus_RollProvider_dnd5eJP.js
diff --git a/src/ceus_RollProvider_ffd20.js b/src/old code/ceus_RollProvider_ffd20.js
similarity index 100%
rename from src/ceus_RollProvider_ffd20.js
rename to src/old code/ceus_RollProvider_ffd20.js
diff --git a/src/ceus_RollProvider_ose.js b/src/old code/ceus_RollProvider_ose.js
similarity index 100%
rename from src/ceus_RollProvider_ose.js
rename to src/old code/ceus_RollProvider_ose.js
diff --git a/src/ceus_RollProvider_pf2e.js b/src/old code/ceus_RollProvider_pf2e.js
similarity index 100%
rename from src/ceus_RollProvider_pf2e.js
rename to src/old code/ceus_RollProvider_pf2e.js
diff --git a/src/ceus_RollProvider_sw5e.js b/src/old code/ceus_RollProvider_sw5e.js
similarity index 100%
rename from src/ceus_RollProvider_sw5e.js
rename to src/old code/ceus_RollProvider_sw5e.js
diff --git a/src/requestor.js b/src/old code/requestor.js
similarity index 100%
rename from src/requestor.js
rename to src/old code/requestor.js
diff --git a/src/old code/roller.js b/src/old code/roller.js
new file mode 100644
index 0000000..a1a9236
--- /dev/null
+++ b/src/old code/roller.js
@@ -0,0 +1,584 @@
+import { Ceus } from "./ceus.js";
+
+export class CeusRoller extends Application {
+
+ constructor(actors, data) {
+ super();
+ this.actors = actors;
+ this.data = data;
+ this.abilities = data.abilities;
+ this.saves = data.saves;
+ this.skills = data.skills;
+ this.advantage = data.advantage;
+ this.mode = data.mode;
+ this.message = data.message;
+ this.tables = data.tables;
+ this.chooseOne = data.chooseOne ?? false;
+ this.dc = data.dc;
+
+ if (data.title) {
+ this.options.title = data.title;
+ }
+
+ this.hasMidi = game.modules.get("midi-qol")?.active;
+ this.midiUseNewRoller = isNewerVersion(game.modules.get("midi-qol")?.version, "10.0.26");
+
+ Handlebars.registerHelper('canFailAbilityChecks', function (name, ability) {
+ if (Ceus.currentRollProvider.canFailChecks()) {
+ return `
` +
+ `
` +
+ `
` +
+ `${Ceus.d20Svg}` +
+ `
` +
+ `
`;
+ } else {
+ return '';
+ }
+ });
+
+ Handlebars.registerHelper('canFailSaveChecks', function (name, ability) {
+ if (Ceus.currentRollProvider.canFailChecks()) {
+ return `
` +
+ `
` +
+ `
` +
+ `${Ceus.d20Svg}` +
+ `
` +
+ `
`;
+ } else {
+ return '';
+ }
+ });
+
+ Handlebars.registerHelper('canFailSkillChecks', function (name, skill) {
+ if (Ceus.currentRollProvider.canFailChecks()) {
+ return `
` +
+ `
` +
+ `
` +
+ `${Ceus.d20Svg}` +
+ `
` +
+ `
`;
+ } else {
+ return '';
+ }
+ });
+ }
+
+ static get defaultOptions() {
+ const options = super.defaultOptions;
+ options.title = game.i18n.localize("Ceus.Title");
+ options.template = "modules/ceus/templates/roller.html";
+ options.popOut = true;
+ options.width = 400;
+ options.height = "auto";
+ options.classes = ["ceus", "ceus-roller"];
+ if (game.settings.get('ceus', 'enableParchmentTheme')) {
+ options.classes.push('ceus-parchment');
+ }
+ return options;
+ }
+
+ static requestAbilityChecks(actor, abilities, options={}) {
+ if (!actor || !abilities) return;
+ if (typeof(abilities) === "string") abilities = [abilities];
+ const data = mergeObject(options, {
+ abilities: [],
+ saves: [],
+ skills: []
+ }, {inplace: false});
+ data.abilities = abilities;
+ new CeusRoller([actor], data).render(true);
+ }
+ static requestSkillChecks(actor, skills, options={}) {
+ if (!actor || !skills) return;
+ if (typeof(skills) === "string") skills = [skills];
+ const data = mergeObject(options, {
+ abilities: [],
+ saves: [],
+ skills: []
+ }, {inplace: false});
+ data.skills = skills;
+ new CeusRoller([actor], data).render(true);
+ }
+ static requestSavingThrows(actor, saves, options={}) {
+ if (!actor || !saves) return;
+ if (typeof(saves) === "string") saves = [saves];
+ const data = mergeObject(options, {
+ abilities: [],
+ saves: [],
+ skills: []
+ }, {inplace: false});
+ data.saves = saves;
+ new CeusRoller([actor], data).render(true);
+ }
+ static rollTypes() {
+ return {
+ ABILITY: "ability",
+ SAVE: "save",
+ SKILL: "skill",
+ PERCEPTION: "perception",
+ INITIATIVE: "initiative",
+ DEATHSAVE: "deathsave",
+ DICE: "dice",
+ CUSTOM: "custom"
+ };
+ }
+
+ async getData() {
+ let note = ""
+ if (this.advantage == 1)
+ note = game.i18n.localize("Ceus.AdvantageNote");
+ else if (this.advantage == -1)
+ note = game.i18n.localize("Ceus.DisadvantageNote");
+
+ let abilities = {}
+ let saves = {}
+ let skills = {}
+ this.abilities.forEach(a => abilities[a] = Ceus.currentRollProvider.abilities()[a])
+ this.saves.forEach(a => saves[a] = Ceus.currentRollProvider.saves()[a])
+ this.skills
+ .sort((a, b) => {
+ const skillA = (Ceus.currentRollProvider.skills()[a]?.label) ? Ceus.currentRollProvider.skills()[a].label : Ceus.currentRollProvider.skills()[a];
+ const skillB = (Ceus.currentRollProvider.skills()[b]?.label) ? Ceus.currentRollProvider.skills()[b].label : Ceus.currentRollProvider.skills()[b];
+ game.i18n.localize(skillA).localeCompare(skillB)
+ })
+ .forEach(s => {
+ const skill = (Ceus.currentRollProvider.skills()[s]?.label) ? Ceus.currentRollProvider.skills()[s].label : Ceus.currentRollProvider.skills()[s];
+ skills[s] = skill;
+ });
+
+ const data = {
+ actors: this.actors,
+ abilities: abilities,
+ saves: saves,
+ skills: skills,
+ note: note,
+ message: this.message,
+ customFormula: this.data.formula || false,
+ deathsave: this.data.deathsave,
+ initiative: this.data.initiative,
+ perception: this.data.perception,
+ tables: this.tables,
+ chooseOne: this.chooseOne,
+ };
+
+ return data;
+ }
+
+ activateListeners(html) {
+ super.activateListeners(html);
+ this.element.find(".ceus-ability-check").click(this._onAbilityCheck.bind(this))
+ this.element.find(".ceus-ability-save").click(this._onAbilitySave.bind(this))
+ this.element.find(".ceus-skill-check").click(this._onSkillCheck.bind(this))
+ this.element.find(".ceus-custom-formula").click(this._onCustomFormula.bind(this))
+ this.element.find(".ceus-roll-table").click(this._onRollTable.bind(this));
+ var specialRolls = Ceus.currentRollProvider.specialRolls();
+ if(specialRolls['initiative']) {
+ this.element.find(".ceus-initiative").click(this._onInitiative.bind(this))
+ }
+ if(specialRolls['deathsave']) {
+ this.element.find(".ceus-death-save").click(this._onDeathSave.bind(this))
+ }
+ if(specialRolls['perception']) {
+ this.element.find(".ceus-perception").click(this._onPerception.bind(this))
+ }
+
+ this.element.find(".enable-ceus-ability-check-fail").click(this._onToggleFailAbilityRoll.bind(this));
+ this.element.find(".ceus-ability-check-fail").click(this._onFailAbilityCheck.bind(this));
+
+ this.element.find(".enable-ceus-ability-save-fail").click(this._onToggleFailSaveRoll.bind(this));
+ this.element.find(".ceus-ability-save-fail").click(this._onFailAbilitySave.bind(this));
+
+ this.element.find(".enable-ceus-skill-check-fail").click(this._onToggleFailSkillRoll.bind(this));
+ this.element.find(".ceus-skill-check-fail").click(this._onFailSkillCheck.bind(this));
+ }
+
+ _checkClose() {
+ if (this.element.find("button").filter((i, e) => !e.disabled).length === 0 || this.chooseOne) {
+ this.close();
+ }
+ }
+
+ _disableButtons(event) {
+ event.currentTarget.disabled = true;
+
+ if (Ceus.canFailChecks) {
+ const buttonSelector = `${event.currentTarget.className}`;
+ let oppositeSelector = "";
+ let dataSelector = "";
+
+ if (
+ event.currentTarget.className.indexOf('ability-check') > 0 ||
+ event.currentTarget.className.indexOf('ability-save') > 0
+ ) {
+ dataSelector = `[data-ability *= '${event?.currentTarget?.dataset?.ability}']`;
+ } else {
+ dataSelector = `[data-skill *= '${event?.currentTarget?.dataset?.skill}']`;
+ }
+
+ if (event.currentTarget.className.indexOf('fail') > 0) {
+ oppositeSelector = event.currentTarget.className.substring(0, event.currentTarget.className.indexOf('fail') - 1);
+ } else {
+ oppositeSelector = `${event.currentTarget.className}-fail`;
+ }
+
+ const enableButton = document.querySelector(`.enable-${buttonSelector}${dataSelector}`);
+ if (enableButton) {
+ enableButton.disabled = true;
+ enableButton.classList.add('disabled-button');
+ }
+
+ const oppositeButton = document.querySelector(`.${oppositeSelector}${dataSelector}`);
+ if (oppositeButton) oppositeButton.disabled = true;
+ }
+ }
+
+ _getRollOptions(event, failRoll) {
+ let options;
+ switch(this.advantage) {
+ case -1:
+ options = {... Ceus.currentRollProvider.disadvantageRollEvent() };
+ break;
+ case 0:
+ options = {... Ceus.currentRollProvider.normalRollEvent() };
+ break;
+ case 1:
+ options = {... Ceus.currentRollProvider.advantageRollEvent() };
+ break;
+ case 2:
+ options = { event: event };
+ break;
+ }
+
+ if (failRoll) {
+ options["parts"] = [-100];
+ }
+
+ return options;
+ }
+
+ async _makeRoll(event, rollMethod, rolledType, failRoll, ...args) {
+ let options = this._getRollOptions(event, failRoll);
+
+ // save the current roll mode to reset it after this roll
+ const rollMode = game.settings.get("core", "rollMode");
+ game.settings.set("core", "rollMode", this.mode || CONST.DICE_ROLL_MODES);
+
+ for (let actor of this.actors) {
+ Hooks.once("preCreateChatMessage", this._tagMessage.bind(this));
+
+ if (Ceus.currentRollProvider.handleCustomRoll(actor, event, rollMethod, rolledType, failRoll, this.dc, args)) {
+ continue;
+ }
+
+ await actor[rollMethod].call(actor, ...args, options);
+ }
+
+ game.settings.set("core", "rollMode", rollMode);
+
+ this._disableButtons(event);
+ this._checkClose();
+ }
+
+ _makePF2EInitiativeRoll(event) {
+ // save the current roll mode to reset it after this roll
+ const rollMode = game.settings.get("core", "rollMode");
+ game.settings.set("core", "rollMode", this.mode || CONST.DICE_ROLL_MODES);
+
+ for (let actor of this.actors) {
+ const initiative = actor.data.data.attributes.initiative;
+ const rollNames = ['all', 'initiative'];
+ if (initiative.ability === 'perception') {
+ rollNames.push('wis-based');
+ rollNames.push('perception');
+ } else {
+ const skill = actor.data.data.skills[initiative.ability];
+ rollNames.push(`${skill.ability}-based`);
+ rollNames.push(skill.name);
+ }
+ const options = actor.getRollOptions(rollNames);
+ initiative.roll({ event, options });
+ }
+
+ game.settings.set("core", "rollMode", rollMode);
+
+ event.currentTarget.disabled = true;
+ this._checkClose();
+ }
+
+ _tagMessage(candidate, data, options) {
+ candidate.updateSource({"flags.ceus": {"message": this.data.message, "data": this.data.attach, "blind": candidate.blind}});
+ }
+
+ async _makeDiceRoll(event, formula, defaultMessage = null) {
+ if (formula.startsWith("1d20")) {
+ if (this.advantage === 1)
+ formula = formula.replace("1d20", "2d20kh1")
+ else if (this.advantage === -1)
+ formula = formula.replace("1d20", "2d20kl1")
+ }
+
+ const messageFlag = {"message": this.data.message, "data": this.data.attach};
+
+ const rollMessages = [];
+ const rollMessagePromises = this.actors.map(async (actor) => {
+ const speaker = ChatMessage.getSpeaker({actor: actor});
+
+ const rollData = actor.getRollData();
+ const roll = new Roll(formula, rollData);
+ const rollMessageData = await roll.toMessage(
+ {"flags.ceus": messageFlag},
+ {rollMode: this.mode, create: false},
+ );
+
+ rollMessages.push(
+ mergeObject(
+ rollMessageData,
+ {
+ speaker: {
+ alias: speaker.alias,
+ scene: speaker.scene,
+ token: speaker.token,
+ actor: speaker.actor,
+ },
+ flavor: this.message || defaultMessage,
+ rollMode: this.mode,
+ },
+ ),
+ );
+ })
+
+ await Promise.allSettled(rollMessagePromises);
+ await ChatMessage.create(rollMessages, {rollMode: this.mode});
+
+ event.currentTarget.disabled = true;
+ this._checkClose();
+ }
+
+ _drawTable(event, table) {
+ const icons = {
+ Actor: 'fas fa-user',
+ Item: 'fas fa-suitcase',
+ Scene: 'fas fa-map',
+ JournalEntry: 'fas fa-book-open',
+ Macro: 'fas fa-terminal',
+ Playlist: '',
+ Compendium: 'fas fa-atlas',
+ }
+
+ let chatMessages = [];
+ let count = 0;
+ const rollTable = game.tables.getName(table);
+
+ if (rollTable) {
+ for (let actor of this.actors) {
+ rollTable.draw({ displayChat: false }).then((res) => {
+ count++;
+ const rollResults = res.results;
+
+ const nr = rollResults.length > 1 ? `${rollResults.length} results` : "a result";
+ let content = "";
+
+ for (const rollResult of rollResults) {
+ const result = rollResult;
+
+ if (!result.documentCollection) {
+ content += `
${result.text}
`;
+ } else if (['Actor', 'Item', 'Scene', 'JournalEntry', 'Macro'].includes(result.documentCollection)) {
+ content += `
+ ${result.text}
`;
+ } else if (result.documentCollection === 'Playlist') {
+ content += `
@${result.documentCollection}[${result.documentId}]{${result.text}}
`;
+ } else if (result.documentCollection) { // if not specific collection, then is compendium
+ content += `
+ ${result.text}
`;
+ }
+ }
+ let chatData = {
+ user: game.user.id,
+ speaker: ChatMessage.getSpeaker({actor}),
+ flavor: `Draws ${nr} from the ${table} table.`,
+ content: content,
+ type: CONST.CHAT_MESSAGE_TYPES.OTHER,
+ };
+
+ if ( ["gmroll", "blindroll"].includes(this.mode) ) {
+ chatData.whisper = ChatMessage.getWhisperRecipients("GM");
+ }
+ if ( this.mode === "selfroll" ) chatData.whisper = [game.user.id];
+ if ( this.mode === "blindroll" ) chatData.blind = true;
+
+ setProperty(chatData, "flags.ceus", {"message": this.data.message, "data": this.data.attach, "blind": chatData.blind});
+
+ chatMessages.push(chatData);
+
+ if (count === this.actors.length) {
+ ChatMessage.create(chatMessages, {});
+
+ event.currentTarget.disabled = true;
+ this._checkClose();
+ }
+ });
+ }
+ }
+ }
+
+ _onAbilityCheck(event) {
+ event.preventDefault();
+ const ability = event.currentTarget.dataset.ability;
+
+ // until patching has been removed
+ if (!this.hasMidi || this.midiUseNewRoller) {
+ this._makeRoll(event, Ceus.currentRollProvider.abilityRollMethod(), CeusRoller.rollTypes().ABILITY, false, ability);
+ } else {
+ this._makeRoll(event, Ceus.currentRollProvider.abilityRollMethod(), CeusRoller.rollTypes().ABILITY, ability);
+ }
+ }
+
+ _onFailAbilityCheck(event) {
+ event.preventDefault();
+ const ability = event.currentTarget.dataset.ability;
+
+ // until patching has been removed
+ if (!this.hasMidi || this.midiUseNewRoller) {
+ this._makeRoll(event, Ceus.currentRollProvider.abilityRollMethod(), CeusRoller.rollTypes().ABILITY, true, ability);
+ } else {
+ this._makeRoll(event, Ceus.currentRollProvider.abilityRollMethod(), CeusRoller.rollTypes().ABILITY, ability);
+ }
+ }
+
+ _onAbilitySave(event) {
+ event.preventDefault();
+ const saves = event.currentTarget.dataset.ability;
+
+ // until patching has been removed
+ if (!this.hasMidi || this.midiUseNewRoller) {
+ this._makeRoll(event, Ceus.currentRollProvider.saveRollMethod(), CeusRoller.rollTypes().SAVE, false, saves);
+ } else {
+ this._makeRoll(event, Ceus.currentRollProvider.saveRollMethod(), CeusRoller.rollTypes().SAVE, saves);
+ }
+ }
+
+ _onFailAbilitySave(event) {
+ event.preventDefault();
+ const saves = event.currentTarget.dataset.ability;
+
+ // until patching has been removed
+ if (!this.hasMidi || this.midiUseNewRoller) {
+ this._makeRoll(event, Ceus.currentRollProvider.saveRollMethod(), CeusRoller.rollTypes().SAVE, true, saves);
+ } else {
+ this._makeRoll(event, Ceus.currentRollProvider.saveRollMethod(), CeusRoller.rollTypes().SAVE, saves);
+ }
+ }
+
+ _onSkillCheck(event) {
+ event.preventDefault();
+ const skill = event.currentTarget.dataset.skill;
+
+ // until patching has been removed
+ if (!this.hasMidi || this.midiUseNewRoller) {
+ this._makeRoll(event, Ceus.currentRollProvider.skillRollMethod(), CeusRoller.rollTypes().SKILL, false, skill);
+ } else {
+ this._makeRoll(event, Ceus.currentRollProvider.skillRollMethod(), CeusRoller.rollTypes().SKILL, skill);
+ }
+ }
+
+ _onFailSkillCheck(event) {
+ event.preventDefault();
+ const skill = event.currentTarget.dataset.skill;
+
+ // until patching has been removed
+ if (!this.hasMidi || this.midiUseNewRoller) {
+ this._makeRoll(event, Ceus.currentRollProvider.skillRollMethod(), CeusRoller.rollTypes().SKILL, true, skill);
+ } else {
+ this._makeRoll(event, Ceus.currentRollProvider.skillRollMethod(), CeusRoller.rollTypes().SKILL, skill);
+ }
+ }
+
+ async _onCustomFormula(event) {
+ event.preventDefault();
+ await this._makeDiceRoll(event, this.data.formula);
+ }
+
+ _onInitiative(event) {
+ event.preventDefault();
+
+ //Custom Event Handling for Initiative Rolls (if needed)
+ var initRollHandling = Ceus.currentRollProvider.handleInitiativeRoll(event, this.mode, this.actors);
+ if (initRollHandling && initRollHandling.isHandled) {
+ if (initRollHandling.checkClose) {
+ this._checkClose();
+ }
+ return;
+ }
+
+ if (this.data.initiative) {
+ for (let actor of this.actors) {
+ actor.rollInitiative();
+ }
+ event.currentTarget.disabled = true;
+ this._checkClose();
+ } else {
+ const initiative = CONFIG.Combat.initiative.formula || game.system.data.initiative;
+ this._makeDiceRoll(event, initiative, game.i18n.localize("Ceus.InitiativeRollMessage"));
+ }
+ }
+
+ _onDeathSave(event) {
+ event.preventDefault();
+
+ var deathSaveHandling = Ceus.currentRollProvider.handleDeathSave(this.actors, event);
+ if (deathSaveHandling && deathSaveHandling.isHandled) {
+ if (deathSaveHandling.checkClose) {
+ this._checkClose();
+ }
+ return;
+ }
+ this._makeDiceRoll(event, "1d20", game.i18n.localize("Ceus.DeathSaveRollMessage"));
+ }
+
+ _onPerception(event) {
+ event.preventDefault();
+ this._makeDiceRoll(event, `1d20 + @attributes.perception.totalModifier`, game.i18n.localize("Ceus.PerceptionRollMessage"));
+ }
+
+ _onRollTable(event) {
+ event.preventDefault();
+ const table = event.currentTarget.dataset.table;
+ this._drawTable(event, table);
+ }
+
+ _onToggleFailAbilityRoll(event) {
+ event.preventDefault();
+ if (event.currentTarget.classList.contains('disabled-button')) return;
+
+ const failButton = document.querySelector(`.ceus-ability-check-fail[data-ability *= '${event?.currentTarget?.dataset?.ability}']`);
+ if (failButton) failButton.disabled = !failButton.disabled;
+
+ const normalButton = document.querySelector(`.ceus-ability-check[data-ability *= '${event?.currentTarget?.dataset?.ability}']`);
+ if (normalButton) normalButton.disabled = !normalButton.disabled;
+ }
+
+ _onToggleFailSaveRoll(event) {
+ event.preventDefault();
+ if (event.currentTarget.classList.contains('disabled-button')) return;
+
+ const failButton = document.querySelector(`.ceus-ability-save-fail[data-ability *= '${event?.currentTarget?.dataset?.ability}']`);
+ if (failButton) failButton.disabled = !failButton.disabled;
+
+ const normalButton = document.querySelector(`.ceus-ability-save[data-ability *= '${event?.currentTarget?.dataset?.ability}']`);
+ if (normalButton) normalButton.disabled = !normalButton.disabled;
+ }
+
+ _onToggleFailSkillRoll(event) {
+ event.preventDefault();
+ if (event.currentTarget.classList.contains('disabled-button')) return;
+
+ const failButton = document.querySelector(`.ceus-skill-check-fail[data-skill *= '${event?.currentTarget?.dataset?.skill}']`);
+ if (failButton) failButton.disabled = !failButton.disabled;
+
+ const normalButton = document.querySelector(`.ceus-skill-check[data-ability *= '${event?.currentTarget?.dataset?.ability}']`);
+ if (normalButton) normalButton.disabled = !normalButton.disabled;
+ }
+}
+
+console.log("Ceus | roller.js loaded");
\ No newline at end of file
diff --git a/src/roller.js b/src/roller.js
index a1a9236..5c11266 100644
--- a/src/roller.js
+++ b/src/roller.js
@@ -1,115 +1,6 @@
import { Ceus } from "./ceus.js";
-export class CeusRoller extends Application {
-
- constructor(actors, data) {
- super();
- this.actors = actors;
- this.data = data;
- this.abilities = data.abilities;
- this.saves = data.saves;
- this.skills = data.skills;
- this.advantage = data.advantage;
- this.mode = data.mode;
- this.message = data.message;
- this.tables = data.tables;
- this.chooseOne = data.chooseOne ?? false;
- this.dc = data.dc;
-
- if (data.title) {
- this.options.title = data.title;
- }
-
- this.hasMidi = game.modules.get("midi-qol")?.active;
- this.midiUseNewRoller = isNewerVersion(game.modules.get("midi-qol")?.version, "10.0.26");
-
- Handlebars.registerHelper('canFailAbilityChecks', function (name, ability) {
- if (Ceus.currentRollProvider.canFailChecks()) {
- return `
` +
- `
` +
- `
` +
- `${Ceus.d20Svg}` +
- `
` +
- `
`;
- } else {
- return '';
- }
- });
-
- Handlebars.registerHelper('canFailSaveChecks', function (name, ability) {
- if (Ceus.currentRollProvider.canFailChecks()) {
- return `
` +
- `
` +
- `
` +
- `${Ceus.d20Svg}` +
- `
` +
- `
`;
- } else {
- return '';
- }
- });
-
- Handlebars.registerHelper('canFailSkillChecks', function (name, skill) {
- if (Ceus.currentRollProvider.canFailChecks()) {
- return `
` +
- `
` +
- `
` +
- `${Ceus.d20Svg}` +
- `
` +
- `
`;
- } else {
- return '';
- }
- });
- }
-
- static get defaultOptions() {
- const options = super.defaultOptions;
- options.title = game.i18n.localize("Ceus.Title");
- options.template = "modules/ceus/templates/roller.html";
- options.popOut = true;
- options.width = 400;
- options.height = "auto";
- options.classes = ["ceus", "ceus-roller"];
- if (game.settings.get('ceus', 'enableParchmentTheme')) {
- options.classes.push('ceus-parchment');
- }
- return options;
- }
-
- static requestAbilityChecks(actor, abilities, options={}) {
- if (!actor || !abilities) return;
- if (typeof(abilities) === "string") abilities = [abilities];
- const data = mergeObject(options, {
- abilities: [],
- saves: [],
- skills: []
- }, {inplace: false});
- data.abilities = abilities;
- new CeusRoller([actor], data).render(true);
- }
- static requestSkillChecks(actor, skills, options={}) {
- if (!actor || !skills) return;
- if (typeof(skills) === "string") skills = [skills];
- const data = mergeObject(options, {
- abilities: [],
- saves: [],
- skills: []
- }, {inplace: false});
- data.skills = skills;
- new CeusRoller([actor], data).render(true);
- }
- static requestSavingThrows(actor, saves, options={}) {
- if (!actor || !saves) return;
- if (typeof(saves) === "string") saves = [saves];
- const data = mergeObject(options, {
- abilities: [],
- saves: [],
- skills: []
- }, {inplace: false});
- data.saves = saves;
- new CeusRoller([actor], data).render(true);
- }
+export class CeusRoller {
static rollTypes() {
return {
ABILITY: "ability",
@@ -122,463 +13,4 @@ export class CeusRoller extends Application {
CUSTOM: "custom"
};
}
-
- async getData() {
- let note = ""
- if (this.advantage == 1)
- note = game.i18n.localize("Ceus.AdvantageNote");
- else if (this.advantage == -1)
- note = game.i18n.localize("Ceus.DisadvantageNote");
-
- let abilities = {}
- let saves = {}
- let skills = {}
- this.abilities.forEach(a => abilities[a] = Ceus.currentRollProvider.abilities()[a])
- this.saves.forEach(a => saves[a] = Ceus.currentRollProvider.saves()[a])
- this.skills
- .sort((a, b) => {
- const skillA = (Ceus.currentRollProvider.skills()[a]?.label) ? Ceus.currentRollProvider.skills()[a].label : Ceus.currentRollProvider.skills()[a];
- const skillB = (Ceus.currentRollProvider.skills()[b]?.label) ? Ceus.currentRollProvider.skills()[b].label : Ceus.currentRollProvider.skills()[b];
- game.i18n.localize(skillA).localeCompare(skillB)
- })
- .forEach(s => {
- const skill = (Ceus.currentRollProvider.skills()[s]?.label) ? Ceus.currentRollProvider.skills()[s].label : Ceus.currentRollProvider.skills()[s];
- skills[s] = skill;
- });
-
- const data = {
- actors: this.actors,
- abilities: abilities,
- saves: saves,
- skills: skills,
- note: note,
- message: this.message,
- customFormula: this.data.formula || false,
- deathsave: this.data.deathsave,
- initiative: this.data.initiative,
- perception: this.data.perception,
- tables: this.tables,
- chooseOne: this.chooseOne,
- };
-
- return data;
- }
-
- activateListeners(html) {
- super.activateListeners(html);
- this.element.find(".ceus-ability-check").click(this._onAbilityCheck.bind(this))
- this.element.find(".ceus-ability-save").click(this._onAbilitySave.bind(this))
- this.element.find(".ceus-skill-check").click(this._onSkillCheck.bind(this))
- this.element.find(".ceus-custom-formula").click(this._onCustomFormula.bind(this))
- this.element.find(".ceus-roll-table").click(this._onRollTable.bind(this));
- var specialRolls = Ceus.currentRollProvider.specialRolls();
- if(specialRolls['initiative']) {
- this.element.find(".ceus-initiative").click(this._onInitiative.bind(this))
- }
- if(specialRolls['deathsave']) {
- this.element.find(".ceus-death-save").click(this._onDeathSave.bind(this))
- }
- if(specialRolls['perception']) {
- this.element.find(".ceus-perception").click(this._onPerception.bind(this))
- }
-
- this.element.find(".enable-ceus-ability-check-fail").click(this._onToggleFailAbilityRoll.bind(this));
- this.element.find(".ceus-ability-check-fail").click(this._onFailAbilityCheck.bind(this));
-
- this.element.find(".enable-ceus-ability-save-fail").click(this._onToggleFailSaveRoll.bind(this));
- this.element.find(".ceus-ability-save-fail").click(this._onFailAbilitySave.bind(this));
-
- this.element.find(".enable-ceus-skill-check-fail").click(this._onToggleFailSkillRoll.bind(this));
- this.element.find(".ceus-skill-check-fail").click(this._onFailSkillCheck.bind(this));
- }
-
- _checkClose() {
- if (this.element.find("button").filter((i, e) => !e.disabled).length === 0 || this.chooseOne) {
- this.close();
- }
- }
-
- _disableButtons(event) {
- event.currentTarget.disabled = true;
-
- if (Ceus.canFailChecks) {
- const buttonSelector = `${event.currentTarget.className}`;
- let oppositeSelector = "";
- let dataSelector = "";
-
- if (
- event.currentTarget.className.indexOf('ability-check') > 0 ||
- event.currentTarget.className.indexOf('ability-save') > 0
- ) {
- dataSelector = `[data-ability *= '${event?.currentTarget?.dataset?.ability}']`;
- } else {
- dataSelector = `[data-skill *= '${event?.currentTarget?.dataset?.skill}']`;
- }
-
- if (event.currentTarget.className.indexOf('fail') > 0) {
- oppositeSelector = event.currentTarget.className.substring(0, event.currentTarget.className.indexOf('fail') - 1);
- } else {
- oppositeSelector = `${event.currentTarget.className}-fail`;
- }
-
- const enableButton = document.querySelector(`.enable-${buttonSelector}${dataSelector}`);
- if (enableButton) {
- enableButton.disabled = true;
- enableButton.classList.add('disabled-button');
- }
-
- const oppositeButton = document.querySelector(`.${oppositeSelector}${dataSelector}`);
- if (oppositeButton) oppositeButton.disabled = true;
- }
- }
-
- _getRollOptions(event, failRoll) {
- let options;
- switch(this.advantage) {
- case -1:
- options = {... Ceus.currentRollProvider.disadvantageRollEvent() };
- break;
- case 0:
- options = {... Ceus.currentRollProvider.normalRollEvent() };
- break;
- case 1:
- options = {... Ceus.currentRollProvider.advantageRollEvent() };
- break;
- case 2:
- options = { event: event };
- break;
- }
-
- if (failRoll) {
- options["parts"] = [-100];
- }
-
- return options;
- }
-
- async _makeRoll(event, rollMethod, rolledType, failRoll, ...args) {
- let options = this._getRollOptions(event, failRoll);
-
- // save the current roll mode to reset it after this roll
- const rollMode = game.settings.get("core", "rollMode");
- game.settings.set("core", "rollMode", this.mode || CONST.DICE_ROLL_MODES);
-
- for (let actor of this.actors) {
- Hooks.once("preCreateChatMessage", this._tagMessage.bind(this));
-
- if (Ceus.currentRollProvider.handleCustomRoll(actor, event, rollMethod, rolledType, failRoll, this.dc, args)) {
- continue;
- }
-
- await actor[rollMethod].call(actor, ...args, options);
- }
-
- game.settings.set("core", "rollMode", rollMode);
-
- this._disableButtons(event);
- this._checkClose();
- }
-
- _makePF2EInitiativeRoll(event) {
- // save the current roll mode to reset it after this roll
- const rollMode = game.settings.get("core", "rollMode");
- game.settings.set("core", "rollMode", this.mode || CONST.DICE_ROLL_MODES);
-
- for (let actor of this.actors) {
- const initiative = actor.data.data.attributes.initiative;
- const rollNames = ['all', 'initiative'];
- if (initiative.ability === 'perception') {
- rollNames.push('wis-based');
- rollNames.push('perception');
- } else {
- const skill = actor.data.data.skills[initiative.ability];
- rollNames.push(`${skill.ability}-based`);
- rollNames.push(skill.name);
- }
- const options = actor.getRollOptions(rollNames);
- initiative.roll({ event, options });
- }
-
- game.settings.set("core", "rollMode", rollMode);
-
- event.currentTarget.disabled = true;
- this._checkClose();
- }
-
- _tagMessage(candidate, data, options) {
- candidate.updateSource({"flags.ceus": {"message": this.data.message, "data": this.data.attach, "blind": candidate.blind}});
- }
-
- async _makeDiceRoll(event, formula, defaultMessage = null) {
- if (formula.startsWith("1d20")) {
- if (this.advantage === 1)
- formula = formula.replace("1d20", "2d20kh1")
- else if (this.advantage === -1)
- formula = formula.replace("1d20", "2d20kl1")
- }
-
- const messageFlag = {"message": this.data.message, "data": this.data.attach};
-
- const rollMessages = [];
- const rollMessagePromises = this.actors.map(async (actor) => {
- const speaker = ChatMessage.getSpeaker({actor: actor});
-
- const rollData = actor.getRollData();
- const roll = new Roll(formula, rollData);
- const rollMessageData = await roll.toMessage(
- {"flags.ceus": messageFlag},
- {rollMode: this.mode, create: false},
- );
-
- rollMessages.push(
- mergeObject(
- rollMessageData,
- {
- speaker: {
- alias: speaker.alias,
- scene: speaker.scene,
- token: speaker.token,
- actor: speaker.actor,
- },
- flavor: this.message || defaultMessage,
- rollMode: this.mode,
- },
- ),
- );
- })
-
- await Promise.allSettled(rollMessagePromises);
- await ChatMessage.create(rollMessages, {rollMode: this.mode});
-
- event.currentTarget.disabled = true;
- this._checkClose();
- }
-
- _drawTable(event, table) {
- const icons = {
- Actor: 'fas fa-user',
- Item: 'fas fa-suitcase',
- Scene: 'fas fa-map',
- JournalEntry: 'fas fa-book-open',
- Macro: 'fas fa-terminal',
- Playlist: '',
- Compendium: 'fas fa-atlas',
- }
-
- let chatMessages = [];
- let count = 0;
- const rollTable = game.tables.getName(table);
-
- if (rollTable) {
- for (let actor of this.actors) {
- rollTable.draw({ displayChat: false }).then((res) => {
- count++;
- const rollResults = res.results;
-
- const nr = rollResults.length > 1 ? `${rollResults.length} results` : "a result";
- let content = "";
-
- for (const rollResult of rollResults) {
- const result = rollResult;
-
- if (!result.documentCollection) {
- content += `
${result.text}
`;
- } else if (['Actor', 'Item', 'Scene', 'JournalEntry', 'Macro'].includes(result.documentCollection)) {
- content += `
- ${result.text}
`;
- } else if (result.documentCollection === 'Playlist') {
- content += `
@${result.documentCollection}[${result.documentId}]{${result.text}}
`;
- } else if (result.documentCollection) { // if not specific collection, then is compendium
- content += `
- ${result.text}
`;
- }
- }
- let chatData = {
- user: game.user.id,
- speaker: ChatMessage.getSpeaker({actor}),
- flavor: `Draws ${nr} from the ${table} table.`,
- content: content,
- type: CONST.CHAT_MESSAGE_TYPES.OTHER,
- };
-
- if ( ["gmroll", "blindroll"].includes(this.mode) ) {
- chatData.whisper = ChatMessage.getWhisperRecipients("GM");
- }
- if ( this.mode === "selfroll" ) chatData.whisper = [game.user.id];
- if ( this.mode === "blindroll" ) chatData.blind = true;
-
- setProperty(chatData, "flags.ceus", {"message": this.data.message, "data": this.data.attach, "blind": chatData.blind});
-
- chatMessages.push(chatData);
-
- if (count === this.actors.length) {
- ChatMessage.create(chatMessages, {});
-
- event.currentTarget.disabled = true;
- this._checkClose();
- }
- });
- }
- }
- }
-
- _onAbilityCheck(event) {
- event.preventDefault();
- const ability = event.currentTarget.dataset.ability;
-
- // until patching has been removed
- if (!this.hasMidi || this.midiUseNewRoller) {
- this._makeRoll(event, Ceus.currentRollProvider.abilityRollMethod(), CeusRoller.rollTypes().ABILITY, false, ability);
- } else {
- this._makeRoll(event, Ceus.currentRollProvider.abilityRollMethod(), CeusRoller.rollTypes().ABILITY, ability);
- }
- }
-
- _onFailAbilityCheck(event) {
- event.preventDefault();
- const ability = event.currentTarget.dataset.ability;
-
- // until patching has been removed
- if (!this.hasMidi || this.midiUseNewRoller) {
- this._makeRoll(event, Ceus.currentRollProvider.abilityRollMethod(), CeusRoller.rollTypes().ABILITY, true, ability);
- } else {
- this._makeRoll(event, Ceus.currentRollProvider.abilityRollMethod(), CeusRoller.rollTypes().ABILITY, ability);
- }
- }
-
- _onAbilitySave(event) {
- event.preventDefault();
- const saves = event.currentTarget.dataset.ability;
-
- // until patching has been removed
- if (!this.hasMidi || this.midiUseNewRoller) {
- this._makeRoll(event, Ceus.currentRollProvider.saveRollMethod(), CeusRoller.rollTypes().SAVE, false, saves);
- } else {
- this._makeRoll(event, Ceus.currentRollProvider.saveRollMethod(), CeusRoller.rollTypes().SAVE, saves);
- }
- }
-
- _onFailAbilitySave(event) {
- event.preventDefault();
- const saves = event.currentTarget.dataset.ability;
-
- // until patching has been removed
- if (!this.hasMidi || this.midiUseNewRoller) {
- this._makeRoll(event, Ceus.currentRollProvider.saveRollMethod(), CeusRoller.rollTypes().SAVE, true, saves);
- } else {
- this._makeRoll(event, Ceus.currentRollProvider.saveRollMethod(), CeusRoller.rollTypes().SAVE, saves);
- }
- }
-
- _onSkillCheck(event) {
- event.preventDefault();
- const skill = event.currentTarget.dataset.skill;
-
- // until patching has been removed
- if (!this.hasMidi || this.midiUseNewRoller) {
- this._makeRoll(event, Ceus.currentRollProvider.skillRollMethod(), CeusRoller.rollTypes().SKILL, false, skill);
- } else {
- this._makeRoll(event, Ceus.currentRollProvider.skillRollMethod(), CeusRoller.rollTypes().SKILL, skill);
- }
- }
-
- _onFailSkillCheck(event) {
- event.preventDefault();
- const skill = event.currentTarget.dataset.skill;
-
- // until patching has been removed
- if (!this.hasMidi || this.midiUseNewRoller) {
- this._makeRoll(event, Ceus.currentRollProvider.skillRollMethod(), CeusRoller.rollTypes().SKILL, true, skill);
- } else {
- this._makeRoll(event, Ceus.currentRollProvider.skillRollMethod(), CeusRoller.rollTypes().SKILL, skill);
- }
- }
-
- async _onCustomFormula(event) {
- event.preventDefault();
- await this._makeDiceRoll(event, this.data.formula);
- }
-
- _onInitiative(event) {
- event.preventDefault();
-
- //Custom Event Handling for Initiative Rolls (if needed)
- var initRollHandling = Ceus.currentRollProvider.handleInitiativeRoll(event, this.mode, this.actors);
- if (initRollHandling && initRollHandling.isHandled) {
- if (initRollHandling.checkClose) {
- this._checkClose();
- }
- return;
- }
-
- if (this.data.initiative) {
- for (let actor of this.actors) {
- actor.rollInitiative();
- }
- event.currentTarget.disabled = true;
- this._checkClose();
- } else {
- const initiative = CONFIG.Combat.initiative.formula || game.system.data.initiative;
- this._makeDiceRoll(event, initiative, game.i18n.localize("Ceus.InitiativeRollMessage"));
- }
- }
-
- _onDeathSave(event) {
- event.preventDefault();
-
- var deathSaveHandling = Ceus.currentRollProvider.handleDeathSave(this.actors, event);
- if (deathSaveHandling && deathSaveHandling.isHandled) {
- if (deathSaveHandling.checkClose) {
- this._checkClose();
- }
- return;
- }
- this._makeDiceRoll(event, "1d20", game.i18n.localize("Ceus.DeathSaveRollMessage"));
- }
-
- _onPerception(event) {
- event.preventDefault();
- this._makeDiceRoll(event, `1d20 + @attributes.perception.totalModifier`, game.i18n.localize("Ceus.PerceptionRollMessage"));
- }
-
- _onRollTable(event) {
- event.preventDefault();
- const table = event.currentTarget.dataset.table;
- this._drawTable(event, table);
- }
-
- _onToggleFailAbilityRoll(event) {
- event.preventDefault();
- if (event.currentTarget.classList.contains('disabled-button')) return;
-
- const failButton = document.querySelector(`.ceus-ability-check-fail[data-ability *= '${event?.currentTarget?.dataset?.ability}']`);
- if (failButton) failButton.disabled = !failButton.disabled;
-
- const normalButton = document.querySelector(`.ceus-ability-check[data-ability *= '${event?.currentTarget?.dataset?.ability}']`);
- if (normalButton) normalButton.disabled = !normalButton.disabled;
- }
-
- _onToggleFailSaveRoll(event) {
- event.preventDefault();
- if (event.currentTarget.classList.contains('disabled-button')) return;
-
- const failButton = document.querySelector(`.ceus-ability-save-fail[data-ability *= '${event?.currentTarget?.dataset?.ability}']`);
- if (failButton) failButton.disabled = !failButton.disabled;
-
- const normalButton = document.querySelector(`.ceus-ability-save[data-ability *= '${event?.currentTarget?.dataset?.ability}']`);
- if (normalButton) normalButton.disabled = !normalButton.disabled;
- }
-
- _onToggleFailSkillRoll(event) {
- event.preventDefault();
- if (event.currentTarget.classList.contains('disabled-button')) return;
-
- const failButton = document.querySelector(`.ceus-skill-check-fail[data-skill *= '${event?.currentTarget?.dataset?.skill}']`);
- if (failButton) failButton.disabled = !failButton.disabled;
-
- const normalButton = document.querySelector(`.ceus-skill-check[data-ability *= '${event?.currentTarget?.dataset?.ability}']`);
- if (normalButton) normalButton.disabled = !normalButton.disabled;
- }
}
-
-console.log("Ceus | roller.js loaded");
\ No newline at end of file