mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-04-21 23:13:39 +02:00
Compare commits
2 commits
ca097c21a3
...
e3673c50c6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3673c50c6 | ||
|
|
e4b3f5d5bd |
14 changed files with 129 additions and 167 deletions
|
|
@ -236,6 +236,8 @@
|
|||
},
|
||||
"defaultHopeDice": "Default Hope Dice",
|
||||
"defaultFearDice": "Default Fear Dice",
|
||||
"defaultAdvantageDice": "Default Advantage Dice",
|
||||
"defaultDisadvantageDice": "Default Disadvantage Dice",
|
||||
"disadvantageSources": {
|
||||
"label": "Disadvantage Sources",
|
||||
"hint": "Add single words or short text as reminders and hints of what a character has disadvantage on."
|
||||
|
|
@ -3210,8 +3212,6 @@
|
|||
"companion": "Level {level} - {partner}",
|
||||
"companionNoPartner": "No Partner",
|
||||
"duplicateToNewTier": "Duplicate to New Tier",
|
||||
"activateParty": "Make Activate Party",
|
||||
"partyIsActive": "Active",
|
||||
"createAdversary": "Create Adversary",
|
||||
"pickTierTitle": "Pick a new tier for this adversary"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -123,6 +123,10 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
context.advantage = this.config.roll?.advantage;
|
||||
context.disadvantage = this.config.roll?.disadvantage;
|
||||
context.diceOptions = CONFIG.DH.GENERAL.diceTypes;
|
||||
context.diceFaces = CONFIG.DH.GENERAL.dieFaces.reduce((acc, face) => {
|
||||
acc[face] = `d${face}`;
|
||||
return acc;
|
||||
}, {});
|
||||
context.isLite = this.config.roll?.lite;
|
||||
context.extraFormula = this.config.extraFormula;
|
||||
context.formula = this.roll.constructFormula(this.config);
|
||||
|
|
@ -153,6 +157,9 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
if (this.config.uses) this.config.uses = foundry.utils.mergeObject(this.config.uses, rest.uses);
|
||||
if (rest.roll?.dice) {
|
||||
Object.entries(rest.roll.dice).forEach(([key, value]) => {
|
||||
if(key === 'advantageFaces')
|
||||
this.roll[key] = Number.parseInt(value);
|
||||
else
|
||||
this.roll[key] = value;
|
||||
});
|
||||
}
|
||||
|
|
@ -173,6 +180,16 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
this.disadvantage = advantage === -1;
|
||||
|
||||
this.config.roll.advantage = this.config.roll.advantage === advantage ? 0 : advantage;
|
||||
|
||||
if(this.config.roll.advantage === 1 && this.config.data.rules.roll.defaultAdvantageDice) {
|
||||
const faces = Number.parseInt(this.config.data.rules.roll.defaultAdvantageDice);
|
||||
this.roll.advantageFaces = Number.isNaN(faces) ? this.roll.advantageFaces : faces;
|
||||
}
|
||||
else if(this.config.roll.advantage === -1 && this.config.data.rules.roll.defaultDisadvantageDice) {
|
||||
const faces = Number.parseInt(this.config.data.rules.roll.defaultDisadvantageDice);
|
||||
this.roll.advantageFaces = Number.isNaN(faces) ? this.roll.advantageFaces : faces;
|
||||
}
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,8 +46,7 @@ export default class DhActorDirectory extends foundry.applications.sidebar.tabs.
|
|||
|
||||
_getEntryContextOptions() {
|
||||
const options = super._getEntryContextOptions();
|
||||
options.push(
|
||||
{
|
||||
options.push({
|
||||
name: 'DAGGERHEART.UI.Sidebar.actorDirectory.duplicateToNewTier',
|
||||
icon: `<i class="fa-solid fa-arrow-trend-up" inert></i>`,
|
||||
condition: li => {
|
||||
|
|
@ -90,27 +89,7 @@ export default class DhActorDirectory extends foundry.applications.sidebar.tabs.
|
|||
ui.notifications.info(`Tier ${tier} ${actor.name} created`);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'DAGGERHEART.UI.Sidebar.actorDirectory.activateParty',
|
||||
icon: `<i class="fa-regular fa-square"></i>`,
|
||||
condition: li => {
|
||||
const actor = game.actors.get(li.dataset.entryId);
|
||||
return actor && actor.type === 'party' && !actor.system.active;
|
||||
},
|
||||
callback: async li => {
|
||||
const actor = game.actors.get(li.dataset.entryId);
|
||||
if (!actor) throw new Error('Unexpected missing actor');
|
||||
|
||||
const currentActiveParty = game.actors.find(x => x.type === 'party' && x.system.active);
|
||||
if (currentActiveParty)
|
||||
await currentActiveParty.update({ 'system.active': false });
|
||||
|
||||
await actor.update({ 'system.active': true });
|
||||
ui.actors.render();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return options;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -289,7 +289,23 @@ export default class DhCharacter extends DhCreature {
|
|||
guaranteedCritical: new fields.BooleanField({
|
||||
label: 'DAGGERHEART.ACTORS.Character.roll.guaranteedCritical.label',
|
||||
hint: 'DAGGERHEART.ACTORS.Character.roll.guaranteedCritical.hint'
|
||||
})
|
||||
}),
|
||||
defaultAdvantageDice: new fields.NumberField({
|
||||
nullable: true,
|
||||
required: true,
|
||||
integer: true,
|
||||
choices: CONFIG.DH.GENERAL.dieFaces,
|
||||
initial: null,
|
||||
label: 'DAGGERHEART.ACTORS.Character.defaultAdvantageDice'
|
||||
}),
|
||||
defaultDisadvantageDice: new fields.NumberField({
|
||||
nullable: true,
|
||||
required: true,
|
||||
integer: true,
|
||||
choices: CONFIG.DH.GENERAL.dieFaces,
|
||||
initial: null,
|
||||
label: 'DAGGERHEART.ACTORS.Character.defaultDisadvantageDice'
|
||||
}),
|
||||
})
|
||||
})
|
||||
};
|
||||
|
|
|
|||
|
|
@ -61,6 +61,24 @@ export default class DhCompanion extends DhCreature {
|
|||
initial: false,
|
||||
label: 'DAGGERHEART.GENERAL.Rules.conditionImmunities.vulnerable'
|
||||
})
|
||||
}),
|
||||
roll: new fields.SchemaField({
|
||||
defaultAdvantageDice: new fields.NumberField({
|
||||
nullable: true,
|
||||
required: true,
|
||||
integer: true,
|
||||
choices: CONFIG.DH.GENERAL.dieFaces,
|
||||
initial: null,
|
||||
label: 'DAGGERHEART.ACTORS.Character.defaultAdvantageDice'
|
||||
}),
|
||||
defaultDisadvantageDice: new fields.NumberField({
|
||||
nullable: true,
|
||||
required: true,
|
||||
integer: true,
|
||||
choices: CONFIG.DH.GENERAL.dieFaces,
|
||||
initial: null,
|
||||
label: 'DAGGERHEART.ACTORS.Character.defaultDisadvantageDice'
|
||||
}),
|
||||
})
|
||||
}),
|
||||
attack: new ActionField({
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ export default class DhParty extends BaseDataActor {
|
|||
const fields = foundry.data.fields;
|
||||
return {
|
||||
...super.defineSchema(),
|
||||
active: new fields.BooleanField(),
|
||||
partyMembers: new ForeignDocumentUUIDArrayField({ type: 'Actor' }, { prune: true }),
|
||||
notes: new fields.HTMLField(),
|
||||
gold: new fields.SchemaField({
|
||||
|
|
@ -45,15 +44,6 @@ export default class DhParty extends BaseDataActor {
|
|||
}
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async _preCreate(data, options, user) {
|
||||
const allowed = await super._preCreate(data, options, user);
|
||||
if (allowed === false) return;
|
||||
|
||||
if (!game.actors.some(x => x.type === 'party' && x.active))
|
||||
await this.updateSource({ active: true });
|
||||
}
|
||||
|
||||
_onDelete(options, userId) {
|
||||
super._onDelete(options, userId);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { itemAbleRollParse } from '../../../helpers/utils.mjs';
|
||||
import FormulaField from '../formulaField.mjs';
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
|
@ -37,12 +36,13 @@ export default class DHSummonField extends fields.ArrayField {
|
|||
const rolls = [];
|
||||
const summonData = [];
|
||||
for (const summon of this.summon) {
|
||||
const roll = new Roll(itemAbleRollParse(summon.count, this.actor, this.item));
|
||||
let count = summon.count;
|
||||
const roll = new Roll(summon.count);
|
||||
if (!roll.isDeterministic) {
|
||||
await roll.evaluate();
|
||||
const count = roll.total;
|
||||
if (!roll.isDeterministic && game.modules.get('dice-so-nice')?.active)
|
||||
rolls.push(roll);
|
||||
|
||||
if (game.modules.get('dice-so-nice')?.active) rolls.push(roll);
|
||||
count = roll.total;
|
||||
}
|
||||
|
||||
const actor = await DHSummonField.getWorldActor(await foundry.utils.fromUuid(summon.actorUUID));
|
||||
/* Extending summon data in memory so it's available in actionField.toChat. Think it's harmless, but ugly. Could maybe find a better way. */
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import D20Roll from './d20Roll.mjs';
|
|||
import { parseRallyDice, setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs';
|
||||
|
||||
export default class DualityRoll extends D20Roll {
|
||||
_advantageFaces = 6;
|
||||
_advantageNumber = 1;
|
||||
_rallyIndex;
|
||||
|
||||
|
|
@ -11,6 +10,9 @@ export default class DualityRoll extends D20Roll {
|
|||
super(formula, data, options);
|
||||
this.rallyChoices = this.setRallyChoices();
|
||||
this.guaranteedCritical = options.guaranteedCritical;
|
||||
|
||||
const advantageFaces = data.rules?.roll?.defaultAdvantageDice ? Number.parseInt(data.rules.roll.defaultAdvantageDice) : 6
|
||||
this.advantageFaces = Number.isNaN(advantageFaces) ? 6 : advantageFaces;
|
||||
}
|
||||
|
||||
static messageType = 'dualityRoll';
|
||||
|
|
@ -51,14 +53,6 @@ export default class DualityRoll extends D20Roll {
|
|||
return this.dice[2] instanceof game.system.api.dice.diceTypes.DisadvantageDie ? this.dice[2] : null;
|
||||
}
|
||||
|
||||
get advantageFaces() {
|
||||
return this._advantageFaces;
|
||||
}
|
||||
|
||||
set advantageFaces(faces) {
|
||||
this._advantageFaces = this.getFaces(faces);
|
||||
}
|
||||
|
||||
get advantageNumber() {
|
||||
return this._advantageNumber;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -600,7 +600,6 @@ export default class DhpActor extends Actor {
|
|||
rollData.system = this.system.getRollData();
|
||||
rollData.prof = this.system.proficiency ?? 1;
|
||||
rollData.cast = this.system.spellcastModifier ?? 1;
|
||||
|
||||
return rollData;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -189,15 +189,7 @@ export const getDeleteKeys = (property, innerProperty, innerPropertyDefaultValue
|
|||
|
||||
// Fix on Foundry native formula replacement for DH
|
||||
const nativeReplaceFormulaData = Roll.replaceFormulaData;
|
||||
Roll.replaceFormulaData = function (formula, baseData = {}, { missing, warn = false } = {}) {
|
||||
/* Inserting global data */
|
||||
const data = {
|
||||
...baseData,
|
||||
partySize:
|
||||
!game.actors ? 0 :
|
||||
game.actors.find(x => x.type === 'party' && x.system.active)?.system.partyMembers.length ?? 0,
|
||||
};
|
||||
|
||||
Roll.replaceFormulaData = function (formula, data = {}, { missing, warn = false } = {}) {
|
||||
const terms = Object.keys(CONFIG.DH.GENERAL.multiplierTypes).map(type => {
|
||||
return { term: type, default: 1 };
|
||||
});
|
||||
|
|
|
|||
|
|
@ -174,9 +174,12 @@
|
|||
"src": "systems/daggerheart/assets/icons/documents/actors/dragon-head.svg",
|
||||
"anchorX": 0.5,
|
||||
"anchorY": 0.5,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"fit": "contain",
|
||||
"scaleX": 1,
|
||||
"scaleY": 1,
|
||||
"rotation": 0,
|
||||
"tint": "#ffffff",
|
||||
"alphaThreshold": 0.75
|
||||
},
|
||||
|
|
@ -227,7 +230,7 @@
|
|||
"saturation": 0,
|
||||
"contrast": 0
|
||||
},
|
||||
"detectionModes": {},
|
||||
"detectionModes": [],
|
||||
"occludable": {
|
||||
"radius": 0
|
||||
},
|
||||
|
|
@ -253,8 +256,7 @@
|
|||
"flags": {},
|
||||
"randomImg": false,
|
||||
"appendNumber": false,
|
||||
"prependAdjective": false,
|
||||
"depth": 1
|
||||
"prependAdjective": false
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
|
|
@ -494,42 +496,34 @@
|
|||
"description": "<p><strong>Spend a Fear</strong> to summon a number of @UUID[Compendium.daggerheart.adversaries.Actor.OsLG2BjaEdTZUJU9]{Fallen Shock Troops} equal to twice the number of PCs. The Shock Troops appear at Far range.</p>",
|
||||
"resource": null,
|
||||
"actions": {
|
||||
"SrU7qbh8LcOgfozT": {
|
||||
"type": "summon",
|
||||
"_id": "SrU7qbh8LcOgfozT",
|
||||
"hGMzqw00JTlYfHYy": {
|
||||
"type": "effect",
|
||||
"_id": "hGMzqw00JTlYfHYy",
|
||||
"systemPath": "actions",
|
||||
"baseAction": false,
|
||||
"description": "",
|
||||
"chatDisplay": true,
|
||||
"originItem": {
|
||||
"type": "itemCollection"
|
||||
},
|
||||
"actionType": "action",
|
||||
"triggers": [],
|
||||
"cost": [
|
||||
{
|
||||
"scalable": false,
|
||||
"key": "fear",
|
||||
"value": 1,
|
||||
"itemId": null,
|
||||
"step": null,
|
||||
"consumeOnSuccess": false
|
||||
"step": null
|
||||
}
|
||||
],
|
||||
"uses": {
|
||||
"value": null,
|
||||
"max": "",
|
||||
"recovery": null,
|
||||
"consumeOnSuccess": false
|
||||
"recovery": null
|
||||
},
|
||||
"effects": [],
|
||||
"target": {
|
||||
"type": "self",
|
||||
"amount": null
|
||||
},
|
||||
"summon": [
|
||||
{
|
||||
"actorUUID": "Compendium.daggerheart.adversaries.Actor.OsLG2BjaEdTZUJU9",
|
||||
"count": "@partySize*2"
|
||||
}
|
||||
],
|
||||
"name": "Spend Fear",
|
||||
"range": "far"
|
||||
"img": "icons/magic/death/undead-skeleton-worn-blue.webp",
|
||||
"range": ""
|
||||
}
|
||||
},
|
||||
"originItemType": null,
|
||||
|
|
|
|||
|
|
@ -52,9 +52,12 @@
|
|||
"src": "systems/daggerheart/assets/icons/documents/actors/forest.svg",
|
||||
"anchorX": 0.5,
|
||||
"anchorY": 0.5,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"fit": "contain",
|
||||
"scaleX": 1,
|
||||
"scaleY": 1,
|
||||
"rotation": 0,
|
||||
"tint": "#ffffff",
|
||||
"alphaThreshold": 0.75
|
||||
},
|
||||
|
|
@ -105,7 +108,7 @@
|
|||
"saturation": 0,
|
||||
"contrast": 0
|
||||
},
|
||||
"detectionModes": {},
|
||||
"detectionModes": [],
|
||||
"occludable": {
|
||||
"radius": 0
|
||||
},
|
||||
|
|
@ -131,8 +134,7 @@
|
|||
"flags": {},
|
||||
"randomImg": false,
|
||||
"appendNumber": false,
|
||||
"prependAdjective": false,
|
||||
"depth": 1
|
||||
"prependAdjective": false
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
|
|
@ -321,42 +323,7 @@
|
|||
"system": {
|
||||
"description": "<p>A @UUID[Compendium.daggerheart.adversaries.Actor.8yUj2Mzvnifhxegm]{Young Dryad}, two @UUID[Compendium.daggerheart.adversaries.Actor.VtFBt9XBE0WrGGxP]{Sylvan Soldiers}, and a number of @UUID[Compendium.daggerheart.adversaries.Actor.G62k4oSkhkoXEs2D]{Minor Treants} equal to the number of PCs appear to confront the party for their intrusion.</p><section id=\"secret-01hkXuVJc5Kei4QW\" class=\"secret\"><p><em>What are the grove guardians concealing? What threat to the forest could the PCs confront to appease the Dryad?</em></p></section>",
|
||||
"resource": null,
|
||||
"actions": {
|
||||
"TPm6rpKA4mbili82": {
|
||||
"type": "summon",
|
||||
"_id": "TPm6rpKA4mbili82",
|
||||
"systemPath": "actions",
|
||||
"baseAction": false,
|
||||
"description": "",
|
||||
"chatDisplay": true,
|
||||
"originItem": {
|
||||
"type": "itemCollection"
|
||||
},
|
||||
"actionType": "action",
|
||||
"triggers": [],
|
||||
"cost": [],
|
||||
"uses": {
|
||||
"value": null,
|
||||
"max": null,
|
||||
"recovery": null,
|
||||
"consumeOnSuccess": false
|
||||
},
|
||||
"summon": [
|
||||
{
|
||||
"actorUUID": "Compendium.daggerheart.adversaries.Actor.8yUj2Mzvnifhxegm",
|
||||
"count": "1"
|
||||
},
|
||||
{
|
||||
"actorUUID": "Compendium.daggerheart.adversaries.Actor.VtFBt9XBE0WrGGxP",
|
||||
"count": "2"
|
||||
},
|
||||
{
|
||||
"actorUUID": "Compendium.daggerheart.adversaries.Actor.G62k4oSkhkoXEs2D",
|
||||
"count": "@partySize"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"actions": {},
|
||||
"originItemType": null,
|
||||
"originId": null,
|
||||
"featureForm": "action"
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@
|
|||
{{/times}}
|
||||
</select>
|
||||
<select name="roll.dice.advantageFaces"{{#unless advantage}} disabled{{/unless}}>
|
||||
{{selectOptions diceOptions selected=(concat 'd' @root.roll.advantageFaces)}}
|
||||
{{selectOptions diceFaces selected=@root.roll.advantageFaces}}
|
||||
</select>
|
||||
</div>
|
||||
{{#if abilities}}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,6 @@
|
|||
{{else}}
|
||||
<span class="entry-subtitle">{{localize "DAGGERHEART.UI.Sidebar.actorDirectory.companionNoPartner"}}</span>
|
||||
{{/if}}
|
||||
{{else if (eq type "party")}}
|
||||
{{#if system.active}}
|
||||
<span class="entry-subtitle">{{localize "DAGGERHEART.UI.Sidebar.actorDirectory.partyIsActive"}}</span>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue