mirror of
https://github.com/fzumpe/foundry-dnd5e-adaptive-resistances.git
synced 2026-06-06 21:10:02 +02:00
added non-profane and all damage resistance and immunity features and skip if damage has vulnerability
This commit is contained in:
parent
54a201d4b1
commit
727606f480
10
lang/de.json
10
lang/de.json
@ -70,5 +70,13 @@
|
||||
"ADR.Features.Single.slashing.Name": "Adaptive Resistenz: Hieb",
|
||||
"ADR.Features.Single.slashing.Description": "Das Wesen passt sich an Hiebschaden an, sobald dieser tatsächlich durch seine Abwehr dringt.",
|
||||
"ADR.Features.Single.thunder.Name": "Adaptive Resistenz: Donner",
|
||||
"ADR.Features.Single.thunder.Description": "Das Wesen passt sich an Donnerschaden an, sobald dieser tatsächlich durch seine Abwehr dringt."
|
||||
"ADR.Features.Single.thunder.Description": "Das Wesen passt sich an Donnerschaden an, sobald dieser tatsächlich durch seine Abwehr dringt.",
|
||||
"ADR.Features.Set.NonProfane.Name": "Nicht-Profan",
|
||||
"ADR.Features.Set.NonProfane.Description": "Das Wesen passt sich an Schaden an, der nicht aus einfacher körperlicher Gewalt entsteht: Säure, Kälte, Feuer, Energie, Blitz, nekrotisch, Gift, psychisch, gleißend und Donner.",
|
||||
"ADR.Features.Set.All.Name": "Alle Schadensarten",
|
||||
"ADR.Features.Set.All.Description": "Das Wesen passt sich an jede registrierte dnd5e-Schadensart an, sofern der Schaden tatsächlich durch seine Abwehr dringt.",
|
||||
"ADR.Features.NonProfane.Name": "Adaptive Resistenz: Nicht-Profan",
|
||||
"ADR.Features.NonProfane.Description": "Das Wesen passt sich an Schaden an, der nicht aus einfacher körperlicher Gewalt entsteht: Säure, Kälte, Feuer, Energie, Blitz, nekrotisch, Gift, psychisch, gleißend und Donner.",
|
||||
"ADR.Features.All.Name": "Adaptive Resistenz: Alle Schadensarten",
|
||||
"ADR.Features.All.Description": "Das Wesen passt sich an jede registrierte dnd5e-Schadensart an, sofern der Schaden tatsächlich durch seine Abwehr dringt."
|
||||
}
|
||||
|
||||
10
lang/en.json
10
lang/en.json
@ -70,5 +70,13 @@
|
||||
"ADR.Features.Single.slashing.Name": "Adaptive Resistance: Slashing",
|
||||
"ADR.Features.Single.slashing.Description": "The creature adapts to slashing damage once it truly pierces its defenses.",
|
||||
"ADR.Features.Single.thunder.Name": "Adaptive Resistance: Thunder",
|
||||
"ADR.Features.Single.thunder.Description": "The creature adapts to thunder damage once it truly pierces its defenses."
|
||||
"ADR.Features.Single.thunder.Description": "The creature adapts to thunder damage once it truly pierces its defenses.",
|
||||
"ADR.Features.Set.NonProfane.Name": "Non-Profane",
|
||||
"ADR.Features.Set.NonProfane.Description": "The creature adapts to damage that is not simple bodily violence: acid, cold, fire, force, lightning, necrotic, poison, psychic, radiant, and thunder.",
|
||||
"ADR.Features.Set.All.Name": "All Damage",
|
||||
"ADR.Features.Set.All.Description": "The creature adapts to any registered dnd5e damage type as long as the damage truly pierces its defenses.",
|
||||
"ADR.Features.NonProfane.Name": "Adaptive Resistance: Non-Profane",
|
||||
"ADR.Features.NonProfane.Description": "The creature adapts to damage that is not simple bodily violence: acid, cold, fire, force, lightning, necrotic, poison, psychic, radiant, and thunder.",
|
||||
"ADR.Features.All.Name": "Adaptive Resistance: All Damage",
|
||||
"ADR.Features.All.Description": "The creature adapts to any registered dnd5e damage type as long as the damage truly pierces its defenses."
|
||||
}
|
||||
|
||||
@ -4,6 +4,9 @@ export const PACK_ID = `${MODULE_ID}.${PACK_NAME}`;
|
||||
export const FEATURE_FLAG = "adaptiveResistanceFeature";
|
||||
export const EFFECT_FLAG = "adaptiveResistanceEffect";
|
||||
|
||||
export const PROFANE_DAMAGE_TYPES = Object.freeze(["bludgeoning", "piercing", "slashing"]);
|
||||
export const PROFANE_BYPASSES = Object.freeze(["ada", "mgc", "sil"]);
|
||||
|
||||
export const ADAPTATION_TYPES = Object.freeze({
|
||||
RESISTANCE: "resistance",
|
||||
IMMUNITY: "immunity"
|
||||
@ -65,6 +68,18 @@ export const DAMAGE_SETS = Object.freeze({
|
||||
descriptionKey: "ADR.Features.Set.Profane.Description",
|
||||
damageTypes: ["bludgeoning", "piercing", "slashing"]
|
||||
},
|
||||
nonProfane: {
|
||||
id: "nonProfane",
|
||||
nameKey: "ADR.Features.Set.NonProfane.Name",
|
||||
descriptionKey: "ADR.Features.Set.NonProfane.Description",
|
||||
damageTypes: ["acid", "cold", "fire", "force", "lightning", "necrotic", "poison", "psychic", "radiant", "thunder"]
|
||||
},
|
||||
all: {
|
||||
id: "all",
|
||||
nameKey: "ADR.Features.Set.All.Name",
|
||||
descriptionKey: "ADR.Features.Set.All.Description",
|
||||
damageTypes: ["acid", "bludgeoning", "cold", "fire", "force", "lightning", "necrotic", "piercing", "poison", "psychic", "radiant", "slashing", "thunder"]
|
||||
},
|
||||
acid: {
|
||||
id: "acid",
|
||||
nameKey: "ADR.Features.Set.Single.acid.Name",
|
||||
|
||||
44
scripts/effects.js
vendored
44
scripts/effects.js
vendored
@ -1,4 +1,11 @@
|
||||
import { MODULE_ID, EFFECT_FLAG, ADAPTATION_CONFIG, ADAPTATION_TYPES } from "./constants.js";
|
||||
import {
|
||||
MODULE_ID,
|
||||
EFFECT_FLAG,
|
||||
ADAPTATION_CONFIG,
|
||||
ADAPTATION_TYPES,
|
||||
PROFANE_DAMAGE_TYPES,
|
||||
PROFANE_BYPASSES
|
||||
} from "./constants.js";
|
||||
import { getDamageTypeLabel } from "./utils.js";
|
||||
|
||||
export async function removeOldAdaptiveEffects(actor) {
|
||||
@ -8,6 +15,32 @@ export async function removeOldAdaptiveEffects(actor) {
|
||||
await actor.deleteEmbeddedDocuments("ActiveEffect", oldEffects.map(effect => effect.id));
|
||||
}
|
||||
|
||||
function getAdaptiveChanges(config, damageType) {
|
||||
const changes = [
|
||||
{
|
||||
key: config.traitKey,
|
||||
mode: CONST.ACTIVE_EFFECT_MODES.ADD,
|
||||
value: damageType,
|
||||
priority: 20
|
||||
}
|
||||
];
|
||||
|
||||
if (PROFANE_DAMAGE_TYPES.includes(damageType)) {
|
||||
const bypassKey = config.traitKey.replace(/\.value$/, ".bypasses");
|
||||
|
||||
for (const bypass of PROFANE_BYPASSES) {
|
||||
changes.push({
|
||||
key: bypassKey,
|
||||
mode: CONST.ACTIVE_EFFECT_MODES.ADD,
|
||||
value: bypass,
|
||||
priority: 20
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
export async function createAdaptiveEffect(actor, damageType, adaptationType = ADAPTATION_TYPES.RESISTANCE) {
|
||||
const config = ADAPTATION_CONFIG[adaptationType] ?? ADAPTATION_CONFIG[ADAPTATION_TYPES.RESISTANCE];
|
||||
const label = getDamageTypeLabel(damageType);
|
||||
@ -26,14 +59,7 @@ export async function createAdaptiveEffect(actor, damageType, adaptationType = A
|
||||
}
|
||||
}
|
||||
},
|
||||
changes: [
|
||||
{
|
||||
key: config.traitKey,
|
||||
mode: CONST.ACTIVE_EFFECT_MODES.ADD,
|
||||
value: damageType,
|
||||
priority: 20
|
||||
}
|
||||
]
|
||||
changes: getAdaptiveChanges(config, damageType)
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
@ -37,6 +37,14 @@ const ENGLISH_SET_TEXT = Object.freeze({
|
||||
name: "Profane",
|
||||
description: "The creature adapts to bodily violence from bludgeoning, piercing, and slashing harm. This follows the dnd5e damage types and does not reliably distinguish magical from nonmagical weapons."
|
||||
},
|
||||
nonProfane: {
|
||||
name: "Non-Profane",
|
||||
description: "The creature adapts to damage that is not simple bodily violence: acid, cold, fire, force, lightning, necrotic, poison, psychic, radiant, and thunder."
|
||||
},
|
||||
all: {
|
||||
name: "All Damage",
|
||||
description: "The creature adapts to any registered dnd5e damage type as long as the damage truly pierces its defenses."
|
||||
},
|
||||
acid: {
|
||||
name: "Acid",
|
||||
description: "The creature adapts to acid damage once it truly pierces its defenses."
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { MODULE_ID } from "./constants.js";
|
||||
import {
|
||||
actorAlreadyProtected,
|
||||
actorVulnerableTo,
|
||||
getAdaptiveFeatureItems,
|
||||
getCandidatesForActor,
|
||||
getDominantDamageCandidate,
|
||||
@ -32,6 +33,15 @@ Hooks.on("dnd5e.preCalculateDamage", (actor, damages, options = {}) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const vulnerable = candidates.some(candidate => actorVulnerableTo(actor, candidate.type));
|
||||
if (vulnerable) {
|
||||
storeDamageSelection(options, {
|
||||
skip: true,
|
||||
reason: "damage-has-vulnerability"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const candidate = getDominantDamageCandidate(candidates);
|
||||
if (!candidate?.type || !candidate?.adaptationType) return;
|
||||
|
||||
|
||||
@ -62,6 +62,14 @@ export function actorImmunityValues(actor) {
|
||||
return toArrayValue(actor?.system?.traits?.di?.value);
|
||||
}
|
||||
|
||||
export function actorVulnerabilityValues(actor) {
|
||||
return toArrayValue(actor?.system?.traits?.dv?.value);
|
||||
}
|
||||
|
||||
export function actorVulnerableTo(actor, damageType) {
|
||||
return actorVulnerabilityValues(actor).includes(damageType);
|
||||
}
|
||||
|
||||
export function actorAlreadyResists(actor, damageType) {
|
||||
return actorResistanceValues(actor).includes(damageType);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user