generated from League-of-Foundry-Developers/foundry-typescript-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
37 changed files
with
4,328 additions
and
112 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"version": "2.0.0", | ||
"tasks": [ | ||
{ | ||
"type": "npm", | ||
"script": "build", | ||
"group": {"kind": "build", "isDefault": true}, | ||
"problemMatcher": [], | ||
"label": "npm: build", | ||
"detail": "gulp build" | ||
} | ||
] | ||
} |
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 |
---|---|---|
@@ -1,38 +1,22 @@ | ||
# Changelog | ||
*Please for the love of all that you hold dear, do everyone a favor and include a changelog here rather than making people guess at the capabilities of your module since last release* | ||
|
||
# Description | ||
This is a typescript template to get you started. This is not intended for beginners. | ||
|
||
Please use the javascript template as necessary for your stuff. | ||
|
||
|
||
## Manifest Plus | ||
Adds the following fields to the manifest for package browsers to pick up and show information better: | ||
|
||
``` | ||
- includes: [] # list of files to include in the zip | ||
- icon: "" # link to icon img | ||
- cover: "" #link to cover img | ||
- screenshots: [] #links to screenshot images | ||
- video: "" | ||
- authors: [ | ||
{ | ||
"name": "name", | ||
"email": "email", | ||
"discord": "discord" | ||
} | ||
] | ||
``` | ||
|
||
|
||
## Versioned Releases | ||
|
||
The Github Actions script will automatically create a Latest release which will always have a module.json that points to the latest release, and a versioned release whenever you update the version in your module.json. | ||
|
||
This allows people who depend on a specific version of your module to just install that and be version locked. The versioned releases will *not* auto update. | ||
|
||
|
||
# License | ||
MIT License. Do what you will. PRs welcome. | ||
manifest url: https://raw.githubusercontent.com/danielrab/smooth-combat/master/module.json <br><br> | ||
This module was inspired primarily by MidiQOL and tries to provide automation of combat for dnd5e. <br> | ||
Currently it is on a very early stage of development, so it only dealt with weapon attacks (not spells and feats). <br> | ||
My main goal when developing this module is first and foremost smooth user experience. It means that if a click or a keypress is avoidable, I will try to avoid it. It also means that on every step, the information must be presented in the cleanest form, and the user should have full control over every step of the process. <br> | ||
For now, what the module does is: <br> | ||
1) When an item is dragged to the macro panel, the script that is created is replaced with one that allows to roll the attack even if no token is selected. | ||
2) When a weapon is used, the following will happen: <br> | ||
2.1) You will be switched to target selection. <br> | ||
2.2) All targets will be cleared. <br> | ||
2.3) You will be asked to select a target and given an option to abort the execution or to select another amount of targets. <br> | ||
2.4) Selection of multiple targets will be inverted (no need to hold shift to select multiple). <br> | ||
2.5) Once you selected the target(s), an attack will be rolled for each target and damage will be rolled for each attack that hits showing each damage formula and their damage types separately (in case the enemy has resistance to some but not all of the damage dealt) <br> | ||
2.6) After all of this you will be returned to the tool and layer you were at, and the target selection will return to normal. <br> | ||
2.7) Damage will be applied using resistances, immunities, and vulnerabilities of the hit creatures (the weapons are assumed to be nonmagical until i find a way to differentiate between magical and nonmagical weapons). <br><br> | ||
when using an item, alt will use advantage, ctrl will use disadvantage, shift will use versitile. <br><br> | ||
planned in the near future:<br> | ||
1) sttings. | ||
2) a damage card for the DM to know how much damage was actually dealt after the resistances, as well as have an option to reverse it. | ||
3) ability to define a secondary use with multiple formulas. (currently versitle replaces only the first one). | ||
4) ability to define a weapon as magical for purposes of bypassing resistances. | ||
5) automatic disadvantage for ranged weapons depending on range. | ||
6) ability to define a token as in partial cover. |
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 |
---|---|---|
@@ -1,38 +1,22 @@ | ||
# Changelog | ||
*Please for the love of all that you hold dear, do everyone a favor and include a changelog here rather than making people guess at the capabilities of your module since last release* | ||
|
||
# Description | ||
This is a typescript template to get you started. This is not intended for beginners. | ||
|
||
Please use the javascript template as necessary for your stuff. | ||
|
||
|
||
## Manifest Plus | ||
Adds the following fields to the manifest for package browsers to pick up and show information better: | ||
|
||
``` | ||
- includes: [] # list of files to include in the zip | ||
- icon: "" # link to icon img | ||
- cover: "" #link to cover img | ||
- screenshots: [] #links to screenshot images | ||
- video: "" | ||
- authors: [ | ||
{ | ||
"name": "name", | ||
"email": "email", | ||
"discord": "discord" | ||
} | ||
] | ||
``` | ||
|
||
|
||
## Versioned Releases | ||
|
||
The Github Actions script will automatically create a Latest release which will always have a module.json that points to the latest release, and a versioned release whenever you update the version in your module.json. | ||
|
||
This allows people who depend on a specific version of your module to just install that and be version locked. The versioned releases will *not* auto update. | ||
|
||
|
||
# License | ||
MIT License. Do what you will. PRs welcome. | ||
manifest url: https://raw.githubusercontent.com/danielrab/smooth-combat/master/module.json <br><br> | ||
This module was inspired primarily by MidiQOL and tries to provide automation of combat for dnd5e. <br> | ||
Currently it is on a very early stage of development, so it only dealt with weapon attacks (not spells and feats). <br> | ||
My main goal when developing this module is first and foremost smooth user experience. It means that if a click or a keypress is avoidable, I will try to avoid it. It also means that on every step, the information must be presented in the cleanest form, and the user should have full control over every step of the process. <br> | ||
For now, what the module does is: <br> | ||
1) When an item is dragged to the macro panel, the script that is created is replaced with one that allows to roll the attack even if no token is selected. | ||
2) When a weapon is used, the following will happen: <br> | ||
2.1) You will be switched to target selection. <br> | ||
2.2) All targets will be cleared. <br> | ||
2.3) You will be asked to select a target and given an option to abort the execution or to select another amount of targets. <br> | ||
2.4) Selection of multiple targets will be inverted (no need to hold shift to select multiple). <br> | ||
2.5) Once you selected the target(s), an attack will be rolled for each target and damage will be rolled for each attack that hits showing each damage formula and their damage types separately (in case the enemy has resistance to some but not all of the damage dealt) <br> | ||
2.6) After all of this you will be returned to the tool and layer you were at, and the target selection will return to normal. <br> | ||
2.7) Damage will be applied using resistances, immunities, and vulnerabilities of the hit creatures (the weapons are assumed to be nonmagical until i find a way to differentiate between magical and nonmagical weapons). <br><br> | ||
when using an item, alt will use advantage, ctrl will use disadvantage, shift will use versitile. <br><br> | ||
planned in the near future:<br> | ||
1) sttings. | ||
2) a damage card for the DM to know how much damage was actually dealt after the resistances, as well as have an option to reverse it. | ||
3) ability to define a secondary use with multiple formulas. (currently versitle replaces only the first one). | ||
4) ability to define a weapon as magical for purposes of bypassing resistances. | ||
5) automatic disadvantage for ranged weapons depending on range. | ||
6) ability to define a token as in partial cover. |
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,39 @@ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
class AttackRollHandler { | ||
constructor(roll, target) { | ||
this.roll = roll; | ||
this.target = target; | ||
} | ||
get hits() { | ||
return this.total >= this.target.actor.ac && !this.fumble; | ||
} | ||
get die() { | ||
return this.roll.terms[0]; | ||
} | ||
get total() { | ||
return this.roll.total; | ||
} | ||
get formula() { | ||
return this.roll._formula; | ||
} | ||
get critical() { | ||
return this.die.results[0].result >= this.die.options.critical; | ||
} | ||
get fumble() { | ||
return this.die.results[0].result <= this.die.options.fumble; | ||
} | ||
} | ||
export default function attackRoll(item, target, options) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const roll = yield item.rollAttack(Object.assign(Object.assign({}, options), { fastForward: true, chatMessage: false })); | ||
return new AttackRollHandler(roll, target); | ||
}); | ||
} |
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,33 @@ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
import { DamageRollPart } from './DamageRollPart.js'; | ||
import settings from './settings.js'; | ||
class DamageRollHandler { | ||
constructor(parts) { | ||
this.parts = parts; | ||
} | ||
apply(target) { | ||
const damage = this.parts.map((part) => part.getDamage(target)).reduce((a, b) => a + b); | ||
if (settings.applyDamage) | ||
target.actor.applyDamage(damage); | ||
return damage; | ||
} | ||
} | ||
export default function damageRoll(item, versatile, critical) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const damageParts = item.data.data.damage.parts; | ||
const rollParts = yield Promise.all(damageParts.map((part) => __awaiter(this, void 0, void 0, function* () { return DamageRollPart(item, part, critical); }))); | ||
if (versatile && item.data.data.damage.versatile) { | ||
const versatileRollPart = yield DamageRollPart(item, [item.data.data.damage.versatile, damageParts[0][1]], critical); | ||
rollParts[0] = versatileRollPart; | ||
} | ||
return new DamageRollHandler(rollParts); | ||
}); | ||
} |
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,36 @@ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
export class DamageRollPartHandler { | ||
constructor(roll, type) { | ||
this.roll = roll; | ||
this.type = type; | ||
} | ||
get total() { | ||
return this.roll.total; | ||
} | ||
get formula() { | ||
return this.roll._formula; | ||
} | ||
getDamage(target) { | ||
return Math.floor(target.actor.damageMultiplier(this.type) * this.total); | ||
} | ||
} | ||
export function DamageRollPart(item, [formula, type], critical) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const roll = yield game.dnd5e.dice.damageRoll({ | ||
parts: [formula], | ||
data: item.getRollData(), | ||
critical, | ||
fastForward: true, | ||
chatMessage: false, | ||
}); | ||
return new DamageRollPartHandler(roll, type); | ||
}); | ||
} |
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,38 @@ | ||
/* eslint-disable func-names */ | ||
Handlebars.registerHelper('ifObject', function (item, options) { | ||
if (typeof item === 'object') { | ||
return options.fn(this); | ||
} | ||
return options.inverse(this); | ||
}); | ||
Handlebars.registerHelper('when', function (operand1, operator, operand2, options) { | ||
const operators = { | ||
eq(l, r) { | ||
return l === r; | ||
}, | ||
noteq(l, r) { | ||
return l !== r; | ||
}, | ||
gt(l, r) { | ||
return Number(l) > Number(r); | ||
}, | ||
or(l, r) { | ||
return l || r; | ||
}, | ||
and(l, r) { | ||
return l && r; | ||
}, | ||
'%': function (l, r) { | ||
return (l % r) === 0; | ||
}, | ||
}; | ||
const result = operators[operator](operand1, operand2); | ||
if (result) | ||
return options.fn(this); | ||
return options.inverse(this); | ||
}); | ||
Hooks.on('init', () => loadTemplates([ | ||
'./modules/smooth-combat/templates/rollDetails.hbs', | ||
'./modules/smooth-combat/templates/damageRoll.hbs', | ||
'./modules/smooth-combat/templates/roll.hbs', | ||
])); |
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,14 @@ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
export default function attackResultHTML(result) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return renderTemplate('./modules/smooth-combat/templates/attackResult.hbs', result); | ||
}); | ||
} |
Oops, something went wrong.