Sync 621 missing item-effect scripts from FR and translate to German

scripts/ was missing 621 of FR's 2114 effect scripts (referenced via
game.wfrp4e.config.effectScripts by Foundry item id). Copied them all
over so the registry is complete, then translated the 129 that still
contained French user-facing text: skill/talent/trapping name arrays
in NPC-statblock-building scripts, chat/notification messages, and
dialog prompts. Skill/talent/trait names were cross-checked against
the already-translated core compendium rather than translated ad hoc,
since Foundry looks these up by exact document name.

Also fixed real bugs found along the way (present in FR's originals
too, just inherited via the copy):
- Two "let x / let x" duplicate-declaration scripts (SyntaxError)
- A "0rgs.actor" typo (ReferenceError) for "args.actor"
- Two "effet.update(...)" typos for "effect.update(...)"
- A corrupted ui.notifications.warn(...) template literal in 3 of the
  NPC-statblock scripts, mangled into stray leftover code text
- 19 scripts across the whole scripts/ folder (not just the 621) using
  the wrong game.i18n.localize() key (NAME.Résistance/Démoniaque/
  Mort-vivant instead of the actual English key names NAME.Endurance/
  Daemonic/Undead), which silently failed to resolve in any language

Rebuilt modules/loadScripts.js via `npm run build` (2114 scripts).

Known follow-up (out of scope here, pre-existing in the scripts DE
already had before this sync): 7 scripts elsewhere in scripts/ have
unrelated syntax bugs, and one has a lingering French accent.
This commit is contained in:
2026-07-20 23:43:47 +02:00
parent d542e1fdab
commit a7f30267fd
659 changed files with 5275 additions and 73 deletions
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
if (args.test.result.misfire && args.test.result.roll !== 100) {
delete args.test.result.misfire
}
+1 -1
View File
@@ -18,5 +18,5 @@ if (spellsWithLore.length > 0)
}
else
{
ui.notifications.notify(`Could not find ${lore} spell. Try Again`)
ui.notifications.notify(`${lore} nicht gefunden spell. Try Again`)
}
+4
View File
@@ -0,0 +1,4 @@
if ( args.actor.has(game.i18n.localize("NAME.AA"), "talent") ||
args.actor.has(game.i18n.localize("NAME.SecondSight"), "talent") ) {
args.modifiers.other.push({label : this.effect.name, value : 5, details : "Das Ziel besitzt Ätherharmonisierung oder Zweites Gesicht"});
}
+1
View File
@@ -0,0 +1 @@
return args.characteristic != "int" || args.type != "characteristic"
+4
View File
@@ -0,0 +1,4 @@
if (!this.item.system.properties.qualities.fast)
this.item.system.qualities.value.push({name : 'fast'});
if (!this.item.system.properties.qualities.magical)
this.item.system.qualities.value.push({name : 'magical'});
+1
View File
@@ -0,0 +1 @@
return args.skill?.name !== game.i18n.localize("NAME.Cool") && args.skill?.name !== game.i18n.localize("NAME.Endurance");
+1
View File
@@ -0,0 +1 @@
this.item.update({"system.AP" : {lArm : 0, rArm : 0, lLeg : 0, rLeg: 0}});
+3
View File
@@ -0,0 +1,3 @@
let wounds = this.effect.sourceActor.system.characteristics.wp.bonus;
this.actor.modifyWounds(wounds);
this.script.message(`Soigne ${wounds} Blessures`);
+1
View File
@@ -0,0 +1 @@
this.item.system.encumbrance.value = Math.max(0, this.item.system.encumbrance.value - 1)
+1
View File
@@ -0,0 +1 @@
if (!this.actor.has(game.i18n.localize("NAME.SecondSight"),"talent")) this.actor.addEffectItems("Compendium.wfrp4e-core.items.Item.OEjUvJKi0xmBwbS2", this.effect)
+5
View File
@@ -0,0 +1,5 @@
let fearCounter = this.item.effects.filter(i => i.name == this.effect.name).length;
fearCounter += Number(this.actor.has("Peur")?.system.specification.value) || 0
game.wfrp4e.utility.postPeur(fearCounter || 1, this.effect.name)
+1
View File
@@ -0,0 +1 @@
return args.item?.system?.attackType == "ranged" && !this.actor.system.canFly.effects.filter(e => e.name == "Flying")[0].disabled
+3
View File
@@ -0,0 +1,3 @@
let species = await ValueDialog.create({text : "Zielspezies eingeben (Singular)", title : this.effect.name})
this.effect.updateSource({name : this.effect.setSpecifier(species)});
+7
View File
@@ -0,0 +1,7 @@
let value = await ValueDialog.create({
title : this.script.label,
text: "Sieges-Notizen für das Erfahrungs-Journal"
});
value
? this.actor.system.awardExp(50, value)
: this.actor.system.awardExp(50, this.script.label)
+4
View File
@@ -0,0 +1,4 @@
if (args.test.options.doomboltRolled)
{
args.test.result.damage += 4;
}
+18
View File
@@ -0,0 +1,18 @@
let melee = ["Compendium.wfrp4e-core.items.Item.4MJJCiOKPkBByYwW", "Compendium.wfrp4e-core.items.Item.RWJrupj9seau0w31", "Compendium.wfrp4e-core.items.Item.jt0DmVK9IiF6Sd2h"];
let ranged = ["Compendium.wfrp4e-core.items.Item.5eDd6iFeR9G6cCfz", "Compendium.wfrp4e-core.items.Item.jrYW2OyDHd1Md2my", "Compendium.wfrp4e-core.items.Item.cygaI9gq4BQJvbB5"];
if (args.equipped)
{
if (this.item.system.isMelee)
{
this.actor.addEffectItems(melee, this.effect);
}
else
{
this.actor.addEffectItems(ranged, this.effect);
}
}
else
{
this.effect.deleteCreatedItems();
}
+18
View File
@@ -0,0 +1,18 @@
const balanced = game.i18n.localize("WFRP4E.YenluiBalanced");
const light = game.i18n.localize("WFRP4E.YenluiLight");
const dark = game.i18n.localize("WFRP4E.YenluiDark");
let newName, newDescription;
if (this.effect.name === game.i18n.localize("WFRP4E.YenluiDark")) {
newName = game.i18n.localize("WFRP4E.YenluiBalanced");
newDescription = game.i18n.localize("WFRP4E.YenluiBalancedDesc");
} else if (this.effect.name === game.i18n.localize("WFRP4E.YenluiBalanced")) {
newName = game.i18n.localize("WFRP4E.YenluiLight");
newDescription = game.i18n.localize("WFRP4E.YenluiLightDesc");
}
if (newName) {
await this.effect.update({name: newName});
await this.item.update({name: newName, "system.description.value": newDescription});
}
+5
View File
@@ -0,0 +1,5 @@
let property = this.effect.getFlag("wfrp4e", "property");
if (property && !this.item.system.flaws.value.find(i => i.name == property));
{
this.item.system.flaws.value.push({name : property});
}
+21
View File
@@ -0,0 +1,21 @@
let damage = await new Roll("1d10").roll();
damage.toMessage(this.script.getChatData());
this.actor.applyDamage(damage.total, {
damageType: game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL,
createMessage: this.script.getChatData()
});
const test = await this.actor.setupSkill(
game.i18n.localize("NAME.Endurance"),
{
fields: {difficulty: "average"},
skipTargets: true,
appendTitle: `${this.effect.name}`,
},
);
await test.roll();
if (test.failed)
{
this.actor.addCondition("stunned");
}
+1 -1
View File
@@ -30,7 +30,7 @@
}
else
{
ui.notifications.warn(`Could not find ${talent}`, {permanent : true})
ui.notifications.warn(`${talent} nicht gefunden`, {permanent : true})
}
}
+2 -2
View File
@@ -62,7 +62,7 @@ for (let talent of talents)
}
else
{
ui.notifications.warn(`Impossible de trouver ${talent}`, {permanent : true})
ui.notifications.warn(`${talent} nicht gefunden`, {permanent : true})
}
}
@@ -79,7 +79,7 @@ for (let trapping of trappings)
}
else
{
ui.notifications.warn(`Impossible de trouver ${trapping}`, {permanent : true})
ui.notifications.warn(`${trapping} nicht gefunden`, {permanent : true})
}
}
+10
View File
@@ -0,0 +1,10 @@
if (args.equipped === true && this.actor.name !== "Kurgorn Three-eyes")
{
this.actor.addCondition("blinded", 1, {"statuses" : ["blinded", "blind"]})
this.script.notification(`Geblendet durch das Tragen von ${this.item.name}`);
}
if (args.equipped === false && this.actor.name !== "Kurgorn Three-eyes")
{
this.actor.removeCondition("blinded")
}
+1
View File
@@ -0,0 +1 @@
this.actor.addEffectItems("Compendium.wfrp4e-core.items.Item.eowbsW6oHGSNJmxV", this.effect)
+8
View File
@@ -0,0 +1,8 @@
let effects = this.item.effects.contents.filter(i => i.id != this.effect.id);
let choice = await ItemDialog.create(effects, 1, {title : this.effect.name, text: "Choisissez une Rune"});
if (choice[0])
{
choice[0].performEffectApplication();
}
+3
View File
@@ -0,0 +1,3 @@
const qualities = foundry.utils.deepClone(args.item.system.qualities.value);
qualities.push({name:"fine", value: 1});
args.item?.update({"system.qualities.value": qualities});
+8
View File
@@ -0,0 +1,8 @@
if ( args.totalWoundLoss > 0 ) {
let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {difficulty: "average"})
await test.roll();
if (!test.succeeded)
{
this.actor.addSystemEffect("gangrene");
}
}
+4
View File
@@ -0,0 +1,4 @@
let fear = await fromUuid("Compendium.wfrp4e-core.items.Item.pTorrE0l3VybAbtn")
fear = fear.toObject();
fear.system.specification.value = 1;
await this.actor.createEmbeddedDocuments("Item", [fear], {fromEffect : this.effect.id})
+6
View File
@@ -0,0 +1,6 @@
if (args.test.result.castOutcome == "success" && args.test.spell.system.lore.value.includes("high"))
{
this.effect.update({name: this.effect.setSpecifier(parseInt(this.effect.specifier - 1))})
this.script.message("La valeur de Protection est maintenant de " + (this.effect.specifier - 1), {flavor: this.effect.sourceItem.name})
}
+1
View File
@@ -0,0 +1 @@
if (!this.item.system.properties.qualities.pummel) this.item.system.qualities.value.push({name : 'pummel'});if (!this.item.system.properties.qualities.hack) this.item.system.qualities.value.push({name : 'hack'})
+1
View File
@@ -0,0 +1 @@
return game.messages.get(args.context.dispel)?.system.test.spell.system.magicMissile.value;
+6
View File
@@ -0,0 +1,6 @@
let broken = this.actor.hasCondition("broken");
if (broken) {
broken.delete();
this.script.notification("Zustand Gebrochen entfernt.");
}
+6
View File
@@ -0,0 +1,6 @@
let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {difficulty: "hard"})
await test.roll();
if (!test.succeeded)
{
await this.actor.addCondition("unconscious");
}
+3
View File
@@ -0,0 +1,3 @@
return !this.item.equipped.value
|| !args?.weapon
|| !(["goblin"].includes(args.target.Species.toLowerCase()))
+1
View File
@@ -0,0 +1 @@
this.actor.system.status.corruption.value += 1
+1
View File
@@ -0,0 +1 @@
this.actor.system.status.corruption.value += 2
+9
View File
@@ -0,0 +1,9 @@
const {targetUuid} = this.effect.flags.wfrp4e;
if (args.attacker.uuid !== targetUuid) return;
let recordedWounds = this.effect.getFlag("wfrp4e", "damageToReturn") ?? 0;
recordedWounds += args.totalWoundLoss;
this.effect.setFlag("wfrp4e", "damageToReturn", recordedWounds);
+1
View File
@@ -0,0 +1 @@
return !args.skill?.name.includes("Focalisation");
+1
View File
@@ -0,0 +1 @@
CorruptionMessageModel.createCorruptionMessage("major", this.script.getChatData());
+6
View File
@@ -0,0 +1,6 @@
let damage = await new Roll("1d10 + 1").roll();
damage.toMessage(this.script.getChatData());
this.actor.applyDamage(damage.total, {
damageType: game.wfrp4e.config.DAMAGE_TYPE.IGNORE_AP,
createMessage: this.script.getChatData()
});
+1
View File
@@ -0,0 +1 @@
return args.skill?.name == "Segeln (Luftschiff)"
+2
View File
@@ -0,0 +1,2 @@
const duration = 3600 * (1 + Number(this.effect.sourceTest.result.SL));
this.effect.update({"duration.seconds": duration});
+3
View File
@@ -0,0 +1,3 @@
const qualities = foundry.utils.deepClone(args.item.system.qualities.value);
qualities.push({name:"lightweight"});
args.item?.update({"system.qualities.value": qualities});
+3
View File
@@ -0,0 +1,3 @@
return !args.actor?.has(game.i18n.localize("NAME.Swarm")) ||
![game.wfrp4e.config.actorSizeNums.tiny, game.wfrp4e.config.actorSizeNums.ltl]
.includes(args.actor?.sizeNum)
+14
View File
@@ -0,0 +1,14 @@
if (Number(this.actor.system.details.age.value) > 870) {
if (["t", "wp", "fel"].includes(args.characteristic))
args.fields.slBonus -= 3;
if (["ag", "dex", "int"].includes(args.characteristic))
args.fields.slBonus -= 2;
} else if (Number(this.actor.system.details.age.value) > 350) {
if (["t", "wp"].includes(args.characteristic))
args.fields.slBonus -= 2;
if (["fel"].includes(args.characteristic))
args.fields.slBonus -= 1;
} else {
if (["t", "wp"].includes(args.characteristic))
args.fields.slBonus -= 1;
}
+10
View File
@@ -0,0 +1,10 @@
if (args.type == "effect" && args.options.action == "delete" && ["prone"].some(i => args.document.statuses.has(i)))
{
this.script.notification("Impossible de retirer " + args.document.name);
let resist = await this.effect.resistEffect();
if (resist)
{
this.effect.delete();
}
return resist;
}
+1
View File
@@ -0,0 +1 @@
this.effect.updateSource({name: this.effect.setSpecifier("9")});
+1
View File
@@ -0,0 +1 @@
await this.actor.addEffectItems("Compendium.wfrp4e-core.items.Item.5hH73j2NgPdsLCZN", this.effect, {name: "Haine (Tous les ennemis)"});
+5
View File
@@ -0,0 +1,5 @@
if (["dragon"].includes(args.opposedTest.defender.details.species.value.toLowerCase()))
{
args.applyTB = false;
args.opposedTest.result.other.push("<b>Wyrmslayer</b>: Ignore le BE contre les Dragons")
}
+1
View File
@@ -0,0 +1 @@
args.context.doombolt = true;
+2
View File
@@ -0,0 +1,2 @@
args.abort = true;
this.script.notification("Impossible d'attaquer cette cible !");
+12
View File
@@ -0,0 +1,12 @@
const test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {
difficulty: "challenging",
context: {
failure: "Erhält den Zustand @Condition[Fatigued] wegen Albträumen.",
success: "Hatte Albträume, aber ausreichend geschlafen."
}
});
await test.roll();
if (test.failed) {
await this.actor.addCondition("fatigued");
}
+21
View File
@@ -0,0 +1,21 @@
let weaponData = await this.effect.setFlag("wfrp4e", "weaponData", this.item.system.toObject());
try {
await this.item.update({
system: {
"weaponGroup.value": "throwing",
"qualities.value": this.item.system.qualities.value.concat([{ name: "accurate" }]),
"range.value": "SB * 3",
"consumesAmmo.value" : false
}
})
let test = await this.actor.setupWeapon(this.item, {}, {resolveClose : true});
await test?.roll();
this.item.update({ system: this.effect.getFlag("wfrp4e", "weaponData") })
}
catch (e) {
this.item.update({ system: this.effect.getFlag("wfrp4e", "weaponData") })
}
+3
View File
@@ -0,0 +1,3 @@
const blinded = this.actor.hasCondition("blinded");
if (!blinded)
this.actor.addCondition("blinded");
+7
View File
@@ -0,0 +1,7 @@
let test = await this.actor.setupSkill(game.i18n.localize("NAME.Pray"), {appendTitle: ` - ${this.effect.name}`});
await test.roll();
if (test.succeeded)
{
this.actor.removeCondition("blinded", 1 + parseInt(test.result.SL));
}
+1
View File
@@ -0,0 +1 @@
return this.effect.name !== game.i18n.localize("WFRP4E.YenluiLight")
+3
View File
@@ -0,0 +1,3 @@
if ( !this.actor.hasCondition("poisoned") ) {
this.effect.delete();
}
+1
View File
@@ -0,0 +1 @@
args.options.terror
+1
View File
@@ -0,0 +1 @@
return args.item?.system.isRanged;
+14
View File
@@ -0,0 +1,14 @@
const venomUUID = "Compendium.wfrp4e-core.items.gFkRm9wS65qe18Xv";
const venom = this.actor.itemTags.trait.find(t => t.name === "Venin");
if (venom) {
await this.effect.setFlag("wfrp4e-tribes", "venom", {
_id: venom.id,
"system.specification.value": venom.system.specification.value
});
await venom.update({"system.specification.value": "Difficult"});
} else {
await this.actor.addEffectItems(venomUUID, this.effect, {
"system.specification.value": "Challenging"
});
}
+4
View File
@@ -0,0 +1,4 @@
if (this.item.equipped.value && args.totalWoundLoss > 10) {
args.totalWoundLoss = Math.min(10, args.totalWoundLoss)
args.extraMessages.push(`<strong>${this.effect.name}</strong>: Blessed-Verlust auf 10 begrenzt`)
}
+2 -2
View File
@@ -48,7 +48,7 @@ for (let talent of talents)
}
else
{
ui.notifications.warn(`Could not find ${talent}`, {permanent : true})
ui.notifications.warn(`${talent} nicht gefunden`, {permanent : true})
}
}
@@ -65,7 +65,7 @@ for (let trapping of trappings)
}
else
{
ui.notifications.warn(`Could not find ${trapping}`, {permanent : true})
ui.notifications.warn(`${trapping} nicht gefunden`, {permanent : true})
}
}
+1
View File
@@ -0,0 +1 @@
return !args.title.includes("Spellbreaking")
+1
View File
@@ -0,0 +1 @@
this.actor.addEffectItems("Compendium.wfrp4e-core.items.Item.EO05HX7jql0g605A", this.effect, {"system.specification.value": this.actor.system.characteristics.ag.value});
+50
View File
@@ -0,0 +1,50 @@
let characteristics = {
"ws" : -10,
"bs" : -10,
"s" : 0,
"t" : 0,
"i" : -10,
"ag" : -10,
"dex" : 0,
"int" : -200,
"wp" : -200,
"fel" : -200
}
let traits = [ {name:"Rüstung", value: 2}, {name:"Konstrukt"}, {name:"Dunkelsicht"}, {name:"Angst", value: 2}, {name:"Schmerzfrei"},{name:"Untot"},{name:"Instabil"} ];
let items = [];
let updateObj = this.actor.toObject();
for (let ch in characteristics)
{
updateObj.system.characteristics[ch].modifier += characteristics[ch];
}
updateObj.system.characteristics.int.initial = 0;
updateObj.system.characteristics.wp.initial = 0;
updateObj.system.characteristics.fel.initial = 0;
for (let trait of traits)
{
let traitItem = await game.wfrp4e.utility.find(trait.name, "trait")
if (traitItem)
{
let t = traitItem.toObject();
t.system.specification.value = trait.value;
if (trait.disabled)
{
t.system.disabled = true;
}
items.push(t);
}
else
{
ui.notifications.warn(`${trait.name} nicht gefunden`, {permanent : true})
}
}
updateObj.name = updateObj.name += " " + this.effect.name
await this.actor.update(updateObj)
this.actor.createEmbeddedDocuments("Item", items);
+1
View File
@@ -0,0 +1 @@
args.fields.slBonus += this.effect.getFlag("wfrp4e", "slBonus") || 0;
+6
View File
@@ -0,0 +1,6 @@
let roll = await new Roll("2d10 + @sin", {sin: this.actor.system.status.sin.value || 0}).roll();
roll.toMessage(this.script.getChatData());
this.effect.updateSource({duration: {
value: roll.total,
units: "days"
}});
+112
View File
@@ -0,0 +1,112 @@
let characteristics = {
"ws" : 25,
"bs" : 10,
"s" : 15,
"t" : 15,
"i" : 25,
"ag" : 20,
"dex" : 0,
"int" : 10,
"wp" : 25,
"fel" : 10
}
let skills = ["Besonnenheit", "Ausweichen", "Einschüchtern", "Intuition", "Sprache (Schlachtenzunge)", "Anführen", "Wissen (Kriegsführung)", "Wahrnehmung"]
let skillAdvancements = [15, 15, 15, 15, 10, 15, 10, 10]
let talents = ["Kampfsinn", "Meisterkämpfer", "Kampfreflexe", "Inspirierend", "Entschlossen", "Mitreißender Anführer"]
let trappings = ["Waffe", "Schild", "Kürass", "Plattenarme", "Helm", "Plattenbeine"]
let specialItems = []
let items = [];
let updateObj = this.actor.toObject();
for (let ch in characteristics)
{
updateObj.system.characteristics[ch].modifier += characteristics[ch];
}
for (let item of specialItems) {
let newItem
if (item.type == "weapon") {
newItem = new ItemWFRP4e({ name: item.name, type: item.type, system: { equipped: true, damage: {value: item.damage}} })
} else if (item.type == "trapping") {
newItem = new ItemWFRP4e({ img: "systems/wfrp4e/icons/blank.png", name: item.name, type: item.type, system: { worn: true, trappingType: { value: item.trappingType} } } )
} else {
newItem = new ItemWFRP4e({ img: "systems/wfrp4e/icons/blank.png", name: item.name, type: item.type })
}
items.push(newItem.toObject())
}
for (let index = 0; index < skills.length; index++)
{
let skill = skills[index]
let skillItem;
skillItem = updateObj.items.find(i => i.name == skill && i.type == "skill")
if (skillItem)
skillItem.system.advances.value += skillAdvancements[index]
else
{
skillItem = await game.wfrp4e.utility.findSkill(skill)
skillItem = skillItem.toObject();
skillItem.system.advances.value = skillAdvancements[index];
items.push(skillItem);
}
}
for (let talent of talents)
{
let talentItem = await game.wfrp4e.utility.findTalent(talent)
if (talentItem)
{
items.push(talentItem.toObject());
}
else
{
ui.notifications.warn(`${talent} nicht gefunden`, {permanent : true})
}
}
for (let trapping of trappings)
{
let trappingItem = await game.wfrp4e.utility.findItem(trapping)
if (trappingItem)
{
trappingItem = trappingItem.toObject()
trappingItem.system.equipped.value = true;
items.push(trappingItem);
}
else
{
ui.notifications.warn(`${trapping} nicht gefunden`, {permanent : true})
}
}
let filters = [
{
property : "type",
value : "weapon"
},
{
property : "system.weaponGroup.value",
value : ["twohanded", "polearm"]
}
]
items = items.concat(await ItemDialog.createFromFilters(filters, 1, {text : "Wähle eine passende Stangenwaffe oder zweihändige Waffe"}))
let ride = await foundry.applications.api.DialogV2.confirm({title : "Fähigkeit", content : "Chaos Steed und +20 auf Reiten (Pferd) hinzufügen?", window : {title : this.effect.name}})
if (ride)
{
let skill = await game.wfrp4e.utility.findSkill("Reiten (Pferd)")
skill = skill.toObject();
skill.system.advances.value = 20;
items = items.concat({name : "Chaos Steed", type: "trapping", "system.trappingType.value" : "misc"}, skill)
}
updateObj.name = updateObj.name += " " + this.effect.name
await this.actor.update(updateObj)
this.actor.createEmbeddedDocuments("Item", items);
+2
View File
@@ -0,0 +1,2 @@
const diseaseIds = this.actor.items.filter(i => i.type == "disease").map(i => i.id)
this.actor.deleteEmbeddedDocuments("Item", diseaseIds)
+4
View File
@@ -0,0 +1,4 @@
let item1 = await fromUuid("Compendium.wfrp4e-core.items.Item.EO05HX7jql0g605A")
let item2 = await fromUuid("Compendium.wfrp4e-core.items.Item.Bvd2aZ0gQUXHfCTh")
let ids = await this.actor.createEmbeddedDocuments("Item", [item1, item2], {fromEffect : this.effect.id})
this.actor.updateEmbeddedDocuments('Item', [ {_id: ids[0].id, 'system.specification.value': 16} ] )
+27
View File
@@ -0,0 +1,27 @@
this.script.message(await this.actor.applyBasicDamage(8, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_AP, suppressMsg: true}))
let msg = ``
let weapons = args.actor.itemTypes.weapon.filter(i => !i.system.location.value);
let armour = args.actor.itemTags.armour.filter(i => !i.system.location.value);
for(let item of weapons)
{
if (item.system.properties.qualities.shield)
{
await item.system.damageItem(1, "shield");
}
else
{
await item.system.damageItem(1);
}
msg += `<p><strong>${item.name}</strong> um 1 beschädigt</p>`
}
for(let item of armour)
{
await item.system.damageItem(1);
msg += `<p><strong>${item.name}</strong> um 1 beschädigt</p>`
}
if (msg)
{
this.script.message(msg, {speaker : {alias : args.actor.name}});
}
+2 -2
View File
@@ -48,7 +48,7 @@ for (let talent of talents)
}
else
{
ui.notifications.warn(`Could not find ${talent}`, {permanent : true})
ui.notifications.warn(`${talent} nicht gefunden`, {permanent : true})
}
}
@@ -65,7 +65,7 @@ for (let trapping of trappings)
}
else
{
ui.notifications.warn(`Could not find ${trapping}`, {permanent : true})
ui.notifications.warn(`${trapping} nicht gefunden`, {permanent : true})
}
}
+2 -2
View File
@@ -48,7 +48,7 @@ for (let talent of talents)
}
else
{
ui.notifications.warn(`Could not find ${talent}`, {permanent : true})
ui.notifications.warn(`${talent} nicht gefunden`, {permanent : true})
}
}
@@ -65,7 +65,7 @@ for (let trapping of trappings)
}
else
{
ui.notifications.warn(`Could not find ${trapping}`, {permanent : true})
ui.notifications.warn(`${trapping} nicht gefunden`, {permanent : true})
}
}
+1
View File
@@ -0,0 +1 @@
args.data.reversal = {allowed : true, if: "worse"};
+3
View File
@@ -0,0 +1,3 @@
if (!this.actor.has("Gesegnet (Taal)", "talent")) return;
this.actor.system.characteristics.wp.modifier += 15;
+6
View File
@@ -0,0 +1,6 @@
let roll = await new Roll("2d10 + @sin", {sin: this.actor.system.status.sin.value || 0}).roll();
roll.toMessage(this.script.getChatData());
this.effect.updateSource({duration: {
value: roll.total,
units: "rounds"
}});
+1
View File
@@ -0,0 +1 @@
await this.effect.update({duration:{rounds: this.actor.system.characteristics.ws.bonus}});
+9
View File
@@ -0,0 +1,9 @@
let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields: {difficulty : "average"}, appendTitle : " - Wounded"})
await test.roll();
if (test.failed)
{
fromUuid("Compendium.wfrp4e-core.items.kKccDTGzWzSXCBOb").then(disease => {
this.actor.createEmbeddedDocuments("Item", [disease.toObject()])
this.script.scriptNotification("Gain de " + disease.name)
})
}
+1
View File
@@ -0,0 +1 @@
this.actor.modifyWounds(-1);
+49
View File
@@ -0,0 +1,49 @@
const trait = this.actor.itemTags.trait.find(t => t.name === "Regenerieren");
const name = "Fäulnisregeneration";
if (!trait) return;
const effect = trait.effects.find(e => e.name === "Regenerieren");
const scriptData = effect.system.scriptData;
scriptData[0].script = `
let chatData = {whisper: ChatMessage.getWhisperRecipients("GM")};
let message = "";
let wounds = foundry.utils.duplicate(this.actor.status.wounds);
let regenRoll = await new Roll("1d10").roll({allowInteractive : false});
let regen = regenRoll.total;
if (wounds.value >= wounds.max)
return;
if (wounds.value > 0) {
wounds.value += Math.floor(regen / 2);
if (wounds.value > wounds.max) {
wounds.value = wounds.max;
}
message += \`<b>\${this.actor.name}</b> regeneriert \${regen} Wunden.\`;
if (regen === 10) {
message += "<br>Außerdem regeneriert er eine Kritische Verletzung.";
}
} else if (regen >= 8) {
message += \`<b>\${this.actor.name}</b> hat eine \${regen} erzielt und regeneriert 1 Wunde.\`;
wounds.value += 1;
if (regen === 10) {
message += "<br>Außerdem regeneriert er eine Kritische Verletzung.";
}
} else {
message += \`<b>\${this.actor.name}</b> Regenerationsergebnis von \${regen} - Kein Effekt.\`;
}
await this.actor.update({"system.status.wounds": wounds});
this.script.message(message, {whisper: ChatMessage.getWhisperRecipients("GM")});
`
await effect.update({
name,
"system.scriptData": scriptData
});
await trait.update({ name });
+2 -2
View File
@@ -48,7 +48,7 @@ for (let talent of talents)
}
else
{
ui.notifications.warn(`Could not find ${talent}`, {permanent : true})
ui.notifications.warn(`${talent} nicht gefunden`, {permanent : true})
}
}
@@ -65,7 +65,7 @@ for (let trapping of trappings)
}
else
{
ui.notifications.warn(`Could not find ${trapping}`, {permanent : true})
ui.notifications.warn(`${trapping} nicht gefunden`, {permanent : true})
}
}
+2
View File
@@ -0,0 +1,2 @@
args.test.preData.reversal = {allowed : true, if: "better"};
this.effect.delete();
+3
View File
@@ -0,0 +1,3 @@
if (this.actor.has("Arboricole","trait")) return
this.actor.addEffectItems("Compendium.wfrp4e-core.items.Item.rOV2s6PQBBrhpMOv", this.effect)
+2
View File
@@ -0,0 +1,2 @@
const traits = this.actor.itemTypes.trait.filter(t => ["bestial", "skittish"].includes(s.name.toLowerCase()));
trait.system.disabled = true;
+9
View File
@@ -0,0 +1,9 @@
if (
this.item == args.defenderTest.item
&& args.defenderTest.succeeded
&& args.defenderTest.item?.system?.attackType == 'melee'
&& (args.attackerTest.item.properties.qualities?.magical || args.attackerTest.item.properties.unusedQualities?.magical)
)
{
args.opposedTest.result.other.push(`<strong>${this.effect.name}:</strong> zerstört magische ${args.attackerTest.item.name}.`)
}
+1
View File
@@ -0,0 +1 @@
this.script.message(await this.actor.applyBasicDamage(12, {suppressMsg: true, loc: "roll"}))
+1
View File
@@ -0,0 +1 @@
return !!args.skill
+21
View File
@@ -0,0 +1,21 @@
let damage = await new Roll("1d10 + @sin", {sin: this.actor.system.status.sin.value || 0}).roll();
damage.toMessage(this.script.getChatData());
this.actor.applyDamage(damage.total, {
damageType: game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL,
createMessage: this.script.getChatData()
});
const test = await this.actor.setupSkill(
game.i18n.localize("NAME.Endurance"),
{
fields: {difficulty: "difficult"},
skipTargets: true,
appendTitle: `${this.effect.name}`,
},
);
await test.roll();
if (test.failed)
{
this.actor.addCondition("stunned");
}
+17
View File
@@ -0,0 +1,17 @@
if (this.item.flags.runeOfLuck || this.actor.type != "character") return
const currentFortune = this.actor.status.fortune.value
const runesOfLuck = this.item.effects.contents.filter(e => e.name == this.effect.name)
const runeFortune = parseInt(runesOfLuck.length)
if (args.equipped) {
this.item.flags.runeOfLuck = true
await this.actor.update({"system.status.fortune.value" : runeFortune + currentFortune})
this.script.message(`Glückspunkte von ${currentFortune} auf ${runeFortune + currentFortune} erhöht.`)
}
else
{
this.item.flags.runeOfLuck = true
await this.actor.update({"system.status.fortune.value" : Math.max(0, currentFortune - runeFortune)})
this.script.message(`Glückspunkte auf ${Math.max(0, currentFortune - runeFortune)} reduziert.`)
}
+3
View File
@@ -0,0 +1,3 @@
const SL = this.effect.getFlag("wfrp4e", "SL") ?? 0;
args.fields.slBonus += SL;
+1
View File
@@ -0,0 +1 @@
return args.skill?.name.includes("Focalisation");
+4
View File
@@ -0,0 +1,4 @@
if (["t", "s"].includes(args.characteristic))
{
args.fields.modifier += 10;
}
+5
View File
@@ -0,0 +1,5 @@
const stupid = this.actor.items.find(i => i.name === "Stupidee");
if (!stupid) return;
await stupid.update({"system.disabled": true});
+1
View File
@@ -0,0 +1 @@
args.fields.slBonus ++
+6
View File
@@ -0,0 +1,6 @@
const deduct = this.effect.setFlag("wfrp4e", "failed");
if (!deduct) return;
this.actor.system.characteristics.ws.modifier -= 20;
this.actor.system.characteristics.bs.modifier -= 20;
+27
View File
@@ -0,0 +1,27 @@
let roll = await new Roll("1d10").roll();
roll.toMessage(this.script.getChatData());
if (roll.total == 1)
{
this.item.updateSource({"system.description.value" : this.item.system.description.value += `<p><strong>${this.effect.name}</strong>: The weapon counts as a @Corruption[minor]{minor source of Corruption}.</p>`});
}
else if (roll.total <= 5)
{
let quirks = await fromUuid("Compendium.wfrp4e-archives2.tables.RollTable.LbNZOF6Ov7xKHS5Z");
if (quirks)
{
let quirkRoll = await new Roll("1d100 + 40").roll();
quirkRoll.toMessage(this.script.getChatData());
let quirkResult = (await quirks.roll({roll: quirkRoll})).results[0].text;
this.item.updateSource({"system.description.value" : this.item.system.description.value += `<p><strong>${this.effect.name}</strong>: ${quirkResult.replace("<p>", "")}</p>`});
}
else
{
this.item.updateSource({"system.description.value" : this.item.system.description.value += `<p><strong>${this.effect.name}</strong>: Generate an additional Quirk or Curse by rolling on the @UUID[Compendium.wfrp4e-archives2.tables.RollTable.LbNZOF6Ov7xKHS5Z]{Quirks and Curses} Table and adding +40 to the result.</p>`});
}
}
else
{
this.item.updateSource({"system.description.value" : this.item.system.description.value += `<p><strong>${this.effect.name}</strong>: People who recognise the weapon are subject to @UUID[Compendium.wfrp4e-core.items.Item.0VpT5yubw4UL7j6f]{Animosity} towards the bearer.</p>`});
}
+1
View File
@@ -0,0 +1 @@
args.fields.slBonus += this.effect.sourceActor.system.characteristics.fel.bonus;
+5
View File
@@ -0,0 +1,5 @@
if (this.actor.system.status?.ward?.value) {
this.actor.system.status.ward.value = Math.max(7, this.actor.system.status.ward.value-1);
} else {
this.actor.system.status.ward.value = 9;
}
+7
View File
@@ -0,0 +1,7 @@
let test = await this.actor.setupSkill(game.i18n.localize("NAME.Dodge"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`})
await test.roll();
if (test.failed)
{
let sourceActor = this.effect.sourceActor;
this.script.message(await this.actor.applyBasicDamage(4 + sourceActor.system.characteristics.s.bonus, {suppressMsg : true}))
}
+1
View File
@@ -0,0 +1 @@
args.context.grudge = true;

Some files were not shown because too many files have changed in this diff Show More