Foundry VTT/P2FE: Difference between revisions
Jump to navigation
Jump to search
Line 277: | Line 277: | ||
} | } | ||
</pre> | </pre> | ||
== keywords == |
Revision as of 02:42, 27 August 2024
Macros
Basic Action Macro
await game.PF2eWorkbench.basicActionMacros();
Camping Sheet
game.pf2eKingmakerTools.macros.openCampingSheet()
Exploration
const tokens = canvas.tokens.controlled.filter((t) => ['character'].includes(t.actor.type), ) if (tokens.length === 0) { ui.notifications.error(`You must select at least one pc token`) } else { tokens.forEach((token) => { let actor = token.actor let tokenID = token.id explorationActivity(actor, tokenID) }) } function explorationActivity(actor, tokenID) { let token = canvas.tokens.get(tokenID) let content = '' let selectedActivity let activities = { 'Avoid Notice': '@Compendium[pf2e.actionspf2e.IE2nThCmoyhQA0Jn]{Avoid Notice}', 'Cover Tracks': '@Compendium[pf2e.actionspf2e.SB7cMECVtE06kByk]{Cover Tracks}', Defend: '@Compendium[pf2e.actionspf2e.cYtYKa1gDEl7y2N0]{Defend}', 'Detect Magic': '@Compendium[pf2e.actionspf2e.Yb0C1uLzeHrVLl7a]{Detect Magic}', 'Follow the Expert': '@Compendium[pf2e.actionspf2e.tfa4Sh7wcxCEqL29]{Follow the Expert}', Hustle: '@Compendium[pf2e.actionspf2e.JuqmIAnkL9hVGai8]{Hustle}', Investigate: '@Compendium[pf2e.actionspf2e.EwgTZBWsc8qKaViP]{Investigate}', 'Repeat a Spell': '@Compendium[pf2e.actionspf2e.OQaFzDtVEOMWizJJ]{Repeat a Spell}', Scout: '@Compendium[pf2e.actionspf2e.kV3XM0YJeS2KCSOb]{Scout}', Search: '@Compendium[pf2e.actionspf2e.TiNDYUGlMmxzxBYU]{Search}', Track: '@Compendium[pf2e.actionspf2e.EA5vuSgJfiHH7plD]{Track}', } let additionalActions = { 'Borrow an Arcane Spell': '@Compendium[pf2e.actionspf2e.OizxuPb44g3eHPFh]{Borrow an Arcane Spell}', Coerce: '@Compendium[pf2e.actionspf2e.tHCqgwjtQtzNqVvd]{Coerce}', 'Cover Tracks': '@Compendium[pf2e.actionspf2e.SB7cMECVtE06kByk]{Cover Tracks}', 'Decipher Writing': '@Compendium[pf2e.actionspf2e.d9gbpiQjChYDYA2L]{Decypher Writing}', 'Gather Information': '@Compendium[pf2e.actionspf2e.plBGdZhqq5JBl1D8]{Gather Information}', 'Identify Alchemy': '@Compendium[pf2e.actionspf2e.Q4kdWVOf2ztIBFg1]{Identify Alchemy}', 'Identify Magic': '@Compendium[pf2e.actionspf2e.eReSHVEPCsdkSL4G]{Identify Magic}', Impersonate: '@Compendium[pf2e.actionspf2e.AJstokjdG6iDjVjE]{Impersonate}', 'Learn a Spell': '@Compendium[pf2e.actionspf2e.Q5iIYCFdqJFM31GW]{Learn a Spell}', 'Make an Impression': '@Compendium[pf2e.actionspf2e.OX4fy22hQgUHDr0q]{Make an Impression}', 'Sense Direction': '@Compendium[pf2e.actionspf2e.fJImDBQfqfjKJOhk]{Sense Direction}', Squeeze: '@Compendium[pf2e.actionspf2e.kMcV8e5EZUxa6evt]{Squeeze}', 'Treat Wounds': '@Compendium[pf2e.actionspf2e.1kGNdIIhuglAjIp9]{Treat Wounds}', } //contentUpdate(); const dialogStyle = ` <style> .my-class { margin-bottom: 12px; } </style>` content = dialogStyle content += `<div id="pf2e-explorationActivity-scripts-content"><label for="activity">Choose an activity: </label> <select class ="my-class" name="activity" id="activity">` content += `<optgroup label="common">` for (let i = 0; i < Object.keys(activities).length; i++) { content += `<option value="${activities[Object.keys(activities)[i]]}">${ Object.keys(activities)[i] }</option>` } content += `</optgroup>` content += `<optgroup label="additional">` for (let i = 0; i < Object.keys(additionalActions).length; i++) { content += `<option value="${ additionalActions[Object.keys(additionalActions)[i]] }">${Object.keys(additionalActions)[i]}</option>` } content += `</optgroup>` content += `</select></div>` let d = new Dialog({ title: 'Exploration Activity', content, buttons: { select: { icon: '', label: 'Select', callback: (html) => { selectedActivity = '<h3>I will <b>' + html.find('#activity')[0].value + '</b></h3>' generateChat(actor, selectedActivity) applyEffect(actor, html.find('#activity')[0].value) }, }, cancel: { icon: '', label: 'Cancel', callback: () => { selectedActivity = '<h3>I will do nothing in particular.</h3>' generateChat(actor, selectedActivity) }, }, }, }) d.options.width = 250 d.position.width = 250 d.render(true) // used to create the chat messages async function generateChat(actor, output) { let chatData = { user: game.user._id, speaker: { alias: actor.name, }, content: output, } await ChatMessage.create(chatData, {}) } //used to apply effect async function applyEffect(actor, selectedEffect) { const re = /\{(.*)\}/i let effectName = selectedEffect.match(re)[1] const explorationEffects = { 'Avoid Notice': 'Compendium.pf2e-exploration-effects.exploration-effects.N8vpuGy4TzU10y8E', 'Cover Tracks': 'Compendium.pf2e-exploration-effects.exploration-effects.F6vJYLZTWDpnrnCZ', Defend: 'Compendium.pf2e-exploration-effects.exploration-effects.GYOyFj4ziZX060rZ', 'Detect Magic': 'Compendium.pf2e-exploration-effects.exploration-effects.OjRHL0B4WAUUQc13', 'Follow the Expert': 'ompendium.pf2e-exploration-effects.exploration-effects.V347nnVBGDrVWh7k', Hustle: 'Compendium.pf2e-exploration-effects.exploration-effects.vNUrKvoOSvEnqzhM', Investigate: 'Compendium.pf2e-exploration-effects.exploration-effects.tDsgl8YmhZbx2May', 'Repeat a Spell': 'Compendium.pf2e-exploration-effects.exploration-effects.kh1QdKkvbNZ0qBsQ', Scout: 'Compendium.pf2e-exploration-effects.exploration-effects.mGFBHM1lvHNZ9BsH', Search: 'Compendium.pf2e-exploration-effects.exploration-effects.XiVLHjg5lQVMX8Fj', Track: 'Compendium.pf2e-exploration-effects.exploration-effects.OcCXjJab7rSR3mDf', } let effect = explorationEffects[effectName] if (effect != undefined) { console.log('the effect is ' + effect) let item = (await fromUuid(effect)).toObject() await token.actor.createEmbeddedDocuments('Item', [item]) } } }
Raise Shield
game.pf2e.actions.raiseAShield({ actors: [token?.actor ?? actor ?? game.user.character].filter((actor) => actor) })
Recall Knowledge
/** This compendium link macro will always call the most recent version from the compendium included with this module meaning you do not need to reimport newer versions. The source of the macros that get called is https://gitlab.com/symonsch/my-foundryvtt-macros/-/tree/main/PF2e */ /* Start of documentation from the original macro: */ /* Based on the macro by bipedalshark and WesBelmont and Allalinor. updated by darkim, Dalvyn, and julie.winchester Recall Knowledge This macro will roll several knowledge checks if no target is selected. If one ore more targets are selected it will only roll the relevant knowledge skills and compare the result to the DC. Handles lore skills (as far as possible) Handles Cognitive Mutagen and other Bonus effects Should pick up most single target trait based mods automatically now if predicates are set properly. Limitations: * Does not handle assurance. * Does not handle things like bardic knowledge. */ /* End of original macro documentation. */ async function _executeMacroByName( macroName, compendiumName = "xdy-pf2e-workbench.asymonous-benefactor-macros-internal" ) { const pack = game.packs.get(compendiumName); if (pack) { const macro_data = (await pack.getDocuments()).find((i) => i.name === macroName)?.toObject(); if (macro_data) { const temp_macro = new Macro(macro_data); temp_macro.permission.default = CONST.DOCUMENT_PERMISSION_LEVELS.OWNER; temp_macro.execute(); } else { ui.notifications.error("Macro " + macroName + " not found"); } } else { ui.notifications.error("Compendium " + compendiumName + " not found"); } } _executeMacroByName('XDY DO_NOT_IMPORT Recall_Knowledge'); /* This compendium link macro is based on one originally posted by DrentalBot: https://discord.com/channels/880968862240239708/880975811279204402/910490804554973274; and modified by Mark Pearce https://discord.com/channels/880968862240239708/880969174661353484/972962446098702376 */
Refocus
await game.PF2eWorkbench.refocus();
Scouting
game.pf2e.rollItemMacro("2FxTHADqPM7Y2MYA", event);
or
const actors = game.user.getActiveTokens().flatMap((t) => t.actor ?? []); if (actors.length === 0) { return ui.notifications.error("PF2E.ErrorMessage.NoTokenSelected", { localize: true }); } const ITEM_UUID = "Compendium.pf2e.other-effects.Item.EMqGwUi3VMhCjTlF"; // Effect: Scouting const item = await fromUuid(ITEM_UUID); if (item?.type === "condition") { for (const actor of actors) { actor.toggleCondition(item.slug); } } else if (item?.type === "effect") { const source = item.toObject(); source.flags = mergeObject(source.flags ?? {}, { core: { sourceId: ITEM_UUID } }); for (const actor of actors) { const existing = actor.itemTypes.effect.find((e) => e.flags.core?.sourceId === ITEM_UUID); if (existing) { await existing.delete(); } else { await actor.createEmbeddedDocuments("Item", [source]); } } } else { ui.notifications.error(game.i18n.format("PF2E.ErrorMessage.ItemNotFoundByUUID", { uuid: ITEM_UUID })); }