mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
[Feature] Armor/Weapon Compendiums (#459)
* Fixed localization * . * Added all Secondary Weapons * Added all armors * Added Tier1 weapons * Tier2 Physical * Tier 2 magical * Tier 3 Physical * Tier 3 Magical * Tier 4 Physical * Tier 4 Magical * Added wheelchairs
This commit is contained in:
parent
8e516df7cb
commit
2c4d3bd4a3
277 changed files with 34221 additions and 431 deletions
|
|
@ -133,7 +133,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
|
|||
const resource = this.action.parent.resource;
|
||||
if (resource) {
|
||||
options[this.action.parent.parent.id] = {
|
||||
label: "DAGGERHEART.GENERAL.itemResource",
|
||||
label: 'DAGGERHEART.GENERAL.itemResource',
|
||||
group: 'Global'
|
||||
};
|
||||
}
|
||||
|
|
@ -143,10 +143,10 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
|
|||
|
||||
getRollTypeOptions() {
|
||||
const types = foundry.utils.deepClone(CONFIG.DH.GENERAL.rollTypes);
|
||||
if(!this.action.actor) return types;
|
||||
if (!this.action.actor) return types;
|
||||
Object.values(types).forEach(t => {
|
||||
if(this.action.actor.type !== 'character' && t.playerOnly) delete types[t.id];
|
||||
})
|
||||
if (this.action.actor.type !== 'character' && t.playerOnly) delete types[t.id];
|
||||
});
|
||||
return types;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { emitAsGM, GMUpdateEvent } from "../../systemRegistration/socket.mjs";
|
||||
import { emitAsGM, GMUpdateEvent } from '../../systemRegistration/socket.mjs';
|
||||
|
||||
export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLog {
|
||||
constructor(options) {
|
||||
|
|
@ -100,22 +100,24 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
if (message.system.source.item && message.system.source.action) {
|
||||
const action = this.getAction(actor, message.system.source.item, message.system.source.action);
|
||||
if (!action || !action?.hasSave) return;
|
||||
action.rollSave(token.actor, event, message).then(result => emitAsGM(
|
||||
GMUpdateEvent.UpdateSaveMessage,
|
||||
action.updateSaveMessage.bind(action, result, message, token.id),
|
||||
{
|
||||
action: action.uuid,
|
||||
message: message._id,
|
||||
token: token.id,
|
||||
result
|
||||
}
|
||||
));
|
||||
action.rollSave(token.actor, event, message).then(result =>
|
||||
emitAsGM(
|
||||
GMUpdateEvent.UpdateSaveMessage,
|
||||
action.updateSaveMessage.bind(action, result, message, token.id),
|
||||
{
|
||||
action: action.uuid,
|
||||
message: message._id,
|
||||
token: token.id,
|
||||
result
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async onRollAllSave(event, message) {
|
||||
event.stopPropagation();
|
||||
if(!game.user.isGM) return;
|
||||
if (!game.user.isGM) return;
|
||||
const targets = event.target.parentElement.querySelectorAll(
|
||||
'.target-section > [data-token] .target-save-container'
|
||||
);
|
||||
|
|
@ -124,16 +126,17 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
targets.forEach(async el => {
|
||||
const tokenId = el.closest('[data-token]')?.dataset.token,
|
||||
token = game.canvas.tokens.get(tokenId);
|
||||
if(!token.actor) return;
|
||||
if(game.user === token.actor.owner)
|
||||
el.dispatchEvent(new PointerEvent('click', { shiftKey: true }));
|
||||
if (!token.actor) return;
|
||||
if (game.user === token.actor.owner) el.dispatchEvent(new PointerEvent('click', { shiftKey: true }));
|
||||
else {
|
||||
token.actor.owner.query('reactionRoll', {
|
||||
actionId: action.uuid,
|
||||
actorId: token.actor.uuid,
|
||||
event,
|
||||
message
|
||||
}).then(result => action.updateSaveMessage(result, message, token.id));
|
||||
token.actor.owner
|
||||
.query('reactionRoll', {
|
||||
actionId: action.uuid,
|
||||
actorId: token.actor.uuid,
|
||||
event,
|
||||
message
|
||||
})
|
||||
.then(result => action.updateSaveMessage(result, message, token.id));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -172,7 +175,9 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
return {
|
||||
isHit,
|
||||
targets: isHit
|
||||
? message.system.targets.filter(t => t.hit === true).map(target => game.canvas.tokens.documentCollection.find(t => t.actor.uuid === target.actorId))
|
||||
? message.system.targets
|
||||
.filter(t => t.hit === true)
|
||||
.map(target => game.canvas.tokens.documentCollection.find(t => t.actor.uuid === target.actorId))
|
||||
: Array.from(game.user.targets)
|
||||
};
|
||||
}
|
||||
|
|
@ -234,10 +239,8 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
});
|
||||
}
|
||||
|
||||
if(message.system.hasHealing)
|
||||
target.actor.takeHealing(damages);
|
||||
else
|
||||
target.actor.takeDamage(damages);
|
||||
if (message.system.hasHealing) target.actor.takeHealing(damages);
|
||||
else target.actor.takeDamage(damages);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -203,7 +203,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
|
||||
async consume(config) {
|
||||
const usefulResources = foundry.utils.deepClone(this.actor.system.resources);
|
||||
|
||||
|
||||
for (var cost of config.costs) {
|
||||
if (cost.keyIsID) {
|
||||
usefulResources[cost.key] = {
|
||||
|
|
@ -224,10 +224,9 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
keyIsID: resource.keyIsID
|
||||
};
|
||||
});
|
||||
console.log(resources)
|
||||
console.log(resources);
|
||||
await this.actor.modifyResource(resources);
|
||||
if (config.uses?.enabled)
|
||||
this.update({ 'uses.value': this.uses.value + 1 });
|
||||
if (config.uses?.enabled) this.update({ 'uses.value': this.uses.value + 1 });
|
||||
}
|
||||
/* */
|
||||
|
||||
|
|
|
|||
|
|
@ -26,19 +26,20 @@ export default class CostField extends fields.ArrayField {
|
|||
}
|
||||
|
||||
static calcCosts(costs) {
|
||||
console.log(costs, CostField.getResources.call(this, costs))
|
||||
console.log(costs, CostField.getResources.call(this, costs));
|
||||
const resources = CostField.getResources.call(this, costs);
|
||||
return costs.map(c => {
|
||||
c.scale = c.scale ?? 1;
|
||||
c.step = c.step ?? 1;
|
||||
c.total = c.value + ((c.scale - 1) * c.step);
|
||||
c.total = c.value + (c.scale - 1) * c.step;
|
||||
c.enabled = c.hasOwnProperty('enabled') ? c.enabled : true;
|
||||
c.max = c.key === 'fear'
|
||||
? game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear)
|
||||
: resources[c.key].isReversed
|
||||
? resources[c.key].max
|
||||
: resources[c.key].value
|
||||
if(c.scalable) c.maxStep = Math.floor(c.max / c.step);
|
||||
c.max =
|
||||
c.key === 'fear'
|
||||
? game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear)
|
||||
: resources[c.key].isReversed
|
||||
? resources[c.key].max
|
||||
: resources[c.key].value;
|
||||
if (c.scalable) c.maxStep = Math.floor(c.max / c.step);
|
||||
return c;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,34 +69,34 @@ export class DHActionRollData extends foundry.abstract.DataModel {
|
|||
|
||||
getModifier() {
|
||||
const modifiers = [];
|
||||
if(!this.parent?.actor) return modifiers;
|
||||
if (!this.parent?.actor) return modifiers;
|
||||
switch (this.parent.actor.type) {
|
||||
case 'character':
|
||||
const trait = this.useDefault || !this.trait ? (this.parent.item.system.attack.roll.trait ?? 'agility') : this.trait;
|
||||
if(this.type === CONFIG.DH.GENERAL.rollTypes.attack.id || this.type === CONFIG.DH.GENERAL.rollTypes.trait.id)
|
||||
modifiers.push(
|
||||
{
|
||||
label: `DAGGERHEART.CONFIG.Traits.${trait}.name`,
|
||||
value: this.parent.actor.system.traits[trait].value
|
||||
}
|
||||
)
|
||||
else if(this.type === CONFIG.DH.GENERAL.rollTypes.spellcast.id)
|
||||
modifiers.push(
|
||||
{
|
||||
label: `DAGGERHEART.CONFIG.RollTypes.spellcast.name`,
|
||||
value: this.parent.actor.system.spellcastModifier
|
||||
}
|
||||
)
|
||||
const trait =
|
||||
this.useDefault || !this.trait
|
||||
? (this.parent.item.system.attack.roll.trait ?? 'agility')
|
||||
: this.trait;
|
||||
if (
|
||||
this.type === CONFIG.DH.GENERAL.rollTypes.attack.id ||
|
||||
this.type === CONFIG.DH.GENERAL.rollTypes.trait.id
|
||||
)
|
||||
modifiers.push({
|
||||
label: `DAGGERHEART.CONFIG.Traits.${trait}.name`,
|
||||
value: this.parent.actor.system.traits[trait].value
|
||||
});
|
||||
else if (this.type === CONFIG.DH.GENERAL.rollTypes.spellcast.id)
|
||||
modifiers.push({
|
||||
label: `DAGGERHEART.CONFIG.RollTypes.spellcast.name`,
|
||||
value: this.parent.actor.system.spellcastModifier
|
||||
});
|
||||
break;
|
||||
case 'companion':
|
||||
case 'adversary':
|
||||
if(this.type === CONFIG.DH.GENERAL.rollTypes.attack.id)
|
||||
modifiers.push(
|
||||
{
|
||||
label: 'Bonus to Hit',
|
||||
value: this.bonus ?? this.parent.actor.system.attack.roll.bonus
|
||||
}
|
||||
)
|
||||
if (this.type === CONFIG.DH.GENERAL.rollTypes.attack.id)
|
||||
modifiers.push({
|
||||
label: 'Bonus to Hit',
|
||||
value: this.bonus ?? this.parent.actor.system.attack.roll.bonus
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import FormulaField from "../formulaField.mjs";
|
||||
import FormulaField from '../formulaField.mjs';
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ export default class UsesField extends fields.SchemaField {
|
|||
static hasUses(uses) {
|
||||
if (!uses) return true;
|
||||
let max = uses.max ?? 0;
|
||||
if(isNaN(max)) {
|
||||
if (isNaN(max)) {
|
||||
const roll = new Roll(Roll.replaceFormulaData(uses.max, this.getRollData())).evaluateSync();
|
||||
max = roll.total;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,13 +71,14 @@ export default class DHArmor extends AttachableItem {
|
|||
for (var feature of added) {
|
||||
const featureData = armorFeatures[feature.value];
|
||||
if (featureData.effects?.length > 0) {
|
||||
const embeddedItems = await this.parent.createEmbeddedDocuments('ActiveEffect', [
|
||||
{
|
||||
name: game.i18n.localize(featureData.label),
|
||||
description: game.i18n.localize(featureData.description),
|
||||
changes: featureData.effects.flatMap(x => x.changes)
|
||||
}
|
||||
]);
|
||||
const embeddedItems = await this.parent.createEmbeddedDocuments(
|
||||
'ActiveEffect',
|
||||
featureData.effects.map(effect => ({
|
||||
...effect,
|
||||
name: game.i18n.localize(effect.name),
|
||||
description: game.i18n.localize(effect.description)
|
||||
}))
|
||||
);
|
||||
feature.effectIds = embeddedItems.map(x => x.id);
|
||||
}
|
||||
|
||||
|
|
@ -93,6 +94,7 @@ export default class DHArmor extends AttachableItem {
|
|||
description: game.i18n.localize(effect.description)
|
||||
}))
|
||||
);
|
||||
feature.effectIds = [...(feature.effectIds ?? []), ...embeddedEffects.map(x => x.id)];
|
||||
|
||||
const cls = game.system.api.models.actions.actionsTypes[action.type];
|
||||
const actionId = foundry.utils.randomID();
|
||||
|
|
|
|||
|
|
@ -118,13 +118,14 @@ export default class DHWeapon extends AttachableItem {
|
|||
for (let weaponFeature of added) {
|
||||
const featureData = CONFIG.DH.ITEM.weaponFeatures[weaponFeature.value];
|
||||
if (featureData.effects?.length > 0) {
|
||||
const embeddedItems = await this.parent.createEmbeddedDocuments('ActiveEffect', [
|
||||
{
|
||||
name: game.i18n.localize(featureData.label),
|
||||
description: game.i18n.localize(featureData.description),
|
||||
changes: featureData.effects.flatMap(x => x.changes)
|
||||
}
|
||||
]);
|
||||
const embeddedItems = await this.parent.createEmbeddedDocuments(
|
||||
'ActiveEffect',
|
||||
featureData.effects.map(effect => ({
|
||||
...effect,
|
||||
name: game.i18n.localize(effect.name),
|
||||
description: game.i18n.localize(effect.description)
|
||||
}))
|
||||
);
|
||||
weaponFeature.effectIds = embeddedItems.map(x => x.id);
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +141,10 @@ export default class DHWeapon extends AttachableItem {
|
|||
description: game.i18n.localize(effect.description)
|
||||
}))
|
||||
);
|
||||
weaponFeature.effectIds = [
|
||||
...(weaponFeature.effectIds ?? []),
|
||||
...embeddedEffects.map(x => x.id)
|
||||
];
|
||||
|
||||
const cls = game.system.api.models.actions.actionsTypes[action.type];
|
||||
const actionId = foundry.utils.randomID();
|
||||
|
|
|
|||
|
|
@ -85,9 +85,9 @@ export default class DamageRoll extends DHRoll {
|
|||
const modifiers = [],
|
||||
type = this.options.messageType ?? (this.options.isHealing ? 'healing' : 'damage'),
|
||||
options = part ?? this.options;
|
||||
|
||||
|
||||
modifiers.push(...this.getBonus(`${type}`, `${type.capitalize()} Bonus`));
|
||||
if(!this.options.isHealing) {
|
||||
if (!this.options.isHealing) {
|
||||
options.damageTypes?.forEach(t => {
|
||||
modifiers.push(...this.getBonus(`${type}.${t}`, `${t.capitalize()} ${type.capitalize()} Bonus`));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -194,11 +194,12 @@ export const registerRollDiceHooks = () => {
|
|||
if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1 });
|
||||
|
||||
if (config.rerolledRoll) {
|
||||
if (config.rerolledRoll.isCritical || config.rerolledRoll.result.duality === 1) updates.push({ key: 'hope', value: -1 });
|
||||
if (config.rerolledRoll.isCritical || config.rerolledRoll.result.duality === 1)
|
||||
updates.push({ key: 'hope', value: -1 });
|
||||
if (config.rerolledRoll.isCritical) updates.push({ key: 'stress', value: 1 });
|
||||
if (config.rerolledRoll.result.duality === -1) updates.push({ key: 'fear', value: -1 });
|
||||
}
|
||||
|
||||
|
||||
if (updates.length) {
|
||||
const target = actor.system.partner ?? actor;
|
||||
if (!['dead', 'unconcious'].some(x => actor.statuses.has(x))) {
|
||||
|
|
|
|||
|
|
@ -481,7 +481,9 @@ export default class DhpActor extends Actor {
|
|||
this.system.armor &&
|
||||
this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes)
|
||||
) {
|
||||
const armorSlotResult = await this.owner.query('armorSlot', {
|
||||
const armorSlotResult = await this.owner.query(
|
||||
'armorSlot',
|
||||
{
|
||||
actorId: this.uuid,
|
||||
damage: hpDamage.value,
|
||||
type: [...hpDamage.damageTypes]
|
||||
|
|
@ -569,7 +571,7 @@ export default class DhpActor extends Actor {
|
|||
armor: { target: this.system.armor, resources: {} },
|
||||
items: {}
|
||||
};
|
||||
|
||||
|
||||
resources.forEach(r => {
|
||||
if (r.keyIsID) {
|
||||
updates.items[r.key] = {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ export default class DHToken extends TokenDocument {
|
|||
for (const [name, field] of Object.entries(schema.fields)) {
|
||||
const p = _path.concat([name]);
|
||||
if (field instanceof foundry.data.fields.NumberField) attributes.value.push(p);
|
||||
if (field instanceof foundry.data.fields.BooleanField && field.options.isAttributeChoice) attributes.value.push(p);
|
||||
if (field instanceof foundry.data.fields.BooleanField && field.options.isAttributeChoice)
|
||||
attributes.value.push(p);
|
||||
if (field instanceof foundry.data.fields.StringField) attributes.value.push(p);
|
||||
if (field instanceof foundry.data.fields.ArrayField) attributes.value.push(p);
|
||||
const isSchema = field instanceof foundry.data.fields.SchemaField;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export default class RegisterHandlebarsHelpers {
|
|||
}
|
||||
|
||||
static formulaValue(formula, item) {
|
||||
if(isNaN(formula)) {
|
||||
if (isNaN(formula)) {
|
||||
const data = item.getRollData.bind(item)(),
|
||||
roll = new Roll(Roll.replaceFormulaData(formula, data)).evaluateSync();
|
||||
formula = roll.total;
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ export function updateLinkedItemApps(options, sheet) {
|
|||
export const itemAbleRollParse = (value, actor, item) => {
|
||||
if (!value) return value;
|
||||
|
||||
const isItemTarget = value.toLowerCase().startsWith('item.');
|
||||
const isItemTarget = value.toLowerCase().replace('item.@', '@');
|
||||
const slicedValue = isItemTarget ? value.slice(5) : value;
|
||||
try {
|
||||
return Roll.replaceFormulaData(slicedValue, isItemTarget ? item : actor);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ export const registerSocketHooks = () => {
|
|||
case GMUpdateEvent.UpdateSaveMessage:
|
||||
const action = await fromUuid(data.update.action),
|
||||
message = game.messages.get(data.update.message);
|
||||
if(!action || !message) return;
|
||||
if (!action || !message) return;
|
||||
action.updateSaveMessage(data.update.result, message, data.update.token);
|
||||
break;
|
||||
}
|
||||
|
|
@ -79,7 +79,7 @@ export const registerSocketHooks = () => {
|
|||
export const registerUserQueries = () => {
|
||||
CONFIG.queries.armorSlot = DamageReductionDialog.armorSlotQuery;
|
||||
CONFIG.queries.reactionRoll = game.system.api.models.actions.actionsTypes.base.rollSaveQuery;
|
||||
}
|
||||
};
|
||||
|
||||
export const emitAsGM = async (eventName, callback, update, uuid = null) => {
|
||||
if (!game.user.isGM) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue