import DFRollPrompt from "./DFRollPrompt" ; import SETTINGS from "../../common/Settings" ; declare global { interface String { dfmr_replaceAll ( token , replacement ) : string ; } } String . prototype . dfmr_replaceAll = function ( token , replacement ) { return this . split ( token ) . join ( replacement ) ; } ; export default class DFManualRolls { static PREF_GM_STATE = 'gm' ; static PREF_PC_STATE = 'pc' ; static PREF_FLAGGED = 'flagged' ; static PREF_TOGGLED = 'toggled' ; static get flagged ( ) : boolean { return SETTINGS . get ( DFManualRolls . PREF_FLAGGED ) ; } static get toggled ( ) : boolean { return SETTINGS . get ( DFManualRolls . PREF_TOGGLED ) ; } static setToggled ( value ) { return SETTINGS . set ( DFManualRolls . PREF_TOGGLED , value ) ; } static get toggleable ( ) { return SETTINGS . get ( game . user . isGM ? DFManualRolls . PREF_GM_STATE : DFManualRolls . PREF_PC_STATE ) === 'toggle' ; } static tempDisable = false ; static get shouldRollManually ( ) { const state = SETTINGS . get ( game . user . isGM ? DFManualRolls . PREF_GM_STATE : DFManualRolls . PREF_PC_STATE ) ; return ! this . tempDisable && ( state === 'always' || ( state === 'toggle' && this . toggled ) ) ; } static patch ( ) { libWrapper . register ( SETTINGS . MOD_NAME , 'Roll.prototype._evaluate' , this . _Roll_evaluate , 'MIXED' ) ; libWrapper . register ( SETTINGS . MOD_NAME , 'DiceTerm.prototype._evaluate' , this . _DiceTerm_evaluate , 'MIXED' ) ; } static unpatch ( ) { libWrapper . unregister ( SETTINGS . MOD_NAME , 'Roll.prototype._identifyTerms' , false ) ; libWrapper . unregister ( SETTINGS . MOD_NAME , 'DiceTerm.prototype.roll' , false ) ; } private static async _Roll_evaluate ( this , wrapper , { minimize = false , maximize = false } = { } ) { if ( ! DFManualRolls . shouldRollManually || minimize || maximize ) { return wrapper ( { minimize , maximize } ) ; } /****** THIS IS CAPTURED DIRECTLY FROM Roll.prototype._evaluate ******/ const intermediate = [ ] ; for ( const element of this . terms ) { let term = element ; if ( ! ( term instanceof RollTerm ) ) { throw new Error ( "Roll evaluation encountered an invalid term which was not a RollTerm instance" ) ; } if ( term . isIntermediate ) { await term . evaluate ( { minimize , maximize , async : true } ) ; this . _dice = this . _dice . concat ( ( < any > term ) . dice ) ; term = new NumericTerm ( { number : < number > term . total , options : ( < any > term ) . options } ) ; } intermediate . push ( term ) ; } this . terms = intermediate ; this . terms = Roll . simplifyTerms ( this . terms ) ; /****** DF MANUAL ROLLS MODIFICATION ******/ const rollPrompt = new DFRollPrompt ( { } , this . options . flavor ? { title : this . options . flavor } : { } ) ; for ( const term of this . terms ) { if ( ! ( term instanceof DiceTerm ) ) continue ; ( < any > term ) . rollPrompt = rollPrompt ; } const promises = [ ] ; for ( const term of this . terms ) { if ( term . _evaluated ) continue ; promises . push ( term . evaluate ( { minimize , maximize , async : true } ) ) ; } await rollPrompt . render ( true ) ; await Promise . all ( promises ) ; /************ END MODIFICATION ************/ this . _total = this . _evaluateTotal ( ) ; return this ; } private static async _DiceTerm_evaluate ( this , wrapper , { minimize = false , maximize = false } = { } ) { const rollPrompt = ( < any > this ) . rollPrompt ; if ( ! DFManualRolls . shouldRollManually || ! rollPrompt || minimize || maximize ) return wrapper ( minimize , maximize ) ; const results = await rollPrompt . requestResult ( this ) ; for ( const x of results ) this . results . push ( { result : x , active : true } ) ; this . _evaluateModifiers ( ) ; return this ; } }