mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-11 11:15:21 +01:00
Hotfix 1.0.2 (#916)
* Updated the background image for the system * Fixed so Weapon/Armor features are added again * Fixed so fear is available as a resource to be deducted by actions (#757) * Changed to use the config labels and src * Updated Weapons * Fixed so the decrease button of simple fear tracker is not visible when not hovered * Fixed so armor preUpdate doesn't fail if no system changes are made * Updated .gitignore and author details (#777) * Add author details and name mapping for chrisryan10 (#773) Co-authored-by: Chris Ryan <chrisr@blackhole> * Add build to ignore for my linux dev (#775) Co-authored-by: Chris Ryan <chrisr@blackhole> --------- Co-authored-by: Chris Ryan <chrisr@blackhole> * Corrected sneak attack active effect (#780) * Fixed a spelling error (#779) * Fix bardic rally showing in damage dialog when it should not (#783) * update spelling (#786) * Translating inventory descriptions (#782) * updated credits for 1.0.1 release (#797) * updated credits for 1.0.1 release * further updated artwork credits * Chagned handlebarhelper rollparsed to be more defensive (#794) * Added missing scene refreshType (#790) * Remove ability use buttons for not owned abilities (#795) * [Fix] PrayerDice Fixed (#799) * Fixed prayer dice, and wheelchair images * Fixed -settings data sources * Dragging features from one adversary to another (#788) * [Fix] Levelup Fixes (#787) * Fixed crash on experience selection. Fixed subclass error on multiclassing * Fixed so multiclasses do not gain the hope feature for the class * Fixed so Class/Subclass features are properly deleted on delevel * Removed automatic deletion of features on delevel when not using levelup auto * Fixed so custom domains can be selected in levelup when multiclassing * Changed so encounter countdowns is a button (#804) * Fixed so that dropping on class/subclass...creates the item on the character (#803) * [BUG] - Importing All Adversaries/Environments (#814) Fixes #774 Co-authored-by: Joaquin Pereyra <joaquinpereyra98@users.noreply.github.com> * Bug/671 reaction roll chat title (#809) * Update Reaction Roll Chat Message Title * Removed console log --------- Co-authored-by: WBHarry <williambjrklund@gmail.com> * Improve Trait tooltip display (#817) Fixes #806 Co-authored-by: Joaquin Pereyra <joaquinpereyra98@users.noreply.github.com> * [BUG] - Combat Tracker d12 logo not found (#812) Fixes #764 Co-authored-by: Joaquin Pereyra <joaquinpereyra98@users.noreply.github.com> * Compendium Browser (#821) * Corrected timbending description localization (#816) * [Fix] Compendium Item (#810) * Corrected Emberwoven Armor * Fixed subclass regression * Fixed so character's with wildcard images don't break beastform (#815) * Fix roll result based duality damage (#822) * Impproved Adversary Sheet Data Display (#751) * Impproved Adversary Sheet Data Display Fixes #604 * FIX: formula lables for attacks and weapons --------- Co-authored-by: Joaquin Pereyra <joaquinpereyra98@users.noreply.github.com> * Fixed so exp increases can be selected normally (#835) * Update localization of rollSelection.hbs (#841) The Fear label lacked a localization path * renamed .md files (#834) * Removed the unintended icons that came from merge conflicts (#838) * Sheet image position (#861) * Remove extra result text from reaction chat message (#860) * Remove extra result text from reaction chat message * Remove log * [Fix] 850 - Downtime Refreshes (#859) * Fixed the filtering of refreshable features * Raised version * [Fix] 691 - CharacterCreation Improvement (#863) * Removed main creation tab. Added equipment to remaining tab * Fixed MixedAncestry name setting * Fixed tab after first creation * Fix/857 generic roll buttons (#866) * Action Macro working again * Remove buttons from generic roll for non-gm * Update sidebar.less Armor Slots label padding, for translations (#872) Equalizes the vertical and horizontal padding on the Armor Slots status label, to allow for more (much needed) room for the upcoming French translation (and others in the future). Doesn't change anything for the display in English. * Hid item attachments for now (#876) * Fixed so effects supposed to use item data use the model directly, since items have no rolldata (#883) * Made sure the beastform user isn't moved onto other duplicate actors. Fixed scrolling text duplication (#882) * Change the critical damage max calculation (#890) * Change the critical damage max calculation to avoid setting the rolled portion to maximum all the time. * Change to the more neater code * Restored package.json --------- Co-authored-by: Chris Ryan <chrisr@blackhole> Co-authored-by: WBHarry <williambjrklund@gmail.com> * Fix movement (#885) * Changed so companion can level up on its own (#879) * Fix the missing ancestries in the SRD (#888) Co-authored-by: Chris Ryan <chrisr@blackhole> * Removed the old, now unused companion levelup button (#893) * Fixed so custom downtime moves will display their descriptions in the tooltip (#894) * Made coinflip icons in chat round (#895) * Fixed undefined case (#898) * Fix/877 hope update order (#896) * Action Macro working again * k * Fix Hope gain on Duality Roll * [Feature] Descriptions enhancements (#887) * add style to hover items and add start setting to features be expanded by default * REFACTOR: now prepare description onRender and simply the other methods * add setting to extend description from items and add molilo contacts in system.json --------- Co-authored-by: Joaquin Pereyra <joaquinpereyra98@users.noreply.github.com> * Fixed traits container styling in light-mode (#899) * [BUG] - Movement Button selector not showing current mode (#912) Fixes #910 Co-authored-by: Joaquin Pereyra <joaquinpereyra98@users.noreply.github.com> * Fix/864 chat targeting (#911) * Fix targeting * Fix chat target selection * Uncomment chatDisplay * Removed unessecary arg * [Feature] 648 - Mark Defeated Actors (#914) * Improved death marking styling * Added automation for defeated status * Fixed so the tracker recognises and sets the correct defeated statuses depending on type * Fixed so missing statuses doesn't cause crashes * Increased companion sheet width by 40 pixels * Added missing inheritDoc * Removed fas * FIX: use img instead of icons con statusEffectConfigns (#917) Authored-by: Joaquin Pereyra <joaquinpereyra98@users.noreply.github.com> --------- Co-authored-by: Chris Ryan <73275196+chrisryan10@users.noreply.github.com> Co-authored-by: Chris Ryan <chrisr@blackhole> Co-authored-by: Dapoulp <74197441+Dapoulp@users.noreply.github.com> Co-authored-by: IrkTheImp <41175833+IrkTheImp@users.noreply.github.com> Co-authored-by: CPTN_Cosmo <cptncosmo@gmail.com> Co-authored-by: Josh Q. <jshqntnr13@gmail.com> Co-authored-by: joaquinpereyra98 <24190917+joaquinpereyra98@users.noreply.github.com> Co-authored-by: Joaquin Pereyra <joaquinpereyra98@users.noreply.github.com> Co-authored-by: SunnySunSun <snysun@pm.me> Co-authored-by: Murilo Brito <91566541+moliloo@users.noreply.github.com>
This commit is contained in:
parent
67d3b6c0e3
commit
5e56c7ec2e
208 changed files with 1450 additions and 895 deletions
39
lang/en.json
39
lang/en.json
|
|
@ -189,7 +189,11 @@
|
|||
"title": "Multiclass Subclass",
|
||||
"text": "Do you want to add this subclass as your multiclass subclass?"
|
||||
},
|
||||
"cannotRemoveCoreExperience": "You are using Levelup Auto. You cannot remove an experience given to you by the rule progression."
|
||||
"cannotRemoveCoreExperience": "You are using Levelup Auto. You cannot remove an experience given to you by the rule progression.",
|
||||
"companionLevelup": {
|
||||
"confirmTitle": "Companion Levelup",
|
||||
"confirmText": "Would you like to level up your companion {name} by {levelChange} levels at this time? (You can do it manually later)"
|
||||
}
|
||||
},
|
||||
"Companion": {
|
||||
"FIELDS": {
|
||||
|
|
@ -233,13 +237,14 @@
|
|||
},
|
||||
"APPLICATIONS": {
|
||||
"CharacterCreation": {
|
||||
"setupTabs": {
|
||||
"tabs": {
|
||||
"ancestry": "Ancestry",
|
||||
"community": "Community",
|
||||
"class": "Class",
|
||||
"experience": "Experience",
|
||||
"traits": "Traits",
|
||||
"domainCards": "Domain Cards"
|
||||
"domainCards": "Domain Cards",
|
||||
"equipment": "Equipment"
|
||||
},
|
||||
"ancestryNamePlaceholder": "Your ancestry's name",
|
||||
"buttonTitle": "Character Setup",
|
||||
|
|
@ -816,6 +821,10 @@
|
|||
"name": "Dead",
|
||||
"description": "The character is dead"
|
||||
},
|
||||
"defeated": {
|
||||
"name": "Defeated",
|
||||
"description": "This adversary is defeated."
|
||||
},
|
||||
"hidden": {
|
||||
"name": "Hidden",
|
||||
"description": "While Hidden, attacks cannot be made directly targeting them nd any rolls against them are at disadvantage.\nWhen a Hidden creature moves or attacks, they are no longer Hidden. However, if a creature is Hidden when they begin making an attack, the roll has advantage; the Hidden condition isn’t cleared until after the attack is resolved."
|
||||
|
|
@ -1865,7 +1874,8 @@
|
|||
"tier3": "Tier 3",
|
||||
"tier4": "tier 4",
|
||||
"domains": "Domains",
|
||||
"downtime": "Downtime"
|
||||
"downtime": "Downtime",
|
||||
"rules": "Rules"
|
||||
},
|
||||
"Tiers": {
|
||||
"singular": "Tier",
|
||||
|
|
@ -1934,6 +1944,7 @@
|
|||
"itemResource": "Item Resource",
|
||||
"label": "Label",
|
||||
"level": "Level",
|
||||
"levelShort": "Lv",
|
||||
"levelUp": "Level Up",
|
||||
"loadout": "Loadout",
|
||||
"max": "Max",
|
||||
|
|
@ -2081,7 +2092,12 @@
|
|||
"FIELDS": {
|
||||
"displayFear": { "label": "Fear Display" },
|
||||
"dualityColorScheme": { "label": "Chat Style" },
|
||||
"showGenericStatusEffects": { "label": "Show Foundry Status Effects" }
|
||||
"showGenericStatusEffects": { "label": "Show Foundry Status Effects" },
|
||||
"expandedTitle": "Auto-expand Descriptions",
|
||||
"extendCharacterDescriptions": { "label": "Characters" },
|
||||
"extendAdversaryDescriptions": { "label": "Adversaries" },
|
||||
"extendEnvironmentDescriptions": { "label": "Environments" },
|
||||
"extendItemDescriptions": { "label": "Items" }
|
||||
},
|
||||
"fearDisplay": {
|
||||
"token": "Tokens",
|
||||
|
|
@ -2099,6 +2115,13 @@
|
|||
"label": "Damage Reduction Rules Default",
|
||||
"hint": "Wether using armor and reductions has rules on by default"
|
||||
},
|
||||
"defeated": {
|
||||
"enabled": { "label": "Enabled" },
|
||||
"overlay": { "label": "Overlay Effect" },
|
||||
"characterDefault": { "label": "Character Default Defeated Status" },
|
||||
"adversaryDefault": { "label": "Adversary Default Defeated Status" },
|
||||
"companionDefault": { "label": "Companion Default Defeated Status" }
|
||||
},
|
||||
"hopeFear": {
|
||||
"label": "Hope & Fear",
|
||||
"gm": { "label": "GM" },
|
||||
|
|
@ -2130,6 +2153,9 @@
|
|||
"label": "Players Can Manually Edit Character Settings",
|
||||
"hint": "Players are allowed to access the manual Character Settings and change their statistics beyond the rules."
|
||||
}
|
||||
},
|
||||
"defeated": {
|
||||
"title": "Defeated Handling"
|
||||
}
|
||||
},
|
||||
"Homebrew": {
|
||||
|
|
@ -2369,7 +2395,8 @@
|
|||
"rulesOn": "Rules On",
|
||||
"rulesOff": "Rules Off",
|
||||
"remainingUses": "Uses refresh on {type}",
|
||||
"rightClickExtand": "Right-Click to extand"
|
||||
"rightClickExtand": "Right-Click to extand",
|
||||
"companionPartnerLevelBlock": "The companion needs an assigned partner to level up."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
|
||||
this.setup = {
|
||||
traits: this.character.system.traits,
|
||||
ancestryName: '',
|
||||
ancestryName: {
|
||||
primary: '',
|
||||
secondary: ''
|
||||
},
|
||||
mixedAncestry: false,
|
||||
primaryAncestry: this.character.system.ancestry ?? {},
|
||||
secondaryAncestry: {},
|
||||
|
|
@ -83,131 +86,70 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
|
||||
static PARTS = {
|
||||
tabs: { template: 'systems/daggerheart/templates/characterCreation/tabs.hbs' },
|
||||
setup: { template: 'systems/daggerheart/templates/characterCreation/tabs/setup.hbs' },
|
||||
ancestry: { template: 'systems/daggerheart/templates/characterCreation/setupTabs/ancestry.hbs' },
|
||||
community: { template: 'systems/daggerheart/templates/characterCreation/setupTabs/community.hbs' },
|
||||
class: { template: 'systems/daggerheart/templates/characterCreation/setupTabs/class.hbs' },
|
||||
traits: { template: 'systems/daggerheart/templates/characterCreation/setupTabs/traits.hbs' },
|
||||
experience: { template: 'systems/daggerheart/templates/characterCreation/setupTabs/experience.hbs' },
|
||||
domainCards: { template: 'systems/daggerheart/templates/characterCreation/setupTabs/domainCards.hbs' },
|
||||
equipment: { template: 'systems/daggerheart/templates/characterCreation/tabs/equipment.hbs' },
|
||||
// story: { template: 'systems/daggerheart/templates/characterCreation/tabs/story.hbs' },
|
||||
ancestry: { template: 'systems/daggerheart/templates/characterCreation/tabs/ancestry.hbs' },
|
||||
community: { template: 'systems/daggerheart/templates/characterCreation/tabs/community.hbs' },
|
||||
class: { template: 'systems/daggerheart/templates/characterCreation/tabs/class.hbs' },
|
||||
traits: { template: 'systems/daggerheart/templates/characterCreation/tabs/traits.hbs' },
|
||||
experience: { template: 'systems/daggerheart/templates/characterCreation/tabs/experience.hbs' },
|
||||
domainCards: { template: 'systems/daggerheart/templates/characterCreation/tabs/domainCards.hbs' },
|
||||
equipment: { template: 'systems/daggerheart/templates/characterCreation/equipment.hbs' },
|
||||
// story: { template: 'systems/daggerheart/templates/characterCreation/story.hbs' },
|
||||
footer: { template: 'systems/daggerheart/templates/characterCreation/footer.hbs' }
|
||||
};
|
||||
|
||||
static TABS = {
|
||||
setup: {
|
||||
active: true,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'setup',
|
||||
label: 'DAGGERHEART.GENERAL.Tabs.setup'
|
||||
},
|
||||
equipment: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'equipment',
|
||||
label: 'DAGGERHEART.GENERAL.Tabs.equipment',
|
||||
optional: true
|
||||
}
|
||||
// story: {
|
||||
// active: false,
|
||||
// cssClass: '',
|
||||
// group: 'primary',
|
||||
// id: 'story',
|
||||
// label: 'DAGGERHEART.GENERAL.Tabs.story',
|
||||
// optional: true
|
||||
// }
|
||||
};
|
||||
|
||||
static SETUPTABS = {
|
||||
ancestry: {
|
||||
active: true,
|
||||
cssClass: '',
|
||||
group: 'setup',
|
||||
id: 'ancestry',
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.setupTabs.ancestry'
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.ancestry'
|
||||
},
|
||||
community: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'setup',
|
||||
id: 'community',
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.setupTabs.community'
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.community'
|
||||
},
|
||||
class: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'setup',
|
||||
id: 'class',
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.setupTabs.class'
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.class'
|
||||
},
|
||||
traits: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'setup',
|
||||
id: 'traits',
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.setupTabs.traits'
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.traits'
|
||||
},
|
||||
experience: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'setup',
|
||||
id: 'experience',
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.setupTabs.experience'
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.experience'
|
||||
},
|
||||
domainCards: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'setup',
|
||||
id: 'domainCards',
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.setupTabs.domainCards'
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.domainCards'
|
||||
},
|
||||
equipment: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'setup',
|
||||
id: 'equipment',
|
||||
label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.equipment'
|
||||
}
|
||||
};
|
||||
|
||||
_getTabs(tabs) {
|
||||
for (const v of Object.values(tabs)) {
|
||||
v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
|
||||
v.cssClass = v.active ? 'active' : '';
|
||||
|
||||
switch (v.id) {
|
||||
case 'setup':
|
||||
const ancestryFinished = this.setup.primaryAncestry.uuid;
|
||||
const communityFinished = this.setup.community.uuid;
|
||||
const classFinished = this.setup.class.uuid && this.setup.subclass.uuid;
|
||||
const traitsFinished = Object.values(this.setup.traits).every(x => x.value !== null);
|
||||
const experiencesFinished = Object.values(this.setup.experiences).every(x => x.name);
|
||||
const domainCardsFinished = Object.values(this.setup.domainCards).every(x => x.uuid);
|
||||
v.finished =
|
||||
ancestryFinished &&
|
||||
communityFinished &&
|
||||
classFinished &&
|
||||
traitsFinished &&
|
||||
experiencesFinished &&
|
||||
domainCardsFinished;
|
||||
break;
|
||||
case 'equipment':
|
||||
const armorFinished = this.equipment.armor?.uuid;
|
||||
const primaryFinished = this.equipment.primaryWeapon?.uuid;
|
||||
const secondaryFinished =
|
||||
this.equipment.secondaryWeapon?.uuid ||
|
||||
(primaryFinished && this.equipment.primaryWeapon.system.burden == burden.twoHanded.value);
|
||||
const choiceAFinished = this.equipment.inventory.choiceA?.uuid;
|
||||
const choiceBFinished = this.equipment.inventory.choiceB?.uuid;
|
||||
|
||||
v.finished =
|
||||
armorFinished && primaryFinished && secondaryFinished && choiceAFinished && choiceBFinished;
|
||||
}
|
||||
}
|
||||
|
||||
tabs.equipment.cssClass = tabs.setup.finished ? tabs.equipment.cssClass : 'disabled';
|
||||
// tabs.story.cssClass = tabs.setup.finished ? tabs.story.cssClass : 'disabled';
|
||||
|
||||
return tabs;
|
||||
}
|
||||
|
||||
_getSetupTabs(tabs) {
|
||||
for (const v of Object.values(tabs)) {
|
||||
v.active = this.tabGroups[v.group]
|
||||
? this.tabGroups[v.group] === v.id
|
||||
|
|
@ -232,37 +174,15 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
case 'domainCards':
|
||||
v.disabled = this.setup.visibility < 6;
|
||||
break;
|
||||
case 'equipment':
|
||||
v.disabled = this.setup.visibility < 7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return tabs;
|
||||
}
|
||||
|
||||
changeTab(tab, group, options) {
|
||||
super.changeTab(tab, group, options);
|
||||
|
||||
if (group === 'primary') {
|
||||
for (var listTab of Object.keys(this.constructor.TABS)) {
|
||||
const marker = options.navElement.querySelector(`a[data-action="tab"].${listTab} .finish-marker`);
|
||||
if (listTab === tab) {
|
||||
marker.classList.add('active');
|
||||
} else {
|
||||
marker.classList.remove('active');
|
||||
}
|
||||
}
|
||||
|
||||
if (tab === 'equipment') {
|
||||
this.tabGroups.setup = null;
|
||||
this.element.querySelector('section[data-group="setup"].active')?.classList?.remove?.('active');
|
||||
} else {
|
||||
this.tabGroups.setup = 'domainCards';
|
||||
this.element
|
||||
.querySelector('section[data-group="setup"][data-tab="domainCards"]')
|
||||
?.classList?.add?.('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_attachPartListeners(partId, htmlElement, options) {
|
||||
super._attachPartListeners(partId, htmlElement, options);
|
||||
|
||||
|
|
@ -274,14 +194,71 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
});
|
||||
}
|
||||
|
||||
async _preFirstRender(_context, _options) {
|
||||
this.tabGroups.primary = 'setup';
|
||||
this.tabGroups.setup = 'ancestry';
|
||||
}
|
||||
|
||||
async _prepareContext(_options) {
|
||||
this.tabGroups.setup = this.tabGroups.setup ?? 'ancestry';
|
||||
const context = await super._prepareContext(_options);
|
||||
|
||||
context.tabs = this._getTabs(this.constructor.TABS);
|
||||
const availableTraitModifiers = game.settings
|
||||
.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew)
|
||||
.traitArray.map(trait => ({ key: trait, name: trait }));
|
||||
for (let trait of Object.values(this.setup.traits).filter(x => x.value !== null)) {
|
||||
const index = availableTraitModifiers.findIndex(x => x.key === trait.value);
|
||||
if (index !== -1) {
|
||||
availableTraitModifiers.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
context.suggestedTraits = this.setup.class.system
|
||||
? Object.keys(this.setup.class.system.characterGuide.suggestedTraits).map(traitKey => {
|
||||
const trait = this.setup.class.system.characterGuide.suggestedTraits[traitKey];
|
||||
return `${game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${traitKey}.short`)} ${trait > 0 ? `+${trait}` : trait}`;
|
||||
})
|
||||
: [];
|
||||
context.traits = {
|
||||
values: Object.keys(this.setup.traits).map(traitKey => {
|
||||
const trait = this.setup.traits[traitKey];
|
||||
const options = [...availableTraitModifiers];
|
||||
if (trait.value !== null && !options.some(x => x.key === trait.value))
|
||||
options.push({ key: trait.value, name: trait.value });
|
||||
|
||||
return {
|
||||
...trait,
|
||||
key: traitKey,
|
||||
name: game.i18n.localize(abilities[traitKey].label),
|
||||
options: options
|
||||
};
|
||||
})
|
||||
};
|
||||
context.traits.nrTotal = Object.keys(context.traits.values).length;
|
||||
context.traits.nrSelected = this.getNrSelectedTrait();
|
||||
|
||||
context.experience = {
|
||||
values: this.setup.experiences,
|
||||
nrTotal: Object.keys(this.setup.experiences).length,
|
||||
nrSelected: Object.values(this.setup.experiences).reduce((acc, exp) => acc + (exp.name ? 1 : 0), 0)
|
||||
};
|
||||
|
||||
context.mixedAncestry = Number(this.setup.mixedAncestry);
|
||||
|
||||
const { primary, secondary, overwrite } = this.setup.ancestryName;
|
||||
context.ancestryName = overwrite ?? (primary && secondary ? `${primary}/${secondary}` : primary);
|
||||
context.primaryAncestry = { ...this.setup.primaryAncestry, compendium: 'ancestries' };
|
||||
context.secondaryAncestry = { ...this.setup.secondaryAncestry, compendium: 'ancestries' };
|
||||
context.community = { ...this.setup.community, compendium: 'communities' };
|
||||
context.class = { ...this.setup.class, compendium: 'classes' };
|
||||
context.subclass = { ...this.setup.subclass, compendium: 'subclasses' };
|
||||
|
||||
const allDomainData = CONFIG.DH.DOMAIN.allDomains();
|
||||
context.classDomains = context.class.uuid
|
||||
? context.class.system.domains.map(key => game.i18n.localize(allDomainData[key].label))
|
||||
: [];
|
||||
context.domainCards = Object.keys(this.setup.domainCards).reduce((acc, x) => {
|
||||
acc[x] = { ...this.setup.domainCards[x], compendium: 'domains' };
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
context.visibility = this.setup.visibility;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
|
@ -289,7 +266,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
async _preparePartContext(partId, context) {
|
||||
switch (partId) {
|
||||
case 'footer':
|
||||
context.isLastTab = this.tabGroups.setup === 'domainCards' || this.tabGroups.primary !== 'setup';
|
||||
context.isLastTab = this.tabGroups.setup === 'equipment';
|
||||
switch (this.tabGroups.setup) {
|
||||
case null:
|
||||
case 'ancestry':
|
||||
|
|
@ -307,69 +284,11 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
case 'experience':
|
||||
context.nextDisabled = this.setup.visibility === 5;
|
||||
break;
|
||||
case 'domainCards':
|
||||
context.nextDisabled = this.setup.visibility === 6;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'setup':
|
||||
context.setupTabs = this._getSetupTabs(this.constructor.SETUPTABS);
|
||||
const availableTraitModifiers = game.settings
|
||||
.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew)
|
||||
.traitArray.map(trait => ({ key: trait, name: trait }));
|
||||
for (let trait of Object.values(this.setup.traits).filter(x => x.value !== null)) {
|
||||
const index = availableTraitModifiers.findIndex(x => x.key === trait.value);
|
||||
if (index !== -1) {
|
||||
availableTraitModifiers.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
context.suggestedTraits = this.setup.class.system
|
||||
? Object.keys(this.setup.class.system.characterGuide.suggestedTraits).map(traitKey => {
|
||||
const trait = this.setup.class.system.characterGuide.suggestedTraits[traitKey];
|
||||
return `${game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${traitKey}.short`)} ${trait > 0 ? `+${trait}` : trait}`;
|
||||
})
|
||||
: [];
|
||||
context.traits = {
|
||||
values: Object.keys(this.setup.traits).map(traitKey => {
|
||||
const trait = this.setup.traits[traitKey];
|
||||
const options = [...availableTraitModifiers];
|
||||
if (trait.value !== null && !options.some(x => x.key === trait.value))
|
||||
options.push({ key: trait.value, name: trait.value });
|
||||
|
||||
return {
|
||||
...trait,
|
||||
key: traitKey,
|
||||
name: game.i18n.localize(abilities[traitKey].label),
|
||||
options: options
|
||||
};
|
||||
})
|
||||
};
|
||||
context.traits.nrTotal = Object.keys(context.traits.values).length;
|
||||
context.traits.nrSelected = this.getNrSelectedTrait();
|
||||
|
||||
context.experience = {
|
||||
values: this.setup.experiences,
|
||||
nrTotal: Object.keys(this.setup.experiences).length,
|
||||
nrSelected: Object.values(this.setup.experiences).reduce((acc, exp) => acc + (exp.name ? 1 : 0), 0)
|
||||
};
|
||||
|
||||
context.mixedAncestry = Number(this.setup.mixedAncestry);
|
||||
context.ancestryName = this.setup.ancestryName;
|
||||
context.primaryAncestry = { ...this.setup.primaryAncestry, compendium: 'ancestries' };
|
||||
context.secondaryAncestry = { ...this.setup.secondaryAncestry, compendium: 'ancestries' };
|
||||
context.community = { ...this.setup.community, compendium: 'communities' };
|
||||
context.class = { ...this.setup.class, compendium: 'classes' };
|
||||
context.subclass = { ...this.setup.subclass, compendium: 'subclasses' };
|
||||
|
||||
const allDomainData = CONFIG.DH.DOMAIN.allDomains();
|
||||
context.classDomains = context.class.uuid
|
||||
? context.class.system.domains.map(key => game.i18n.localize(allDomainData[key].label))
|
||||
: [];
|
||||
context.domainCards = Object.keys(this.setup.domainCards).reduce((acc, x) => {
|
||||
acc[x] = { ...this.setup.domainCards[x], compendium: 'domains' };
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
context.visibility = this.setup.visibility;
|
||||
break;
|
||||
case 'equipment':
|
||||
const suggestions = await this.getEquipmentSuggestions(
|
||||
|
|
@ -438,8 +357,10 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
|
||||
getUpdateVisibility() {
|
||||
switch (this.setup.visibility) {
|
||||
case 7:
|
||||
return 7;
|
||||
case 6:
|
||||
return 6;
|
||||
return Object.values(this.setup.domainCards).every(x => x.uuid) ? 7 : 6;
|
||||
case 5:
|
||||
return Object.values(this.setup.experiences).every(x => x.name) ? 6 : 5;
|
||||
case 4:
|
||||
|
|
@ -505,7 +426,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
|
||||
const presets = {
|
||||
compendium: 'daggerheart',
|
||||
folder: equipment.includes(type) ? "equipments" : type,
|
||||
folder: equipment.includes(type) ? 'equipments' : type,
|
||||
render: {
|
||||
noFolder: true
|
||||
}
|
||||
|
|
@ -565,6 +486,9 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
case 6:
|
||||
this.tabGroups.setup = 'domainCards';
|
||||
break;
|
||||
case 7:
|
||||
this.tabGroups.setup = 'equipment';
|
||||
break;
|
||||
}
|
||||
|
||||
this.render();
|
||||
|
|
@ -576,9 +500,10 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
? this.setup.secondaryAncestry.system.secondaryFeature
|
||||
: this.setup.primaryAncestry.system.secondaryFeature;
|
||||
|
||||
const { primary, secondary, overwrite } = this.setup.ancestryName;
|
||||
const ancestry = {
|
||||
...this.setup.primaryAncestry,
|
||||
name: this.setup.ancestryName ?? this.setup.primaryAncestry.name,
|
||||
name: overwrite ?? (primary && secondary ? `${primary}/${secondary}` : primary),
|
||||
system: {
|
||||
...this.setup.primaryAncestry.system,
|
||||
features: [
|
||||
|
|
@ -650,13 +575,14 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||
const item = await foundry.utils.fromUuid(data.uuid);
|
||||
if (item.type === 'ancestry' && event.target.closest('.primary-ancestry-card')) {
|
||||
this.setup.ancestryName = item.name;
|
||||
this.setup.ancestryName.primary = item.name;
|
||||
this.setup.primaryAncestry = {
|
||||
...item,
|
||||
effects: Array.from(item.effects).map(x => x.toObject()),
|
||||
uuid: item.uuid
|
||||
};
|
||||
} else if (item.type === 'ancestry' && event.target.closest('.secondary-ancestry-card')) {
|
||||
this.setup.ancestryName.secondary = item.name;
|
||||
this.setup.secondaryAncestry = {
|
||||
...item,
|
||||
effects: Array.from(item.effects).map(x => x.toObject()),
|
||||
|
|
|
|||
|
|
@ -95,8 +95,9 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
|||
if (x.system.actions) {
|
||||
const recoverable = x.system.actions.reduce((acc, action) => {
|
||||
if (
|
||||
(action.uses.recovery && (action.uses.recovery === 'longRest') === !this.shortrest) ||
|
||||
action.uses.recovery === 'shortRest'
|
||||
action.uses.recovery &&
|
||||
((action.uses.recovery === 'longRest' && !this.shortrest) ||
|
||||
action.uses.recovery === 'shortRest')
|
||||
) {
|
||||
acc.push({
|
||||
title: x.name,
|
||||
|
|
|
|||
|
|
@ -49,12 +49,7 @@ export default class DhCharacterLevelUp extends LevelUpBase {
|
|||
const experienceIncreases = Object.values(advancementChoices.experience ?? {});
|
||||
const experienceIncreaseValues = experienceIncreases
|
||||
.filter(exp => exp.data.length > 0)
|
||||
.flatMap(exp =>
|
||||
exp.data.map(data => {
|
||||
const experience = Object.keys(this.actor.system.experiences)[data];
|
||||
return this.actor.system.experiences[experience].name;
|
||||
})
|
||||
);
|
||||
.flatMap(exp => exp.data);
|
||||
context.experienceIncreases = {
|
||||
values: experienceIncreaseValues,
|
||||
active: experienceIncreases.length > 0,
|
||||
|
|
|
|||
|
|
@ -37,12 +37,7 @@ export default class DhCompanionLevelUp extends BaseLevelUp {
|
|||
const experienceIncreases = Object.values(advancementChoices.experience ?? {});
|
||||
const experienceIncreaseValues = experienceIncreases
|
||||
.filter(exp => exp.data.length > 0)
|
||||
.flatMap(exp =>
|
||||
exp.data.map(data => {
|
||||
const experience = Object.keys(this.actor.system.experiences)[data];
|
||||
return this.actor.system.experiences[experience].name;
|
||||
})
|
||||
);
|
||||
.flatMap(exp => exp.data);
|
||||
context.experienceIncreases = {
|
||||
values: experienceIncreaseValues,
|
||||
active: experienceIncreases.length > 0,
|
||||
|
|
@ -72,6 +67,28 @@ export default class DhCompanionLevelUp extends BaseLevelUp {
|
|||
const levelKeys = Object.keys(this.levelup.levels);
|
||||
const actorDamageDice = this.actor.system.attack.damage.parts[0].value.dice;
|
||||
const actorRange = this.actor.system.attack.range;
|
||||
|
||||
let achievementExperiences = [];
|
||||
for (var levelKey of levelKeys) {
|
||||
const level = this.levelup.levels[levelKey];
|
||||
if (Number(levelKey) < this.levelup.startLevel) continue;
|
||||
|
||||
achievementExperiences = level.achievements.experiences
|
||||
? Object.values(level.achievements.experiences).reduce((acc, experience) => {
|
||||
if (experience.name) acc.push(experience);
|
||||
return acc;
|
||||
}, [])
|
||||
: [];
|
||||
}
|
||||
context.achievements = {
|
||||
experiences: {
|
||||
values: achievementExperiences,
|
||||
shown: achievementExperiences.length > 0
|
||||
}
|
||||
};
|
||||
|
||||
context.achievements = context.achievements.experiences.shown ? context.achievements : undefined;
|
||||
|
||||
const advancement = {};
|
||||
for (var levelKey of levelKeys) {
|
||||
const level = this.levelup.levels[levelKey];
|
||||
|
|
|
|||
|
|
@ -31,8 +31,19 @@ export default class DhAutomationSettings extends HandlebarsApplicationMixin(App
|
|||
};
|
||||
|
||||
static PARTS = {
|
||||
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
||||
header: { template: 'systems/daggerheart/templates/settings/automation-settings/header.hbs' },
|
||||
general: { template: 'systems/daggerheart/templates/settings/automation-settings/general.hbs' },
|
||||
rules: { template: 'systems/daggerheart/templates/settings/automation-settings/rules.hbs' },
|
||||
footer: { template: 'systems/daggerheart/templates/settings/automation-settings/footer.hbs' }
|
||||
};
|
||||
|
||||
/** @inheritdoc */
|
||||
static TABS = {
|
||||
main: {
|
||||
template: 'systems/daggerheart/templates/settings/automation-settings.hbs'
|
||||
tabs: [{ id: 'general' }, { id: 'rules' }],
|
||||
initial: 'general',
|
||||
labelPrefix: 'DAGGERHEART.GENERAL.Tabs'
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { GMUpdateEvent, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||
import DhCompanionlevelUp from '../levelup/companionLevelup.mjs';
|
||||
import DHBaseActorSettings from '../sheets/api/actor-setting.mjs';
|
||||
|
||||
/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
|
||||
|
|
@ -11,8 +10,7 @@ export default class DHCompanionSettings extends DHBaseActorSettings {
|
|||
position: { width: 455, height: 'auto' },
|
||||
actions: {
|
||||
addExperience: DHCompanionSettings.#addExperience,
|
||||
removeExperience: DHCompanionSettings.#removeExperience,
|
||||
levelUp: DHCompanionSettings.#levelUp
|
||||
removeExperience: DHCompanionSettings.#removeExperience
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -121,12 +119,4 @@ export default class DHCompanionSettings extends DHBaseActorSettings {
|
|||
|
||||
await this.actor.update({ [`system.experiences.-=${target.dataset.experience}`]: null });
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the companion level-up dialog for the associated actor.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #levelUp() {
|
||||
new DhCompanionlevelUp(this.actor).render({ force: true });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -638,15 +638,21 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
ability: abilityLabel
|
||||
})
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
this.consumeResource(result?.costs);
|
||||
}, 50);
|
||||
|
||||
this.consumeResource(result?.costs);
|
||||
}
|
||||
|
||||
// Remove when Action Refactor part #2 done
|
||||
async consumeResource(costs) {
|
||||
if (!costs?.length) return;
|
||||
const usefulResources = foundry.utils.deepClone(this.actor.system.resources);
|
||||
const usefulResources = {
|
||||
...foundry.utils.deepClone(this.actor.system.resources),
|
||||
fear: {
|
||||
value: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear),
|
||||
max: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear,
|
||||
reversed: false
|
||||
}
|
||||
};
|
||||
const resources = game.system.api.fields.ActionFields.CostField.getRealCosts(costs).map(c => {
|
||||
const resource = usefulResources[c.key];
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import DhCompanionLevelUp from '../../levelup/companionLevelup.mjs';
|
||||
import DHBaseActorSheet from '../api/base-actor.mjs';
|
||||
|
||||
/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
|
||||
|
|
@ -5,8 +6,10 @@ import DHBaseActorSheet from '../api/base-actor.mjs';
|
|||
export default class DhCompanionSheet extends DHBaseActorSheet {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['actor', 'companion'],
|
||||
position: { width: 300 },
|
||||
actions: {}
|
||||
position: { width: 340 },
|
||||
actions: {
|
||||
levelManagement: DhCompanionSheet.#levelManagement
|
||||
}
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
|
|
@ -25,4 +28,25 @@ export default class DhCompanionSheet extends DHBaseActorSheet {
|
|||
labelPrefix: 'DAGGERHEART.GENERAL.Tabs'
|
||||
}
|
||||
};
|
||||
|
||||
/** @inheritDoc */
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
|
||||
this.element
|
||||
.querySelector('.level-value')
|
||||
?.addEventListener('change', event => this.document.updateLevel(Number(event.currentTarget.value)));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Application Clicks Actions */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Opens the companions level management window.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static #levelManagement() {
|
||||
new DhCompanionLevelUp(this.document).render({ force: true });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,23 @@ const { HandlebarsApplicationMixin } = foundry.applications.api;
|
|||
import { getDocFromElement, getDocFromElementSync, tagifyElement } from '../../../helpers/utils.mjs';
|
||||
import { ItemBrowser } from '../../ui/itemBrowser.mjs';
|
||||
|
||||
const typeSettingsMap = {
|
||||
character: 'extendCharacterDescriptions',
|
||||
adversary: 'extendAdversaryDescriptions',
|
||||
environment: 'extendEnvironmentDescriptions',
|
||||
ancestry: 'extendItemDescriptions',
|
||||
community: 'extendItemDescriptions',
|
||||
class: 'extendItemDescriptions',
|
||||
subclass: 'extendItemDescriptions',
|
||||
feature: 'extendItemDescriptions',
|
||||
domainCard: 'extendItemDescriptions',
|
||||
loot: 'extendItemDescriptions',
|
||||
consumable: 'extendItemDescriptions',
|
||||
weapon: 'extendItemDescriptions',
|
||||
armor: 'extendItemDescriptions',
|
||||
beastform: 'extendItemDescriptions'
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction
|
||||
*/
|
||||
|
|
@ -137,6 +154,8 @@ export default function DHApplicationMixin(Base) {
|
|||
docs.filter(doc => doc).forEach(doc => (doc.apps[this.id] = this));
|
||||
|
||||
if (!!this.options.contextMenus.length) this._createContextMenus();
|
||||
|
||||
this.#autoExtendDescriptions(context);
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
|
|
@ -149,6 +168,7 @@ export default function DHApplicationMixin(Base) {
|
|||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
this._createTagifyElements(this.options.tagifyConfigs);
|
||||
await this.#prepareInventoryDescription(context);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
|
@ -162,13 +182,7 @@ export default function DHApplicationMixin(Base) {
|
|||
const { actionId, itemUuid } = el.parentElement.dataset;
|
||||
const selector = `${actionId ? `[data-action-id="${actionId}"]` : `[data-item-uuid="${itemUuid}"]`} .extensible`;
|
||||
const newExtensible = newElement.querySelector(selector);
|
||||
|
||||
if (!newExtensible) continue;
|
||||
newExtensible.classList.add('extended');
|
||||
const descriptionElement = newExtensible.querySelector('.invetory-description');
|
||||
if (descriptionElement) {
|
||||
this.#prepareInventoryDescription(newExtensible, descriptionElement);
|
||||
}
|
||||
newExtensible?.classList.add('extended');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -395,6 +409,7 @@ export default function DHApplicationMixin(Base) {
|
|||
context.source = this.document;
|
||||
context.fields = this.document.schema.fields;
|
||||
context.systemFields = this.document.system.schema.fields;
|
||||
context.settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance);
|
||||
return context;
|
||||
}
|
||||
|
||||
|
|
@ -404,32 +419,69 @@ export default function DHApplicationMixin(Base) {
|
|||
|
||||
/**
|
||||
* Prepares and enriches an inventory item or action description for display.
|
||||
* @param {HTMLElement} extensibleElement - The parent element containing the description.
|
||||
* @param {HTMLElement} descriptionElement - The element where the enriched description will be rendered.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async #prepareInventoryDescription(extensibleElement, descriptionElement) {
|
||||
const parent = extensibleElement.closest('[data-item-uuid], [data-action-id]');
|
||||
const { actionId, itemUuid } = parent?.dataset || {};
|
||||
if (!actionId && !itemUuid) return;
|
||||
async #prepareInventoryDescription(context) {
|
||||
// Get all inventory item elements with a data-item-uuid attribute
|
||||
const inventoryItems = this.element.querySelectorAll('.inventory-item[data-item-uuid]');
|
||||
for (const el of inventoryItems) {
|
||||
// Get the doc uuid from the element
|
||||
const { itemUuid } = el?.dataset || {};
|
||||
if (!itemUuid) continue;
|
||||
|
||||
const doc = itemUuid
|
||||
? await getDocFromElement(extensibleElement)
|
||||
: this.document.system.attack?.id === actionId
|
||||
? this.document.system.attack
|
||||
: this.document.system.actions?.get(actionId);
|
||||
if (!doc) return;
|
||||
//get doc by uuid
|
||||
const doc = await fromUuid(itemUuid);
|
||||
|
||||
const description = game.i18n.localize(doc.system?.description ?? doc.description);
|
||||
const isAction = !!actionId;
|
||||
descriptionElement.innerHTML = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
description,
|
||||
{
|
||||
relativeTo: isAction ? doc.parent : doc,
|
||||
rollData: doc.getRollData?.(),
|
||||
secrets: isAction ? doc.parent.isOwner : doc.isOwner
|
||||
//get inventory-item description element
|
||||
const descriptionElement = el.querySelector('.invetory-description');
|
||||
if (!doc || !descriptionElement) continue;
|
||||
|
||||
// localize the description (idk if it's still necessary)
|
||||
const description = game.i18n.localize(doc.system?.description ?? doc.description);
|
||||
|
||||
// Enrich the description and attach it;
|
||||
const isAction = doc.documentName === 'Action';
|
||||
descriptionElement.innerHTML = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
description,
|
||||
{
|
||||
relativeTo: isAction ? doc.parent : doc,
|
||||
rollData: doc.getRollData?.(),
|
||||
secrets: isAction ? doc.parent.isOwner : doc.isOwner
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Extend Descriptions by Settings */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Extend inventory description when enabled in settings.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async #autoExtendDescriptions(context) {
|
||||
const inventoryItems = this.element.querySelectorAll('.inventory-item[data-item-uuid]');
|
||||
for (const el of inventoryItems) {
|
||||
// Get the doc uuid from the element
|
||||
const { itemUuid } = el?.dataset || {};
|
||||
if (!itemUuid) continue;
|
||||
|
||||
//get doc by uuid
|
||||
const doc = await fromUuid(itemUuid);
|
||||
|
||||
//check the type of the document
|
||||
const actorType =
|
||||
doc?.type === 'adversary' && context.document?.type === 'environment'
|
||||
? typeSettingsMap[doc?.type]
|
||||
: doc.actor?.type;
|
||||
|
||||
// If the actor type is defined and the setting is enabled, extend the description
|
||||
if (typeSettingsMap[actorType]) {
|
||||
const settingKey = typeSettingsMap[actorType];
|
||||
if (context.settings[settingKey]) this.#activeExtended(el);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
|
@ -437,8 +489,6 @@ export default function DHApplicationMixin(Base) {
|
|||
/* -------------------------------------------- */
|
||||
|
||||
static async #addNewItem(event, target) {
|
||||
const { type } = target.dataset;
|
||||
|
||||
const createChoice = await foundry.applications.api.DialogV2.wait({
|
||||
classes: ['dh-style', 'two-big-buttons'],
|
||||
buttons: [
|
||||
|
|
@ -606,10 +656,12 @@ export default function DHApplicationMixin(Base) {
|
|||
static async #toggleExtended(_, target) {
|
||||
const container = target.closest('.inventory-item');
|
||||
const extensible = container?.querySelector('.extensible');
|
||||
const t = extensible?.classList.toggle('extended');
|
||||
extensible?.classList.toggle('extended');
|
||||
}
|
||||
|
||||
const descriptionElement = extensible?.querySelector('.invetory-description');
|
||||
if (t && !!descriptionElement) await this.#prepareInventoryDescription(extensible, descriptionElement);
|
||||
async #activeExtended(element) {
|
||||
const extensible = element?.querySelector('.extensible');
|
||||
extensible?.classList.add('extended');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ export default function ItemAttachmentSheet(Base) {
|
|||
...super.TABS,
|
||||
primary: {
|
||||
...super.TABS?.primary,
|
||||
tabs: [...(super.TABS?.primary?.tabs || []), { id: 'attachments' }],
|
||||
tabs: [...(super.TABS?.primary?.tabs || []) /*{ id: 'attachments' }*/], // Disabled until fixed
|
||||
initial: super.TABS?.primary?.initial || 'description',
|
||||
labelPrefix: super.TABS?.primary?.labelPrefix || 'DAGGERHEART.GENERAL.Tabs'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,57 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
|||
];
|
||||
}
|
||||
|
||||
getDefeatedId(combatant) {
|
||||
if (!combatant.actor) return CONFIG.specialStatusEffects.DEFEATED;
|
||||
|
||||
const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).defeated;
|
||||
return settings[`${combatant.actor.type}Default`];
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
async _onToggleDefeatedStatus(combatant) {
|
||||
const isDefeated = !combatant.isDefeated;
|
||||
await combatant.update({ defeated: isDefeated });
|
||||
await combatant.actor?.toggleStatusEffect(this.getDefeatedId(combatant), { overlay: true, active: isDefeated });
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
async _prepareTurnContext(combat, combatant, index) {
|
||||
const { id, name, isOwner, isDefeated, hidden, initiative, permission } = combatant;
|
||||
const resource = permission >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER ? combatant.resource : null;
|
||||
const hasDecimals = Number.isFinite(initiative) && !Number.isInteger(initiative);
|
||||
const turn = {
|
||||
hasDecimals,
|
||||
hidden,
|
||||
id,
|
||||
isDefeated,
|
||||
initiative,
|
||||
isOwner,
|
||||
name,
|
||||
resource,
|
||||
active: index === combat.turn,
|
||||
canPing: combatant.sceneId === canvas.scene?.id && game.user.hasPermission('PING_CANVAS'),
|
||||
img: await this._getCombatantThumbnail(combatant)
|
||||
};
|
||||
|
||||
turn.css = [turn.active ? 'active' : null, hidden ? 'hide' : null, isDefeated ? 'defeated' : null].filterJoin(
|
||||
' '
|
||||
);
|
||||
|
||||
const defeatedId = this.getDefeatedId(combatant);
|
||||
const effects = [];
|
||||
for (const effect of combatant.actor?.temporaryEffects ?? []) {
|
||||
if (effect.statuses.has(defeatedId)) turn.isDefeated = true;
|
||||
else if (effect.img) effects.push({ img: effect.img, name: effect.name });
|
||||
}
|
||||
turn.effects = {
|
||||
icons: effects,
|
||||
tooltip: this._formatEffectsTooltip(effects)
|
||||
};
|
||||
|
||||
return turn;
|
||||
}
|
||||
|
||||
async setCombatantSpotlight(combatantId) {
|
||||
const update = {
|
||||
system: {
|
||||
|
|
|
|||
|
|
@ -15,17 +15,19 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token {
|
|||
acc.push(effect);
|
||||
|
||||
const currentStatusActiveEffects = acc.filter(
|
||||
x => x.statuses.size === 1 && x.name === game.i18n.localize(statusMap.get(x.statuses.first()).name)
|
||||
x => x.statuses.size === 1 && x.name === game.i18n.localize(statusMap.get(x.statuses.first())?.name)
|
||||
);
|
||||
for (var status of effect.statuses) {
|
||||
if (!currentStatusActiveEffects.find(x => x.statuses.has(status))) {
|
||||
const statusData = statusMap.get(status);
|
||||
acc.push({
|
||||
name: game.i18n.localize(statusData.name),
|
||||
statuses: [status],
|
||||
img: statusData.icon,
|
||||
tint: effect.tint
|
||||
});
|
||||
if (statusData) {
|
||||
acc.push({
|
||||
name: game.i18n.localize(statusData.name),
|
||||
statuses: [status],
|
||||
img: statusData.icon,
|
||||
tint: effect.tint
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -164,39 +164,49 @@ export const healingTypes = {
|
|||
}
|
||||
};
|
||||
|
||||
export const conditions = {
|
||||
vulnerable: {
|
||||
id: 'vulnerable',
|
||||
name: 'DAGGERHEART.CONFIG.Condition.vulnerable.name',
|
||||
icon: 'icons/magic/control/silhouette-fall-slip-prone.webp',
|
||||
description: 'DAGGERHEART.CONFIG.Condition.vulnerable.description'
|
||||
},
|
||||
hidden: {
|
||||
id: 'hidden',
|
||||
name: 'DAGGERHEART.CONFIG.Condition.hidden.name',
|
||||
icon: 'icons/magic/perception/silhouette-stealth-shadow.webp',
|
||||
description: 'DAGGERHEART.CONFIG.Condition.hidden.description'
|
||||
},
|
||||
restrained: {
|
||||
id: 'restrained',
|
||||
name: 'DAGGERHEART.CONFIG.Condition.restrained.name',
|
||||
icon: 'icons/magic/control/debuff-chains-shackle-movement-red.webp',
|
||||
description: 'DAGGERHEART.CONFIG.Condition.restrained.description'
|
||||
export const defeatedConditions = {
|
||||
defeated: {
|
||||
id: 'defeated',
|
||||
name: 'DAGGERHEART.CONFIG.Condition.defeated.name',
|
||||
img: 'icons/magic/control/fear-fright-mask-orange.webp',
|
||||
description: 'DAGGERHEART.CONFIG.Condition.defeated.description'
|
||||
},
|
||||
unconscious: {
|
||||
id: 'unconscious',
|
||||
name: 'DAGGERHEART.CONFIG.Condition.unconscious.name',
|
||||
icon: 'icons/magic/control/sleep-bubble-purple.webp',
|
||||
img: 'icons/magic/control/sleep-bubble-purple.webp',
|
||||
description: 'DAGGERHEART.CONFIG.Condition.unconscious.description'
|
||||
},
|
||||
dead: {
|
||||
id: 'dead',
|
||||
name: 'DAGGERHEART.CONFIG.Condition.dead.name',
|
||||
icon: 'icons/magic/death/grave-tombstone-glow-teal.webp',
|
||||
img: 'icons/magic/death/grave-tombstone-glow-teal.webp',
|
||||
description: 'DAGGERHEART.CONFIG.Condition.dead.description'
|
||||
}
|
||||
};
|
||||
|
||||
export const conditions = {
|
||||
vulnerable: {
|
||||
id: 'vulnerable',
|
||||
name: 'DAGGERHEART.CONFIG.Condition.vulnerable.name',
|
||||
img: 'icons/magic/control/silhouette-fall-slip-prone.webp',
|
||||
description: 'DAGGERHEART.CONFIG.Condition.vulnerable.description'
|
||||
},
|
||||
hidden: {
|
||||
id: 'hidden',
|
||||
name: 'DAGGERHEART.CONFIG.Condition.hidden.name',
|
||||
img: 'icons/magic/perception/silhouette-stealth-shadow.webp',
|
||||
description: 'DAGGERHEART.CONFIG.Condition.hidden.description'
|
||||
},
|
||||
restrained: {
|
||||
id: 'restrained',
|
||||
name: 'DAGGERHEART.CONFIG.Condition.restrained.name',
|
||||
img: 'icons/magic/control/debuff-chains-shackle-movement-red.webp',
|
||||
description: 'DAGGERHEART.CONFIG.Condition.restrained.description'
|
||||
},
|
||||
...defeatedConditions
|
||||
};
|
||||
|
||||
export const defaultRestOptions = {
|
||||
shortRest: () => ({
|
||||
tendToWounds: {
|
||||
|
|
|
|||
|
|
@ -42,4 +42,32 @@ export default class DHAttackAction extends DHDamageAction {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a localized label array for this item subtype.
|
||||
* @returns {(string | { value: string, icons: string[] })[]} An array of localized strings and damage label objects.
|
||||
*/
|
||||
_getLabels() {
|
||||
const labels = [];
|
||||
const { roll, range, damage } = this;
|
||||
|
||||
if (roll.trait) labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${roll.trait}.short`))
|
||||
if (range) labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.Range.${range}.short`));
|
||||
|
||||
for (const { value, type } of damage.parts) {
|
||||
const str = Roll.replaceFormulaData(value.getFormula(), this.actor?.getRollData() ?? {});
|
||||
|
||||
const icons = Array.from(type)
|
||||
.map(t => CONFIG.DH.GENERAL.damageTypes[t]?.icon)
|
||||
.filter(Boolean);
|
||||
|
||||
if (icons.length === 0) {
|
||||
labels.push(str);
|
||||
} else {
|
||||
labels.push({ value: str, icons });
|
||||
}
|
||||
}
|
||||
|
||||
return labels;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,13 @@
|
|||
import DHBaseAction from './baseAction.mjs';
|
||||
|
||||
export default class DHMacroAction extends DHBaseAction {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
...super.defineSchema(),
|
||||
documentUUID: new fields.DocumentUUIDField({ type: 'Macro' })
|
||||
};
|
||||
}
|
||||
static extraSchemas = [...super.extraSchemas, 'macro'];
|
||||
|
||||
async trigger(event, ...args) {
|
||||
const fixUUID = !this.documentUUID.includes('Macro.') ? `Macro.${this.documentUUID}` : this.documentUUID,
|
||||
const fixUUID = !this.macro.includes('Macro.') ? `Macro.${this.macro}` : this.macro,
|
||||
macro = await fromUuid(fixUUID);
|
||||
try {
|
||||
if (!macro) throw new Error(`No macro found for the UUID: ${this.documentUUID}.`);
|
||||
if (!macro) throw new Error(`No macro found for the UUID: ${this.macro}.`);
|
||||
macro.execute();
|
||||
} catch (error) {
|
||||
ui.notifications.error(error);
|
||||
|
|
|
|||
|
|
@ -106,6 +106,28 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
|
|||
}, []);
|
||||
options.scrollingTextData = textData;
|
||||
}
|
||||
|
||||
if (changes.system?.resources) {
|
||||
const defeatedSettings = game.settings.get(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.Automation
|
||||
).defeated;
|
||||
const typeForDefeated = ['character', 'adversary', 'companion'].find(x => x === this.parent.type);
|
||||
if (defeatedSettings.enabled && typeForDefeated) {
|
||||
const resource = typeForDefeated === 'companion' ? 'stress' : 'hitPoints';
|
||||
if (changes.system.resources[resource]) {
|
||||
const becameMax = changes.system.resources[resource].value === this.resources[resource].max;
|
||||
const wasMax =
|
||||
this.resources[resource].value === this.resources[resource].max &&
|
||||
this.resources[resource].value !== changes.system.resources[resource].value;
|
||||
if (becameMax) {
|
||||
this.parent.toggleDefeated(true);
|
||||
} else if (wasMax) {
|
||||
this.parent.toggleDefeated(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_onUpdate(changes, options, userId) {
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ export default class DhCharacter extends BaseDataActor {
|
|||
}),
|
||||
attack: new ActionField({
|
||||
initial: {
|
||||
name: 'Attack',
|
||||
name: 'Unarmed Attack',
|
||||
img: 'icons/skills/melee/unarmed-punch-fist-yellow-red.webp',
|
||||
_id: foundry.utils.randomID(),
|
||||
systemPath: 'attack',
|
||||
|
|
@ -394,19 +394,22 @@ export default class DhCharacter extends BaseDataActor {
|
|||
return this.parent.effects.find(x => x.type === 'beastform');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unarmed attackwhen no primary or secondary weapon is equipped.
|
||||
* Returns `null` if either weapon is equipped.
|
||||
* If the actor is in beastform, overrides the attack's name and image.
|
||||
*
|
||||
* @returns {DHAttackAction|null}
|
||||
*/
|
||||
get usedUnarmed() {
|
||||
const primaryWeaponEquipped = this.primaryWeapon?.system?.equipped;
|
||||
const secondaryWeaponEquipped = this.secondaryWeapon?.system?.equipped;
|
||||
return !primaryWeaponEquipped && !secondaryWeaponEquipped
|
||||
? {
|
||||
...this.attack,
|
||||
uuid: this.attack.uuid,
|
||||
id: this.attack.id,
|
||||
name: this.activeBeastform ? 'DAGGERHEART.ITEMS.Beastform.attackName' : this.attack.name,
|
||||
img: this.activeBeastform ? 'icons/creatures/claws/claw-straight-brown.webp' : this.attack.img,
|
||||
actor: this.parent
|
||||
}
|
||||
: null;
|
||||
if (this.primaryWeapon?.system?.equipped || this.secondaryWeapon?.system?.equipped) return null;
|
||||
|
||||
const attack = foundry.utils.deepClone(this.attack);
|
||||
if (this.activeBeastform) {
|
||||
attack.name = 'DAGGERHEART.ITEMS.Beastform.attackName';
|
||||
attack.img = 'icons/creatures/claws/claw-straight-brown.webp';
|
||||
}
|
||||
return attack;
|
||||
}
|
||||
|
||||
get sheetLists() {
|
||||
|
|
@ -599,7 +602,20 @@ export default class DhCharacter extends BaseDataActor {
|
|||
}
|
||||
|
||||
prepareDerivedData() {
|
||||
const baseHope = this.resources.hope.value + (this.companion?.system?.resources?.hope ?? 0);
|
||||
let baseHope = this.resources.hope.value;
|
||||
if (this.companion) {
|
||||
for (let levelKey in this.companion.system.levelData.levelups) {
|
||||
const level = this.companion.system.levelData.levelups[levelKey];
|
||||
for (let selection of level.selections) {
|
||||
switch (selection.type) {
|
||||
case 'hope':
|
||||
this.resources.hope.max += selection.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.resources.hope.value = Math.min(baseHope, this.resources.hope.max);
|
||||
this.attack.roll.trait = this.rules.attack.roll.trait ?? this.attack.roll.trait;
|
||||
|
||||
|
|
|
|||
|
|
@ -40,12 +40,14 @@ export default class DhCompanion extends BaseDataActor {
|
|||
experiences: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
name: new fields.StringField({}),
|
||||
value: new fields.NumberField({ integer: true, initial: 0 })
|
||||
value: new fields.NumberField({ integer: true, initial: 0 }),
|
||||
description: new fields.StringField(),
|
||||
core: new fields.BooleanField({ initial: false })
|
||||
}),
|
||||
{
|
||||
initial: {
|
||||
experience1: { value: 2 },
|
||||
experience2: { value: 2 }
|
||||
experience1: { value: 2, core: true },
|
||||
experience2: { value: 2, core: true }
|
||||
}
|
||||
}
|
||||
),
|
||||
|
|
@ -134,6 +136,23 @@ export default class DhCompanion extends BaseDataActor {
|
|||
}
|
||||
}
|
||||
|
||||
async _preUpdate(changes, options, userId) {
|
||||
const allowed = await super._preUpdate(changes, options, userId);
|
||||
if (allowed === false) return;
|
||||
|
||||
/* The first two experiences are always marked as core */
|
||||
if (changes.system?.experiences && Object.keys(this.experiences).length < 2) {
|
||||
const experiences = new Set(Object.keys(this.experiences));
|
||||
const changeExperiences = new Set(Object.keys(changes.system.experiences));
|
||||
const newExperiences = Array.from(changeExperiences.difference(experiences));
|
||||
|
||||
for (var i = 0; i < Math.min(newExperiences.length, 2 - experiences.size); i++) {
|
||||
const experience = newExperiences[i];
|
||||
changes.system.experiences[experience].core = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async _preDelete() {
|
||||
if (this.partner) {
|
||||
await this.partner.update({ 'system.companion': null });
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
|
|||
if (this.hasTarget) {
|
||||
this.hasHitTarget = this.targets.filter(t => t.hit === true).length > 0;
|
||||
this.currentTargets = this.getTargetList();
|
||||
// this.registerTargetHook();
|
||||
|
||||
if (this.targetMode === true && this.hasRoll) {
|
||||
this.targetShort = this.targets.reduce(
|
||||
|
|
|
|||
|
|
@ -8,4 +8,10 @@ export default class DhCombatant extends foundry.abstract.TypeDataModel {
|
|||
actionTokens: new fields.NumberField({ required: true, integer: true, initial: 3 })
|
||||
};
|
||||
}
|
||||
|
||||
get isDefeated() {
|
||||
const { unconscious, defeated, dead } = CONFIG.DH.GENERAL.conditions;
|
||||
const defeatedConditions = new Set([unconscious.id, defeated.id, dead.id]);
|
||||
return this.defeated || this.actor?.statuses.intersection(defeatedConditions)?.size;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,3 +8,4 @@ export { default as BeastformField } from './beastformField.mjs';
|
|||
export { default as DamageField } from './damageField.mjs';
|
||||
export { default as HealingField } from './healingField.mjs';
|
||||
export { default as RollField } from './rollField.mjs';
|
||||
export { default as MacroField } from './macroField.mjs';
|
||||
|
|
|
|||
7
module/data/fields/action/macroField.mjs
Normal file
7
module/data/fields/action/macroField.mjs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
const fields = foundry.data.fields;
|
||||
|
||||
export default class MacroField extends fields.DocumentUUIDField {
|
||||
constructor(context = {}) {
|
||||
super({ type: "Macro" }, context);
|
||||
}
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ export class ActionField extends foundry.data.fields.ObjectField {
|
|||
getModel(value) {
|
||||
return (
|
||||
game.system.api.models.actions.actionsTypes[value.type] ??
|
||||
game.system.api.models.actions.actionsTypes.attack
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +93,6 @@ export class ActionField extends foundry.data.fields.ObjectField {
|
|||
/** @override */
|
||||
_cleanType(value, options) {
|
||||
if (!(typeof value === 'object')) value = {};
|
||||
|
||||
const cls = this.getModel(value);
|
||||
if (cls) return cls.cleanData(value, options);
|
||||
return value;
|
||||
|
|
|
|||
|
|
@ -144,7 +144,8 @@ export default class DHArmor extends AttachableItem {
|
|||
* @returns {(string | { value: string, icons: string[] })[]} An array of localized strings and damage label objects.
|
||||
*/
|
||||
_getLabels() {
|
||||
const labels = [`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.baseScore}`];
|
||||
const labels = [];
|
||||
if(this.baseScore) labels.push(`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.baseScore}`)
|
||||
return labels;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ export default class DHDomainCard extends BaseDataItem {
|
|||
const tags = [
|
||||
game.i18n.localize(`DAGGERHEART.CONFIG.DomainCardTypes.${this.type}`),
|
||||
this.domainLabel,
|
||||
`${game.i18n.localize('DAGGERHEART.GENERAL.levelShort')}: ${this.level}`,
|
||||
`${game.i18n.localize('DAGGERHEART.ITEMS.DomainCard.recallCost')}: ${this.recallCost}`
|
||||
];
|
||||
|
||||
|
|
@ -88,15 +89,16 @@ export default class DHDomainCard extends BaseDataItem {
|
|||
* @returns {(string | { value: string, icons: string[] })[]} An array of localized strings and damage label objects.
|
||||
*/
|
||||
_getLabels() {
|
||||
const labels = [
|
||||
game.i18n.localize(`DAGGERHEART.CONFIG.DomainCardTypes.${this.type}`),
|
||||
this.domainLabel,
|
||||
{
|
||||
const labels = [];
|
||||
|
||||
if (this.type) labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.DomainCardTypes.${this.type}`));
|
||||
if (this.domainLabel) labels.push(this.domainLabel);
|
||||
if (this.recallCost) {
|
||||
labels.push({
|
||||
value: `${this.recallCost}`, //converts the number to a string
|
||||
icons: ['fa-bolt']
|
||||
}
|
||||
];
|
||||
|
||||
});
|
||||
}
|
||||
return labels;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import AttachableItem from './attachableItem.mjs';
|
||||
import { ActionsField, ActionField } from '../fields/actionField.mjs';
|
||||
import { ActionField } from '../fields/actionField.mjs';
|
||||
|
||||
export default class DHWeapon extends AttachableItem {
|
||||
/** @inheritDoc */
|
||||
|
|
@ -18,12 +18,23 @@ export default class DHWeapon extends AttachableItem {
|
|||
const fields = foundry.data.fields;
|
||||
return {
|
||||
...super.defineSchema(),
|
||||
tier: new fields.NumberField({ required: true, integer: true, initial: 1, min: 1, label: "DAGGERHEART.GENERAL.Tiers.singular" }),
|
||||
tier: new fields.NumberField({
|
||||
required: true,
|
||||
integer: true,
|
||||
initial: 1,
|
||||
min: 1,
|
||||
label: 'DAGGERHEART.GENERAL.Tiers.singular'
|
||||
}),
|
||||
equipped: new fields.BooleanField({ initial: false }),
|
||||
|
||||
//SETTINGS
|
||||
secondary: new fields.BooleanField({ initial: false, label: "DAGGERHEART.ITEMS.Weapon.secondaryWeapon" }),
|
||||
burden: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.burden, initial: 'oneHanded', label: "DAGGERHEART.GENERAL.burden" }),
|
||||
secondary: new fields.BooleanField({ initial: false, label: 'DAGGERHEART.ITEMS.Weapon.secondaryWeapon' }),
|
||||
burden: new fields.StringField({
|
||||
required: true,
|
||||
choices: CONFIG.DH.GENERAL.burden,
|
||||
initial: 'oneHanded',
|
||||
label: 'DAGGERHEART.GENERAL.burden'
|
||||
}),
|
||||
weaponFeatures: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
value: new fields.StringField({
|
||||
|
|
@ -209,26 +220,23 @@ export default class DHWeapon extends AttachableItem {
|
|||
* @returns {(string | { value: string, icons: string[] })[]} An array of localized strings and damage label objects.
|
||||
*/
|
||||
_getLabels() {
|
||||
const labels = [];
|
||||
const { roll, range, damage } = this.attack;
|
||||
|
||||
const labels = [
|
||||
game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${roll.trait}.short`),
|
||||
game.i18n.localize(`DAGGERHEART.CONFIG.Range.${range}.short`)
|
||||
];
|
||||
if (roll.trait) labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${roll.trait}.short`));
|
||||
if (range) labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.Range.${range}.short`));
|
||||
|
||||
for (const { value, type } of damage.parts) {
|
||||
const str = [value.dice];
|
||||
if (value.bonus) str.push(value.bonus.signedString());
|
||||
const str = Roll.replaceFormulaData(value.getFormula(), this.actor?.getRollData() ?? {});
|
||||
|
||||
const icons = Array.from(type)
|
||||
.map(t => CONFIG.DH.GENERAL.damageTypes[t]?.icon)
|
||||
.filter(Boolean);
|
||||
|
||||
const labelValue = str.join('');
|
||||
if (icons.length === 0) {
|
||||
labels.push(labelValue);
|
||||
labels.push(str);
|
||||
} else {
|
||||
labels.push({ value: labelValue, icons });
|
||||
labels.push({ value: str, icons });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -404,7 +404,27 @@ export const defaultCompanionTier = {
|
|||
start: 2,
|
||||
end: 10
|
||||
},
|
||||
initialAchievements: {},
|
||||
initialAchievements: {
|
||||
experience: {
|
||||
nr: 1,
|
||||
modifier: 2
|
||||
}
|
||||
},
|
||||
/* Improved this. Quick solution for companions */
|
||||
extraAchievements: {
|
||||
5: {
|
||||
experience: {
|
||||
nr: 1,
|
||||
modifier: 2
|
||||
}
|
||||
},
|
||||
8: {
|
||||
experience: {
|
||||
nr: 1,
|
||||
modifier: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
availableOptions: 1,
|
||||
domainCardByLevel: 0,
|
||||
options: {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ export class DhLevelup extends foundry.abstract.DataModel {
|
|||
return acc;
|
||||
}, {})
|
||||
: {};
|
||||
|
||||
const domainCards = [...Array(tier.domainCardByLevel).keys()].reduce((acc, _) => {
|
||||
const id = foundry.utils.randomID();
|
||||
acc[id] = { uuid: null, itemUuid: null, level: i };
|
||||
|
|
@ -42,6 +43,20 @@ export class DhLevelup extends foundry.abstract.DataModel {
|
|||
belongingLevels.push(i);
|
||||
}
|
||||
|
||||
/* Improve. Temporary handling for Companion new experiences */
|
||||
Object.keys(tier.extraAchievements ?? {}).forEach(key => {
|
||||
const level = Number(key);
|
||||
if (level >= startLevel && level <= endLevel) {
|
||||
const levelExtras = tier.extraAchievements[level];
|
||||
if (levelExtras.experience) {
|
||||
levels[level].achievements.experiences[foundry.utils.randomID()] = {
|
||||
name: '',
|
||||
modifier: levelExtras.experience.modifier
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
tiers[key] = {
|
||||
name: tier.name,
|
||||
belongingLevels: belongingLevels,
|
||||
|
|
|
|||
|
|
@ -55,6 +55,22 @@ export default class DhAppearance extends foundry.abstract.DataModel {
|
|||
showGenericStatusEffects: new fields.BooleanField({
|
||||
initial: true,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.showGenericStatusEffects.label'
|
||||
}),
|
||||
extendCharacterDescriptions: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.extendCharacterDescriptions.label'
|
||||
}),
|
||||
extendAdversaryDescriptions: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.extendAdversaryDescriptions.label'
|
||||
}),
|
||||
extendEnvironmentDescriptions: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.extendEnvironmentDescriptions.label'
|
||||
}),
|
||||
extendItemDescriptions: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.extendItemDescriptions.label'
|
||||
})
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,36 @@ export default class DhAutomation extends foundry.abstract.DataModel {
|
|||
required: true,
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.playerCanEditSheet.label'
|
||||
}),
|
||||
defeated: new fields.SchemaField({
|
||||
enabled: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.enabled.label'
|
||||
}),
|
||||
overlay: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: true,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.overlay.label'
|
||||
}),
|
||||
characterDefault: new fields.StringField({
|
||||
required: true,
|
||||
choices: CONFIG.DH.GENERAL.defeatedConditions,
|
||||
initial: CONFIG.DH.GENERAL.defeatedConditions.unconscious.id,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.characterDefault.label'
|
||||
}),
|
||||
adversaryDefault: new fields.StringField({
|
||||
required: true,
|
||||
choices: CONFIG.DH.GENERAL.defeatedConditions,
|
||||
initial: CONFIG.DH.GENERAL.defeatedConditions.defeated.id,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.adversaryDefault.label'
|
||||
}),
|
||||
companionDefault: new fields.StringField({
|
||||
required: true,
|
||||
choices: CONFIG.DH.GENERAL.defeatedConditions,
|
||||
initial: CONFIG.DH.GENERAL.defeatedConditions.defeated.id,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.companionDefault.label'
|
||||
})
|
||||
})
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,9 +137,10 @@ export default class DamageRoll extends DHRoll {
|
|||
}
|
||||
|
||||
if (config.isCritical && part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) {
|
||||
const tmpRoll = Roll.fromTerms(part.roll.terms)._evaluateSync({ maximize: true }),
|
||||
criticalBonus = tmpRoll.total - this.constructor.calculateTotalModifiers(tmpRoll);
|
||||
part.roll.terms.push(...this.formatModifier(criticalBonus));
|
||||
const total = part.roll.dice.reduce((acc, term) => acc + term._faces*term._number, 0);
|
||||
if (total > 0) {
|
||||
part.roll.terms.push(...this.formatModifier(total));
|
||||
}
|
||||
}
|
||||
|
||||
/* To Remove When Reaction System */
|
||||
|
|
|
|||
|
|
@ -222,26 +222,27 @@ export const registerRollDiceHooks = () => {
|
|||
)
|
||||
return;
|
||||
|
||||
const actor = await fromUuid(config.source.actor),
|
||||
updates = [];
|
||||
const actor = await fromUuid(config.source.actor);
|
||||
let updates = [];
|
||||
if (!actor) return;
|
||||
if (config.roll.isCritical || config.roll.result.duality === 1) updates.push({ key: 'hope', value: 1 });
|
||||
if (config.roll.isCritical) updates.push({ key: 'stress', value: -1 });
|
||||
if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1 });
|
||||
if (config.roll.isCritical || config.roll.result.duality === 1)
|
||||
updates.push({ key: 'hope', value: 1, total: -1, enabled: true });
|
||||
if (config.roll.isCritical) updates.push({ key: 'stress', value: -1, total: 1, enabled: true });
|
||||
if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1, total: -1, enabled: true });
|
||||
|
||||
if (config.rerolledRoll) {
|
||||
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 });
|
||||
updates.push({ key: 'hope', value: -1, total: 1, enabled: true });
|
||||
if (config.rerolledRoll.isCritical) updates.push({ key: 'stress', value: 1, total: -1, enabled: true });
|
||||
if (config.rerolledRoll.result.duality === -1)
|
||||
updates.push({ key: 'fear', value: -1, total: 1, enabled: true });
|
||||
}
|
||||
|
||||
if (updates.length) {
|
||||
const target = actor.system.partner ?? actor;
|
||||
if (!['dead', 'unconscious'].some(x => actor.statuses.has(x))) {
|
||||
setTimeout(() => {
|
||||
target.modifyResource(updates);
|
||||
}, 50);
|
||||
if (!['dead', 'defeated', 'unconscious'].some(x => actor.statuses.has(x))) {
|
||||
if (config.rerolledRoll) target.modifyResource(updates);
|
||||
else config.costs = [...(config.costs ?? []), ...updates];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -254,5 +255,7 @@ export const registerRollDiceHooks = () => {
|
|||
const currentCombatant = game.combat.combatants.get(game.combat.current?.combatantId);
|
||||
if (currentCombatant?.actorId == actor.id) ui.combat.setCombatantSpotlight(currentCombatant.id);
|
||||
}
|
||||
|
||||
return;
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
|||
|
||||
for (const statusId of this.statuses) {
|
||||
const status = CONFIG.statusEffects.find(s => s.id === statusId);
|
||||
tags.push(game.i18n.localize(status.name));
|
||||
if (status) tags.push(game.i18n.localize(status.name));
|
||||
}
|
||||
|
||||
return tags;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { emitAsGM, GMUpdateEvent } from '../systemRegistration/socket.mjs';
|
|||
import { LevelOptionType } from '../data/levelTier.mjs';
|
||||
import DHFeature from '../data/item/feature.mjs';
|
||||
import { damageKeyToNumber } from '../helpers/utils.mjs';
|
||||
import DhCompanionLevelUp from '../applications/levelup/companionLevelup.mjs';
|
||||
|
||||
export default class DhpActor extends Actor {
|
||||
/**
|
||||
|
|
@ -142,9 +143,6 @@ export default class DhpActor extends Actor {
|
|||
}, {})
|
||||
});
|
||||
this.update(getUpdate());
|
||||
if (this.system.companion) {
|
||||
this.system.companion.update(getUpdate());
|
||||
}
|
||||
}
|
||||
|
||||
if (subclassFeatureState.class) {
|
||||
|
|
@ -195,10 +193,6 @@ export default class DhpActor extends Actor {
|
|||
}
|
||||
});
|
||||
this.sheet.render();
|
||||
|
||||
if (this.system.companion) {
|
||||
this.system.companion.updateLevel(newLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -219,16 +213,6 @@ export default class DhpActor extends Actor {
|
|||
core: true
|
||||
}
|
||||
});
|
||||
|
||||
if (this.system.companion) {
|
||||
await this.system.companion.update({
|
||||
[`system.experiences.${experienceKey}`]: {
|
||||
name: '',
|
||||
value: experience.modifier,
|
||||
core: true
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -405,6 +389,7 @@ export default class DhpActor extends Actor {
|
|||
};
|
||||
}
|
||||
|
||||
const levelChange = this.system.levelData.level.changed - this.system.levelData.level.current;
|
||||
await this.update({
|
||||
system: {
|
||||
levelData: {
|
||||
|
|
@ -417,8 +402,21 @@ export default class DhpActor extends Actor {
|
|||
});
|
||||
this.sheet.render();
|
||||
|
||||
if (this.system.companion) {
|
||||
this.system.companion.updateLevel(this.system.levelData.level.changed);
|
||||
if (this.system.companion && !this.system.companion.system.levelData.canLevelUp) {
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
window: {
|
||||
title: game.i18n.localize('DAGGERHEART.ACTORS.Character.companionLevelup.confirmTitle')
|
||||
},
|
||||
content: game.i18n.format('DAGGERHEART.ACTORS.Character.companionLevelup.confirmText', {
|
||||
name: this.system.companion.name,
|
||||
levelChange: levelChange
|
||||
})
|
||||
});
|
||||
|
||||
if (!confirmed) return;
|
||||
|
||||
await this.system.companion.updateLevel(this.system.companion.system.levelData.level.current + levelChange);
|
||||
new DhCompanionLevelUp(this.system.companion).render({ force: true });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -720,4 +718,21 @@ export default class DhpActor extends Actor {
|
|||
value: 1
|
||||
});
|
||||
}
|
||||
|
||||
async toggleDefeated(defeatedState) {
|
||||
const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).defeated;
|
||||
const { unconscious, defeated, dead } = CONFIG.DH.GENERAL.conditions;
|
||||
const defeatedConditions = new Set([unconscious.id, defeated.id, dead.id]);
|
||||
if (!defeatedState) {
|
||||
for (let defeatedId of defeatedConditions) {
|
||||
await this.toggleStatusEffect(defeatedId, { overlay: settings.overlay, active: defeatedState });
|
||||
}
|
||||
} else {
|
||||
const noDefeatedConditions = this.statuses.intersection(defeatedConditions).size === 0;
|
||||
if (noDefeatedConditions) {
|
||||
const condition = settings[`${this.type}Default`];
|
||||
await this.toggleStatusEffect(condition, { overlay: settings.overlay, active: defeatedState });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
||||
targetHook = null;
|
||||
targetSelection = null;
|
||||
|
||||
async renderHTML() {
|
||||
const actor = game.actors.get(this.speaker.actor);
|
||||
|
|
@ -24,7 +23,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
|||
|
||||
/** @inheritDoc */
|
||||
prepareData() {
|
||||
if (this.isAuthor && this.targetSelection === null) this.targetSelection = this.system.targets?.length > 0;
|
||||
if (this.isAuthor && this.targetSelection === undefined) this.targetSelection = this.system.targets?.length > 0;
|
||||
super.prepareData();
|
||||
}
|
||||
|
||||
|
|
@ -70,9 +69,13 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
|||
}
|
||||
}
|
||||
|
||||
if(!game.user.isGM && !this.isAuthor && !this.speakerActor?.isOwner) {
|
||||
const buttons = html.querySelectorAll(".ability-card-footer > .ability-use-button");
|
||||
buttons.forEach(b => b.remove());
|
||||
if(!game.user.isGM) {
|
||||
const applyButtons = html.querySelector(".apply-buttons");
|
||||
applyButtons?.remove();
|
||||
if(!this.isAuthor && !this.speakerActor?.isOwner) {
|
||||
const buttons = html.querySelectorAll(".ability-card-footer > .ability-use-button");
|
||||
buttons.forEach(b => b.remove());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,4 +72,8 @@ export default class DHToken extends TokenDocument {
|
|||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
_shouldRecordMovementHistory() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,11 +49,11 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
|
|||
const longRest = element.dataset.tooltip?.startsWith('#longRest#');
|
||||
if (shortRest || longRest) {
|
||||
const key = element.dataset.tooltip.slice(shortRest ? 11 : 10);
|
||||
const downtimeOptions = shortRest
|
||||
? CONFIG.DH.GENERAL.defaultRestOptions.shortRest()
|
||||
: CONFIG.DH.GENERAL.defaultRestOptions.longRest();
|
||||
|
||||
const move = downtimeOptions[key];
|
||||
const moves = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).restMoves[
|
||||
element.dataset.restType
|
||||
].moves;
|
||||
const move = moves[key];
|
||||
const description = await TextEditor.enrichHTML(move.description);
|
||||
html = await foundry.applications.handlebars.renderTemplate(
|
||||
`systems/daggerheart/templates/ui/tooltip/downtime.hbs`,
|
||||
|
|
|
|||
|
|
@ -251,13 +251,15 @@ export const adjustRange = (rangeVal, decrease) => {
|
|||
};
|
||||
|
||||
export const updateActorTokens = async (actor, update) => {
|
||||
await actor.prototypeToken.update(update);
|
||||
await actor.prototypeToken.update({ ...update });
|
||||
|
||||
/* Update the tokens in all scenes belonging to Actor */
|
||||
for (let token of actor.getDependentTokens()) {
|
||||
const tokenActor = token.baseActor ?? token.actor;
|
||||
if (tokenActor?.id === actor.id) {
|
||||
await token.update(update);
|
||||
await token.update({
|
||||
...update
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -341,7 +343,7 @@ export const itemAbleRollParse = (value, actor, item) => {
|
|||
const model = isItemTarget ? item : actor;
|
||||
|
||||
try {
|
||||
return Roll.replaceFormulaData(slicedValue, model?.getRollData?.() ?? model);
|
||||
return Roll.replaceFormulaData(slicedValue, isItemTarget || !model?.getRollData ? model : model.getRollData());
|
||||
} catch (_) {
|
||||
return '';
|
||||
}
|
||||
|
|
@ -370,7 +372,7 @@ export function getScrollTextData(resources, resource, key) {
|
|||
|
||||
export function createScrollText(actor, optionsData) {
|
||||
if (actor && optionsData?.length) {
|
||||
actor.getDependentTokens().forEach(token => {
|
||||
actor.getActiveTokens().forEach(token => {
|
||||
optionsData.forEach(data => {
|
||||
const { text, ...options } = data;
|
||||
canvas.interface.createScrollingText(token.getCenterPoint(), data.text, {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,8 @@ export const preloadHandlebarsTemplates = async function () {
|
|||
'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs',
|
||||
'systems/daggerheart/templates/ui/combatTracker/combatTrackerSection.hbs',
|
||||
'systems/daggerheart/templates/actionTypes/damage.hbs',
|
||||
'systems/daggerheart/templates/actionTypes/healing.hbs',
|
||||
'systems/daggerheart/templates/actionTypes/resource.hbs',
|
||||
'systems/daggerheart/templates/actionTypes/uuid.hbs',
|
||||
'systems/daggerheart/templates/actionTypes/macro.hbs',
|
||||
'systems/daggerheart/templates/actionTypes/uses.hbs',
|
||||
'systems/daggerheart/templates/actionTypes/roll.hbs',
|
||||
'systems/daggerheart/templates/actionTypes/save.hbs',
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@
|
|||
},
|
||||
"_id": "TCKVaVweyJzhEArX",
|
||||
"systemPath": "actions",
|
||||
"type": "",
|
||||
"type": "attack",
|
||||
"description": "",
|
||||
"img": "icons/creatures/claws/claw-curved-jagged-yellow.webp",
|
||||
"chatDisplay": true,
|
||||
|
|
@ -708,4 +708,4 @@
|
|||
"_id": "89yAh30vaNQOALlz",
|
||||
"sort": 500000,
|
||||
"_key": "!actors!89yAh30vaNQOALlz"
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -768,4 +769,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!G7jiltRjgvVhZewm"
|
||||
}
|
||||
}
|
||||
|
|
@ -102,7 +102,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/weapons/daggers/dagger-bone-black.webp"
|
||||
"img": "icons/weapons/daggers/dagger-bone-black.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -319,4 +320,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!vNIbYQ4YSzNf0WPE"
|
||||
}
|
||||
}
|
||||
|
|
@ -114,7 +114,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/magic/unholy/beam-ringed-impact-purple.webp"
|
||||
"img": "icons/magic/unholy/beam-ringed-impact-purple.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -817,4 +818,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!WPEOIGfclNJxWb87"
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/weapons/bows/longbow-recurve-leather-brown.webp"
|
||||
"img": "icons/weapons/bows/longbow-recurve-leather-brown.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -393,4 +394,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!JRhrrEg5UroURiAD"
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,8 @@
|
|||
"roll": {
|
||||
"bonus": 0,
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -514,4 +515,4 @@
|
|||
}
|
||||
],
|
||||
"_key": "!actors!0ts6CGd93lLqGZI5"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -528,4 +529,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!h5RuhzGL17dW5FBT"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"range": ""
|
||||
"range": "",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -1284,4 +1285,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!dgH3fW9FTYLaIDvS"
|
||||
}
|
||||
}
|
||||
|
|
@ -111,7 +111,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/creatures/claws/claw-straight-brown.webp"
|
||||
"img": "icons/creatures/claws/claw-straight-brown.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -467,4 +468,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!71qKDLKO3CsrNkdy"
|
||||
}
|
||||
}
|
||||
|
|
@ -107,7 +107,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -441,4 +442,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!B4LZcGuBAHzyVdzy"
|
||||
}
|
||||
}
|
||||
|
|
@ -112,7 +112,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/skills/melee/unarmed-punch-fist-yellow-red.webp"
|
||||
"img": "icons/skills/melee/unarmed-punch-fist-yellow-red.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -526,4 +527,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!2UeZ0tEe7AzgSJNd"
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,8 @@
|
|||
]
|
||||
},
|
||||
"name": "Club",
|
||||
"img": "icons/weapons/clubs/club-banded-barbed-black.webp"
|
||||
"img": "icons/weapons/clubs/club-banded-barbed-black.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -598,4 +599,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!8Zkqk1jU09nKL2fy"
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/magic/light/beam-rays-magenta.webp"
|
||||
"img": "icons/magic/light/beam-rays-magenta.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -561,4 +562,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!jDmHqGvzg5wjgmxE"
|
||||
}
|
||||
}
|
||||
|
|
@ -96,7 +96,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -313,4 +314,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!99TqczuQipBmaB8i"
|
||||
}
|
||||
}
|
||||
|
|
@ -102,7 +102,8 @@
|
|||
]
|
||||
},
|
||||
"name": "Fist Slam",
|
||||
"img": "icons/skills/melee/unarmed-punch-fist-yellow-red.webp"
|
||||
"img": "icons/skills/melee/unarmed-punch-fist-yellow-red.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -631,4 +632,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!uOP5oT9QzXPlnf3p"
|
||||
}
|
||||
}
|
||||
|
|
@ -113,7 +113,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/weapons/daggers/dagger-straight-cracked.webp"
|
||||
"img": "icons/weapons/daggers/dagger-straight-cracked.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -379,4 +380,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!ZxWaWPdzFIUPNC62"
|
||||
}
|
||||
}
|
||||
|
|
@ -107,7 +107,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/weapons/daggers/dagger-twin-green.webp"
|
||||
"img": "icons/weapons/daggers/dagger-twin-green.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -459,4 +460,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!CBBuEXAlLKFMJdjg"
|
||||
}
|
||||
}
|
||||
|
|
@ -114,7 +114,8 @@
|
|||
]
|
||||
},
|
||||
"range": "far",
|
||||
"img": "icons/weapons/staves/staff-ornate-purple.webp"
|
||||
"img": "icons/weapons/staves/staff-ornate-purple.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -723,4 +724,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!0NxCSugvKQ4W8OYZ"
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"range": ""
|
||||
"range": "",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -453,4 +454,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!tyBOpLfigAhI9bU3"
|
||||
}
|
||||
}
|
||||
|
|
@ -95,7 +95,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -312,4 +313,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!zx99sOGTXicP4SSD"
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/magic/nature/root-vines-grow-brown.webp"
|
||||
"img": "icons/magic/nature/root-vines-grow-brown.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -473,4 +474,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!9x2xY9zwc3xzbXo5"
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -384,4 +385,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!pnyjIGxxvurcWmTv"
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -502,4 +503,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!kE4dfhqmIQpNd44e"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -654,4 +655,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!2VN3BftageoTTIzu"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/magic/symbols/rune-sigil-rough-white-teal.webp"
|
||||
"img": "icons/magic/symbols/rune-sigil-rough-white-teal.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -439,4 +440,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!SxSOkM4bcVOFyjbo"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -474,4 +475,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!5lphJAgzoqZI3VoG"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
"bonus": 0,
|
||||
"type": "attack"
|
||||
},
|
||||
"range": ""
|
||||
"range": "",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -421,4 +422,4 @@
|
|||
}
|
||||
],
|
||||
"_key": "!actors!NoRZ1PqB8N5wcIw0"
|
||||
}
|
||||
}
|
||||
|
|
@ -107,7 +107,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/creatures/claws/claw-hooked-curved.webp"
|
||||
"img": "icons/creatures/claws/claw-hooked-curved.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -512,4 +513,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!tBWHW00epmMnkawe"
|
||||
}
|
||||
}
|
||||
|
|
@ -107,7 +107,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/creatures/claws/claw-straight-brown.webp"
|
||||
"img": "icons/creatures/claws/claw-straight-brown.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -499,4 +500,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!wNzeuQLfLUMvgHlQ"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -568,4 +569,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!wR7cFKrHvRzbzhBT"
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,8 @@
|
|||
"bonus": 0,
|
||||
"type": "attack"
|
||||
},
|
||||
"range": ""
|
||||
"range": "",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -411,4 +412,4 @@
|
|||
}
|
||||
],
|
||||
"_key": "!actors!TLzY1nDw0Bu9Ud40"
|
||||
}
|
||||
}
|
||||
|
|
@ -96,7 +96,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -313,4 +314,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!P7h54ZePFPHpYwvB"
|
||||
}
|
||||
}
|
||||
|
|
@ -87,7 +87,7 @@
|
|||
"img": "icons/weapons/polearms/spear-flared-steel.webp",
|
||||
"_id": "jmrgFi8AUL6LTbtU",
|
||||
"systemPath": "actions",
|
||||
"type": "",
|
||||
"type": "attack",
|
||||
"description": "",
|
||||
"chatDisplay": true,
|
||||
"actionType": "action",
|
||||
|
|
@ -435,4 +435,4 @@
|
|||
"_id": "bfhVWMBUh61b9J6n",
|
||||
"sort": 0,
|
||||
"_key": "!actors!bfhVWMBUh61b9J6n"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
]
|
||||
},
|
||||
"img": "icons/creatures/claws/claw-hooked-barbed.webp",
|
||||
"range": ""
|
||||
"range": "",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -411,4 +412,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!ChwwVqowFw8hJQwT"
|
||||
}
|
||||
}
|
||||
|
|
@ -96,7 +96,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -399,4 +400,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!OsLG2BjaEdTZUJU9"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/weapons/staves/staff-animal-skull-bull.webp"
|
||||
"img": "icons/weapons/staves/staff-animal-skull-bull.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -646,4 +647,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!PELRry1vqjBzSAlr"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -452,4 +453,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!8VZIgU12cB3cvlyH"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -484,4 +485,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!YnObCleGjPT7yqEc"
|
||||
}
|
||||
}
|
||||
|
|
@ -87,7 +87,7 @@
|
|||
"img": "icons/creatures/claws/claw-talons-glowing-orange.webp",
|
||||
"_id": "W2KpXQNCg6Nnorbz",
|
||||
"systemPath": "actions",
|
||||
"type": "",
|
||||
"type": "attack",
|
||||
"description": "",
|
||||
"chatDisplay": true,
|
||||
"actionType": "action",
|
||||
|
|
@ -745,4 +745,4 @@
|
|||
"_id": "OMQ0v6PE8s1mSU0K",
|
||||
"sort": 900000,
|
||||
"_key": "!actors!OMQ0v6PE8s1mSU0K"
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,8 @@
|
|||
"bonus": -2,
|
||||
"type": "attack"
|
||||
},
|
||||
"range": ""
|
||||
"range": "",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -453,4 +454,4 @@
|
|||
}
|
||||
],
|
||||
"_key": "!actors!IIWV4ysJPFPnTP7W"
|
||||
}
|
||||
}
|
||||
|
|
@ -100,7 +100,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -343,4 +344,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!4PfLnaCrOcMdb4dK"
|
||||
}
|
||||
}
|
||||
|
|
@ -96,7 +96,8 @@
|
|||
"roll": {
|
||||
"bonus": 1,
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -313,4 +314,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!5s8wSvpyC5rxY5aD"
|
||||
}
|
||||
}
|
||||
|
|
@ -107,7 +107,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -535,4 +536,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!fmfntuJ8mHRCAktP"
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -658,4 +659,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!8KWVLWXFhlY2kYx0"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/weapons/bows/shortbow-recurve-yellow.webp"
|
||||
"img": "icons/weapons/bows/shortbow-recurve-yellow.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -621,4 +622,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!8mJYMpbLTb8qIOrr"
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -632,4 +633,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!dsfB3YhoL5SudvS2"
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -600,4 +601,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!xIICT6tEdnA7dKDV"
|
||||
}
|
||||
}
|
||||
|
|
@ -107,7 +107,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/creatures/slimes/slime-movement-dripping-pseudopods-green.webp"
|
||||
"img": "icons/creatures/slimes/slime-movement-dripping-pseudopods-green.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -601,4 +602,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!SHXedd9zZPVfUgUa"
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -371,4 +372,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!kabueAo6BALApWqp"
|
||||
}
|
||||
}
|
||||
|
|
@ -95,7 +95,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/skills/melee/sword-shield-stylized-white.webp"
|
||||
"img": "icons/skills/melee/sword-shield-stylized-white.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -376,4 +377,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!VENwg7xEFcYObjmT"
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/weapons/polearms/spear-hooked-rounded.webp"
|
||||
"img": "icons/weapons/polearms/spear-hooked-rounded.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -378,4 +379,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!uRtghKE9mHlII4rs"
|
||||
}
|
||||
}
|
||||
|
|
@ -111,7 +111,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -388,4 +389,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!mK3A5FTx6k8iPU3F"
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -665,4 +666,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!i2UNbRvgyoSs07M6"
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/skills/melee/strike-blade-hooked-orange-blue.webp"
|
||||
"img": "icons/skills/melee/strike-blade-hooked-orange-blue.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -611,4 +612,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!r1mbfSSwKWdcFdAU"
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -572,4 +573,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!6hbqmxDXFOzZJDk4"
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -602,4 +603,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!MI126iMOOobQ1Obn"
|
||||
}
|
||||
}
|
||||
|
|
@ -107,7 +107,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"img": "icons/weapons/daggers/dagger-twin-green.webp"
|
||||
"img": "icons/weapons/daggers/dagger-twin-green.webp",
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -349,4 +350,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!5Lh1T0zaT8Pkr2U2"
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,8 @@
|
|||
"base": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "attack"
|
||||
}
|
||||
},
|
||||
"flags": {},
|
||||
|
|
@ -443,4 +444,4 @@
|
|||
],
|
||||
"effects": [],
|
||||
"_key": "!actors!MbBPIOxaxXYNApXz"
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue