-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rolls): add modifier keys and fastforwarding (#121)
* Centralise settings retrieval and setup * Localise settings * Remove redundant imports * Fix documentation * Swap to export functions to match rest of code * Rename function for clarity * General cleanup of export names * Minor documentation change * Add keybindings setup * Setup utils folder * Fix minor errors * Add key modifier processing and skip behaviour for all d20 rolls * Clean up * Add key modifiers to item rolls * Fix incorrect default parameter * Make config values override any modifier * Review suggestions * Add as const to keybindings constant * Fix double dialog * Separate utils
- Loading branch information
Showing
12 changed files
with
241 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { | ||
getSystemKeybinding, | ||
getSystemSetting, | ||
KEYBINDINGS, | ||
SETTINGS, | ||
} from '../settings'; | ||
import { AdvantageMode } from '../types/roll'; | ||
|
||
/** | ||
* Determine if the keys of a requested keybinding are pressed. | ||
* @param {string} action Keybinding action within the system namespace. Can have multiple keybindings associated. | ||
* @returns {boolean} True if one of the keybindings for the requested action are triggered, false otherwise. | ||
*/ | ||
export function areKeysPressed(action: string): boolean { | ||
const keybinds = getSystemKeybinding(action); | ||
|
||
if (!keybinds || keybinds.length === 0) { | ||
return false; | ||
} | ||
|
||
const activeModifiers = {} as Record<string, boolean>; | ||
|
||
const addModifiers = (key: string) => { | ||
if (hasKey(KeyboardManager.MODIFIER_CODES, key)) { | ||
KeyboardManager.MODIFIER_CODES[key].forEach( | ||
(n: string) => | ||
(activeModifiers[n] = game.keyboard!.downKeys.has(n)), | ||
); | ||
} | ||
}; | ||
addModifiers(KeyboardManager.MODIFIER_KEYS.CONTROL); | ||
addModifiers(KeyboardManager.MODIFIER_KEYS.SHIFT); | ||
addModifiers(KeyboardManager.MODIFIER_KEYS.ALT); | ||
|
||
return getSystemKeybinding(action).some((b) => { | ||
if ( | ||
game.keyboard!.downKeys.has(b.key) && | ||
b.modifiers?.every((m) => activeModifiers[m]) | ||
) | ||
return true; | ||
if (b.modifiers?.length) return false; | ||
return activeModifiers[b.key]; | ||
}); | ||
} | ||
|
||
/** | ||
* Checks if a given object has the given property key as a key for indexing. | ||
* Adding this check beforehand allows an object to be indexed by that key directly without typescript errors. | ||
* @param {T} obj The object to check for indexing. | ||
* @param {PropertyKey} key The key to check within the object. | ||
* @returns {boolean} True if the given object has requested property key, false otherwise. | ||
*/ | ||
export function hasKey<T extends object>( | ||
obj: T, | ||
key: PropertyKey, | ||
): key is keyof T { | ||
return key in obj; | ||
} | ||
|
||
/** | ||
* Processes pressed keys and provided config values to determine final values for a roll, specifically: | ||
* if it should skip the configuration dialog, what advantage mode it is using, and if it has raised stakes. | ||
* @param {boolean} [configure] Should the roll dialog be skipped? | ||
* @param {boolean} [advantage] Is something granting this roll advantage? | ||
* @param {boolean} [disadvantage] Is something granting this roll disadvantage? | ||
* @param {boolean} [raiseStakes] Is something granting this roll raised stakes? | ||
* @returns {{fastForward: boolean, advantageMode: AdvantageMode, plotDie: boolean}} Whether a roll should fast forward, have a plot die, and its advantage mode. | ||
*/ | ||
export function determineConfigurationMode( | ||
configure?: boolean, | ||
advantage?: boolean, | ||
disadvantage?: boolean, | ||
raiseStakes?: boolean, | ||
) { | ||
const modifiers = { | ||
advantage: areKeysPressed(KEYBINDINGS.SKIP_DIALOG_ADVANTAGE), | ||
disadvantage: areKeysPressed(KEYBINDINGS.SKIP_DIALOG_DISADVANTAGE), | ||
raiseStakes: areKeysPressed(KEYBINDINGS.SKIP_DIALOG_RAISE_STAKES), | ||
}; | ||
|
||
const fastForward = | ||
configure !== undefined | ||
? !configure | ||
: isFastForward() || Object.values(modifiers).some((k) => k); | ||
|
||
const hasAdvantage = advantage ?? modifiers.advantage; | ||
const hasDisadvantage = disadvantage ?? modifiers.disadvantage; | ||
const advantageMode = hasAdvantage | ||
? AdvantageMode.Advantage | ||
: hasDisadvantage | ||
? AdvantageMode.Disadvantage | ||
: AdvantageMode.None; | ||
const plotDie = raiseStakes ?? modifiers.raiseStakes; | ||
|
||
return { fastForward, advantageMode, plotDie }; | ||
} | ||
|
||
/** | ||
* Processes pressed keys and selected system settings to determine if a roll should fast forward. | ||
* This function allows the swappable behaviour of the Skip/Show Dialog modifier key, making it behave correctly depending on the system setting selected by the user. | ||
* @returns {boolean} Whether a roll should fast forward or not. | ||
*/ | ||
export function isFastForward() { | ||
const skipKeyPressed = areKeysPressed(KEYBINDINGS.SKIP_DIALOG_DEFAULT); | ||
const skipByDefault = getSystemSetting(SETTINGS.ROLL_SKIP_DIALOG_DEFAULT); | ||
|
||
return ( | ||
(skipByDefault && !skipKeyPressed) || (!skipByDefault && skipKeyPressed) | ||
); | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.