daggerheart/module/data/actor/adversary.mjs
WBHarry 261a3a68b0
[PR] [Feature] Party Sheet (#1230)
* start development

* finish party members tab

* start resources tab

* finish resources tab

* finish inventory tab and add inital template to projects tab

* add resource buttons actions methods

* add group roll dialog

* Main implementation

* Fixed costs

* Minor fixes and tweaks for the party sheet (#1239)

* Minor fixes and tweaks for the party sheet

* Fix scroll restoration for party sheet tabs

* Finished GroupRoll

* Removed/commented-out not yet implemented things

* Commented out Difficulty since it's not used yet

* Re-render party when members update (#1242)

* Fixed so style applies in preview chat message

* Added the clown car

* Fixed so items can be dropped into the Party sheet

* Added delete icon to inventory

* Fixed TokenHUD token property useage. Fixed skipping roll message

* Added visible modifier to GroupRoll leader result

* Leader roll displays the large result display right away after rolling

* Corrected tokenHUD for non-player-tokens

* Fixed clowncar tokenData

* Fixed TagTeam roll message and sound

* Removed final TagTeamRoll roll sound

* [PR] [Party Sheets] Sidebar character sheet changes (#1249)

* Something experimenting

* I am silly (wearning Dunce hat)

* Stressful task

* Armor functional to be hit

* CSS Changes to accomadate pip boy

* last minute change to resource section for better visual feeling

* restoring old css for toggle

* Added setting to toggle pip/number display

* toggle functionality added

* Fixed light-mode in characterSheet

* Fixed multi-row resource pips display for character

* Fixed separators

* Added pip-display to Adversary and Companion. Some fixing on armor display

---------

Co-authored-by: WBHarry <williambjrklund@gmail.com>

* Fixed party height and resource armor update

* Fixed deletebutton padding

* Only showing expand-me icon on InventoryItem if there is a description to show

* .

* Fixed menu icon to be beige instead of white in dark mode

---------

Co-authored-by: moliloo <dev.murilobrito@gmail.com>
Co-authored-by: Carlos Fernandez <CarlosFdez@users.noreply.github.com>
Co-authored-by: Nikhil Nagarajan <potter.nikhil@gmail.com>
2025-11-11 16:02:45 +01:00

182 lines
7.3 KiB
JavaScript

import DHAdversarySettings from '../../applications/sheets-configs/adversary-settings.mjs';
import { ActionField } from '../fields/actionField.mjs';
import BaseDataActor from './base.mjs';
import { resourceField, bonusField } from '../fields/actorField.mjs';
export default class DhpAdversary extends BaseDataActor {
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Adversary'];
static get metadata() {
return foundry.utils.mergeObject(super.metadata, {
label: 'TYPES.Actor.adversary',
type: 'adversary',
settingSheet: DHAdversarySettings,
hasAttribution: true
});
}
static defineSchema() {
const fields = foundry.data.fields;
return {
...super.defineSchema(),
tier: new fields.NumberField({
required: true,
integer: true,
choices: CONFIG.DH.GENERAL.tiers,
initial: CONFIG.DH.GENERAL.tiers[1].id
}),
type: new fields.StringField({
required: true,
choices: CONFIG.DH.ACTOR.allAdversaryTypes,
initial: CONFIG.DH.ACTOR.adversaryTypes.standard.id
}),
motivesAndTactics: new fields.StringField(),
notes: new fields.HTMLField(),
difficulty: new fields.NumberField({ required: true, initial: 1, integer: true }),
hordeHp: new fields.NumberField({
required: true,
initial: 1,
integer: true,
label: 'DAGGERHEART.GENERAL.hordeHp'
}),
damageThresholds: new fields.SchemaField({
major: new fields.NumberField({
required: true,
initial: 0,
integer: true,
label: 'DAGGERHEART.GENERAL.DamageThresholds.majorThreshold'
}),
severe: new fields.NumberField({
required: true,
initial: 0,
integer: true,
label: 'DAGGERHEART.GENERAL.DamageThresholds.severeThreshold'
})
}),
resources: new fields.SchemaField({
hitPoints: resourceField(0, 0, 'DAGGERHEART.GENERAL.HitPoints.plural', true),
stress: resourceField(0, 0, 'DAGGERHEART.GENERAL.stress', true)
}),
attack: new ActionField({
initial: {
name: 'Attack',
img: 'icons/skills/melee/blood-slash-foam-red.webp',
_id: foundry.utils.randomID(),
systemPath: 'attack',
chatDisplay: false,
type: 'attack',
range: 'melee',
target: {
type: 'any',
amount: 1
},
roll: {
type: 'attack'
},
damage: {
parts: [
{
type: ['physical'],
value: {
multiplier: 'flat'
}
}
]
}
}
}),
experiences: new fields.TypedObjectField(
new fields.SchemaField({
name: new fields.StringField(),
value: new fields.NumberField({ required: true, integer: true, initial: 1 }),
description: new fields.StringField()
})
),
bonuses: new fields.SchemaField({
roll: new fields.SchemaField({
attack: bonusField('DAGGERHEART.GENERAL.Roll.attack'),
action: bonusField('DAGGERHEART.GENERAL.Roll.action'),
reaction: bonusField('DAGGERHEART.GENERAL.Roll.reaction')
}),
damage: new fields.SchemaField({
physical: bonusField('DAGGERHEART.GENERAL.Damage.physicalDamage'),
magical: bonusField('DAGGERHEART.GENERAL.Damage.magicalDamage')
})
})
};
}
/* -------------------------------------------- */
/**@inheritdoc */
static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/actors/dragon-head.svg';
/* -------------------------------------------- */
get attackBonus() {
return this.attack.roll.bonus;
}
get features() {
return this.parent.items.filter(x => x.type === 'feature');
}
async _preUpdate(changes, options, user) {
const allowed = await super._preUpdate(changes, options, user);
if (allowed === false) return false;
if (this.type === CONFIG.DH.ACTOR.adversaryTypes.horde.id) {
const autoHordeDamage = game.settings.get(
CONFIG.DH.id,
CONFIG.DH.SETTINGS.gameSettings.Automation
).hordeDamage;
if (autoHordeDamage && changes.system?.resources?.hitPoints?.value !== undefined) {
const hordeActiveEffect = this.parent.effects.find(x => x.type === 'horde');
if (hordeActiveEffect) {
const halfHP = Math.ceil(this.resources.hitPoints.max / 2);
const newHitPoints = changes.system.resources.hitPoints.value;
const previouslyAboveHalf = this.resources.hitPoints.value < halfHP;
const loweredBelowHalf = previouslyAboveHalf && newHitPoints >= halfHP;
const raisedAboveHalf = !previouslyAboveHalf && newHitPoints < halfHP;
if (loweredBelowHalf) {
await hordeActiveEffect.update({ disabled: false });
} else if (raisedAboveHalf) {
await hordeActiveEffect.update({ disabled: true });
}
}
}
}
}
_onUpdate(changes, options, userId) {
super._onUpdate(changes, options, userId);
if (game.user.id === userId) {
if (changes.system?.type) {
const existingHordeEffect = this.parent.effects.find(x => x.type === 'horde');
if (changes.system.type === CONFIG.DH.ACTOR.adversaryTypes.horde.id) {
if (!existingHordeEffect)
this.parent.createEmbeddedDocuments('ActiveEffect', [
{
type: 'horde',
name: game.i18n.localize('DAGGERHEART.CONFIG.AdversaryType.horde.label'),
img: 'icons/magic/movement/chevrons-down-yellow.webp',
disabled: true
}
]);
} else {
existingHordeEffect?.delete();
}
}
}
}
_getTags() {
const tags = [
game.i18n.localize(`DAGGERHEART.GENERAL.Tiers.${this.tier}`),
`${game.i18n.localize(`DAGGERHEART.CONFIG.AdversaryType.${this.type}.label`)}`,
`${game.i18n.localize('DAGGERHEART.GENERAL.difficulty')}: ${this.difficulty}`
];
return tags;
}
}