From 978233a420d93e00e082c7109a463ce80eb23ea7 Mon Sep 17 00:00:00 2001 From: Blair McMillan Date: Wed, 10 Apr 2024 11:13:02 +1000 Subject: [PATCH 1/2] expose roll outcomes --- CHANGELOG.md | 4 ++++ module/api/action/actor/actor-initiative-action.js | 4 +++- .../action/actor/actor-party-initiative-action.js | 4 +++- .../api/action/actor/actor-roll-ability-action.js | 4 +++- .../api/action/character/character-broken-action.js | 4 +++- .../api/action/character/character-defend-action.js | 4 +++- .../action/character/character-get-better-action.js | 4 +++- .../character-invoke-extra-resource-action.js | 2 ++ .../character/character-invoke-relic-action.js | 4 +++- .../character/character-invoke-ritual-action.js | 4 +++- .../character/character-luck-per-day-action.js | 2 +- .../api/action/character/character-reload-action.js | 3 +++ .../api/action/character/character-rest-action.js | 4 ++-- .../api/action/creature/creature-morale-action.js | 4 +++- .../api/action/creature/creature-reaction-action.js | 4 +++- module/api/action/ship/ship-broadsides-action.js | 2 +- module/api/action/ship/ship-come-about-action.js | 2 +- module/api/action/ship/ship-full-sail-action.js | 2 +- module/api/action/ship/ship-invoke-shanty-action.js | 5 +++-- module/api/action/ship/ship-ram-action.js | 2 +- module/api/action/ship/ship-repair-action.js | 2 +- .../api/action/ship/ship-shanties-per-day-action.js | 4 +++- module/api/action/ship/ship-sink-action.js | 4 +++- module/api/action/ship/ship-small-arms-action.js | 4 +++- module/api/generator/character-generator.js | 13 +++++++++++-- module/api/utils.js | 2 +- system.json | 2 +- 27 files changed, 72 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 239520ec..94b3d229 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v0.6.15 + +- Exposed the "outcomes" of rolls performed via the Pirate Borg API to allow for better integration with other modules and/or macros. + # v0.6.14 - Updated Rapscallion class. Changes made to: diff --git a/module/api/action/actor/actor-initiative-action.js b/module/api/action/actor/actor-initiative-action.js index 02b8ed1d..a72c23af 100755 --- a/module/api/action/actor/actor-initiative-action.js +++ b/module/api/action/actor/actor-initiative-action.js @@ -3,7 +3,7 @@ import { createInitiativeOutcome } from "../../outcome/actor/initiative-outcome. /** * @param {PBActor} actor - * @returns {Promise.} + * @returns {Promise} */ export const actorInitiativeAction = async (actor) => { const outcome = await createInitiativeOutcome({ actor }); @@ -20,4 +20,6 @@ export const actorInitiativeAction = async (actor) => { combatant.update({ initiative: outcome.roll.total }); } } + + return outcome; }; diff --git a/module/api/action/actor/actor-party-initiative-action.js b/module/api/action/actor/actor-party-initiative-action.js index bf3b3569..899967c9 100755 --- a/module/api/action/actor/actor-party-initiative-action.js +++ b/module/api/action/actor/actor-party-initiative-action.js @@ -2,7 +2,7 @@ import { showGenericCard } from "../../../chat-message/generic-card.js"; import { createPartyInitiativeOutcome } from "../../outcome/actor/party-initiative-outcome.js"; /** - * @returns {Promise.} + * @returns {Promise} */ export const actorPartyInitiativeAction = async () => { const outcome = await createPartyInitiativeOutcome(); @@ -15,4 +15,6 @@ export const actorPartyInitiativeAction = async () => { if (game.combats && game.combat) { await game.combat.setPartyInitiative(outcome.roll.total); } + + return outcome; }; diff --git a/module/api/action/actor/actor-roll-ability-action.js b/module/api/action/actor/actor-roll-ability-action.js index 15bbc131..b5a4d0ae 100755 --- a/module/api/action/actor/actor-roll-ability-action.js +++ b/module/api/action/actor/actor-roll-ability-action.js @@ -5,7 +5,7 @@ import { createTestAbilityOutcome } from "../../outcome/actor/test-ability-outco * @param {PBActor} actor * @param {String} ability * @param {Array.} drModifiers - * @returns {Promise.} + * @returns {Promise} */ export const actorRollAbilityAction = async (actor, ability, drModifiers = []) => { const outcome = await createTestAbilityOutcome({ actor, ability }); @@ -16,6 +16,8 @@ export const actorRollAbilityAction = async (actor, ability, drModifiers = []) = actor, outcomes: [outcome], }); + + return outcome; }; /** diff --git a/module/api/action/character/character-broken-action.js b/module/api/action/character/character-broken-action.js index 053b7488..69858e2c 100755 --- a/module/api/action/character/character-broken-action.js +++ b/module/api/action/character/character-broken-action.js @@ -3,7 +3,7 @@ import { createBrokenOutcome } from "../../outcome/character/broken-outcome.js"; /** * @param {PBActor} actor - * @returns {Promise.} + * @returns {Promise} */ export const characterBrokenAction = async (actor) => { const outcome = await createBrokenOutcome({ actor }); @@ -13,4 +13,6 @@ export const characterBrokenAction = async (actor) => { actor, outcomes: [outcome], }); + + return outcome; }; diff --git a/module/api/action/character/character-defend-action.js b/module/api/action/character/character-defend-action.js index 8e790bae..e08240f5 100755 --- a/module/api/action/character/character-defend-action.js +++ b/module/api/action/character/character-defend-action.js @@ -4,7 +4,7 @@ import { createDefendOutcome } from "../../outcome/character/defend-outcome.js"; /** * @param {PBActor} actor - * @returns {Promise.} + * @returns {Promise} */ export const characterDefendAction = async (actor) => { const { defendArmor, defendDR, incomingAttack, targetToken } = await showDefendDialog({ actor }); @@ -24,4 +24,6 @@ export const characterDefendAction = async (actor) => { items: [actor.equippedArmor, actor.equippedHat].filter((item) => item), target: targetToken, }); + + return outcome; }; diff --git a/module/api/action/character/character-get-better-action.js b/module/api/action/character/character-get-better-action.js index 203e1d8e..06ab6c82 100755 --- a/module/api/action/character/character-get-better-action.js +++ b/module/api/action/character/character-get-better-action.js @@ -8,7 +8,7 @@ import { outcome } from "../../outcome/outcome.js"; /** * @param {PBActor} actor - * @returns {Promise.} + * @returns {Promise} */ export const characterGetBetterAction = async (actor) => { const outcomes = [ @@ -29,6 +29,8 @@ export const characterGetBetterAction = async (actor) => { }); await invokeGettingBetterMacro(actor); + + return outcomes; }; /** diff --git a/module/api/action/character/character-invoke-extra-resource-action.js b/module/api/action/character/character-invoke-extra-resource-action.js index 04ae6fa4..ebc1679c 100755 --- a/module/api/action/character/character-invoke-extra-resource-action.js +++ b/module/api/action/character/character-invoke-extra-resource-action.js @@ -31,4 +31,6 @@ export const characterInvokeExtraResourceAction = async (actor, item) => { }); await characterUseItemAction(actor, item, outcome, chatMessage); + + return outcome; }; diff --git a/module/api/action/character/character-invoke-relic-action.js b/module/api/action/character/character-invoke-relic-action.js index 87085e7f..4075e98e 100755 --- a/module/api/action/character/character-invoke-relic-action.js +++ b/module/api/action/character/character-invoke-relic-action.js @@ -5,7 +5,7 @@ import { characterUseItemAction } from "./character-use-item-action.js"; /** * @param {PBActor} actor * @param {PBItem} item - * @returns {Promise.} + * @returns {Promise} */ export const characterInvokeRelicAction = async (actor, item) => { const outcome = await createInvokeRelicOutcome({ actor }); @@ -18,4 +18,6 @@ export const characterInvokeRelicAction = async (actor, item) => { }); await characterUseItemAction(actor, item, outcome, chatMessage); + + return outcome; }; diff --git a/module/api/action/character/character-invoke-ritual-action.js b/module/api/action/character/character-invoke-ritual-action.js index 99e83bb0..723f215d 100755 --- a/module/api/action/character/character-invoke-ritual-action.js +++ b/module/api/action/character/character-invoke-ritual-action.js @@ -5,7 +5,7 @@ import { characterUseItemAction } from "./character-use-item-action.js"; /** * @param {PBActor} actor * @param {PBItem} item - * @returns {Promise.} + * @returns {Promise} */ export const characterInvokeRitualAction = async (actor, item) => { if (actor.rituals.value < 1) { @@ -27,4 +27,6 @@ export const characterInvokeRitualAction = async (actor, item) => { }); await characterUseItemAction(actor, item, outcome, chatMessage); + + return outcome; }; diff --git a/module/api/action/character/character-luck-per-day-action.js b/module/api/action/character/character-luck-per-day-action.js index 5e309be8..cb34c456 100755 --- a/module/api/action/character/character-luck-per-day-action.js +++ b/module/api/action/character/character-luck-per-day-action.js @@ -5,7 +5,7 @@ import { createLuckPerDayOutcome } from "../../outcome/character/luck-per-day-ou * @param {PBActor} actor * @param {Object} options * @param {Boolean} options.silent - * @returns {Promise.} + * @returns {Promise} */ export const characterLuckPerDayAction = async (actor, { silent = false } = {}) => { const outcome = await createLuckPerDayOutcome({ actor }); diff --git a/module/api/action/character/character-reload-action.js b/module/api/action/character/character-reload-action.js index 9ac20216..952a2347 100755 --- a/module/api/action/character/character-reload-action.js +++ b/module/api/action/character/character-reload-action.js @@ -4,6 +4,7 @@ import { createReloadingOutcome } from "../../outcome/character/reloading-outcom /** * @param {PBActor} actor * @param {PBItem} item + * @returns {Promise} */ export const characterReloadAction = async (actor, item) => { const reloadTime = item.reloadTime || 1; @@ -27,4 +28,6 @@ export const characterReloadAction = async (actor, item) => { }), outcomes: [outcome], }); + + return outcome; }; diff --git a/module/api/action/character/character-rest-action.js b/module/api/action/character/character-rest-action.js index eed8a7ac..074e9cc7 100755 --- a/module/api/action/character/character-rest-action.js +++ b/module/api/action/character/character-rest-action.js @@ -51,7 +51,7 @@ const canRest = (foodAndDrink, infected) => ![REST_FOOD_AND_DRINK.STARVE, REST_F */ const shortRest = async (actor, foodAndDrink, infected) => { const isResting = canRest(foodAndDrink, infected); - await showGenericCard({ + return showGenericCard({ actor, title: game.i18n.localize("PB.Rest"), description: !isResting ? game.i18n.localize("PB.NoEffect") : "", @@ -92,7 +92,7 @@ const longRest = async (actor, foodAndDrink, infected) => { outcomes.push(await characterLuckPerDayAction(actor, { silent: true })); } - await showGenericCard({ + return showGenericCard({ actor, title: game.i18n.localize("PB.Rest"), outcomes, diff --git a/module/api/action/creature/creature-morale-action.js b/module/api/action/creature/creature-morale-action.js index 2cd13a7a..7ef8f239 100755 --- a/module/api/action/creature/creature-morale-action.js +++ b/module/api/action/creature/creature-morale-action.js @@ -3,7 +3,7 @@ import { createMoraleOutcome } from "../../outcome/creature/morale-outcome.js"; /** * @param {PBActor} actor - * @returns {Promise.} + * @returns {Promise} */ export const creatureMoraleAction = async (actor) => { if (!actor.attributes.morale || actor.attributes.morale === "-") { @@ -18,4 +18,6 @@ export const creatureMoraleAction = async (actor) => { actor, outcomes: [outcome], }); + + return outcome; }; diff --git a/module/api/action/creature/creature-reaction-action.js b/module/api/action/creature/creature-reaction-action.js index e4c82fd3..03b68556 100755 --- a/module/api/action/creature/creature-reaction-action.js +++ b/module/api/action/creature/creature-reaction-action.js @@ -3,7 +3,7 @@ import { createReactionOutcome } from "../../outcome/creature/reaction-outcome.j /** * @param {PBActor} actor - * @returns {Promise.} + * @returns {Promise} */ export const creatureReactionAction = async (actor) => { const outcome = await createReactionOutcome(); @@ -13,4 +13,6 @@ export const creatureReactionAction = async (actor) => { actor, outcomes: [outcome], }); + + return outcome; }; diff --git a/module/api/action/ship/ship-broadsides-action.js b/module/api/action/ship/ship-broadsides-action.js index 4aa89e39..bceaa852 100755 --- a/module/api/action/ship/ship-broadsides-action.js +++ b/module/api/action/ship/ship-broadsides-action.js @@ -5,7 +5,7 @@ import { showGenericCard } from "../../../chat-message/generic-card.js"; /** * @param {PBActor} actor * @param {Boolean} isPCAction - * @returns {Promise.} + * @returns {Promise} */ export const shipBroadsidesAction = async (actor, isPCAction) => { const { selectedActor, selectedDR, selectedArmor, targetToken } = await showCrewActionDialog({ diff --git a/module/api/action/ship/ship-come-about-action.js b/module/api/action/ship/ship-come-about-action.js index 76fca6e9..c21aa758 100755 --- a/module/api/action/ship/ship-come-about-action.js +++ b/module/api/action/ship/ship-come-about-action.js @@ -5,7 +5,7 @@ import { createComeAboutOutcome } from "../../outcome/ship/ship-come-about-outco /** * @param {PBActor} actor * @param {Boolean} isPCAction - * @returns {Promise.} + * @returns {Promise} */ export const shipComeAboutAction = async (actor, isPCAction) => { const { selectedActor, selectedDR } = await showCrewActionDialog({ diff --git a/module/api/action/ship/ship-full-sail-action.js b/module/api/action/ship/ship-full-sail-action.js index 27f97aa9..0bc1210f 100755 --- a/module/api/action/ship/ship-full-sail-action.js +++ b/module/api/action/ship/ship-full-sail-action.js @@ -5,7 +5,7 @@ import { showGenericCard } from "../../../chat-message/generic-card.js"; /** * @param {PBActor} actor * @param {Boolean} isPCAction - * @returns {Promise.} + * @returns {Promise} */ export const shipFullSailAction = async (actor, isPCAction) => { const { selectedActor, selectedDR } = await showCrewActionDialog({ diff --git a/module/api/action/ship/ship-invoke-shanty-action.js b/module/api/action/ship/ship-invoke-shanty-action.js index 92f7a9bd..b3c19585 100755 --- a/module/api/action/ship/ship-invoke-shanty-action.js +++ b/module/api/action/ship/ship-invoke-shanty-action.js @@ -4,7 +4,7 @@ import { createInvokeShantyOutcome } from "../../outcome/ship/ship-invoke-shanty /** * @param {PBActor} actor * @param {PBItem} item - * @returns {Promise.} + * @returns {Promise} */ export const shipInvokeShantyAction = async (actor, item) => { if (actor.shanties.value < 1) { @@ -22,5 +22,6 @@ export const shipInvokeShantyAction = async (actor, item) => { description: item.getData().description, outcomes: [outcome], }); - // await this.useActionMacro(item.id); + + return outcome; }; diff --git a/module/api/action/ship/ship-ram-action.js b/module/api/action/ship/ship-ram-action.js index c4190c2a..5a146a09 100755 --- a/module/api/action/ship/ship-ram-action.js +++ b/module/api/action/ship/ship-ram-action.js @@ -6,7 +6,7 @@ import { createRamOutcome } from "../../outcome/ship/ship-ram-outcome.js"; /** * @param {PBActor} actor - * @returns {Promise.} + * @returns {Promise} */ export const shipRamAction = async (actor) => { const { selectedArmor, selectedMovement, targetToken } = await showCrewActionDialog({ diff --git a/module/api/action/ship/ship-repair-action.js b/module/api/action/ship/ship-repair-action.js index 7e5dc49e..3c5e16d4 100755 --- a/module/api/action/ship/ship-repair-action.js +++ b/module/api/action/ship/ship-repair-action.js @@ -5,7 +5,7 @@ import { showGenericCard } from "../../../chat-message/generic-card.js"; /** * @param {PBActor} actor * @param {Boolean} isPCAction - * @returns {Promise.} + * @returns {Promise} */ export const shipRepairAction = async (actor, isPCAction) => { const { selectedActor, selectedDR } = await showCrewActionDialog({ diff --git a/module/api/action/ship/ship-shanties-per-day-action.js b/module/api/action/ship/ship-shanties-per-day-action.js index 14936ef9..27cc3736 100755 --- a/module/api/action/ship/ship-shanties-per-day-action.js +++ b/module/api/action/ship/ship-shanties-per-day-action.js @@ -3,7 +3,7 @@ import { createShantiesPerDayOutcome } from "../../outcome/ship/ship-shanties-pe /** * @param {PBActor} actor - * @returns {Promise.} + * @returns {Promise} */ export const shipShantiesPerDayAction = async (actor) => { const captain = game.actors.get(actor.captain); @@ -17,4 +17,6 @@ export const shipShantiesPerDayAction = async (actor) => { title: game.i18n.localize("PB.ShipMysticShanties"), outcomes: [outcome], }); + + return outcome; }; diff --git a/module/api/action/ship/ship-sink-action.js b/module/api/action/ship/ship-sink-action.js index 921ba174..8d693283 100755 --- a/module/api/action/ship/ship-sink-action.js +++ b/module/api/action/ship/ship-sink-action.js @@ -3,7 +3,7 @@ import { createSinkingOutcome } from "../../outcome/ship/ship-sinking-outcome.js /** * @param {PBActor} actor - * @returns {Promise.} + * @returns {Promise} */ export const shipSinkAction = async (actor) => { const outcome = await createSinkingOutcome({ actor }); @@ -14,4 +14,6 @@ export const shipSinkAction = async (actor) => { actor, outcomes: [outcome], }); + + return outcome; }; diff --git a/module/api/action/ship/ship-small-arms-action.js b/module/api/action/ship/ship-small-arms-action.js index 099691fd..1e3cde4d 100755 --- a/module/api/action/ship/ship-small-arms-action.js +++ b/module/api/action/ship/ship-small-arms-action.js @@ -5,7 +5,7 @@ import { showGenericCard } from "../../../chat-message/generic-card.js"; /** * @param {PBActor} actor * @param {Boolean} isPCAction - * @returns {Promise.} + * @returns {Promise} */ export const shipSmallArmsAction = async (actor, isPCAction) => { const { selectedActor, selectedDR, selectedArmor, targetToken } = await showCrewActionDialog({ @@ -33,4 +33,6 @@ export const shipSmallArmsAction = async (actor, isPCAction) => { outcomes: [outcome], target: targetToken, }); + + return outcome; }; diff --git a/module/api/generator/character-generator.js b/module/api/generator/character-generator.js index 0acd7add..9cfd6f3a 100644 --- a/module/api/generator/character-generator.js +++ b/module/api/generator/character-generator.js @@ -14,21 +14,24 @@ import { evaluateFormula } from "../utils.js"; /** * @param {PBItem} cls - * @returns {Promise.} + * @returns {Promise.} */ export const createCharacter = async (cls) => createActorWithCharacter(await rollCharacterForClass(cls)); /** * @param {PBActor} actor * @param {PBItem} cls + * @returns {Promise.} */ export const regenerateActor = async (actor, cls) => { await updateActorWithCharacter(actor, await rollCharacterForClass(cls)); + + return actor; }; /** * @param {Object} characterData - * @returns {Promise.} + * @returns {Promise.} */ export const createActorWithCharacter = async (characterData) => { const data = characterToActorData(characterData); @@ -43,6 +46,7 @@ export const createActorWithCharacter = async (characterData) => { /** * @param {PBActor} actor * @param {Object} characterData + * @returns {Promise.} */ export const updateActorWithCharacter = async (actor, characterData) => { const data = characterToActorData(characterData); @@ -61,10 +65,13 @@ export const updateActorWithCharacter = async (actor, characterData) => { Hooks.call('updateCharacter', actor); await invokeStartingMacro(actor); + + return actor; }; /** * @param {PBActor} actor + * @returns {Promise.} */ export const invokeStartingMacro = async (actor) => { const cls = actor.characterClass; @@ -79,6 +86,8 @@ export const invokeStartingMacro = async (actor) => { item: baseClass, }); } + + return actor; }; /** diff --git a/module/api/utils.js b/module/api/utils.js index 8692c5da..deeba110 100755 --- a/module/api/utils.js +++ b/module/api/utils.js @@ -89,7 +89,7 @@ export const getInfoFromDropData = async (dropData) => { /** * @param {TableResult} result - * @return {String} + * @return {Number} */ export const getResultType = (result) => result.type ?? result.data.type; diff --git a/system.json b/system.json index 174b06c3..f429c875 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "id": "pirateborg", "title": "PIRATE BORG", "description": "Foundry VTT system for PIRATE BORG.", - "version": "v0.6.14", + "version": "v0.6.15", "compatibility": { "minimum": "10", "verified": "11" From 5a56307beee456f6d3a36abca9b62a9970a0ce27 Mon Sep 17 00:00:00 2001 From: Blair McMillan Date: Sun, 21 Apr 2024 20:27:12 +1000 Subject: [PATCH 2/2] Added API details to readme --- how-to-use-this-system.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/how-to-use-this-system.md b/how-to-use-this-system.md index 8b487701..d4def5ed 100644 --- a/how-to-use-this-system.md +++ b/how-to-use-this-system.md @@ -95,3 +95,30 @@ This is an implementation of the PIRATE BORG rules, with limited adaptations to - Allowed classes: edit the classes in the character generator. - Apply overcapacity Penalty: +2 STR/AGI DR when carrying more than STR+8 items. - Track ammo: Select and auto-decrement ammo for ranged weapons. + +## API + +- An API is exposed at `game.pirateborg.api` for developers and GMs to use. + +The following are some examples provided by `Ashendar` on the Discord server. +- An example of how to use the API to roll a character's attack is: + ```javascript + const outcome = game.pirateborg.api.characterAttackAction(actor, weapon); + ``` +- An example of how to roll a character strength check and test the outcome against a DR 18 is: + ```javascript + const outcome = await game.pirateborg.api.actions.actorRollAbilityAction(actor, "strength", ["Mining DR18"]); + return outcome.roll.total >= 18; + ``` +- An example of combining this with the multiple [landings feature](https://github.com/ironmonk88/monks-module-wiki/wiki/MATT-Landing) of [Monk's Active Tile Triggers](https://foundryvtt.com/packages/monks-active-tiles) is: + ```javascript + const outcome = await game.pirateborg.api.actions.actorRollAbilityAction(actor, "strength", ["Mining DR18"]); + let goto = []; + if (outcome.roll.total >= 18) { + goto.push({ tokens: arguments[0].tokens, tag: "Success" }); + } else { + goto.push({ tokens: arguments[0].tokens, tag: "Fail" }); + } + goto = goto.filter(g => g.tokens.length > 0); + return {goto: goto}; + ``` \ No newline at end of file