Make factory usable from Macros.
This does not yet include any modal interface.
This commit is contained in:
parent
85d4384a3c
commit
27c0ddbca1
4 changed files with 96 additions and 2 deletions
2
package-lock.json
generated
2
package-lock.json
generated
|
@ -2702,7 +2702,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"foundry-pc-types": {
|
"foundry-pc-types": {
|
||||||
"version": "git+https://git.f3l.de/dungeonslayers/foundry-pc-types.git#f84074f63d1aeeb9229e441e8c3ccaa9cba64142",
|
"version": "git+https://git.f3l.de/dungeonslayers/foundry-pc-types.git#5a2140620d5be1f42d90dec6c42b3b88ff165f19",
|
||||||
"from": "git+https://git.f3l.de/dungeonslayers/foundry-pc-types.git#f3l-fixes",
|
"from": "git+https://git.f3l.de/dungeonslayers/foundry-pc-types.git#f3l-fixes",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { DS4Item } from "./item/item";
|
||||||
import { DS4ItemSheet } from "./item/item-sheet";
|
import { DS4ItemSheet } from "./item/item-sheet";
|
||||||
import { DS4 } from "./config";
|
import { DS4 } from "./config";
|
||||||
import { DS4Check } from "./rolls/check";
|
import { DS4Check } from "./rolls/check";
|
||||||
|
import { createCheckRoll } from "./rolls/check-factory";
|
||||||
|
|
||||||
Hooks.once("init", async function () {
|
Hooks.once("init", async function () {
|
||||||
console.log(`DS4 | Initializing the DS4 Game System\n${DS4.ASCII}`);
|
console.log(`DS4 | Initializing the DS4 Game System\n${DS4.ASCII}`);
|
||||||
|
@ -13,6 +14,7 @@ Hooks.once("init", async function () {
|
||||||
DS4Actor,
|
DS4Actor,
|
||||||
DS4Item,
|
DS4Item,
|
||||||
DS4,
|
DS4,
|
||||||
|
createCheckRoll,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Record configuration
|
// Record configuration
|
||||||
|
|
93
src/module/rolls/check-factory.ts
Normal file
93
src/module/rolls/check-factory.ts
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
// TODO: Rename to something sane.
|
||||||
|
|
||||||
|
class DefaultCheckOptions implements CheckOptions {
|
||||||
|
maxCritSuccess = 1;
|
||||||
|
minCritFailure = 20;
|
||||||
|
useSlayingDice = false;
|
||||||
|
rollMode: RollMode = "roll";
|
||||||
|
|
||||||
|
mergeWith(other: Partial<CheckOptions>): CheckOptions {
|
||||||
|
return { ...this, ...other } as CheckOptions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CheckFactory {
|
||||||
|
constructor(
|
||||||
|
private checkTargetValue: number,
|
||||||
|
private gmModifier: number,
|
||||||
|
passedOptions: Partial<CheckOptions> = {},
|
||||||
|
) {
|
||||||
|
this.checkOptions = new DefaultCheckOptions().mergeWith(passedOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkOptions: CheckOptions;
|
||||||
|
|
||||||
|
async execute(): Promise<void> {
|
||||||
|
const rollCls: typeof Roll = CONFIG.Dice.rolls[0];
|
||||||
|
|
||||||
|
const formula = [
|
||||||
|
"ds",
|
||||||
|
this.createTargetValueTerm(),
|
||||||
|
this.createCritTerm(),
|
||||||
|
this.createSlayingDiceTerm(),
|
||||||
|
].filterJoin("");
|
||||||
|
const roll = new rollCls(formula);
|
||||||
|
|
||||||
|
const rollModeTemplate = this.checkOptions.rollMode;
|
||||||
|
return roll.toMessage({}, { rollMode: rollModeTemplate, create: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Term generators
|
||||||
|
createTargetValueTerm(): string {
|
||||||
|
if (this.checkTargetValue != null) {
|
||||||
|
return "v" + this.checkTargetValue;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createCritTerm(): string {
|
||||||
|
const minCritRequired = this.checkOptions.minCritFailure !== CheckFactory.defaultCheckOptions.minCritFailure;
|
||||||
|
const maxCritRequired = this.checkOptions.maxCritSuccess !== CheckFactory.defaultCheckOptions.maxCritSuccess;
|
||||||
|
|
||||||
|
if (minCritRequired || maxCritRequired) {
|
||||||
|
return "c" + (this.checkOptions.maxCritSuccess ?? "") + "," + (this.checkOptions.minCritFailure ?? "");
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createSlayingDiceTerm(): string {
|
||||||
|
return this.checkOptions.useSlayingDice ? "x" : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultCheckOptions = new DefaultCheckOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Figure out return of roll (void should be Ok, tough?)
|
||||||
|
export async function createCheckRoll(targetValue: number, options: Partial<CheckOptions>): Promise<void> {
|
||||||
|
// Ask for additional required data;
|
||||||
|
const gmModifier = await askGmModifier();
|
||||||
|
|
||||||
|
// Create Factory
|
||||||
|
const cf = new CheckFactory(targetValue, gmModifier, options);
|
||||||
|
|
||||||
|
// Possibly additional processing
|
||||||
|
|
||||||
|
// Execute roll
|
||||||
|
await cf.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function askGmModifier(): Promise<number> {
|
||||||
|
// Render model interface and return value
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CheckOptions {
|
||||||
|
maxCritSuccess: number;
|
||||||
|
minCritFailure: number;
|
||||||
|
useSlayingDice: boolean;
|
||||||
|
rollMode: RollMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
type RollMode = "roll" | "gmroll" | "blindroll" | "selfroll";
|
|
@ -132,7 +132,6 @@ export class DS4Check extends DiceTerm {
|
||||||
static readonly DEFAULT_TARGET_VALUE = 10;
|
static readonly DEFAULT_TARGET_VALUE = 10;
|
||||||
static readonly DEFAULT_MAX_CRIT_SUCCESS = 1;
|
static readonly DEFAULT_MAX_CRIT_SUCCESS = 1;
|
||||||
static readonly DEFAULT_MIN_CRIT_FAILURE = 20;
|
static readonly DEFAULT_MIN_CRIT_FAILURE = 20;
|
||||||
// TODO: add to Type declarations
|
|
||||||
static DENOMINATION = "s";
|
static DENOMINATION = "s";
|
||||||
static MODIFIERS = {
|
static MODIFIERS = {
|
||||||
x: "explode",
|
x: "explode",
|
||||||
|
|
Loading…
Reference in a new issue