diff --git a/.gitignore b/.gitignore index 4922a46..4d9ea4c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ debug.log node_modules foundryconfig.json -build \ No newline at end of file +build +scripts/loadEffects.js \ No newline at end of file diff --git a/effects/0FIA8JbwKG8vwpfC.js b/effects/0FIA8JbwKG8vwpfC.js new file mode 100644 index 0000000..61bcaa1 --- /dev/null +++ b/effects/0FIA8JbwKG8vwpfC.js @@ -0,0 +1 @@ +args.fields.pool += 2 * args.actor.system.advances.rank \ No newline at end of file diff --git a/effects/0LckJjaDaLyk3Obu.js b/effects/0LckJjaDaLyk3Obu.js new file mode 100644 index 0000000..f61749d --- /dev/null +++ b/effects/0LckJjaDaLyk3Obu.js @@ -0,0 +1,31 @@ +let condition = this.actor.hasCondition("bleeding"); + +if (condition) +{ + await condition.delete(); + this.script.notification("Removed Bleeding"); +} + +condition = this.actor.hasCondition("exhausted"); + +if (condition) +{ + await condition.delete(); + this.script.notification("Removed Exhausted"); +} + +condition = this.actor.hasCondition("poisoned"); + +if (condition) +{ + await condition.delete(); + this.script.notification("Removed Poisoned"); +} + +condition = this.actor.hasCondition("prone"); + +if (condition) +{ + await condition.delete(); + this.script.notification("Removed Prone"); +} \ No newline at end of file diff --git a/effects/0QqHPcw6j1FdmlvX.js b/effects/0QqHPcw6j1FdmlvX.js new file mode 100644 index 0000000..37ab06b --- /dev/null +++ b/effects/0QqHPcw6j1FdmlvX.js @@ -0,0 +1,8 @@ +if (this.actor.system.combat.wounds.value != 0) +{ + this.actor.applyHealing({wounds : this.effect.sourceTest.result.wounds}, {messageData : this.script.getChatData()}) +} +else if (this.actor.system.combat.shock.value != 0) +{ + this.actor.applyHealing({shock : this.effect.sourceTest.result.shock}, {messageData : this.script.getChatData()}) +} \ No newline at end of file diff --git a/effects/0R4H5ZmawVzuJ6Lh.js b/effects/0R4H5ZmawVzuJ6Lh.js new file mode 100644 index 0000000..dec93a3 --- /dev/null +++ b/effects/0R4H5ZmawVzuJ6Lh.js @@ -0,0 +1,3 @@ +let items = ["Compendium.wng-core.items.Item.JVz6FoVEc7p1DJUj", "Compendium.wng-core.items.Item.n0bj5UJjgglDzFcB"]; + +this.actor.createEmbeddedDocuments("Item", (await Promise.all(items.map(fromUuid))), {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/effects/0cILdPJ3OxVq13jd.js b/effects/0cILdPJ3OxVq13jd.js new file mode 100644 index 0000000..8b7dd6d --- /dev/null +++ b/effects/0cILdPJ3OxVq13jd.js @@ -0,0 +1 @@ +args.fields.difficulty += (2) \ No newline at end of file diff --git a/effects/0uAhcEEn8mexMNwg.js b/effects/0uAhcEEn8mexMNwg.js new file mode 100644 index 0000000..c2ef646 --- /dev/null +++ b/effects/0uAhcEEn8mexMNwg.js @@ -0,0 +1,11 @@ +let target = Array.from(game.user.targets)[0]?.document?.name; + +if (target) +{ + this.script.notification(`Target set to ${target}`) + this.effect.update({name : this.effect.setSpecifier(target)}) +} +else +{ + this.script.notification("Must target a Token"); +} \ No newline at end of file diff --git a/effects/0us3LU3ENKAXsaoq.js b/effects/0us3LU3ENKAXsaoq.js new file mode 100644 index 0000000..14d1db3 --- /dev/null +++ b/effects/0us3LU3ENKAXsaoq.js @@ -0,0 +1 @@ +args.actor.addCondition("vulnerable"); \ No newline at end of file diff --git a/effects/0wdwMAPUHwmONtVM.js b/effects/0wdwMAPUHwmONtVM.js new file mode 100644 index 0000000..b4a8781 --- /dev/null +++ b/effects/0wdwMAPUHwmONtVM.js @@ -0,0 +1 @@ +return !this.actor.statuses.has("halfCover") && !this.actor.statuses.has("fullCover") \ No newline at end of file diff --git a/effects/0yKINsHhGL9Mql2j.js b/effects/0yKINsHhGL9Mql2j.js new file mode 100644 index 0000000..372decf --- /dev/null +++ b/effects/0yKINsHhGL9Mql2j.js @@ -0,0 +1,3 @@ +let report = await this.actor.applyDamage(0, {shock: 1}); + +this.script.message(`Received ${report.shock} Shock`); \ No newline at end of file diff --git a/effects/12LtSFtjEQ1I7EJ6.js b/effects/12LtSFtjEQ1I7EJ6.js new file mode 100644 index 0000000..cdc17c7 --- /dev/null +++ b/effects/12LtSFtjEQ1I7EJ6.js @@ -0,0 +1 @@ +return args.fields.range != "long" \ No newline at end of file diff --git a/effects/14MFhAYpU5TWG7GD.js b/effects/14MFhAYpU5TWG7GD.js new file mode 100644 index 0000000..5dcc4e5 --- /dev/null +++ b/effects/14MFhAYpU5TWG7GD.js @@ -0,0 +1 @@ +return !args.options.multi || !args.weapon || !args.weapon.isRanged; \ No newline at end of file diff --git a/effects/19ADzGXrV4XhQa3C.js b/effects/19ADzGXrV4XhQa3C.js new file mode 100644 index 0000000..d445cf1 --- /dev/null +++ b/effects/19ADzGXrV4XhQa3C.js @@ -0,0 +1,18 @@ +let shock = Math.ceil(CONFIG.Dice.randomUniform() * 3); +let mortal = 0 + +if (this.effect.sourceActor.type == "agent") +{ + shock += this.effect.sourceActor.corruptionLevel || 0 +} + +let test = await this.actor.setupAttributeTest("toughness", {fields : {difficulty : 5}}); + +if (!test.result.isSuccess) +{ + mortal = Math.ceil(CONFIG.Dice.randomUniform() * 3); +} + +let report = await this.actor.applyDamage(0, {mortal, shock}); + +this.script.message(` Received ${report.wounds} Wounds and ${report.shock} Shock`) \ No newline at end of file diff --git a/effects/1CIbPz2M7bjhkuKl.js b/effects/1CIbPz2M7bjhkuKl.js new file mode 100644 index 0000000..0a9b205 --- /dev/null +++ b/effects/1CIbPz2M7bjhkuKl.js @@ -0,0 +1 @@ +this.actor.setupGenericTest("fear", {fields : {difficulty : 1 + this.effect.sourceActor.system.advances.rank * 2}}) \ No newline at end of file diff --git a/effects/1TENfrHWdFXtz1TA.js b/effects/1TENfrHWdFXtz1TA.js new file mode 100644 index 0000000..63d732b --- /dev/null +++ b/effects/1TENfrHWdFXtz1TA.js @@ -0,0 +1 @@ +return !args.weapon || args.fields.distance < 12; \ No newline at end of file diff --git a/effects/1bbFeRFCapNGXysD.js b/effects/1bbFeRFCapNGXysD.js new file mode 100644 index 0000000..5ff1b69 --- /dev/null +++ b/effects/1bbFeRFCapNGXysD.js @@ -0,0 +1 @@ +await this.actor.addCondition("staggered"); \ No newline at end of file diff --git a/effects/1cVdks66HCH9RlIq.js b/effects/1cVdks66HCH9RlIq.js new file mode 100644 index 0000000..82afca6 --- /dev/null +++ b/effects/1cVdks66HCH9RlIq.js @@ -0,0 +1 @@ +return args.data.skill !== 'weaponSkill'; \ No newline at end of file diff --git a/effects/1uagy1u9G4bmT0FP.js b/effects/1uagy1u9G4bmT0FP.js new file mode 100644 index 0000000..bfe41d3 --- /dev/null +++ b/effects/1uagy1u9G4bmT0FP.js @@ -0,0 +1 @@ +return !args.actor.statuses.has("blinded") \ No newline at end of file diff --git a/effects/2SZWFMMApmNukV6O.js b/effects/2SZWFMMApmNukV6O.js new file mode 100644 index 0000000..f16b3cf --- /dev/null +++ b/effects/2SZWFMMApmNukV6O.js @@ -0,0 +1,14 @@ +if (this.actor.type == "agent") +{ + this.actor.update({"system.corruption.current" : this.actor.system.corruption.current + this.effect.sourceTest.result.corruption}) +} + +let table = await fromUuid("RollTable.5jY4Qiah2VaLmBVT"); + +let result = await table.roll() + +let uuid = `Compendium.${result.results[0].documentCollection}.${result.results[0].documentId}`; + +this.actor.addEffectItems(uuid, this.effect) + +this.script.notification(`Added ${this.effect.sourceTest.result.corruption} Corruption and ${result.results[0].text}`) \ No newline at end of file diff --git a/effects/2cM4UeiXanH2SPFl.js b/effects/2cM4UeiXanH2SPFl.js new file mode 100644 index 0000000..6e521ba --- /dev/null +++ b/effects/2cM4UeiXanH2SPFl.js @@ -0,0 +1 @@ +args.fields.pool += args.target.system.advances.tier * 2; \ No newline at end of file diff --git a/effects/2o1X1mbnFEaazgDO.js b/effects/2o1X1mbnFEaazgDO.js new file mode 100644 index 0000000..891ab8b --- /dev/null +++ b/effects/2o1X1mbnFEaazgDO.js @@ -0,0 +1,11 @@ +let roll = await new Roll("dp").roll(); +roll.toMessage(this.script.getChatData()); + +if (roll.total >= 5) +{ + await this.actor.applyHealing({wounds: 1, shock: 1}, {messageData : this.script.getChatData()}); + this.actor.removeCondition("dying"); + this.actor.removeCondition("exhausted"); + this.actor.removeCondition("prone"); + this.actor.removeCondition("dead"); +} \ No newline at end of file diff --git a/effects/2oWIZuaebBy335X7.js b/effects/2oWIZuaebBy335X7.js new file mode 100644 index 0000000..7edee73 --- /dev/null +++ b/effects/2oWIZuaebBy335X7.js @@ -0,0 +1 @@ +return args.weapon || args.power \ No newline at end of file diff --git a/effects/2too0w42AmXEGbW1.js b/effects/2too0w42AmXEGbW1.js new file mode 100644 index 0000000..52e2cbf --- /dev/null +++ b/effects/2too0w42AmXEGbW1.js @@ -0,0 +1 @@ +args.fields.difficulty -= 2 * (args.options.multi - 1); \ No newline at end of file diff --git a/effects/2xUXQUX3f1tUklhl.js b/effects/2xUXQUX3f1tUklhl.js new file mode 100644 index 0000000..2b2b01d --- /dev/null +++ b/effects/2xUXQUX3f1tUklhl.js @@ -0,0 +1 @@ +return !["willpower", "fellowship"].includes(args.attribute) || args.skill == "intimidation" \ No newline at end of file diff --git a/effects/3BoZezNKLz0UbcqM.js b/effects/3BoZezNKLz0UbcqM.js new file mode 100644 index 0000000..e2c0e3d --- /dev/null +++ b/effects/3BoZezNKLz0UbcqM.js @@ -0,0 +1 @@ +args.fields.pool += (args.actor.system.advances.rank) * 3 \ No newline at end of file diff --git a/effects/3JxOovChAEOPU068.js b/effects/3JxOovChAEOPU068.js new file mode 100644 index 0000000..2d1c427 --- /dev/null +++ b/effects/3JxOovChAEOPU068.js @@ -0,0 +1,4 @@ +let wounds = Math.ceil(CONFIG.Dice.randomUniform() * 3) +let shock = Math.ceil(CONFIG.Dice.randomUniform() * 6); + +await this.actor.applyHealing({wounds, shock}, {messageData : this.script.getChatData()}); \ No newline at end of file diff --git a/effects/3LchJbIa1VNRwneO.js b/effects/3LchJbIa1VNRwneO.js new file mode 100644 index 0000000..64bf4a3 --- /dev/null +++ b/effects/3LchJbIa1VNRwneO.js @@ -0,0 +1 @@ +return args.skill != "medicae" \ No newline at end of file diff --git a/effects/3gUH2eynhZbUjqHX.js b/effects/3gUH2eynhZbUjqHX.js new file mode 100644 index 0000000..34eb7f9 --- /dev/null +++ b/effects/3gUH2eynhZbUjqHX.js @@ -0,0 +1 @@ +return !(args.weapon.name === "Paired Hekatarri Blades" && args.options.multi); \ No newline at end of file diff --git a/effects/3hojzkE4Ojom9Kcz.js b/effects/3hojzkE4Ojom9Kcz.js new file mode 100644 index 0000000..7825b9b --- /dev/null +++ b/effects/3hojzkE4Ojom9Kcz.js @@ -0,0 +1,4 @@ +if (this.effect.sourceActor?.uuid == this.actor.uuid) +{ + this.effect.updateSource({"flags.round" : game.combat.round}); +} \ No newline at end of file diff --git a/effects/3jdAfVeD9ckNmouC.js b/effects/3jdAfVeD9ckNmouC.js new file mode 100644 index 0000000..4f245c4 --- /dev/null +++ b/effects/3jdAfVeD9ckNmouC.js @@ -0,0 +1,8 @@ +if (this.actor.statuses.has("halfCover")) +{ + args.fields.difficulty += 1; +} +else if (this.actor.statuses.has("fullCover")) +{ + args.fields.difficulty += 1; +} \ No newline at end of file diff --git a/effects/40CuO0G1aCKWkReH.js b/effects/40CuO0G1aCKWkReH.js new file mode 100644 index 0000000..c26975a --- /dev/null +++ b/effects/40CuO0G1aCKWkReH.js @@ -0,0 +1 @@ +return args.options.resolve || args.options.corruption \ No newline at end of file diff --git a/effects/4JYZtqxPGDojWdqY.js b/effects/4JYZtqxPGDojWdqY.js new file mode 100644 index 0000000..2335ec4 --- /dev/null +++ b/effects/4JYZtqxPGDojWdqY.js @@ -0,0 +1 @@ +return args.options.resolve \ No newline at end of file diff --git a/effects/4PKyEAY439MdUfCH.js b/effects/4PKyEAY439MdUfCH.js new file mode 100644 index 0000000..7784560 --- /dev/null +++ b/effects/4PKyEAY439MdUfCH.js @@ -0,0 +1,6 @@ +let weapons = ["Chainsword", + "Chainaxe", + "Power Sword", + "Power Fist", + "Unarmed Strike"] +return args.weapon && (weapons.includes(args.weapon.name) || args.weapon.keywords.includes("BOLT") || args.weapon.keywords.includes("ADEPTUS ASTARTES")) \ No newline at end of file diff --git a/effects/4dF20jKPuiuv0gcy.js b/effects/4dF20jKPuiuv0gcy.js new file mode 100644 index 0000000..6c8cb0a --- /dev/null +++ b/effects/4dF20jKPuiuv0gcy.js @@ -0,0 +1 @@ +return args.options.conviction || args.options.resolve || args.weapon; \ No newline at end of file diff --git a/effects/4uRdeuQHAiO3o2RQ.js b/effects/4uRdeuQHAiO3o2RQ.js new file mode 100644 index 0000000..fce6f8f --- /dev/null +++ b/effects/4uRdeuQHAiO3o2RQ.js @@ -0,0 +1 @@ +this.actor.applyDamage(0, {shock : 1}); \ No newline at end of file diff --git a/effects/4vVFOoDbyVouBJaI.js b/effects/4vVFOoDbyVouBJaI.js new file mode 100644 index 0000000..fe1d418 --- /dev/null +++ b/effects/4vVFOoDbyVouBJaI.js @@ -0,0 +1 @@ +this.actor.applyHealing({shock : this.actor.system.combat.shock.value}, {messageData : this.script.getChatData()}) \ No newline at end of file diff --git a/effects/53NTjNWaNTEisoIt.js b/effects/53NTjNWaNTEisoIt.js new file mode 100644 index 0000000..23719db --- /dev/null +++ b/effects/53NTjNWaNTEisoIt.js @@ -0,0 +1 @@ +args.fields.difficulty += (1) \ No newline at end of file diff --git a/effects/56lX5USxmNE0rJoo.js b/effects/56lX5USxmNE0rJoo.js new file mode 100644 index 0000000..aff20f6 --- /dev/null +++ b/effects/56lX5USxmNE0rJoo.js @@ -0,0 +1 @@ +return !args.target.system.mob?.value; \ No newline at end of file diff --git a/effects/5879j2uObuDQY4R6.js b/effects/5879j2uObuDQY4R6.js new file mode 100644 index 0000000..0024221 --- /dev/null +++ b/effects/5879j2uObuDQY4R6.js @@ -0,0 +1 @@ +args.fields.difficulty -= 2; \ No newline at end of file diff --git a/effects/5A12EywlpDuJF7Sy.js b/effects/5A12EywlpDuJF7Sy.js new file mode 100644 index 0000000..ed9ddb3 --- /dev/null +++ b/effects/5A12EywlpDuJF7Sy.js @@ -0,0 +1 @@ +return !args.options.corruption && !args.options.mutation \ No newline at end of file diff --git a/effects/5Avn6epl75S6VZHF.js b/effects/5Avn6epl75S6VZHF.js new file mode 100644 index 0000000..02d111c --- /dev/null +++ b/effects/5Avn6epl75S6VZHF.js @@ -0,0 +1 @@ +return args.skill != "psychicMastery" \ No newline at end of file diff --git a/effects/5PBjhK6b1paiQSL0.js b/effects/5PBjhK6b1paiQSL0.js new file mode 100644 index 0000000..d9edafc --- /dev/null +++ b/effects/5PBjhK6b1paiQSL0.js @@ -0,0 +1,4 @@ +let shock = (CONFIG.Dice.randomUniform() * 3) + 1 +let report = await this.actor.applyDamage(0, {shock: 1}); + +this.script.message(`Received ${report.shock} Shock`); \ No newline at end of file diff --git a/effects/5ZI2vWygrweuXVjh.js b/effects/5ZI2vWygrweuXVjh.js new file mode 100644 index 0000000..7f334c2 --- /dev/null +++ b/effects/5ZI2vWygrweuXVjh.js @@ -0,0 +1,8 @@ +if (args.target.statuses.has("fullCover")) +{ + args.fields.difficulty -= 2; +} +else if (args.target.statuses.has("halfCover")) +{ + args.fields.difficulty -= 1; +} \ No newline at end of file diff --git a/effects/5dcXsqAYfSc0XsGu.js b/effects/5dcXsqAYfSc0XsGu.js new file mode 100644 index 0000000..af8636f --- /dev/null +++ b/effects/5dcXsqAYfSc0XsGu.js @@ -0,0 +1 @@ +return !args.weapon || (args.weapon.isRanged && args.weapon.traitList.pistol) \ No newline at end of file diff --git a/effects/5uMGCreXCE2Lz2Fj.js b/effects/5uMGCreXCE2Lz2Fj.js new file mode 100644 index 0000000..a094799 --- /dev/null +++ b/effects/5uMGCreXCE2Lz2Fj.js @@ -0,0 +1,20 @@ +condition = this.actor.hasCondition("blinded"); +if (condition) +{ + await condition.delete(); + this.script.notification("Removed Blinded"); +} + +let condition = this.actor.hasCondition("bleeding"); +if (condition) +{ + await condition.delete(); + this.script.notification("Removed Bleeding"); +} + +condition = this.actor.hasCondition("poisoned"); +if (condition) +{ + await condition.delete(); + this.script.notification("Removed Poisoned"); +} \ No newline at end of file diff --git a/effects/5zi5aYysSkGrQaRf.js b/effects/5zi5aYysSkGrQaRf.js new file mode 100644 index 0000000..0eb2241 --- /dev/null +++ b/effects/5zi5aYysSkGrQaRf.js @@ -0,0 +1 @@ +args.fields.damage += 2; \ No newline at end of file diff --git a/effects/62hMTw6MQiiYm0mg.js b/effects/62hMTw6MQiiYm0mg.js new file mode 100644 index 0000000..0ffb9e1 --- /dev/null +++ b/effects/62hMTw6MQiiYm0mg.js @@ -0,0 +1 @@ +return args.fileds.range == "short"; \ No newline at end of file diff --git a/effects/6AC775QniHCQ9WzK.js b/effects/6AC775QniHCQ9WzK.js new file mode 100644 index 0000000..0c1bae3 --- /dev/null +++ b/effects/6AC775QniHCQ9WzK.js @@ -0,0 +1 @@ +return !args.weapon.isMelee; \ No newline at end of file diff --git a/effects/6GtlOX0l9XA8MgWq.js b/effects/6GtlOX0l9XA8MgWq.js new file mode 100644 index 0000000..7a15452 --- /dev/null +++ b/effects/6GtlOX0l9XA8MgWq.js @@ -0,0 +1 @@ +return !args.target?.system.combat.fly; \ No newline at end of file diff --git a/effects/6MfHNLZcAULy0cPX.js b/effects/6MfHNLZcAULy0cPX.js new file mode 100644 index 0000000..b411225 --- /dev/null +++ b/effects/6MfHNLZcAULy0cPX.js @@ -0,0 +1,7 @@ +let attribute = await ItemDialog.create(ItemDialog.objectToArray(systemConfig().attributes, this.effect.img), 1, {title : this.effect.name}) + +if (attribute[0]) +{ + this.item.updateSource({name : this.item.name.replace("Attribute", attribute[0].name)}); + this.effect.updateSource({name : this.item.name, "flags.wrath-and-glory.attribute" : attribute[0].id}) +} \ No newline at end of file diff --git a/effects/6O49JUv1z2bf7CGH.js b/effects/6O49JUv1z2bf7CGH.js new file mode 100644 index 0000000..55cbe4a --- /dev/null +++ b/effects/6O49JUv1z2bf7CGH.js @@ -0,0 +1 @@ +return args.target?.effects.contents.some(e => e.statuses.has("halfCover") || e.statuses.has("fullCover")); \ No newline at end of file diff --git a/effects/6cGh0fZBduJtCAEy.js b/effects/6cGh0fZBduJtCAEy.js new file mode 100644 index 0000000..a090a77 --- /dev/null +++ b/effects/6cGh0fZBduJtCAEy.js @@ -0,0 +1 @@ +return args.skill != "ballisticSkill" \ No newline at end of file diff --git a/effects/6gDZdFsjx5Fpn7no.js b/effects/6gDZdFsjx5Fpn7no.js new file mode 100644 index 0000000..7103359 --- /dev/null +++ b/effects/6gDZdFsjx5Fpn7no.js @@ -0,0 +1 @@ +return !["intimidation", "leadership"].includes(args.skill) \ No newline at end of file diff --git a/effects/6jsNtkioqGJW2JJy.js b/effects/6jsNtkioqGJW2JJy.js new file mode 100644 index 0000000..bfd926d --- /dev/null +++ b/effects/6jsNtkioqGJW2JJy.js @@ -0,0 +1 @@ +return args.attribute != "intellect" \ No newline at end of file diff --git a/effects/6kzMfJv70NiCv84x.js b/effects/6kzMfJv70NiCv84x.js new file mode 100644 index 0000000..d546b85 --- /dev/null +++ b/effects/6kzMfJv70NiCv84x.js @@ -0,0 +1,2 @@ +let report = await this.actor.applyDamage(0, {mortal: 1}); +this.script.message(`Received ${report.wounds} Mortal Wound`); \ No newline at end of file diff --git a/effects/6q2PhkCvoJqmtwdS.js b/effects/6q2PhkCvoJqmtwdS.js new file mode 100644 index 0000000..06e252c --- /dev/null +++ b/effects/6q2PhkCvoJqmtwdS.js @@ -0,0 +1 @@ +return this.actor.statuses.has("halfCover") || this.actor.statuses.has("fullCover") \ No newline at end of file diff --git a/effects/6qyhFOQ3lgjrzusR.js b/effects/6qyhFOQ3lgjrzusR.js new file mode 100644 index 0000000..1acbb44 --- /dev/null +++ b/effects/6qyhFOQ3lgjrzusR.js @@ -0,0 +1 @@ +return args.target.statuses.has("fullCover") || args.target.statuses.has("halfCover"); \ No newline at end of file diff --git a/effects/6wNMuZ5al7DPtsWX.js b/effects/6wNMuZ5al7DPtsWX.js new file mode 100644 index 0000000..23cd569 --- /dev/null +++ b/effects/6wNMuZ5al7DPtsWX.js @@ -0,0 +1,10 @@ +let name = args.item._source.name; +if (name !== "Scything Talon" && name !== "Lash Whip") +{ + return; +} + +if (!args.item._source.system.traits.list.find(i => i.name == "inflict")) +{ + args.item.system.traits.list.push({name : "inflict", rating:"Poisoned(4)"}); +} \ No newline at end of file diff --git a/effects/6x9mD1GGnzqhjuOh.js b/effects/6x9mD1GGnzqhjuOh.js new file mode 100644 index 0000000..3ee6ee4 --- /dev/null +++ b/effects/6x9mD1GGnzqhjuOh.js @@ -0,0 +1 @@ +this.actor.setupGenericTest("corruption", {fields: {difficulty: 1}}) \ No newline at end of file diff --git a/effects/7biphiKt2ypBulRr.js b/effects/7biphiKt2ypBulRr.js new file mode 100644 index 0000000..fa9393c --- /dev/null +++ b/effects/7biphiKt2ypBulRr.js @@ -0,0 +1 @@ +return !args.weapon || !args.weapon.isMelee; \ No newline at end of file diff --git a/effects/7cDipKtebsB9pCEj.js b/effects/7cDipKtebsB9pCEj.js new file mode 100644 index 0000000..c6a3d23 --- /dev/null +++ b/effects/7cDipKtebsB9pCEj.js @@ -0,0 +1,2 @@ +await this.actor.addCondition("vulnerable", {[game.system.id] : {value : Math.abs(this.effect.sourceTest.result.defence)}}) +await this.actor.addCondition("hindered",{[game.system.id] : {value : Math.abs(this.effect.sourceTest.result.penalty)}}) \ No newline at end of file diff --git a/effects/7imBh0BPLrQnXG9I.js b/effects/7imBh0BPLrQnXG9I.js new file mode 100644 index 0000000..a5986ed --- /dev/null +++ b/effects/7imBh0BPLrQnXG9I.js @@ -0,0 +1 @@ +return args.weapon || args.power; \ No newline at end of file diff --git a/effects/7mnXZc4kMpkCGScW.js b/effects/7mnXZc4kMpkCGScW.js new file mode 100644 index 0000000..04a2dff --- /dev/null +++ b/effects/7mnXZc4kMpkCGScW.js @@ -0,0 +1 @@ +return args.skill == "scholar" \ No newline at end of file diff --git a/effects/7slYBl8Pv8czLe30.js b/effects/7slYBl8Pv8czLe30.js new file mode 100644 index 0000000..0bab6a7 --- /dev/null +++ b/effects/7slYBl8Pv8czLe30.js @@ -0,0 +1 @@ +return args.options.conviction || args.options.determination \ No newline at end of file diff --git a/effects/8cWc8m3TKBh9q35p.js b/effects/8cWc8m3TKBh9q35p.js new file mode 100644 index 0000000..caf356b --- /dev/null +++ b/effects/8cWc8m3TKBh9q35p.js @@ -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: this.script.name}); + +if (choice[0]) +{ + choice[0].updateSource({"system.transferData.type" : "document"}) +} \ No newline at end of file diff --git a/effects/8gwRPxUjCTtMmJmZ.js b/effects/8gwRPxUjCTtMmJmZ.js new file mode 100644 index 0000000..e114d93 --- /dev/null +++ b/effects/8gwRPxUjCTtMmJmZ.js @@ -0,0 +1,2 @@ +this.actor.combat.resilience.invulnerable = true; +this.actor.combat.resilience.armour += 2; \ No newline at end of file diff --git a/effects/8wvVPtRfQtgAfAzs.js b/effects/8wvVPtRfQtgAfAzs.js new file mode 100644 index 0000000..cbd30f4 --- /dev/null +++ b/effects/8wvVPtRfQtgAfAzs.js @@ -0,0 +1,9 @@ +if (!this.actor.hasKeyword("PSYKER")) +{ + + +let keyword = await fromUuid("Compendium.wng-core.items.Item.JVz6FoVEc7p1DJUj"); + +this.actor.createEmbeddedDocuments("Item", [keyword], {fromEffect: this.effect.id}) + +} \ No newline at end of file diff --git a/effects/91SCyNkOTrw4U4zJ.js b/effects/91SCyNkOTrw4U4zJ.js new file mode 100644 index 0000000..65d3b08 --- /dev/null +++ b/effects/91SCyNkOTrw4U4zJ.js @@ -0,0 +1 @@ +return !["willpower", "fellowship"].includes(args.attribute) \ No newline at end of file diff --git a/effects/9DVUzshl2xnSKhJW.js b/effects/9DVUzshl2xnSKhJW.js new file mode 100644 index 0000000..94a9121 --- /dev/null +++ b/effects/9DVUzshl2xnSKhJW.js @@ -0,0 +1 @@ +return !args.target || !args.target.system.advances?.tier; \ No newline at end of file diff --git a/effects/9GC3eLhOC6YMEtdc.js b/effects/9GC3eLhOC6YMEtdc.js new file mode 100644 index 0000000..d070aba --- /dev/null +++ b/effects/9GC3eLhOC6YMEtdc.js @@ -0,0 +1 @@ +return !args.options.conviction && !args.options.determination \ No newline at end of file diff --git a/effects/9GRenPwwZaH576mF.js b/effects/9GRenPwwZaH576mF.js new file mode 100644 index 0000000..bb06e2a --- /dev/null +++ b/effects/9GRenPwwZaH576mF.js @@ -0,0 +1 @@ +args.fields.pool += (1); \ No newline at end of file diff --git a/effects/9ItWr4dV38zN8Qsl.js b/effects/9ItWr4dV38zN8Qsl.js new file mode 100644 index 0000000..075b63d --- /dev/null +++ b/effects/9ItWr4dV38zN8Qsl.js @@ -0,0 +1,4 @@ +if (this.effect.sourceTest.testData.shifted.wounds) +{ + await this.actor.applyHealing({wounds: this.effect.sourceTest.testData.shifted.wounds.dice.length, shock: 0}, {messageData : this.script.getChatData()}); +} \ No newline at end of file diff --git a/effects/9aHFUvD1bKbwBv65.js b/effects/9aHFUvD1bKbwBv65.js new file mode 100644 index 0000000..f91fa9d --- /dev/null +++ b/effects/9aHFUvD1bKbwBv65.js @@ -0,0 +1 @@ +this.effect.delete(); \ No newline at end of file diff --git a/effects/9iAdpvynLswAjkOT.js b/effects/9iAdpvynLswAjkOT.js new file mode 100644 index 0000000..72d8201 --- /dev/null +++ b/effects/9iAdpvynLswAjkOT.js @@ -0,0 +1 @@ +return args.skill != "investigation" \ No newline at end of file diff --git a/effects/9n7XTVnfdJQ6TZPc.js b/effects/9n7XTVnfdJQ6TZPc.js new file mode 100644 index 0000000..7057703 --- /dev/null +++ b/effects/9n7XTVnfdJQ6TZPc.js @@ -0,0 +1 @@ +return args.weapon?.isRanged && this.actor.itemTypes.weapon.some(i => i.traitList.parry) \ No newline at end of file diff --git a/effects/9zwIQfxDjFcGVE1y.js b/effects/9zwIQfxDjFcGVE1y.js new file mode 100644 index 0000000..9cb9386 --- /dev/null +++ b/effects/9zwIQfxDjFcGVE1y.js @@ -0,0 +1 @@ +this.fields.pool += 2; \ No newline at end of file diff --git a/effects/A0mJlGOlM3vZncax.js b/effects/A0mJlGOlM3vZncax.js new file mode 100644 index 0000000..451e7d5 --- /dev/null +++ b/effects/A0mJlGOlM3vZncax.js @@ -0,0 +1 @@ +return args.actor.itemTypes.armour.filter(i => i.system.isEquipped && i.hasKeyword("HEAVY")).length > 0 \ No newline at end of file diff --git a/effects/A5hyKXJMUPEtCre9.js b/effects/A5hyKXJMUPEtCre9.js new file mode 100644 index 0000000..d45bda4 --- /dev/null +++ b/effects/A5hyKXJMUPEtCre9.js @@ -0,0 +1,13 @@ +let myConviction = this.actor.system.combat.conviction.total; +let shaperConviction = this.effect.sourceActor.system.combat.conviction.total +if ( myConviction < shaperConviction ) +{ + this.actor.system.combat.conviction.total = shaperConviction; +} + +let myResolve = this.actor.system.combat.resolve.total; +let shaperResolve = this.effect.sourceActor.system.combat.resolve.total +if ( myResolve < shaperResolve ) +{ + this.actor.system.combat.resolve.total = shaperResolve; +} \ No newline at end of file diff --git a/effects/A766gvj4lxclZVuo.js b/effects/A766gvj4lxclZVuo.js new file mode 100644 index 0000000..8eabc28 --- /dev/null +++ b/effects/A766gvj4lxclZVuo.js @@ -0,0 +1 @@ +return !args.weapon \ No newline at end of file diff --git a/effects/A9erE3GTUTBg7FwY.js b/effects/A9erE3GTUTBg7FwY.js new file mode 100644 index 0000000..e4385e5 --- /dev/null +++ b/effects/A9erE3GTUTBg7FwY.js @@ -0,0 +1,5 @@ +let roll = Math.ceil(CONFIG.Dice.randomUniform() * 3); + +let shock = this.effect.sourceActor.system.advances.rank * 2 + roll; + +this.actor.applyHealing({shock}, {messageData : this.script.getChatData()}); \ No newline at end of file diff --git a/effects/ABgzV2bS45Tv2sVb.js b/effects/ABgzV2bS45Tv2sVb.js new file mode 100644 index 0000000..02d6a53 --- /dev/null +++ b/effects/ABgzV2bS45Tv2sVb.js @@ -0,0 +1,4 @@ +if (args.test?.result.isWrathCritical && args.test?.item?.system.isMelee) +{ + args.modifiers.mortal.push({label : this.effect.name, value : 4}) +} \ No newline at end of file diff --git a/effects/AGvYMSSTglLGo4EY.js b/effects/AGvYMSSTglLGo4EY.js new file mode 100644 index 0000000..eefd164 --- /dev/null +++ b/effects/AGvYMSSTglLGo4EY.js @@ -0,0 +1 @@ +return !args.weapon || args.weapon.traitList.inflict?.rating != "On Fire" \ No newline at end of file diff --git a/effects/APpTseZxCahlA77s.js b/effects/APpTseZxCahlA77s.js new file mode 100644 index 0000000..86aa512 --- /dev/null +++ b/effects/APpTseZxCahlA77s.js @@ -0,0 +1,3 @@ +this.actor.update({"system.corruption.current" : this.actor.system.corruption.current + 1}); + +this.script.notification("Added +1 Corruption"); \ No newline at end of file diff --git a/effects/AWtOoK7JHmHpVIea.js b/effects/AWtOoK7JHmHpVIea.js new file mode 100644 index 0000000..f9cf2f6 --- /dev/null +++ b/effects/AWtOoK7JHmHpVIea.js @@ -0,0 +1 @@ +args.fields.difficulty += (3) \ No newline at end of file diff --git a/effects/Aa5IigIPUKd1isA1.js b/effects/Aa5IigIPUKd1isA1.js new file mode 100644 index 0000000..6c37694 --- /dev/null +++ b/effects/Aa5IigIPUKd1isA1.js @@ -0,0 +1,4 @@ +if (args.weapon.hasKeyword("BLADE") || args.weapon.hasKeyword("CHAIN") || args.weapon.hasKeyword("FORCE") || args.weapon.hasKeyword("POWER FIELD")) +{ + args.addShiftOption("armourbane", "Armourbane", "A") +} \ No newline at end of file diff --git a/effects/Al97hu95Ill2dPBR.js b/effects/Al97hu95Ill2dPBR.js new file mode 100644 index 0000000..b9bf34a --- /dev/null +++ b/effects/Al97hu95Ill2dPBR.js @@ -0,0 +1 @@ +args.fields.ed.value += (args.actor.system.advances.rank * 2) \ No newline at end of file diff --git a/effects/Awdlr5BAmiJTXc3H.js b/effects/Awdlr5BAmiJTXc3H.js new file mode 100644 index 0000000..3c66bf1 --- /dev/null +++ b/effects/Awdlr5BAmiJTXc3H.js @@ -0,0 +1 @@ +args.fields.pool += args.actor.system.advances.rank \ No newline at end of file diff --git a/effects/AxqgtlCw60kOoesX.js b/effects/AxqgtlCw60kOoesX.js new file mode 100644 index 0000000..667e9a2 --- /dev/null +++ b/effects/AxqgtlCw60kOoesX.js @@ -0,0 +1 @@ +return args.skill == "ballisticSkill" \ No newline at end of file diff --git a/effects/B3sBL1gjTphredxy.js b/effects/B3sBL1gjTphredxy.js new file mode 100644 index 0000000..7abbf90 --- /dev/null +++ b/effects/B3sBL1gjTphredxy.js @@ -0,0 +1 @@ +return !["persuasion", "leadership"].includes(args.skill) || args.actor.system.resources.faith.current == 0 \ No newline at end of file diff --git a/effects/BD8adlqXBtxcgEeT.js b/effects/BD8adlqXBtxcgEeT.js new file mode 100644 index 0000000..3b07001 --- /dev/null +++ b/effects/BD8adlqXBtxcgEeT.js @@ -0,0 +1 @@ +return args.attribute != this.effect.getFlag(game.system.id, "attribute"); \ No newline at end of file diff --git a/effects/Be00piKt2tG7VOX2.js b/effects/Be00piKt2tG7VOX2.js new file mode 100644 index 0000000..a818b57 --- /dev/null +++ b/effects/Be00piKt2tG7VOX2.js @@ -0,0 +1,4 @@ +let wounds = Math.ceil(CONFIG.Dice.randomUniform() * 3); +let report = await this.actor.applyDamage(0, {mortal:wounds}); + +this.script.message(`${this.actor.name} took ${report.mortal} Wounds`); \ No newline at end of file diff --git a/effects/BlIq9WVygXecUJ99.js b/effects/BlIq9WVygXecUJ99.js new file mode 100644 index 0000000..b7d578f --- /dev/null +++ b/effects/BlIq9WVygXecUJ99.js @@ -0,0 +1 @@ +return args.actor.statuses.has("halfCover") || args.actor.statuses.has("fullCover"); \ No newline at end of file diff --git a/effects/Blhy4vTA7nd8eb1i.js b/effects/Blhy4vTA7nd8eb1i.js new file mode 100644 index 0000000..e47bff1 --- /dev/null +++ b/effects/Blhy4vTA7nd8eb1i.js @@ -0,0 +1 @@ +return args.skill != "investigation" && !args.options.influence \ No newline at end of file diff --git a/effects/BrT6piUnOYUmM2Ip.js b/effects/BrT6piUnOYUmM2Ip.js new file mode 100644 index 0000000..1e0717f --- /dev/null +++ b/effects/BrT6piUnOYUmM2Ip.js @@ -0,0 +1,6 @@ +let wounds = this.effect.getFlag(game.system.id, "wounds"); + +if (wounds) +{ + this.actor.applyHealing({wounds : wounds * 2}, {messageData : this.script.getChatData()}) +} \ No newline at end of file diff --git a/effects/Brhe83cWXvseTm2n.js b/effects/Brhe83cWXvseTm2n.js new file mode 100644 index 0000000..cb02807 --- /dev/null +++ b/effects/Brhe83cWXvseTm2n.js @@ -0,0 +1,3 @@ +let mortal = Math.ceil(CONFIG.Dice.randomUniform() * 6); +let report = await this.actor.applyDamage(0, {mortal}); +this.script.message(`Received ${report.wounds} Wounds and ${report.shock} Shock`) \ No newline at end of file diff --git a/effects/BsgiKeowhYzXeHln.js b/effects/BsgiKeowhYzXeHln.js new file mode 100644 index 0000000..922af41 --- /dev/null +++ b/effects/BsgiKeowhYzXeHln.js @@ -0,0 +1,11 @@ +if (this.actor.hasCondition("staggered")) +{ + +let resisted = await this.effect.resistEffect(); + +if (resisted) +{ + this.actor.removeCondition("staggered"); +} + +} \ No newline at end of file diff --git a/effects/C3f6PAWu1EMtjqkc.js b/effects/C3f6PAWu1EMtjqkc.js new file mode 100644 index 0000000..21c20d6 --- /dev/null +++ b/effects/C3f6PAWu1EMtjqkc.js @@ -0,0 +1,2 @@ +let keyword = this.effect.specifier; +return args.target?.hasKeyword(keyword); \ No newline at end of file diff --git a/effects/C7pMcQJxsZS6Y0pp.js b/effects/C7pMcQJxsZS6Y0pp.js new file mode 100644 index 0000000..89d23a9 --- /dev/null +++ b/effects/C7pMcQJxsZS6Y0pp.js @@ -0,0 +1,5 @@ +if (args.test.weapon?.isRanged) +{ + args.modifiers.resilience.push({value : 1, label : this.effect.label}) + args.resilience.invulnerable = true; +} \ No newline at end of file diff --git a/effects/C8i148sLeDQ3K1JA.js b/effects/C8i148sLeDQ3K1JA.js new file mode 100644 index 0000000..c7e593c --- /dev/null +++ b/effects/C8i148sLeDQ3K1JA.js @@ -0,0 +1 @@ +args.addShiftOption("hardy", "Hardy", "H") \ No newline at end of file diff --git a/effects/CAmyzmufywSe5ZUw.js b/effects/CAmyzmufywSe5ZUw.js new file mode 100644 index 0000000..afc83d3 --- /dev/null +++ b/effects/CAmyzmufywSe5ZUw.js @@ -0,0 +1 @@ +return !["willpower", "fellowship", "initiative", "intellect"].includes(args.attribute) \ No newline at end of file diff --git a/effects/CFkKklyHbcDiKwsL.js b/effects/CFkKklyHbcDiKwsL.js new file mode 100644 index 0000000..9d39f04 --- /dev/null +++ b/effects/CFkKklyHbcDiKwsL.js @@ -0,0 +1 @@ +await this.actor.applyHealing({wounds: 1, shock: 1}, {messageData : this.script.getChatData()}); \ No newline at end of file diff --git a/effects/CI1w8HHmUshU3euA.js b/effects/CI1w8HHmUshU3euA.js new file mode 100644 index 0000000..4e81776 --- /dev/null +++ b/effects/CI1w8HHmUshU3euA.js @@ -0,0 +1 @@ +args.fields.difficulty++; \ No newline at end of file diff --git a/effects/CKhtZefLmNzwrOl6.js b/effects/CKhtZefLmNzwrOl6.js new file mode 100644 index 0000000..b61577f --- /dev/null +++ b/effects/CKhtZefLmNzwrOl6.js @@ -0,0 +1,20 @@ +if (this.item.specifier == "Skill") + { + let skills = Object.keys(systemConfig().skills).map(i => { + return {id : i, name : systemConfig().skills[i], img : this.effect.img} + }).filter(i => this.actor.system.skills[i.id].rating >= 4); + + if (skills.length == 0) + { + this.script.notification(`No Skills match the requirement`, "error") + return false; + } + + let choice = await ItemDialog.create(skills, 1, {title : this.effect.name, text : "Select Skill"}) + + if (choice[0]) + { + this.item.updateSource({name : this.item.name.replace("Skill", choice[0].name)}) + this.effect.updateSource({name : `${this.item.name}`, "flags.wrath-and-glory.skill" : choice[0].id}); + } +} \ No newline at end of file diff --git a/effects/CP8NUqEi2SZYGmZ9.js b/effects/CP8NUqEi2SZYGmZ9.js new file mode 100644 index 0000000..81fd440 --- /dev/null +++ b/effects/CP8NUqEi2SZYGmZ9.js @@ -0,0 +1 @@ +return args.skill == "athletics" \ No newline at end of file diff --git a/effects/CTpN3Iuy4XpZLTmF.js b/effects/CTpN3Iuy4XpZLTmF.js new file mode 100644 index 0000000..6047c52 --- /dev/null +++ b/effects/CTpN3Iuy4XpZLTmF.js @@ -0,0 +1 @@ +return !args.weapon || args.weapon.isMelee || !args.weapon.hasKeyword("PRIMARIS") \ No newline at end of file diff --git a/effects/Cl0NORHSIPZGKMni.js b/effects/Cl0NORHSIPZGKMni.js new file mode 100644 index 0000000..d89cb31 --- /dev/null +++ b/effects/Cl0NORHSIPZGKMni.js @@ -0,0 +1 @@ +return args.skill == "cunning" \ No newline at end of file diff --git a/effects/CobcJwDZCfYI7RXM.js b/effects/CobcJwDZCfYI7RXM.js new file mode 100644 index 0000000..2f615b4 --- /dev/null +++ b/effects/CobcJwDZCfYI7RXM.js @@ -0,0 +1 @@ +args.fields.difficulty += 2 \ No newline at end of file diff --git a/effects/CxcKLAeyq0qsOEtv.js b/effects/CxcKLAeyq0qsOEtv.js new file mode 100644 index 0000000..94af0af --- /dev/null +++ b/effects/CxcKLAeyq0qsOEtv.js @@ -0,0 +1,5 @@ +let wound = 0 + this.effect.sourceTest.result.wound; +let shock = Math.ceil(CONFIG.Dice.randomUniform() * 3) + this.effect.sourceTest.result.shock;; + + +await this.actor.applyHealing({wounds: wound, shock: shock}, {messageData : this.script.getChatData()}); \ No newline at end of file diff --git a/effects/DDw6ZRQGqShyROa2.js b/effects/DDw6ZRQGqShyROa2.js new file mode 100644 index 0000000..42162a0 --- /dev/null +++ b/effects/DDw6ZRQGqShyROa2.js @@ -0,0 +1 @@ +return !["willpower", "toughness"].includes(args.attribute) \ No newline at end of file diff --git a/effects/DIQtlogkgKy7sNzG.js b/effects/DIQtlogkgKy7sNzG.js new file mode 100644 index 0000000..bd729a7 --- /dev/null +++ b/effects/DIQtlogkgKy7sNzG.js @@ -0,0 +1,5 @@ +if(args.options.fear || args.options.resolve) +{ + return false +} +return args.weapon || args.power || !["willpower", "intellect", "fellowship"].includes(args.attribute) \ No newline at end of file diff --git a/effects/DLKCiOfPGMDwgMPU.js b/effects/DLKCiOfPGMDwgMPU.js new file mode 100644 index 0000000..59201d3 --- /dev/null +++ b/effects/DLKCiOfPGMDwgMPU.js @@ -0,0 +1,5 @@ +for(let skill in args.system.skills) +{ + if (args.system.skills[skill].total < 3) + args.system.skills[skill].total = 3; +} \ No newline at end of file diff --git a/effects/DPin1O0dp6nU6gzn.js b/effects/DPin1O0dp6nU6gzn.js new file mode 100644 index 0000000..2874bce --- /dev/null +++ b/effects/DPin1O0dp6nU6gzn.js @@ -0,0 +1 @@ +return args.weapon.traitList.inflict?.rating == "On Fire"; \ No newline at end of file diff --git a/effects/DSDRdmg0jOGtNyjx.js b/effects/DSDRdmg0jOGtNyjx.js new file mode 100644 index 0000000..da14585 --- /dev/null +++ b/effects/DSDRdmg0jOGtNyjx.js @@ -0,0 +1 @@ +return args.skill != "stealth" \ No newline at end of file diff --git a/effects/DSHCECbXssRxCwtk.js b/effects/DSHCECbXssRxCwtk.js new file mode 100644 index 0000000..e9894fd --- /dev/null +++ b/effects/DSHCECbXssRxCwtk.js @@ -0,0 +1 @@ +return args.attribute != "fellowship" && args.skill != "survival" \ No newline at end of file diff --git a/effects/DUHfuHQK7gydcaBp.js b/effects/DUHfuHQK7gydcaBp.js new file mode 100644 index 0000000..9d8a3a3 --- /dev/null +++ b/effects/DUHfuHQK7gydcaBp.js @@ -0,0 +1 @@ +args.addShiftOption("wounds", "Wounds", "W"); \ No newline at end of file diff --git a/effects/DUI6OBk8lrBeHvqf.js b/effects/DUI6OBk8lrBeHvqf.js new file mode 100644 index 0000000..e31b0e5 --- /dev/null +++ b/effects/DUI6OBk8lrBeHvqf.js @@ -0,0 +1,7 @@ +let img = this.item.img; +let choice = await ItemDialog.create([{id : "WS", name : "Weapon Skill", img}, {id : "BS", name : "Ballistic Skill", img}]) + +if (choice[0]) +{ + this.item.updateSource({name : this.item.name + ` [${choice[0].id}]`}); +} \ No newline at end of file diff --git a/effects/DWXWAhr2s4muITW1.js b/effects/DWXWAhr2s4muITW1.js new file mode 100644 index 0000000..d95a369 --- /dev/null +++ b/effects/DWXWAhr2s4muITW1.js @@ -0,0 +1 @@ +return !args.actor.system.combat.stealth \ No newline at end of file diff --git a/effects/DkgzIdxwoXcGusDV.js b/effects/DkgzIdxwoXcGusDV.js new file mode 100644 index 0000000..8ddd01b --- /dev/null +++ b/effects/DkgzIdxwoXcGusDV.js @@ -0,0 +1,2 @@ +this.actor.spend("system.resources.faith.current") +this.script.notification("Spent 1 Faith"); \ No newline at end of file diff --git a/effects/DnkY4E4frqtmNw10.js b/effects/DnkY4E4frqtmNw10.js new file mode 100644 index 0000000..1e296c1 --- /dev/null +++ b/effects/DnkY4E4frqtmNw10.js @@ -0,0 +1,5 @@ +let item = (await fromUuid("Compendium.wng-core.items.Item.HSTXKR5NVmndHpOT")).toObject(); + +item.system.equipped = true; + +this.actor.createEmbeddedDocuments("Item", [item], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/effects/DtGXkwrXvo1HRFMe.js b/effects/DtGXkwrXvo1HRFMe.js new file mode 100644 index 0000000..90f5331 --- /dev/null +++ b/effects/DtGXkwrXvo1HRFMe.js @@ -0,0 +1 @@ +return args.actor.statuses.has("wounded") \ No newline at end of file diff --git a/effects/Dv2FHMh1PeyDnMow.js b/effects/Dv2FHMh1PeyDnMow.js new file mode 100644 index 0000000..4e04d37 --- /dev/null +++ b/effects/Dv2FHMh1PeyDnMow.js @@ -0,0 +1 @@ +return args.options.fear \ No newline at end of file diff --git a/effects/DzXwv7X6jCAnO9UU.js b/effects/DzXwv7X6jCAnO9UU.js new file mode 100644 index 0000000..d4fea81 --- /dev/null +++ b/effects/DzXwv7X6jCAnO9UU.js @@ -0,0 +1,4 @@ +if (args.combat.combatant?.token?.actor.uuid == this.effect.sourceActor.uuid) +{ + this.effect.delete(); +} \ No newline at end of file diff --git a/effects/EDZOzmX7jeJxvBqp.js b/effects/EDZOzmX7jeJxvBqp.js new file mode 100644 index 0000000..8c85fdb --- /dev/null +++ b/effects/EDZOzmX7jeJxvBqp.js @@ -0,0 +1 @@ +return args.skill != "deception" \ No newline at end of file diff --git a/effects/EPpf9etWAFHBjEfg.js b/effects/EPpf9etWAFHBjEfg.js new file mode 100644 index 0000000..9158499 --- /dev/null +++ b/effects/EPpf9etWAFHBjEfg.js @@ -0,0 +1 @@ +return !args.weapon || !args.weapon.isRanged || !args.target.system.advances?.tier; \ No newline at end of file diff --git a/effects/EjPuVimeJAQR1Wl6.js b/effects/EjPuVimeJAQR1Wl6.js new file mode 100644 index 0000000..98127db --- /dev/null +++ b/effects/EjPuVimeJAQR1Wl6.js @@ -0,0 +1,4 @@ +if (args.test?.item?.type == "psychicPower") +{ + args.mortalDetermination = true; +} \ No newline at end of file diff --git a/effects/EknZ9g3HNqdZzWM0.js b/effects/EknZ9g3HNqdZzWM0.js new file mode 100644 index 0000000..3ad92e9 --- /dev/null +++ b/effects/EknZ9g3HNqdZzWM0.js @@ -0,0 +1 @@ +args.fields.ed.value += (args.actor.system.advances.rank) \ No newline at end of file diff --git a/effects/EofUDIUTQaDBmDWf.js b/effects/EofUDIUTQaDBmDWf.js new file mode 100644 index 0000000..850b9e0 --- /dev/null +++ b/effects/EofUDIUTQaDBmDWf.js @@ -0,0 +1 @@ +return args.attribute == this.effect.getFlag(game.system.id, "attribute"); \ No newline at end of file diff --git a/effects/EpWGJjgVutx3kJXO.js b/effects/EpWGJjgVutx3kJXO.js new file mode 100644 index 0000000..64fdcd6 --- /dev/null +++ b/effects/EpWGJjgVutx3kJXO.js @@ -0,0 +1 @@ +args.resilience.invulnerable = false; \ No newline at end of file diff --git a/effects/Eq9PeNuPABX5Ist3.js b/effects/Eq9PeNuPABX5Ist3.js new file mode 100644 index 0000000..28766c2 --- /dev/null +++ b/effects/Eq9PeNuPABX5Ist3.js @@ -0,0 +1,5 @@ +let roll = Math.ceil(CONFIG.Dice.randomUniform() * 3); + +let shock = this.effect.sourceActor.system.advances.rank + roll; + +this.actor.applyHealing({shock}, {messageData : this.script.getChatData()}); \ No newline at end of file diff --git a/effects/ErneCiMv3usTHl3h.js b/effects/ErneCiMv3usTHl3h.js new file mode 100644 index 0000000..266d6ad --- /dev/null +++ b/effects/ErneCiMv3usTHl3h.js @@ -0,0 +1 @@ +args.fields.pool += 4; \ No newline at end of file diff --git a/effects/F0lqM12xDvYNF1KO.js b/effects/F0lqM12xDvYNF1KO.js new file mode 100644 index 0000000..ebd68fa --- /dev/null +++ b/effects/F0lqM12xDvYNF1KO.js @@ -0,0 +1,4 @@ +if (args.fields.level != "unbound") +{ + args.fields.level = "unbound"; +} \ No newline at end of file diff --git a/effects/F4QyV4jeDJ9UyQL1.js b/effects/F4QyV4jeDJ9UyQL1.js new file mode 100644 index 0000000..a863452 --- /dev/null +++ b/effects/F4QyV4jeDJ9UyQL1.js @@ -0,0 +1 @@ +return args.skill == this.effect.getFlag(game.system.id, "skill"); \ No newline at end of file diff --git a/effects/F9z9SZ9nikSYIqBj.js b/effects/F9z9SZ9nikSYIqBj.js new file mode 100644 index 0000000..d7a07db --- /dev/null +++ b/effects/F9z9SZ9nikSYIqBj.js @@ -0,0 +1,24 @@ +if (this.item.specifier == "Skill") + { + let skills = ["athletics", + "deception", + "intimidation", + "persuasion", + "tech"].map(i => { + return {id : i, name : systemConfig().skills[i], img : this.effect.img} + }).filter(i => this.actor.system.skills[i.id].rating >= 4); + + if (skills.length == 0) + { + this.script.notification(`No Skills match the requirement`, "error") + return false; + } + + let choice = await ItemDialog.create(skills, 1, {title : this.effect.name, text : "Select Skill"}) + + if (choice[0]) + { + this.item.updateSource({name : this.item.name.replace("Skill", choice[0].name)}) + this.effect.updateSource({name : `${this.item.name}`, "flags.wrath-and-glory.skill" : choice[0].id}); + } +} \ No newline at end of file diff --git a/effects/FEQWJ4DGNHm3gbDf.js b/effects/FEQWJ4DGNHm3gbDf.js new file mode 100644 index 0000000..f9da80e --- /dev/null +++ b/effects/FEQWJ4DGNHm3gbDf.js @@ -0,0 +1 @@ +return !args.options.fear && !args.options.corruption \ No newline at end of file diff --git a/effects/FWM1XKT6uSGVm8o1.js b/effects/FWM1XKT6uSGVm8o1.js new file mode 100644 index 0000000..c91d41f --- /dev/null +++ b/effects/FWM1XKT6uSGVm8o1.js @@ -0,0 +1 @@ +return !args.target.statuses.has("fullCover") && !args.target.statuses.has("halfCover"); \ No newline at end of file diff --git a/effects/FfuXSl90FhKLFAV5.js b/effects/FfuXSl90FhKLFAV5.js new file mode 100644 index 0000000..4f80d6b --- /dev/null +++ b/effects/FfuXSl90FhKLFAV5.js @@ -0,0 +1 @@ +args.fields.pool += args.actor.system.mob.value; \ No newline at end of file diff --git a/effects/FjfWaGeBfWlAWQFW.js b/effects/FjfWaGeBfWlAWQFW.js new file mode 100644 index 0000000..209c177 --- /dev/null +++ b/effects/FjfWaGeBfWlAWQFW.js @@ -0,0 +1,11 @@ +let effects = this.item.effects.contents.filter(i => i.id != this.effect.id); + +effects.forEach(e => { + e.update({disabled : true}) +}) + +let e = effects.find(i => i.id == "93ZacxDC5SSsOAfb"); + +e.update({disabled : false}); + +this.script.notification(`${e.name} (+3 Defence) Activated`) \ No newline at end of file diff --git a/effects/Fv2f4myS5meJjkzs.js b/effects/Fv2f4myS5meJjkzs.js new file mode 100644 index 0000000..40eb894 --- /dev/null +++ b/effects/Fv2f4myS5meJjkzs.js @@ -0,0 +1 @@ +return args.weapon.system.isMelee; \ No newline at end of file diff --git a/effects/G8XJl9hmqiEVxHvz.js b/effects/G8XJl9hmqiEVxHvz.js new file mode 100644 index 0000000..313607f --- /dev/null +++ b/effects/G8XJl9hmqiEVxHvz.js @@ -0,0 +1,5 @@ +if (args.item.type == "weapon" && args.item.hasKeyword(["POWER FIELD"])) +{ + // See https://github.com/foundryvtt/foundryvtt/issues/7987 + args.item.system.damage.ap.bonus -= this.actor.system.advances.rank / 2 +} \ No newline at end of file diff --git a/effects/G8kIIKqPTgQHCZ5D.js b/effects/G8kIIKqPTgQHCZ5D.js new file mode 100644 index 0000000..3aac636 --- /dev/null +++ b/effects/G8kIIKqPTgQHCZ5D.js @@ -0,0 +1 @@ +args.fields.difficulty += (this.effect.sourceTest.result.defence) \ No newline at end of file diff --git a/effects/GtMnwu9j9pCbSpiO.js b/effects/GtMnwu9j9pCbSpiO.js new file mode 100644 index 0000000..0eac8ea --- /dev/null +++ b/effects/GtMnwu9j9pCbSpiO.js @@ -0,0 +1 @@ +args.fields.pool += (args.actor.system.test.result.bonus) \ No newline at end of file diff --git a/effects/GxyOrCjQTV8uiXBd.js b/effects/GxyOrCjQTV8uiXBd.js new file mode 100644 index 0000000..9c1a0d4 --- /dev/null +++ b/effects/GxyOrCjQTV8uiXBd.js @@ -0,0 +1,20 @@ +let effects = this.effect.sourceItem.effects.contents.filter(i => i.id != this.effect.id); + +if (this.actor.name === "Aberrant") +{ + let choice = await ItemDialog.create(effects, 1, {title : this.effect.name, text: this.script.name}); + + if (choice[0]) + { + this.actor.applyEffect({effectUuids: choice[0].uuid}); + } +} +else +{ + let roll = await new Roll("1d3").roll(); + + roll.toMessage(this.script.getChatData()); + + let chosenEffect = effects[roll.total-1]; + this.actor.applyEffect({effectUuids: chosenEffect.uuid}); +} \ No newline at end of file diff --git a/effects/H25ksa52eRFkWQnT.js b/effects/H25ksa52eRFkWQnT.js new file mode 100644 index 0000000..cb0268b --- /dev/null +++ b/effects/H25ksa52eRFkWQnT.js @@ -0,0 +1 @@ +return args.skill != "insight" \ No newline at end of file diff --git a/effects/H9a2LNH7YSDMvZzh.js b/effects/H9a2LNH7YSDMvZzh.js new file mode 100644 index 0000000..2bde595 --- /dev/null +++ b/effects/H9a2LNH7YSDMvZzh.js @@ -0,0 +1,14 @@ +let skills = ["awareness", + "cunning", + "deception", + "insight", + "persuasion", + "psychicMastery", + "stealth"].map(i => { + return {id : i, name : systemConfig().skills[i], img : this.effect.img} + }); + let choice = await ItemDialog.create(skills, 1, {title : this.effect.name, text : "Select Skill"}) + if (choice[0]) + { + this.effect.updateSource({name : `${this.item.name} [${choice[0].name}]`, "flags.wrath-and-glory.skill" : choice[0].id}); + } \ No newline at end of file diff --git a/effects/HW2u4vWec1VNrBkX.js b/effects/HW2u4vWec1VNrBkX.js new file mode 100644 index 0000000..84633d3 --- /dev/null +++ b/effects/HW2u4vWec1VNrBkX.js @@ -0,0 +1 @@ +args.fields.pool += (args.actor.system.advances.rank) \ No newline at end of file diff --git a/effects/HnaVYE8Th4xFalOM.js b/effects/HnaVYE8Th4xFalOM.js new file mode 100644 index 0000000..af942cf --- /dev/null +++ b/effects/HnaVYE8Th4xFalOM.js @@ -0,0 +1 @@ +return args.skill != this.effect.getFlag(game.system.id, "skill"); \ No newline at end of file diff --git a/effects/HoK2qFwgUkl1RKW2.js b/effects/HoK2qFwgUkl1RKW2.js new file mode 100644 index 0000000..354e7e3 --- /dev/null +++ b/effects/HoK2qFwgUkl1RKW2.js @@ -0,0 +1 @@ +this.actor.system.combat.resilience.invulnerable = true; \ No newline at end of file diff --git a/effects/I1dYoHN21F2dbyol.js b/effects/I1dYoHN21F2dbyol.js new file mode 100644 index 0000000..d32f244 --- /dev/null +++ b/effects/I1dYoHN21F2dbyol.js @@ -0,0 +1 @@ +return args.options.corruption || args.options.mutation \ No newline at end of file diff --git a/effects/IFMyExNp5b9jIzqV.js b/effects/IFMyExNp5b9jIzqV.js new file mode 100644 index 0000000..70e69d2 --- /dev/null +++ b/effects/IFMyExNp5b9jIzqV.js @@ -0,0 +1,2 @@ +this.actor.system.combat.resilience.invulnerable = true; +this.actor.system.combat.resilience.total += 1; \ No newline at end of file diff --git a/effects/IP3rY6Lb4LX3AcxT.js b/effects/IP3rY6Lb4LX3AcxT.js new file mode 100644 index 0000000..fd65aa2 --- /dev/null +++ b/effects/IP3rY6Lb4LX3AcxT.js @@ -0,0 +1 @@ +return args.options.fear || args.options.corruption \ No newline at end of file diff --git a/effects/IQhq0N46YRPDHtbr.js b/effects/IQhq0N46YRPDHtbr.js new file mode 100644 index 0000000..deb4eb7 --- /dev/null +++ b/effects/IQhq0N46YRPDHtbr.js @@ -0,0 +1 @@ +return this.actor.statuses.has("wounded") \ No newline at end of file diff --git a/effects/ISH5OJH9DkzLC0ot.js b/effects/ISH5OJH9DkzLC0ot.js new file mode 100644 index 0000000..18d4eee --- /dev/null +++ b/effects/ISH5OJH9DkzLC0ot.js @@ -0,0 +1 @@ +args.fields.damage += 1; \ No newline at end of file diff --git a/effects/IdfHvESnId2ZRGZA.js b/effects/IdfHvESnId2ZRGZA.js new file mode 100644 index 0000000..4b619ae --- /dev/null +++ b/effects/IdfHvESnId2ZRGZA.js @@ -0,0 +1,4 @@ +if (this.actor.spend("system.resources.faith.current", 2)) +{ + this.script.message("Spent 2 Faith"); +} \ No newline at end of file diff --git a/effects/In83yMaxcTlgZ887.js b/effects/In83yMaxcTlgZ887.js new file mode 100644 index 0000000..9959c68 --- /dev/null +++ b/effects/In83yMaxcTlgZ887.js @@ -0,0 +1 @@ +return !["scholar", "deception", "cunning"].includes(args.skill) \ No newline at end of file diff --git a/effects/InAf6SJ93t3jEliQ.js b/effects/InAf6SJ93t3jEliQ.js new file mode 100644 index 0000000..1384c23 --- /dev/null +++ b/effects/InAf6SJ93t3jEliQ.js @@ -0,0 +1 @@ +return args.skill != "weaponSkill" \ No newline at end of file diff --git a/effects/IpYIXx6ESt9E0D3I.js b/effects/IpYIXx6ESt9E0D3I.js new file mode 100644 index 0000000..f050c75 --- /dev/null +++ b/effects/IpYIXx6ESt9E0D3I.js @@ -0,0 +1,9 @@ +if (args.result.isSuccess) +{ + let shock = 1 + this.actor.system.advances.rank * 2 + (this.effect.sourceTest.testData.shifted.hardy.dice.length || 0) + this.actor.applyHealing({shock}, {messageData : this.script.getChatData()}) +} +else +{ + this.actor.applyHealing({shock : 1}, {messageData : this.script.getChatData()}) +} \ No newline at end of file diff --git a/effects/Iq9NZ7FHOFDYqkGk.js b/effects/Iq9NZ7FHOFDYqkGk.js new file mode 100644 index 0000000..c5ee7a9 --- /dev/null +++ b/effects/Iq9NZ7FHOFDYqkGk.js @@ -0,0 +1,13 @@ +if (args.item.system.isEquipped && args.item.type == "weapon" && args.item.hasKeyword("BLADE")) +{ +if (args.item._source.system.traits.list.find(i => i.name == "parry")) +{ + args.item.flags.hasParry= true; +} +else +{ + args.item.system.traits.list.push({name : "parry"}) +} + + +} \ No newline at end of file diff --git a/effects/IrgVdpyPNCZXhnet.js b/effects/IrgVdpyPNCZXhnet.js new file mode 100644 index 0000000..132e661 --- /dev/null +++ b/effects/IrgVdpyPNCZXhnet.js @@ -0,0 +1 @@ +return args.skill != "awareness" \ No newline at end of file diff --git a/effects/IsseGpLLkviAFz2R.js b/effects/IsseGpLLkviAFz2R.js new file mode 100644 index 0000000..146059b --- /dev/null +++ b/effects/IsseGpLLkviAFz2R.js @@ -0,0 +1 @@ +return args.weapon.isRanged \ No newline at end of file diff --git a/effects/Iyygo7jRj0uw2TTH.js b/effects/Iyygo7jRj0uw2TTH.js new file mode 100644 index 0000000..3a3c8ef --- /dev/null +++ b/effects/Iyygo7jRj0uw2TTH.js @@ -0,0 +1,6 @@ +if (args.combat.combatant?.token?.actor?.uuid == this.effect.sourceActor.uuid) +{ + +this.actor.setupAttributeTest("willpower", {appendTitle : ` - ${this.effect.name}`}); + +} \ No newline at end of file diff --git a/effects/JFE35oMF5rNK2udD.js b/effects/JFE35oMF5rNK2udD.js new file mode 100644 index 0000000..4e8b42f --- /dev/null +++ b/effects/JFE35oMF5rNK2udD.js @@ -0,0 +1 @@ +args.fields.pool += (this.effect.sourceTest.result.WSBonus) \ No newline at end of file diff --git a/effects/JPmpOPoLol0cnAIa.js b/effects/JPmpOPoLol0cnAIa.js new file mode 100644 index 0000000..21ed82b --- /dev/null +++ b/effects/JPmpOPoLol0cnAIa.js @@ -0,0 +1 @@ +this.effect.updateSource({name : this.effect.setSpecifier(this.effect.getFlag(game.system.id, 'value') || 1)}) \ No newline at end of file diff --git a/effects/JQbgTsNyhe6rL4lJ.js b/effects/JQbgTsNyhe6rL4lJ.js new file mode 100644 index 0000000..5e38689 --- /dev/null +++ b/effects/JQbgTsNyhe6rL4lJ.js @@ -0,0 +1 @@ +args.fields.pool += 1; \ No newline at end of file diff --git a/effects/JuKaOYhSmcApqIc1.js b/effects/JuKaOYhSmcApqIc1.js new file mode 100644 index 0000000..4600ad0 --- /dev/null +++ b/effects/JuKaOYhSmcApqIc1.js @@ -0,0 +1 @@ +args.fields.pool += this.actor.system.advances.rank \ No newline at end of file diff --git a/effects/Jyf9Km4G1kNkcEyX.js b/effects/Jyf9Km4G1kNkcEyX.js new file mode 100644 index 0000000..a6f168f --- /dev/null +++ b/effects/Jyf9Km4G1kNkcEyX.js @@ -0,0 +1 @@ +return !this.effect.specifier || args.skill != "survival" \ No newline at end of file diff --git a/effects/K0MBJAgg4qU98fxN.js b/effects/K0MBJAgg4qU98fxN.js new file mode 100644 index 0000000..113a0fb --- /dev/null +++ b/effects/K0MBJAgg4qU98fxN.js @@ -0,0 +1,4 @@ +if (args.test?.item?.flags?.hasBrutal) +{ + args.modifiers.damage.push({label : this.effect.name, value : 1}) +} \ No newline at end of file diff --git a/effects/K8eBW9NiQHrTY7jP.js b/effects/K8eBW9NiQHrTY7jP.js new file mode 100644 index 0000000..f192886 --- /dev/null +++ b/effects/K8eBW9NiQHrTY7jP.js @@ -0,0 +1 @@ +args.fields.pool += (this.effect.sourceTest.result.stealth) \ No newline at end of file diff --git a/effects/KBhnj53oQ6huS93m.js b/effects/KBhnj53oQ6huS93m.js new file mode 100644 index 0000000..7f48b40 --- /dev/null +++ b/effects/KBhnj53oQ6huS93m.js @@ -0,0 +1,14 @@ +let fear = this.actor.hasCondition("fear"); +let terror = this.actor.hasCondition("terror"); + +if (fear) +{ + this.script.notification("Removed Fear"); +} +if (terror) +{ + this.script.notification("Removed Terror"); +} + +fear?.delete(); +terror?.delete(); \ No newline at end of file diff --git a/effects/KCw9i0XxO94qhZeK.js b/effects/KCw9i0XxO94qhZeK.js new file mode 100644 index 0000000..e78b8b3 --- /dev/null +++ b/effects/KCw9i0XxO94qhZeK.js @@ -0,0 +1 @@ +return !args.options.corruption \ No newline at end of file diff --git a/effects/KInyOtvNgm4LPm6C.js b/effects/KInyOtvNgm4LPm6C.js new file mode 100644 index 0000000..8c9a686 --- /dev/null +++ b/effects/KInyOtvNgm4LPm6C.js @@ -0,0 +1 @@ +args.fields.pool += (this.effect.sourceTest.result.defenceAndStealth) \ No newline at end of file diff --git a/effects/KpRXZG54C6JQrlHG.js b/effects/KpRXZG54C6JQrlHG.js new file mode 100644 index 0000000..18afa7f --- /dev/null +++ b/effects/KpRXZG54C6JQrlHG.js @@ -0,0 +1 @@ +args.fields.difficulty += 4 \ No newline at end of file diff --git a/effects/KppzdgCK5UQ16G7M.js b/effects/KppzdgCK5UQ16G7M.js new file mode 100644 index 0000000..fec8633 --- /dev/null +++ b/effects/KppzdgCK5UQ16G7M.js @@ -0,0 +1 @@ +return !(args.target && (args.target.statuses.has("halfCover") || args.target.statuses.has("fullCover"))); \ No newline at end of file diff --git a/effects/KsnmyJkm0xCTnxTJ.js b/effects/KsnmyJkm0xCTnxTJ.js new file mode 100644 index 0000000..2091ed2 --- /dev/null +++ b/effects/KsnmyJkm0xCTnxTJ.js @@ -0,0 +1 @@ +return !args.attribute === 'willpower' && !args.options.conviction && !args.options.resolve; \ No newline at end of file diff --git a/effects/KtJx2wvotTdvRb6Z.js b/effects/KtJx2wvotTdvRb6Z.js new file mode 100644 index 0000000..f5fa3e4 --- /dev/null +++ b/effects/KtJx2wvotTdvRb6Z.js @@ -0,0 +1,6 @@ +if (args.test.result.isWrathCritical) +{ + args.modifiers.mortal.push({label: this.effect.name, value: 1}); +} + +let report = await this.actor.applyDamage(0, {mortal: 1}); \ No newline at end of file diff --git a/effects/L3U59xnZcFAwHT7C.js b/effects/L3U59xnZcFAwHT7C.js new file mode 100644 index 0000000..b54df2a --- /dev/null +++ b/effects/L3U59xnZcFAwHT7C.js @@ -0,0 +1,2 @@ +game.wng.RuinGloryCounter.changeCounter(1, "ruin"); +this.script.notification("Gained 1 Ruin"); \ No newline at end of file diff --git a/effects/LDFsgiIy9pAyTAaf.js b/effects/LDFsgiIy9pAyTAaf.js new file mode 100644 index 0000000..3b69f17 --- /dev/null +++ b/effects/LDFsgiIy9pAyTAaf.js @@ -0,0 +1,5 @@ +await this.actor.update({"system.combat.wounds.value" : this.actor.system.combat.wounds.value + this.actor.system.advances.tier}) + +this.item.effects.getName("Flagellated").update({disabled: false}) + +this.script.message(`Self-inflicted ${this.actor.system.advances.tier} Wounds`) \ No newline at end of file diff --git a/effects/LDKGK25becwc1usF.js b/effects/LDKGK25becwc1usF.js new file mode 100644 index 0000000..ed7c9f4 --- /dev/null +++ b/effects/LDKGK25becwc1usF.js @@ -0,0 +1,2 @@ +this.effect.update({name : this.effect.baseName}) +this.script.notification(`Target Cleared`) \ No newline at end of file diff --git a/effects/LGstPMwG2Wa8dmG1.js b/effects/LGstPMwG2Wa8dmG1.js new file mode 100644 index 0000000..36a3f0f --- /dev/null +++ b/effects/LGstPMwG2Wa8dmG1.js @@ -0,0 +1,6 @@ +if (args.options.resolve) +{ + this.script.notification("Does not makes Resolve Tests"); + args.abort = true; +} +else return true; \ No newline at end of file diff --git a/effects/LJSFGNiAzZ9RtrR0.js b/effects/LJSFGNiAzZ9RtrR0.js new file mode 100644 index 0000000..f69a3fa --- /dev/null +++ b/effects/LJSFGNiAzZ9RtrR0.js @@ -0,0 +1,18 @@ +let items = ["Compendium.wng-core.items.Item.JVz6FoVEc7p1DJUj", "Compendium.wng-core.items.Item.n0bj5UJjgglDzFcB"]; + +let minor = await Promise.all(["Compendium.wng-core.items.uQKBlm3iW0GYDy83", +"Compendium.wng-core.items.33nu3kaw8zNOPx8h", +"Compendium.wng-core.items.ehGa28RU82KxCDrZ", +"Compendium.wng-core.items.qPAsmaoh7YuxMAbt", +"Compendium.wng-core.items.6uxTxs8yqfJygqsG", +"Compendium.wng-core.items.rWQj4yseWbT0ffSf"].map(fromUuid)) + +let choice = await ItemDialog.create(minor, 1, {title : this.effect.name, text : "Choose 1 Rune of Battle Power"}); + +if (choice[0]) +{ + items.push(choice[0].uuid); +} + + +this.actor.createEmbeddedDocuments("Item", (await Promise.all(items.map(fromUuid))), {fromEffect: this.effect.id}); \ No newline at end of file diff --git a/effects/LOjdxoTYMCnrJIx6.js b/effects/LOjdxoTYMCnrJIx6.js new file mode 100644 index 0000000..063b862 --- /dev/null +++ b/effects/LOjdxoTYMCnrJIx6.js @@ -0,0 +1,2 @@ +let keyword = this.effect.specifier; +return args.target.hasKeyword(keyword); \ No newline at end of file diff --git a/effects/LPBJwM3xygw6bnfK.js b/effects/LPBJwM3xygw6bnfK.js new file mode 100644 index 0000000..b10ffb8 --- /dev/null +++ b/effects/LPBJwM3xygw6bnfK.js @@ -0,0 +1 @@ +return args.weapon?.id == this.effect.getFlag(game.system.id, "trademarkId") \ No newline at end of file diff --git a/effects/LahIj0aZ5UkSRMOb.js b/effects/LahIj0aZ5UkSRMOb.js new file mode 100644 index 0000000..87defc1 --- /dev/null +++ b/effects/LahIj0aZ5UkSRMOb.js @@ -0,0 +1 @@ +return args.skill != "cunning" \ No newline at end of file diff --git a/effects/LlYG6NQFN2ccsIzG.js b/effects/LlYG6NQFN2ccsIzG.js new file mode 100644 index 0000000..6f07daa --- /dev/null +++ b/effects/LlYG6NQFN2ccsIzG.js @@ -0,0 +1 @@ +return args.weapon?.isMelee \ No newline at end of file diff --git a/effects/M0LuZmdoUoSn6wBd.js b/effects/M0LuZmdoUoSn6wBd.js new file mode 100644 index 0000000..4c33be3 --- /dev/null +++ b/effects/M0LuZmdoUoSn6wBd.js @@ -0,0 +1 @@ +return args.skill != "tech" \ No newline at end of file diff --git a/effects/M6sahvW09BCRJ3NN.js b/effects/M6sahvW09BCRJ3NN.js new file mode 100644 index 0000000..16da0a0 --- /dev/null +++ b/effects/M6sahvW09BCRJ3NN.js @@ -0,0 +1 @@ +args.fields.ed.value += args.target.system.advances.tier; \ No newline at end of file diff --git a/effects/MNuH94NRXq3wbhyN.js b/effects/MNuH94NRXq3wbhyN.js new file mode 100644 index 0000000..e762a3c --- /dev/null +++ b/effects/MNuH94NRXq3wbhyN.js @@ -0,0 +1 @@ +return arg.skill != "intimidation" \ No newline at end of file diff --git a/effects/MSNac1iGV1HHHgfO.js b/effects/MSNac1iGV1HHHgfO.js new file mode 100644 index 0000000..8de814c --- /dev/null +++ b/effects/MSNac1iGV1HHHgfO.js @@ -0,0 +1 @@ +this.effect.update({disabled: true}); \ No newline at end of file diff --git a/effects/MbVTjkQEMuZi5Net.js b/effects/MbVTjkQEMuZi5Net.js new file mode 100644 index 0000000..55390d0 --- /dev/null +++ b/effects/MbVTjkQEMuZi5Net.js @@ -0,0 +1 @@ +return !args.target || !args.target?.system.advances?.tier; \ No newline at end of file diff --git a/effects/Mg5O1YeSudh3qRE5.js b/effects/Mg5O1YeSudh3qRE5.js new file mode 100644 index 0000000..4637533 --- /dev/null +++ b/effects/Mg5O1YeSudh3qRE5.js @@ -0,0 +1 @@ +args.fields.pool += 1 \ No newline at end of file diff --git a/effects/MlSeK9tDcqy1XkpH.js b/effects/MlSeK9tDcqy1XkpH.js new file mode 100644 index 0000000..b2303b8 --- /dev/null +++ b/effects/MlSeK9tDcqy1XkpH.js @@ -0,0 +1 @@ +args.mortalDetermination = true; \ No newline at end of file diff --git a/effects/MuKDLBheaG9oW0wB.js b/effects/MuKDLBheaG9oW0wB.js new file mode 100644 index 0000000..0e9dacb --- /dev/null +++ b/effects/MuKDLBheaG9oW0wB.js @@ -0,0 +1 @@ +return args.weapon?.name !== "Scoped Needle Pistol" || args.fields.range != "long"; \ No newline at end of file diff --git a/effects/NGVjoMp9wB80n7xo.js b/effects/NGVjoMp9wB80n7xo.js new file mode 100644 index 0000000..df74f65 --- /dev/null +++ b/effects/NGVjoMp9wB80n7xo.js @@ -0,0 +1 @@ +return !args.weapon || args.weapon.isRanged || !this.actor.statuses.has("wounded") \ No newline at end of file diff --git a/effects/NN1chi0lu14wYMGw.js b/effects/NN1chi0lu14wYMGw.js new file mode 100644 index 0000000..82e5ff3 --- /dev/null +++ b/effects/NN1chi0lu14wYMGw.js @@ -0,0 +1 @@ +return !["leadership", "intimidation"].includes(args.skill) \ No newline at end of file diff --git a/effects/NOL4VOguuH3lLMHP.js b/effects/NOL4VOguuH3lLMHP.js new file mode 100644 index 0000000..cb80a1d --- /dev/null +++ b/effects/NOL4VOguuH3lLMHP.js @@ -0,0 +1 @@ +this.actor.removeCondition("hindered") \ No newline at end of file diff --git a/effects/NTdpO0kFNkWuX2Ry.js b/effects/NTdpO0kFNkWuX2Ry.js new file mode 100644 index 0000000..a2da4d9 --- /dev/null +++ b/effects/NTdpO0kFNkWuX2Ry.js @@ -0,0 +1 @@ +return args.power; \ No newline at end of file diff --git a/effects/NdU2gZsMZmJOY6CM.js b/effects/NdU2gZsMZmJOY6CM.js new file mode 100644 index 0000000..fa54478 --- /dev/null +++ b/effects/NdU2gZsMZmJOY6CM.js @@ -0,0 +1 @@ +args.fields.ed.value += (this.effect.sourceTest.result.edBonus) \ No newline at end of file diff --git a/effects/NhtHwF6MBxFiV6iE.js b/effects/NhtHwF6MBxFiV6iE.js new file mode 100644 index 0000000..147969a --- /dev/null +++ b/effects/NhtHwF6MBxFiV6iE.js @@ -0,0 +1 @@ +return args.skill !== "stealth"; \ No newline at end of file diff --git a/effects/NwmyFJv6SXZZc6sR.js b/effects/NwmyFJv6SXZZc6sR.js new file mode 100644 index 0000000..026dba2 --- /dev/null +++ b/effects/NwmyFJv6SXZZc6sR.js @@ -0,0 +1,8 @@ +let dying = this.actor.hasCondition("dying") +if (dying) +{ + await dying.delete(); + await this.actor.update({"system.combat.wounds.value": this.actor.system.combat.wounds.max - 1}) + await this.effect.update({"disabled" : true}); + this.script.notification("Prevented Dying"); +} \ No newline at end of file diff --git a/effects/Nwo2XQpXvaxqkd13.js b/effects/Nwo2XQpXvaxqkd13.js new file mode 100644 index 0000000..30bf458 --- /dev/null +++ b/effects/Nwo2XQpXvaxqkd13.js @@ -0,0 +1 @@ +return != args.options.resolve; \ No newline at end of file diff --git a/effects/OZOFbqSXc32c1dcp.js b/effects/OZOFbqSXc32c1dcp.js new file mode 100644 index 0000000..2566dd5 --- /dev/null +++ b/effects/OZOFbqSXc32c1dcp.js @@ -0,0 +1 @@ +return args.weapon?.isRanged \ No newline at end of file diff --git a/effects/Ox1wW1KM6ou0u6Sd.js b/effects/Ox1wW1KM6ou0u6Sd.js new file mode 100644 index 0000000..3376454 --- /dev/null +++ b/effects/Ox1wW1KM6ou0u6Sd.js @@ -0,0 +1,2 @@ +this.actor.addCondition("prone"); +this.actor.addCondition("restrained"); \ No newline at end of file diff --git a/effects/P5SH2LHnW76styQF.js b/effects/P5SH2LHnW76styQF.js new file mode 100644 index 0000000..42de360 --- /dev/null +++ b/effects/P5SH2LHnW76styQF.js @@ -0,0 +1 @@ +return args.skill == "deception" \ No newline at end of file diff --git a/effects/PBy7IGCnIhzN1eOJ.js b/effects/PBy7IGCnIhzN1eOJ.js new file mode 100644 index 0000000..a844559 --- /dev/null +++ b/effects/PBy7IGCnIhzN1eOJ.js @@ -0,0 +1 @@ +args.fields.difficulty += this.effect.sourceActor.system.attributes.willpower.total \ No newline at end of file diff --git a/effects/PHel0Bush3ZEHpcE.js b/effects/PHel0Bush3ZEHpcE.js new file mode 100644 index 0000000..0fbd8c6 --- /dev/null +++ b/effects/PHel0Bush3ZEHpcE.js @@ -0,0 +1 @@ +return !this.effect.specifier || !args.weapon || args.weapon.isRanged \ No newline at end of file diff --git a/effects/PQVukt8ftbDCmvrA.js b/effects/PQVukt8ftbDCmvrA.js new file mode 100644 index 0000000..83ccf64 --- /dev/null +++ b/effects/PQVukt8ftbDCmvrA.js @@ -0,0 +1 @@ +return args.data.weapon; \ No newline at end of file diff --git a/effects/PYT5fqC4zkcLrnWX.js b/effects/PYT5fqC4zkcLrnWX.js new file mode 100644 index 0000000..05f2ce5 --- /dev/null +++ b/effects/PYT5fqC4zkcLrnWX.js @@ -0,0 +1 @@ +return !args.weapon.hasKeyword("SHURIKEN"); \ No newline at end of file diff --git a/effects/PrhIVyqSEt53cOvR.js b/effects/PrhIVyqSEt53cOvR.js new file mode 100644 index 0000000..bff3d73 --- /dev/null +++ b/effects/PrhIVyqSEt53cOvR.js @@ -0,0 +1 @@ +return args.type == "corruption" && this.actor.corruption.current == 0 \ No newline at end of file diff --git a/effects/PyQkC1VM4692Fw0y.js b/effects/PyQkC1VM4692Fw0y.js new file mode 100644 index 0000000..4d46ed7 --- /dev/null +++ b/effects/PyQkC1VM4692Fw0y.js @@ -0,0 +1 @@ +this.actor.applyHealing({shock : this.actor.system.advances.rank}, {messageData : this.script.getChatData()}) \ No newline at end of file diff --git a/effects/QFuGceUxNi14pKXW.js b/effects/QFuGceUxNi14pKXW.js new file mode 100644 index 0000000..1298fc6 --- /dev/null +++ b/effects/QFuGceUxNi14pKXW.js @@ -0,0 +1 @@ +return args.fields.range === "short"; \ No newline at end of file diff --git a/effects/QMumWKn7liGyHCby.js b/effects/QMumWKn7liGyHCby.js new file mode 100644 index 0000000..a18be59 --- /dev/null +++ b/effects/QMumWKn7liGyHCby.js @@ -0,0 +1,11 @@ +let effects = this.item.effects.contents.filter(i => i.id != this.effect.id); + +effects.forEach(e => { + e.update({disabled : true}) +}) + +let e = effects.find(i => i.id == "02qHBz2ng62Xg1Zx"); + +e.update({disabled : false}); + +this.script.notification(`${e.name} (+2 Defence) Activated`) \ No newline at end of file diff --git a/effects/QQk2JRCB7NvfVbuv.js b/effects/QQk2JRCB7NvfVbuv.js new file mode 100644 index 0000000..4b2ab03 --- /dev/null +++ b/effects/QQk2JRCB7NvfVbuv.js @@ -0,0 +1 @@ +return !args.weapon || args.weapon?.system.isRanged || !this.effect.specifier \ No newline at end of file diff --git a/effects/Qz75uz3MiSoTyz46.js b/effects/Qz75uz3MiSoTyz46.js new file mode 100644 index 0000000..9f0fafd --- /dev/null +++ b/effects/Qz75uz3MiSoTyz46.js @@ -0,0 +1 @@ +this.actor.system.combat.resilience.invulnerable = false; \ No newline at end of file diff --git a/effects/R1eu0gVwClSnKCEQ.js b/effects/R1eu0gVwClSnKCEQ.js new file mode 100644 index 0000000..2c12e39 --- /dev/null +++ b/effects/R1eu0gVwClSnKCEQ.js @@ -0,0 +1 @@ +return ['weaponSkill', 'ballisticSkill', 'psychicMastery'].includes(args.skill) \ No newline at end of file diff --git a/effects/R4couNzoEwZ1KiUh.js b/effects/R4couNzoEwZ1KiUh.js new file mode 100644 index 0000000..a02a949 --- /dev/null +++ b/effects/R4couNzoEwZ1KiUh.js @@ -0,0 +1 @@ +args.fields.pool += this.effect.sourceTest.result.diceBonus || 6; \ No newline at end of file diff --git a/effects/R74wexFtorXmNAOb.js b/effects/R74wexFtorXmNAOb.js new file mode 100644 index 0000000..e4c6368 --- /dev/null +++ b/effects/R74wexFtorXmNAOb.js @@ -0,0 +1 @@ +return !args.options.determination \ No newline at end of file diff --git a/effects/RP5rqKe63nxmH7tb.js b/effects/RP5rqKe63nxmH7tb.js new file mode 100644 index 0000000..94725d3 --- /dev/null +++ b/effects/RP5rqKe63nxmH7tb.js @@ -0,0 +1 @@ +args.fields.pool += (this.effect.sourceActor.system.advances.rank) \ No newline at end of file diff --git a/effects/RVndp78fwAn8MGAw.js b/effects/RVndp78fwAn8MGAw.js new file mode 100644 index 0000000..d6e084b --- /dev/null +++ b/effects/RVndp78fwAn8MGAw.js @@ -0,0 +1 @@ +return args.options.resolve; \ No newline at end of file diff --git a/effects/RWfem3ObJwrC578W.js b/effects/RWfem3ObJwrC578W.js new file mode 100644 index 0000000..a96a9f6 --- /dev/null +++ b/effects/RWfem3ObJwrC578W.js @@ -0,0 +1 @@ +return args.weapon; \ No newline at end of file diff --git a/effects/RfRy3gtFt6iVhaYx.js b/effects/RfRy3gtFt6iVhaYx.js new file mode 100644 index 0000000..1ac6e9b --- /dev/null +++ b/effects/RfRy3gtFt6iVhaYx.js @@ -0,0 +1 @@ +return !args.weapon || !args.weapon.hasKeyword("TRANSONIC") \ No newline at end of file diff --git a/effects/Se8stX2b4hTXBIkk.js b/effects/Se8stX2b4hTXBIkk.js new file mode 100644 index 0000000..6e49e6c --- /dev/null +++ b/effects/Se8stX2b4hTXBIkk.js @@ -0,0 +1 @@ +return !args.options.resist?.includes("psychicPower"); \ No newline at end of file diff --git a/effects/T5V9ecdZwk63IdLu.js b/effects/T5V9ecdZwk63IdLu.js new file mode 100644 index 0000000..2c93a57 --- /dev/null +++ b/effects/T5V9ecdZwk63IdLu.js @@ -0,0 +1,7 @@ +// Bug: https://github.com/foundryvtt/foundryvtt/issues/7987 +// Solution currently is to divide by 2 +if (args.item.system.isRanged && args.item.system.isEquipped) +{ + args.item.system.salvo += this.actor.system.advances.rank / 2; + +} \ No newline at end of file diff --git a/effects/TDDOJIV2EYJrSKg2.js b/effects/TDDOJIV2EYJrSKg2.js new file mode 100644 index 0000000..ee57975 --- /dev/null +++ b/effects/TDDOJIV2EYJrSKg2.js @@ -0,0 +1,4 @@ +let shock = -1 * this.effect.sourceTest.result.shock; +let wounds = -1 * this.effect.sourceTest.result.wounds; +args.modifiers.shock.push({label : this.effect.name, value : shock}) +args.modifiers.wounds.push({label : this.effect.name, value : wounds}) \ No newline at end of file diff --git a/effects/TGUcXMJSG170xgvh.js b/effects/TGUcXMJSG170xgvh.js new file mode 100644 index 0000000..b28676b --- /dev/null +++ b/effects/TGUcXMJSG170xgvh.js @@ -0,0 +1,7 @@ +let bleeding = this.actor.hasCondition("bleeding"); + +if (bleeding) +{ + await bleeding.delete(); + this.script.notification("Removed Bleeding"); +} \ No newline at end of file diff --git a/effects/TJDM9SqHATGH3QQF.js b/effects/TJDM9SqHATGH3QQF.js new file mode 100644 index 0000000..b28596f --- /dev/null +++ b/effects/TJDM9SqHATGH3QQF.js @@ -0,0 +1,10 @@ +if (args.item.system.isEquipped && args.item.type == "weapon") + { + let sourceBlast = args.item._source.system.traits.list.find(i => i.name == "blast") + let blast = args.item.system.traits.list.find(i => i.name == "blast"); + if (sourceBlast && !blast.bombadier) + { + blast.rating = parseInt(blast.rating) + (this.actor.system.advances.rank * 2); + blast.bombadier = true; + } + } \ No newline at end of file diff --git a/effects/TUdLSiK62ZcpBJuX.js b/effects/TUdLSiK62ZcpBJuX.js new file mode 100644 index 0000000..b0f5313 --- /dev/null +++ b/effects/TUdLSiK62ZcpBJuX.js @@ -0,0 +1 @@ +args.options.resist?.includes("psychicPower") \ No newline at end of file diff --git a/effects/Tbav4WV9QmHYGgCG.js b/effects/Tbav4WV9QmHYGgCG.js new file mode 100644 index 0000000..0cf9c9a --- /dev/null +++ b/effects/Tbav4WV9QmHYGgCG.js @@ -0,0 +1,4 @@ +if (args.fields.level != "bound" || args.fields.level != "bound") +{ + args.fields.level = "bound"; +} \ No newline at end of file diff --git a/effects/TjWyU3g5jwGR91zC.js b/effects/TjWyU3g5jwGR91zC.js new file mode 100644 index 0000000..b3b178a --- /dev/null +++ b/effects/TjWyU3g5jwGR91zC.js @@ -0,0 +1 @@ +return args.skill == "stealth" \ No newline at end of file diff --git a/effects/TvI0MSH8mIn1aYGy.js b/effects/TvI0MSH8mIn1aYGy.js new file mode 100644 index 0000000..f4a2e29 --- /dev/null +++ b/effects/TvI0MSH8mIn1aYGy.js @@ -0,0 +1 @@ +return !args.fields.distance || args.fields.distance <= 12; \ No newline at end of file diff --git a/effects/U40htgNxfnoqrQ6u.js b/effects/U40htgNxfnoqrQ6u.js new file mode 100644 index 0000000..4d134b1 --- /dev/null +++ b/effects/U40htgNxfnoqrQ6u.js @@ -0,0 +1 @@ +return args.skill != "persuasion" \ No newline at end of file diff --git a/effects/UKqVvr36UwMajuDY.js b/effects/UKqVvr36UwMajuDY.js new file mode 100644 index 0000000..b1019b9 --- /dev/null +++ b/effects/UKqVvr36UwMajuDY.js @@ -0,0 +1 @@ +return args.skill == "survival" \ No newline at end of file diff --git a/effects/UL9ufbd1T1N6bckp.js b/effects/UL9ufbd1T1N6bckp.js new file mode 100644 index 0000000..4469521 --- /dev/null +++ b/effects/UL9ufbd1T1N6bckp.js @@ -0,0 +1,2 @@ +let tens = Math.floor(args.actor.system.mob.value/10)+1; +args.fields.difficulty -= tens; \ No newline at end of file diff --git a/effects/UMEI7y4VmIn85Yab.js b/effects/UMEI7y4VmIn85Yab.js new file mode 100644 index 0000000..5df4a8a --- /dev/null +++ b/effects/UMEI7y4VmIn85Yab.js @@ -0,0 +1 @@ +return args.fields.range == "long"; \ No newline at end of file diff --git a/effects/UUBcD07BreoSeGA0.js b/effects/UUBcD07BreoSeGA0.js new file mode 100644 index 0000000..399fcf0 --- /dev/null +++ b/effects/UUBcD07BreoSeGA0.js @@ -0,0 +1 @@ +this.actor.setupGenericTest("fear", {fields : {difficulty : 2 + this.effect.sourceActor.system.advances.rank * 2}}) \ No newline at end of file diff --git a/effects/UUv4HOaIDHY9P7xP.js b/effects/UUv4HOaIDHY9P7xP.js new file mode 100644 index 0000000..a543ae6 --- /dev/null +++ b/effects/UUv4HOaIDHY9P7xP.js @@ -0,0 +1 @@ +return !["strength", "agility"].includes(args.attribute) \ No newline at end of file diff --git a/effects/Uag1H6EegkuA9dNR.js b/effects/Uag1H6EegkuA9dNR.js new file mode 100644 index 0000000..e7b7519 --- /dev/null +++ b/effects/Uag1H6EegkuA9dNR.js @@ -0,0 +1 @@ +args.fields.ed.value += (2) \ No newline at end of file diff --git a/effects/UmHQnmKvPVS19IYN.js b/effects/UmHQnmKvPVS19IYN.js new file mode 100644 index 0000000..75e500c --- /dev/null +++ b/effects/UmHQnmKvPVS19IYN.js @@ -0,0 +1 @@ +args.fields.pool += 6; \ No newline at end of file diff --git a/effects/UnNdpT7GynKzEzis.js b/effects/UnNdpT7GynKzEzis.js new file mode 100644 index 0000000..851b334 --- /dev/null +++ b/effects/UnNdpT7GynKzEzis.js @@ -0,0 +1,6 @@ +// https://github.com/foundryvtt/foundryvtt/issues/7987 +if (args.item.type == "weapon" && args.item.system.isEquipped && args.item.traitList.sniper) +{ + let sniper = args.item.system.traits.list.find(i => i.name == "sniper"); + sniper.rating = Number(sniper.rating) + this.actor.system.advances?.rank/2 || 0 +} \ No newline at end of file diff --git a/effects/V4y7lOlGw0Gyl75Q.js b/effects/V4y7lOlGw0Gyl75Q.js new file mode 100644 index 0000000..711595d --- /dev/null +++ b/effects/V4y7lOlGw0Gyl75Q.js @@ -0,0 +1 @@ +return args.skill == "weaponSkill" \ No newline at end of file diff --git a/effects/VCF9VmjA1Js7z6qj.js b/effects/VCF9VmjA1Js7z6qj.js new file mode 100644 index 0000000..edc91bc --- /dev/null +++ b/effects/VCF9VmjA1Js7z6qj.js @@ -0,0 +1 @@ +args.fields.difficulty -= 4 \ No newline at end of file diff --git a/effects/VD1UxKrbZM0n8Msc.js b/effects/VD1UxKrbZM0n8Msc.js new file mode 100644 index 0000000..9ac7a63 --- /dev/null +++ b/effects/VD1UxKrbZM0n8Msc.js @@ -0,0 +1 @@ +return args.type == "corruption" \ No newline at end of file diff --git a/effects/VFd8eBVXny9ZsSCN.js b/effects/VFd8eBVXny9ZsSCN.js new file mode 100644 index 0000000..267fce6 --- /dev/null +++ b/effects/VFd8eBVXny9ZsSCN.js @@ -0,0 +1 @@ +args.fields.pool += 2 \ No newline at end of file diff --git a/effects/VVzWEPiCwTeq6dZw.js b/effects/VVzWEPiCwTeq6dZw.js new file mode 100644 index 0000000..ca1070b --- /dev/null +++ b/effects/VVzWEPiCwTeq6dZw.js @@ -0,0 +1 @@ +args.fields.pool += this.effect.sourceActor.system.attributes.willpower.total \ No newline at end of file diff --git a/effects/VX7h2ugVigZV2QTX.js b/effects/VX7h2ugVigZV2QTX.js new file mode 100644 index 0000000..865036b --- /dev/null +++ b/effects/VX7h2ugVigZV2QTX.js @@ -0,0 +1,9 @@ +let myLeadership = this.actor.system.skills.leadership.total; +let sourceLeadership = this.effect.sourceActor.skills.leadership.total; + +if ( myLeadership < sourceLeadership ) +{ + this.actor.system.skills.leadership.total = sourceLeadership; +} + +this.script.notification(`Changed ${this.actor.name} Leadership to 12`); \ No newline at end of file diff --git a/effects/VZzAvkn1TvQwXahb.js b/effects/VZzAvkn1TvQwXahb.js new file mode 100644 index 0000000..6f3287f --- /dev/null +++ b/effects/VZzAvkn1TvQwXahb.js @@ -0,0 +1 @@ +return args.skill != "survival" \ No newline at end of file diff --git a/effects/VfTxROOPZoZJ3aik.js b/effects/VfTxROOPZoZJ3aik.js new file mode 100644 index 0000000..e20b144 --- /dev/null +++ b/effects/VfTxROOPZoZJ3aik.js @@ -0,0 +1,14 @@ +let attributes = ItemDialog.objectToArray(game.wng.config.attributes, this.effect.img); + +let lowest = Math.min(...attributes.map(i => this.actor.system.attributes[i.id].total)) + +let choices = attributes.filter(i => this.actor.system.attributes[i.id].total == lowest); + +let attribute = await ItemDialog.create(choices, 1, {title : this.effect.name, text : "Choose Attribute Bonus"}) + +if (attribute[0]) +{ + let changes = this.effect.changes.concat([]); + changes[0].key = `system.attributes.${attribute[0].id}.bonus` + this.effect.updateSource({changes}); +} \ No newline at end of file diff --git a/effects/W0fSPg1JfVFwd2jX.js b/effects/W0fSPg1JfVFwd2jX.js new file mode 100644 index 0000000..a483c36 --- /dev/null +++ b/effects/W0fSPg1JfVFwd2jX.js @@ -0,0 +1 @@ +return args.weapon.isMelee \ No newline at end of file diff --git a/effects/WwvEgSjw3K6dNf8u.js b/effects/WwvEgSjw3K6dNf8u.js new file mode 100644 index 0000000..0b3be32 --- /dev/null +++ b/effects/WwvEgSjw3K6dNf8u.js @@ -0,0 +1 @@ +return game.messages.contents(args.options.message)?.item?.type == "psychicPower" \ No newline at end of file diff --git a/effects/X5F5gjW4i2zoHgyG.js b/effects/X5F5gjW4i2zoHgyG.js new file mode 100644 index 0000000..864e847 --- /dev/null +++ b/effects/X5F5gjW4i2zoHgyG.js @@ -0,0 +1,6 @@ +if (args.options.resolve) +{ + args.abort = true; + this.script.notification("Does not need to make Resolve Tests"); +} +else return true \ No newline at end of file diff --git a/effects/XBViGGApHecicjqc.js b/effects/XBViGGApHecicjqc.js new file mode 100644 index 0000000..1ff4286 --- /dev/null +++ b/effects/XBViGGApHecicjqc.js @@ -0,0 +1 @@ +return ["persuasion", "awareness"].includes(this.skill) \ No newline at end of file diff --git a/effects/XF8GhO2pNoRH0Vlm.js b/effects/XF8GhO2pNoRH0Vlm.js new file mode 100644 index 0000000..981e594 --- /dev/null +++ b/effects/XF8GhO2pNoRH0Vlm.js @@ -0,0 +1 @@ +return args.attribute != "fellowship" \ No newline at end of file diff --git a/effects/Xce2Tubcb1lqXA5Q.js b/effects/Xce2Tubcb1lqXA5Q.js new file mode 100644 index 0000000..f522777 --- /dev/null +++ b/effects/Xce2Tubcb1lqXA5Q.js @@ -0,0 +1 @@ +return !["toughness", "willpower"].includes(args.attribute); \ No newline at end of file diff --git a/effects/Y3IDZNg7GwTNiCri.js b/effects/Y3IDZNg7GwTNiCri.js new file mode 100644 index 0000000..b3e78bf --- /dev/null +++ b/effects/Y3IDZNg7GwTNiCri.js @@ -0,0 +1,10 @@ +if (args.item.system.isEquipped && args.item.type == "weapon") + { + let sourceHeavy = args.item._source.system.traits.list.find(i => i.name == "heavy") + let heavy = args.item.system.traits.list.find(i => i.name == "heavy"); + if (sourceHeavy && !heavy.tough) + { + heavy.rating = Math.floor(parseInt(heavy.rating) / 2); + heavy.tough = true; + } + } \ No newline at end of file diff --git a/effects/Y8kmllqudMGUeRjU.js b/effects/Y8kmllqudMGUeRjU.js new file mode 100644 index 0000000..abdfb01 --- /dev/null +++ b/effects/Y8kmllqudMGUeRjU.js @@ -0,0 +1 @@ +return !["persuasion", "awareness"].includes(this.skill) \ No newline at end of file diff --git a/effects/YGRqoOFiDWUAM80D.js b/effects/YGRqoOFiDWUAM80D.js new file mode 100644 index 0000000..dc0650f --- /dev/null +++ b/effects/YGRqoOFiDWUAM80D.js @@ -0,0 +1 @@ +return !args.actor.hasKeyword("T’AU") || !args.weapon || !args.weapon.isRanged; \ No newline at end of file diff --git a/effects/YGlUiKsaxuw8X3NR.js b/effects/YGlUiKsaxuw8X3NR.js new file mode 100644 index 0000000..bbbaf46 --- /dev/null +++ b/effects/YGlUiKsaxuw8X3NR.js @@ -0,0 +1,23 @@ +if (!this.item.specifier) + { + let skills = ["awareness", + "insight", + "investigation", + "scholar"].map(i => { + return {id : i, name : systemConfig().skills[i], img : this.effect.img} + }).filter(i => this.actor.system.skills[i.id].rating >= 3); + + if (skills.length == 0) + { + this.script.notification(`No Skills match the requirement`, "error") + return false; + } + + let choice = await ItemDialog.create(skills, 1, {title : this.effect.name, text : "Select Skill"}) + + if (choice[0]) + { + this.item.updateSource({"system.test" : {type : "skill", specification : choice[0].id, dn: 3}}) + this.effect.updateSource({name : this.effect.setSpecifier(choice[0].name), "flags.wrath-and-glory.skill" : choice[0].id}); + } +} \ No newline at end of file diff --git a/effects/YIqAWv3eiLNZ5Pr0.js b/effects/YIqAWv3eiLNZ5Pr0.js new file mode 100644 index 0000000..0bd19cf --- /dev/null +++ b/effects/YIqAWv3eiLNZ5Pr0.js @@ -0,0 +1 @@ +return !(args.actor?.statuses.has("all-out-attack")); \ No newline at end of file diff --git a/effects/YPWlXm6u2WButPG4.js b/effects/YPWlXm6u2WButPG4.js new file mode 100644 index 0000000..ca441b5 --- /dev/null +++ b/effects/YPWlXm6u2WButPG4.js @@ -0,0 +1 @@ +return !args.options.multi || !args.weapon || !args.weapon.name === "Enmitic Disintegrator Pistol"; \ No newline at end of file diff --git a/effects/YnGzWisVy8f5LZst.js b/effects/YnGzWisVy8f5LZst.js new file mode 100644 index 0000000..d70e5e0 --- /dev/null +++ b/effects/YnGzWisVy8f5LZst.js @@ -0,0 +1 @@ +this.effect.update({disabled:true}); \ No newline at end of file diff --git a/effects/YnndQ9I3Zi56twmp.js b/effects/YnndQ9I3Zi56twmp.js new file mode 100644 index 0000000..2302523 --- /dev/null +++ b/effects/YnndQ9I3Zi56twmp.js @@ -0,0 +1 @@ +return !args.options.resolve \ No newline at end of file diff --git a/effects/Yr0sfyumYCoNvzxZ.js b/effects/Yr0sfyumYCoNvzxZ.js new file mode 100644 index 0000000..66df2c3 --- /dev/null +++ b/effects/Yr0sfyumYCoNvzxZ.js @@ -0,0 +1,2 @@ +// https://github.com/foundryvtt/foundryvtt/issues/7987 +this.item.system.damage.base++; \ No newline at end of file diff --git a/effects/YscjjvV6TPuV9o2J.js b/effects/YscjjvV6TPuV9o2J.js new file mode 100644 index 0000000..b82d3b2 --- /dev/null +++ b/effects/YscjjvV6TPuV9o2J.js @@ -0,0 +1,8 @@ +let attribute = await ItemDialog.create(ItemDialog.objectToArray(game.wng.config.attributes, this.effect.img), 1, {title : this.effect.name, text : "Choose Attribute Bonus"}) + +if (attribute[0]) +{ + let changes = this.effect.changes.concat([]); + changes[0].key = `system.attributes.${attribute[0].id}.bonus` + this.effect.updateSource({changes}); +} \ No newline at end of file diff --git a/effects/YvhKDakdl9g5OLv7.js b/effects/YvhKDakdl9g5OLv7.js new file mode 100644 index 0000000..052f289 --- /dev/null +++ b/effects/YvhKDakdl9g5OLv7.js @@ -0,0 +1,2 @@ +args.fields.damageDice.values.threes += 1; +args.fields.damageDice.values.fives += 1; \ No newline at end of file diff --git a/effects/ZYHZu79DqOc6La3G.js b/effects/ZYHZu79DqOc6La3G.js new file mode 100644 index 0000000..95e810f --- /dev/null +++ b/effects/ZYHZu79DqOc6La3G.js @@ -0,0 +1 @@ +return args.fields.range !== "short"; \ No newline at end of file diff --git a/effects/ZbLoaXOcJ1yMQo5h.js b/effects/ZbLoaXOcJ1yMQo5h.js new file mode 100644 index 0000000..f5dfa81 --- /dev/null +++ b/effects/ZbLoaXOcJ1yMQo5h.js @@ -0,0 +1 @@ +return !["fellowship", "willpower"].includes(args.attribute) \ No newline at end of file diff --git a/effects/ZcwvQDFMK104NTm5.js b/effects/ZcwvQDFMK104NTm5.js new file mode 100644 index 0000000..5e5684e --- /dev/null +++ b/effects/ZcwvQDFMK104NTm5.js @@ -0,0 +1 @@ +return !args.options.fear \ No newline at end of file diff --git a/effects/ZpL6lIJAuwgECrSe.js b/effects/ZpL6lIJAuwgECrSe.js new file mode 100644 index 0000000..4d2dc06 --- /dev/null +++ b/effects/ZpL6lIJAuwgECrSe.js @@ -0,0 +1 @@ +args.fields.difficulty += 1; \ No newline at end of file diff --git a/effects/ZyZcLrPbd5oVwHA5.js b/effects/ZyZcLrPbd5oVwHA5.js new file mode 100644 index 0000000..83a0729 --- /dev/null +++ b/effects/ZyZcLrPbd5oVwHA5.js @@ -0,0 +1 @@ +return args.target.statuses.has("wounded"); \ No newline at end of file diff --git a/effects/aNDK8GD9IdkGnfDp.js b/effects/aNDK8GD9IdkGnfDp.js new file mode 100644 index 0000000..c02e24f --- /dev/null +++ b/effects/aNDK8GD9IdkGnfDp.js @@ -0,0 +1,2 @@ +await this.actor.removeCondition("hindered"); +await this.actor.removeCondition("staggered"); \ No newline at end of file diff --git a/effects/aWRkB6WqmN7V7qfd.js b/effects/aWRkB6WqmN7V7qfd.js new file mode 100644 index 0000000..1241790 --- /dev/null +++ b/effects/aWRkB6WqmN7V7qfd.js @@ -0,0 +1 @@ +return args.weapon.hasKeyword("PRIMARIS") \ No newline at end of file diff --git a/effects/b6K8xiDfpDlxb96b.js b/effects/b6K8xiDfpDlxb96b.js new file mode 100644 index 0000000..a468568 --- /dev/null +++ b/effects/b6K8xiDfpDlxb96b.js @@ -0,0 +1,3 @@ +let shock = this.effect.sourceActor.system.advances.rank + this.effect.sourceTest.result.success; + +this.actor.applyHealing({shock}, {messageData : this.script.getChatData()}) \ No newline at end of file diff --git a/effects/bEBclpmgLB2SmDVx.js b/effects/bEBclpmgLB2SmDVx.js new file mode 100644 index 0000000..2c3e80e --- /dev/null +++ b/effects/bEBclpmgLB2SmDVx.js @@ -0,0 +1,3 @@ +let report = await this.actor.applyDamage(0, {shock : this.effect.sourceTest.result.damage.other.shock}); + +this.script.message(`Received ${report.shock} Shock`) \ No newline at end of file diff --git a/effects/bO7RVQxWDsfuUohf.js b/effects/bO7RVQxWDsfuUohf.js new file mode 100644 index 0000000..2ead2d3 --- /dev/null +++ b/effects/bO7RVQxWDsfuUohf.js @@ -0,0 +1 @@ +args.fields.pool++; \ No newline at end of file diff --git a/effects/bbOJCIdPMEDS495T.js b/effects/bbOJCIdPMEDS495T.js new file mode 100644 index 0000000..51536fc --- /dev/null +++ b/effects/bbOJCIdPMEDS495T.js @@ -0,0 +1 @@ +args.fields.pool += (args.actor.system.advances.rank) * 2 \ No newline at end of file diff --git a/effects/bcKrdTt3aB5s82eZ.js b/effects/bcKrdTt3aB5s82eZ.js new file mode 100644 index 0000000..2a92563 --- /dev/null +++ b/effects/bcKrdTt3aB5s82eZ.js @@ -0,0 +1 @@ +return true \ No newline at end of file diff --git a/effects/bcdbbWzqxibNRaRP.js b/effects/bcdbbWzqxibNRaRP.js new file mode 100644 index 0000000..606127f --- /dev/null +++ b/effects/bcdbbWzqxibNRaRP.js @@ -0,0 +1 @@ +args.fields.pool += 2; \ No newline at end of file diff --git a/effects/biqrW5UvHRnioFQ0.js b/effects/biqrW5UvHRnioFQ0.js new file mode 100644 index 0000000..23ddf0f --- /dev/null +++ b/effects/biqrW5UvHRnioFQ0.js @@ -0,0 +1 @@ +args.fields.difficulty += (6) \ No newline at end of file diff --git a/effects/boHWspNKuKRlaOOL.js b/effects/boHWspNKuKRlaOOL.js new file mode 100644 index 0000000..ee1c983 --- /dev/null +++ b/effects/boHWspNKuKRlaOOL.js @@ -0,0 +1 @@ +args.fields.difficulty += this.actor.system.advances.rank; \ No newline at end of file diff --git a/effects/bx9Bt3I9YwXxtjEN.js b/effects/bx9Bt3I9YwXxtjEN.js new file mode 100644 index 0000000..c9993f0 --- /dev/null +++ b/effects/bx9Bt3I9YwXxtjEN.js @@ -0,0 +1 @@ +return !(args.options.conviction || args.options.resolve || args.weapon); \ No newline at end of file diff --git a/effects/cIGjQHAk6i6ApYAT.js b/effects/cIGjQHAk6i6ApYAT.js new file mode 100644 index 0000000..9b1efd4 --- /dev/null +++ b/effects/cIGjQHAk6i6ApYAT.js @@ -0,0 +1 @@ +args.fields.difficulty += 3; \ No newline at end of file diff --git a/effects/cUIaXaZ59uSkucyk.js b/effects/cUIaXaZ59uSkucyk.js new file mode 100644 index 0000000..cdd180a --- /dev/null +++ b/effects/cUIaXaZ59uSkucyk.js @@ -0,0 +1 @@ +this.actor.system.combat.defence.bonus -= parseInt(this.effect.specifier) \ No newline at end of file diff --git a/effects/cbpC5gCRrKi2riOK.js b/effects/cbpC5gCRrKi2riOK.js new file mode 100644 index 0000000..626fb2c --- /dev/null +++ b/effects/cbpC5gCRrKi2riOK.js @@ -0,0 +1,6 @@ +let tens = Math.floor(this.actor.system.mob.value/10)+1; + +let roll = await new Roll(`${tens}d3`).roll(); + +let report = await this.actor.applyDamage(0, {shock: roll.total}); +this.script.message(`Received ${report.shock} Shock and ${report.wounds} Wounds`); \ No newline at end of file diff --git a/effects/ciIOQivfHgjLInjy.js b/effects/ciIOQivfHgjLInjy.js new file mode 100644 index 0000000..6ae9884 --- /dev/null +++ b/effects/ciIOQivfHgjLInjy.js @@ -0,0 +1 @@ +return !(args.data.skill === 'intimidation' || args.data.skill === 'leadership' || args.data.skill === 'weaponSkill') \ No newline at end of file diff --git a/effects/cidgP9Os1NMnvJe7.js b/effects/cidgP9Os1NMnvJe7.js new file mode 100644 index 0000000..3312cbd --- /dev/null +++ b/effects/cidgP9Os1NMnvJe7.js @@ -0,0 +1 @@ +return !args.weapon || args.weapon.isMelee \ No newline at end of file diff --git a/effects/clYKgwwkDUQ0FSix.js b/effects/clYKgwwkDUQ0FSix.js new file mode 100644 index 0000000..563db29 --- /dev/null +++ b/effects/clYKgwwkDUQ0FSix.js @@ -0,0 +1 @@ +return !args.weapon || !args.weapon.traitList.melta \ No newline at end of file diff --git a/effects/cxyuhg9WV7F6Lo7P.js b/effects/cxyuhg9WV7F6Lo7P.js new file mode 100644 index 0000000..b54fc75 --- /dev/null +++ b/effects/cxyuhg9WV7F6Lo7P.js @@ -0,0 +1 @@ +args.fields.pool += args.target.system.advances.tier; \ No newline at end of file diff --git a/effects/d5tnbLn5zQfV1vF4.js b/effects/d5tnbLn5zQfV1vF4.js new file mode 100644 index 0000000..6364007 --- /dev/null +++ b/effects/d5tnbLn5zQfV1vF4.js @@ -0,0 +1,8 @@ +let weapons = this.actor.itemTypes.weapon; + +let choice = await ItemDialog.create(weapons, 1, {title : this.effect.name}); + +if (choice[0]) +{ + this.effect.update({name : this.effect.baseName + ` [${choice[0].name}]`, "flags.wrath-and-glory.trademarkId" : choice[0].id}); +} \ No newline at end of file diff --git a/effects/dKN6CmYlcO09U6Y7.js b/effects/dKN6CmYlcO09U6Y7.js new file mode 100644 index 0000000..59a2110 --- /dev/null +++ b/effects/dKN6CmYlcO09U6Y7.js @@ -0,0 +1,19 @@ +let item = { + name : "Conjured Flame", + img : this.effect.img, + type : "weapon", + system : { + damage : { + base : 8, + ed : { + base: this.effect.sourceTest.result.damage.ed.value + } + }, + traits : [{name : "inflict", rating : "On Fire"}], + equipped : true + } +} + +this.actor.createEmbeddedDocuments("Item", [item], {fromEffect: this.effect.id}) + +this.script.notification("Weapon Created"); \ No newline at end of file diff --git a/effects/dQyH83wQOByoYt2s.js b/effects/dQyH83wQOByoYt2s.js new file mode 100644 index 0000000..8e5158c --- /dev/null +++ b/effects/dQyH83wQOByoYt2s.js @@ -0,0 +1 @@ +return args.skill != "intimidation" \ No newline at end of file diff --git a/effects/dkcoIue3tbSIzlgV.js b/effects/dkcoIue3tbSIzlgV.js new file mode 100644 index 0000000..ddf4640 --- /dev/null +++ b/effects/dkcoIue3tbSIzlgV.js @@ -0,0 +1 @@ +return args.type == "fear" || args.type == "terror" \ No newline at end of file diff --git a/effects/dpBhmA2SdRssy2fV.js b/effects/dpBhmA2SdRssy2fV.js new file mode 100644 index 0000000..c759738 --- /dev/null +++ b/effects/dpBhmA2SdRssy2fV.js @@ -0,0 +1 @@ +return !args.actor.hasKeyword("GENESTEALER CULT"); \ No newline at end of file diff --git a/effects/dq3xsmx7ETI0RgVp.js b/effects/dq3xsmx7ETI0RgVp.js new file mode 100644 index 0000000..7662c73 --- /dev/null +++ b/effects/dq3xsmx7ETI0RgVp.js @@ -0,0 +1 @@ +return !["medicae", "survival"].includes(args.skill) \ No newline at end of file diff --git a/effects/e7Wh5Ni04a11zdxU.js b/effects/e7Wh5Ni04a11zdxU.js new file mode 100644 index 0000000..7a61e46 --- /dev/null +++ b/effects/e7Wh5Ni04a11zdxU.js @@ -0,0 +1 @@ +args.actor.addCondition("frenzied"); \ No newline at end of file diff --git a/effects/e8GHDZcASdS27Moy.js b/effects/e8GHDZcASdS27Moy.js new file mode 100644 index 0000000..2b9b496 --- /dev/null +++ b/effects/e8GHDZcASdS27Moy.js @@ -0,0 +1 @@ +return args.skill == "awareness" \ No newline at end of file diff --git a/effects/eG9sXowL54uhuTNy.js b/effects/eG9sXowL54uhuTNy.js new file mode 100644 index 0000000..ce2dd78 --- /dev/null +++ b/effects/eG9sXowL54uhuTNy.js @@ -0,0 +1,2 @@ +let report = await this.actor.applyDamage(0, {shock: 1}); +this.script.message(`Received ${report.shock} Shock`); \ No newline at end of file diff --git a/effects/eJHmdYEuhaW2NF1W.js b/effects/eJHmdYEuhaW2NF1W.js new file mode 100644 index 0000000..f3c0b09 --- /dev/null +++ b/effects/eJHmdYEuhaW2NF1W.js @@ -0,0 +1,4 @@ +if (args.wounds || args.mortal) +{ + this.item.effects.getName("Inured to Suffering").update({disabled: false}); +} \ No newline at end of file diff --git a/effects/emLoEakrPK482SEL.js b/effects/emLoEakrPK482SEL.js new file mode 100644 index 0000000..b304698 --- /dev/null +++ b/effects/emLoEakrPK482SEL.js @@ -0,0 +1 @@ +return args.options.determination || args.skill == "tech" \ No newline at end of file diff --git a/effects/esqNRqLBFcUG672G.js b/effects/esqNRqLBFcUG672G.js new file mode 100644 index 0000000..2879270 --- /dev/null +++ b/effects/esqNRqLBFcUG672G.js @@ -0,0 +1 @@ +this.actor.setupGenericTest("corruption", {fields: {difficulty: 5}}) \ No newline at end of file diff --git a/effects/f0I4agsEbXn6mHqf.js b/effects/f0I4agsEbXn6mHqf.js new file mode 100644 index 0000000..067c43e --- /dev/null +++ b/effects/f0I4agsEbXn6mHqf.js @@ -0,0 +1 @@ +return !args.weapon || !args.weapon.isRanged; \ No newline at end of file diff --git a/effects/f8HCFia4qPsSeOCY.js b/effects/f8HCFia4qPsSeOCY.js new file mode 100644 index 0000000..196b2f6 --- /dev/null +++ b/effects/f8HCFia4qPsSeOCY.js @@ -0,0 +1,24 @@ +if (this.item.specifier == "Skill") + { + let skills = ["awareness", + "cunning", + "deception", + "insight", + "persuasion", + "psychicMastery", + "stealth"].map(i => { + return {id : i, name : systemConfig().skills[i], img : this.effect.img} + }); + let choice = await ItemDialog.create(skills, 1, {title : this.effect.name, text : "Select Skill"}) + if (choice[0]) + { + if (this.actor.system.skills[choice[0].id].rating < 1) + { + this.script.notification(`${choice[0].name} Rating not high enough.`, "error") + return false; + } + + this.item.updateSource({name : this.item.name.replace("Skill", choice[0].name), "system.test" : {type : "skill", specification : choice[0].id}}) + this.effect.updateSource({name : `${this.item.name}`}); + } +} \ No newline at end of file diff --git a/effects/fUpCX9Lnd15Z0jUB.js b/effects/fUpCX9Lnd15Z0jUB.js new file mode 100644 index 0000000..1d6018c --- /dev/null +++ b/effects/fUpCX9Lnd15Z0jUB.js @@ -0,0 +1 @@ +args.fields.difficulty += 2; \ No newline at end of file diff --git a/effects/fXsyrJNCwm9DOsx9.js b/effects/fXsyrJNCwm9DOsx9.js new file mode 100644 index 0000000..bd6ad69 --- /dev/null +++ b/effects/fXsyrJNCwm9DOsx9.js @@ -0,0 +1 @@ +return !args.weapon || args.weapon?.isMelee \ No newline at end of file diff --git a/effects/fZzIVhGLtV3RA31t.js b/effects/fZzIVhGLtV3RA31t.js new file mode 100644 index 0000000..531fde2 --- /dev/null +++ b/effects/fZzIVhGLtV3RA31t.js @@ -0,0 +1 @@ +return !["deception", "cunning", "insight", "intimidation", "investigation", "leadership", "persuasion", "pilot", "tech"].includes(args.skill) \ No newline at end of file diff --git a/effects/faj4Tr2pW6zS5CRt.js b/effects/faj4Tr2pW6zS5CRt.js new file mode 100644 index 0000000..4c138f8 --- /dev/null +++ b/effects/faj4Tr2pW6zS5CRt.js @@ -0,0 +1 @@ +return !args.weapon || !args.weapon.isMelee || !args.target.system.advances?.tier; \ No newline at end of file diff --git a/effects/fdS0NlIwU6x2rhda.js b/effects/fdS0NlIwU6x2rhda.js new file mode 100644 index 0000000..f6a7949 --- /dev/null +++ b/effects/fdS0NlIwU6x2rhda.js @@ -0,0 +1 @@ +return !args.weapon; \ No newline at end of file diff --git a/effects/feoIt14PYzLJm1vT.js b/effects/feoIt14PYzLJm1vT.js new file mode 100644 index 0000000..24f96ed --- /dev/null +++ b/effects/feoIt14PYzLJm1vT.js @@ -0,0 +1,3 @@ +this.actor.update({"system.corruption.current" : this.actor.system.corruption.current + 2}); + +this.script.notification("Added +2 Corruption"); \ No newline at end of file diff --git a/effects/g4vy06YF8IUFWbl4.js b/effects/g4vy06YF8IUFWbl4.js new file mode 100644 index 0000000..394ad61 --- /dev/null +++ b/effects/g4vy06YF8IUFWbl4.js @@ -0,0 +1,7 @@ +if (this.effect.sourceActor?.uuid == this.actor.uuid) +{ + if (this.effect.flags.round + 1 < game.combat.round) + { + this.effect.delete(); + } +} \ No newline at end of file diff --git a/effects/g6U46b1iRvU2GxZu.js b/effects/g6U46b1iRvU2GxZu.js new file mode 100644 index 0000000..20d187e --- /dev/null +++ b/effects/g6U46b1iRvU2GxZu.js @@ -0,0 +1 @@ +return args.weapon?.system.isMelee; \ No newline at end of file diff --git a/effects/gE6rYsCMIGx9uqej.js b/effects/gE6rYsCMIGx9uqej.js new file mode 100644 index 0000000..358dc66 --- /dev/null +++ b/effects/gE6rYsCMIGx9uqej.js @@ -0,0 +1 @@ +return !args.weapon || !args.options.multi || !args.weapon || !args.weapon.isMelee; \ No newline at end of file diff --git a/effects/gVMLKdINaJJR5wcF.js b/effects/gVMLKdINaJJR5wcF.js new file mode 100644 index 0000000..d9991e1 --- /dev/null +++ b/effects/gVMLKdINaJJR5wcF.js @@ -0,0 +1 @@ +return !args.weapon || (game.combat && game.combat.round >= 2) \ No newline at end of file diff --git a/effects/gdX6k8VbLy89KTLH.js b/effects/gdX6k8VbLy89KTLH.js new file mode 100644 index 0000000..60b6193 --- /dev/null +++ b/effects/gdX6k8VbLy89KTLH.js @@ -0,0 +1 @@ +args.fields.difficulty += (args.actor.system.advances.rank * -2) \ No newline at end of file diff --git a/effects/gfVWHScavZx37MZG.js b/effects/gfVWHScavZx37MZG.js new file mode 100644 index 0000000..df3a0a3 --- /dev/null +++ b/effects/gfVWHScavZx37MZG.js @@ -0,0 +1 @@ +return !["cunning", "awareness", "insight", "survival"].includes(args.skill); \ No newline at end of file diff --git a/effects/groMMm7RpgZ9xZoZ.js b/effects/groMMm7RpgZ9xZoZ.js new file mode 100644 index 0000000..6045fc0 --- /dev/null +++ b/effects/groMMm7RpgZ9xZoZ.js @@ -0,0 +1 @@ +return !args.actor.statuses.has("wounded") \ No newline at end of file diff --git a/effects/gy3QCEOr9LvlCAmi.js b/effects/gy3QCEOr9LvlCAmi.js new file mode 100644 index 0000000..4bed2b2 --- /dev/null +++ b/effects/gy3QCEOr9LvlCAmi.js @@ -0,0 +1 @@ +return !args.power; \ No newline at end of file diff --git a/effects/gyxdbmv7FzoaojFc.js b/effects/gyxdbmv7FzoaojFc.js new file mode 100644 index 0000000..04b87de --- /dev/null +++ b/effects/gyxdbmv7FzoaojFc.js @@ -0,0 +1,2 @@ +await this.actor.addCondition("hindered", {[game.system.id]:{value : 2}}); +await this.actor.addCondition("staggered"); \ No newline at end of file diff --git a/effects/gztDZA9KRVN9CQrj.js b/effects/gztDZA9KRVN9CQrj.js new file mode 100644 index 0000000..7f30ec7 --- /dev/null +++ b/effects/gztDZA9KRVN9CQrj.js @@ -0,0 +1,7 @@ +if (this.effect.sourceTest.result.brutal && args.item.system.isEquipped) +{ + if (!args.item._source.system.traits.list.find(i => i.name == "brutal")) + { + args.item.system.traits.list.push({name : "brutal"}); + } +} \ No newline at end of file diff --git a/effects/hCdc6hojBo66Z36H.js b/effects/hCdc6hojBo66Z36H.js new file mode 100644 index 0000000..6369f27 --- /dev/null +++ b/effects/hCdc6hojBo66Z36H.js @@ -0,0 +1,31 @@ +let condition = this.actor.hasCondition("blinded"); + +if (condition) +{ + await condition.delete(); + this.script.notification("Removed Blinded"); +} + +condition = this.actor.hasCondition("fear"); + +if (condition) +{ + await condition.delete(); + this.script.notification("Removed Fear"); +} + +condition = this.actor.hasCondition("poisoned"); + +if (condition) +{ + await condition.delete(); + this.script.notification("Removed Poisoned"); +} + +condition = this.actor.hasCondition("terror"); + +if (condition) +{ + await condition.delete(); + this.script.notification("Removed Terror"); +} \ No newline at end of file diff --git a/effects/hP5AxqFBRSCq2mX4.js b/effects/hP5AxqFBRSCq2mX4.js new file mode 100644 index 0000000..51481ab --- /dev/null +++ b/effects/hP5AxqFBRSCq2mX4.js @@ -0,0 +1,7 @@ +let staggered = this.actor.hasCondition("staggered"); + +if (staggered) +{ + await staggered.delete(); + this.script.notification("Removed Staggered"); +} \ No newline at end of file diff --git a/effects/hbQOSfNRBLjzxruD.js b/effects/hbQOSfNRBLjzxruD.js new file mode 100644 index 0000000..1038f11 --- /dev/null +++ b/effects/hbQOSfNRBLjzxruD.js @@ -0,0 +1 @@ +return args.data.skill !== 'tech'; \ No newline at end of file diff --git a/effects/hd7u8cpFQrwFfL9W.js b/effects/hd7u8cpFQrwFfL9W.js new file mode 100644 index 0000000..ff22abf --- /dev/null +++ b/effects/hd7u8cpFQrwFfL9W.js @@ -0,0 +1,7 @@ +if (!args.item.isRanged) + return; + +if (!args.item._source.system.traits.list.find(i => i.name == "inflict")) +{ + args.item.system.traits.list.push({name : "inflict", rating:"Vulnerable"}); +} \ No newline at end of file diff --git a/effects/i3I9MGTg7KK7Oozg.js b/effects/i3I9MGTg7KK7Oozg.js new file mode 100644 index 0000000..b80c391 --- /dev/null +++ b/effects/i3I9MGTg7KK7Oozg.js @@ -0,0 +1,2 @@ +let tens = Math.floor(args.actor.system.mob.value/10)+1; +this.script.message(`Add ${tens} icons to result`); \ No newline at end of file diff --git a/effects/i5yUEQiCIo2NKTwR.js b/effects/i5yUEQiCIo2NKTwR.js new file mode 100644 index 0000000..7d5eff3 --- /dev/null +++ b/effects/i5yUEQiCIo2NKTwR.js @@ -0,0 +1,4 @@ +let shock = Math.ceil(CONFIG.Dice.randomUniform() * 3); + +let report = await this.actor.applyDamage(0, {shock}); +this.script.message(`Received ${report.shock} Shock`); \ No newline at end of file diff --git a/effects/iD1bb8lFykvNCIk4.js b/effects/iD1bb8lFykvNCIk4.js new file mode 100644 index 0000000..315d50e --- /dev/null +++ b/effects/iD1bb8lFykvNCIk4.js @@ -0,0 +1,26 @@ +let items = ["Compendium.wng-core.items.Item.JVz6FoVEc7p1DJUj", "Compendium.wng-core.items.Item.n0bj5UJjgglDzFcB"]; + +let minor = await Promise.all(["Compendium.wng-core.items.KlfSjb1rKKdlYFhc", +"Compendium.wng-core.items.jbIQTvBy7CwO2h5z", +"Compendium.wng-core.items.9AnDpmrRMN5HuerR", +"Compendium.wng-core.items.hR56lZzY4JEW2JPC", +"Compendium.wng-core.items.oIHSFm0K5bAMjIvi", +"Compendium.wng-core.items.osDMPEt7SXTRS7bS", +"Compendium.wng-core.items.3FHZYIJhjgW9IIWB", +"Compendium.wng-core.items.49mSzarl5rOSp2Cb", +"Compendium.wng-core.items.I3705lKAu41owyp3", +"Compendium.wng-core.items.sNtFVD9vHeZmrRO4", +"Compendium.wng-core.items.cb8NYMnLIkt8dp4j", +"Compendium.wng-core.items.pITmVVUIbdcsigzp", +"Compendium.wng-core.items.XaPBgatbPT7tqArI", +"Compendium.wng-core.items.rLmWz3gH7TBmf5IH"].map(fromUuid)) + +let choice = await ItemDialog.create(minor, 1, {title : this.effect.name, text : "Choose 1 Minor Psychic Power"}); + +if (choice[0]) +{ + items.push(choice[0].uuid); +} + + +this.actor.createEmbeddedDocuments("Item", (await Promise.all(items.map(fromUuid))), {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/effects/iU6ad2a8CqtrxBJN.js b/effects/iU6ad2a8CqtrxBJN.js new file mode 100644 index 0000000..c99b4e8 --- /dev/null +++ b/effects/iU6ad2a8CqtrxBJN.js @@ -0,0 +1 @@ +args.fields.difficulty -= 1; \ No newline at end of file diff --git a/effects/iUUp4ouubYFUgtuB.js b/effects/iUUp4ouubYFUgtuB.js new file mode 100644 index 0000000..4533c4c --- /dev/null +++ b/effects/iUUp4ouubYFUgtuB.js @@ -0,0 +1,4 @@ +if (args.combat.combatant?.token?.actor.uuid == this.effect.sourceActor.uuid) +{ + this.effect.delete(); +} \ No newline at end of file diff --git a/effects/iYe5V7unJwy6gUOF.js b/effects/iYe5V7unJwy6gUOF.js new file mode 100644 index 0000000..c7a991f --- /dev/null +++ b/effects/iYe5V7unJwy6gUOF.js @@ -0,0 +1 @@ +return args.attribute != "willpower" \ No newline at end of file diff --git a/effects/idV6ioTFaIuald60.js b/effects/idV6ioTFaIuald60.js new file mode 100644 index 0000000..75e2462 --- /dev/null +++ b/effects/idV6ioTFaIuald60.js @@ -0,0 +1,11 @@ +let roll = await new Roll("dp").roll(); +roll.toMessage(this.script.getChatData()); + +if (roll.total == 6) +{ + await this.actor.applyHealing({wounds: 1, shock: 1}, {messageData : this.script.getChatData()}); + this.actor.removeCondition("dying"); + this.actor.removeCondition("exhausted"); + this.actor.removeCondition("prone"); + this.actor.removeCondition("dead"); +} \ No newline at end of file diff --git a/effects/ij6jW9sSSvHbJwBw.js b/effects/ij6jW9sSSvHbJwBw.js new file mode 100644 index 0000000..be7fde5 --- /dev/null +++ b/effects/ij6jW9sSSvHbJwBw.js @@ -0,0 +1 @@ +args.fields.ignoreShock = true; \ No newline at end of file diff --git a/effects/ijii6HywL12e3Xig.js b/effects/ijii6HywL12e3Xig.js new file mode 100644 index 0000000..f5dc238 --- /dev/null +++ b/effects/ijii6HywL12e3Xig.js @@ -0,0 +1,18 @@ +if (!this.item.name.includes("(")) +{ + let name = this.item.name + + let choice = await ItemDialog.create(ItemDialog.objectToArray({ + taste: "Taste", + sight: "Sight", + smell: "Smell", + hearing: "Hearing", + touch: "Touch" + }, this.item.img), 1, { title: this.item.name, text: "Choose Sense" }); + + if (choice[0]) { + name += ` (${choice[0].name})` + } + this.item.updateSource({ name }) + this.effect.updateSource({ name }) +} \ No newline at end of file diff --git a/effects/iuF3ZVp1EogwdWXe.js b/effects/iuF3ZVp1EogwdWXe.js new file mode 100644 index 0000000..777c8ef --- /dev/null +++ b/effects/iuF3ZVp1EogwdWXe.js @@ -0,0 +1,9 @@ +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: this.script.name}); + +if (choice[0]) +{ + this.item.updateSource({name : this.item.name.replace("Trait", choice[0].name)}); + choice[0].updateSource({name : `Uncanny [${choice[0].name}]`, "system.transferData.type" : "document"}) +} \ No newline at end of file diff --git a/effects/jUuLH5m3pmWbcJNv.js b/effects/jUuLH5m3pmWbcJNv.js new file mode 100644 index 0000000..ff3dd04 --- /dev/null +++ b/effects/jUuLH5m3pmWbcJNv.js @@ -0,0 +1,2 @@ +await this.actor.removeCondition("vulnerable") +await this.actor.removeCondition("hindered") \ No newline at end of file diff --git a/effects/jmbP7QbNLBiGWdqb.js b/effects/jmbP7QbNLBiGWdqb.js new file mode 100644 index 0000000..6cd8310 --- /dev/null +++ b/effects/jmbP7QbNLBiGWdqb.js @@ -0,0 +1 @@ +return args.target?.hasKeyword(["CHAOS", "HERETIC"]); \ No newline at end of file diff --git a/effects/jsAmDWF0lCJDY5ds.js b/effects/jsAmDWF0lCJDY5ds.js new file mode 100644 index 0000000..58c9c9d --- /dev/null +++ b/effects/jsAmDWF0lCJDY5ds.js @@ -0,0 +1 @@ +return args.skill != "stealth"; \ No newline at end of file diff --git a/effects/jsuGIGHvoi6kIwlg.js b/effects/jsuGIGHvoi6kIwlg.js new file mode 100644 index 0000000..0fda8a4 --- /dev/null +++ b/effects/jsuGIGHvoi6kIwlg.js @@ -0,0 +1 @@ +return args.skill == "medicae" \ No newline at end of file diff --git a/effects/k5rHY4zyz4eHaK9p.js b/effects/k5rHY4zyz4eHaK9p.js new file mode 100644 index 0000000..a0079e9 --- /dev/null +++ b/effects/k5rHY4zyz4eHaK9p.js @@ -0,0 +1 @@ +return args.attribute != "weaponSkill" \ No newline at end of file diff --git a/effects/k8GTyix8MCn3Aav5.js b/effects/k8GTyix8MCn3Aav5.js new file mode 100644 index 0000000..6728e8f --- /dev/null +++ b/effects/k8GTyix8MCn3Aav5.js @@ -0,0 +1,9 @@ +if (this.item.name.includes("Keyword")) +{ + let choice = await ValueDialog.create({text: "Enter Loremaster Keyword", title : this.effect.name}); + if (choice) + { + this.item.updateSource({name : this.item.name.replace("Keyword", choice.toUpperCase())}); + this.effect.updateSource({name : this.item.name}); + } +} \ No newline at end of file diff --git a/effects/kVDQ1CJOLAipZJDF.js b/effects/kVDQ1CJOLAipZJDF.js new file mode 100644 index 0000000..dd85212 --- /dev/null +++ b/effects/kVDQ1CJOLAipZJDF.js @@ -0,0 +1,2 @@ +args.fields.ed.value += (args.actor.system.advances.rank) +args.fields.ap.value -= (args.actor.system.advances.rank) \ No newline at end of file diff --git a/effects/kWmUhKdfROjmN14D.js b/effects/kWmUhKdfROjmN14D.js new file mode 100644 index 0000000..0250b5e --- /dev/null +++ b/effects/kWmUhKdfROjmN14D.js @@ -0,0 +1 @@ +this.actor.removeCondition("frenzied"); \ No newline at end of file diff --git a/effects/kYVIfxAaw5yVlv7q.js b/effects/kYVIfxAaw5yVlv7q.js new file mode 100644 index 0000000..19499ba --- /dev/null +++ b/effects/kYVIfxAaw5yVlv7q.js @@ -0,0 +1,7 @@ +// Bug: https://github.com/foundryvtt/foundryvtt/issues/7987 +// Solution currently is to divide by 2 +if (args.item.system.isRanged && args.item.system.isEquipped && args.item.hasKeyword("PROJECTILE")) +{ + args.item.system.salvo += this.actor.system.advances.rank / 2; + +} \ No newline at end of file diff --git a/effects/kaeQpP8uopwR3lEu.js b/effects/kaeQpP8uopwR3lEu.js new file mode 100644 index 0000000..de34d8f --- /dev/null +++ b/effects/kaeQpP8uopwR3lEu.js @@ -0,0 +1 @@ +args.fields.pool += (2) \ No newline at end of file diff --git a/effects/l0B9EGEGwi8qppAQ.js b/effects/l0B9EGEGwi8qppAQ.js new file mode 100644 index 0000000..01edaa2 --- /dev/null +++ b/effects/l0B9EGEGwi8qppAQ.js @@ -0,0 +1,2 @@ +this.actor.update({"system.resources.wrath" : this.actor.system.resources.wrath + 1}); +ui.notifications.info(`${this.effect.sourceItem.name}: Added 1 Wrath`) \ No newline at end of file diff --git a/effects/l5eevl1fQWYhumG8.js b/effects/l5eevl1fQWYhumG8.js new file mode 100644 index 0000000..598849f --- /dev/null +++ b/effects/l5eevl1fQWYhumG8.js @@ -0,0 +1,7 @@ +if (!args.item.isRanged) + return; + +if (!args.item._source.system.traits.list.find(i => i.name == "pistol")) +{ + args.item.system.traits.list.push({name : "pistol"}); +} \ No newline at end of file diff --git a/effects/l67Xry71u1CV0Ub2.js b/effects/l67Xry71u1CV0Ub2.js new file mode 100644 index 0000000..53859fc --- /dev/null +++ b/effects/l67Xry71u1CV0Ub2.js @@ -0,0 +1 @@ +return args.skill == "intimidation" \ No newline at end of file diff --git a/effects/lD2tFqbh0wFkZSrK.js b/effects/lD2tFqbh0wFkZSrK.js new file mode 100644 index 0000000..56f514b --- /dev/null +++ b/effects/lD2tFqbh0wFkZSrK.js @@ -0,0 +1 @@ +args.fields.pool += (this.effect.sourceTest.result.bonus) \ No newline at end of file diff --git a/effects/lER1x79iaiqO1fOW.js b/effects/lER1x79iaiqO1fOW.js new file mode 100644 index 0000000..05c5d55 --- /dev/null +++ b/effects/lER1x79iaiqO1fOW.js @@ -0,0 +1,15 @@ +if (args.item.system.isEquipped && args.item.type == "weapon" && args.item.hasKeyword("BOLT")) +{ +let sourceRF = args.item._source.system.traits.list.find(i => i.name == "rapidFire") +let rf = args.item.system.traits.list.find(i => i.name == "rapidFire"); +if (sourceRF && !rf.bd) +{ + let rf = args.item.system.traits.list.find(i => i.name == "rapidFire"); + rf.rating = parseInt(args.item.traitList.rapidFire.rating) + this.actor.system.advances.rank; + rf.bd = true; +} +else if (!sourceRF && !rf) +{ + args.item.system.traits.list.push({name : "rapidFire", rating: 2}) +} +} \ No newline at end of file diff --git a/effects/lFSnysWskES0QfCg.js b/effects/lFSnysWskES0QfCg.js new file mode 100644 index 0000000..d266c22 --- /dev/null +++ b/effects/lFSnysWskES0QfCg.js @@ -0,0 +1 @@ +return args.options.resist?.includes("psychicPower") \ No newline at end of file diff --git a/effects/lIeTkWRe7wmkZN6W.js b/effects/lIeTkWRe7wmkZN6W.js new file mode 100644 index 0000000..e348170 --- /dev/null +++ b/effects/lIeTkWRe7wmkZN6W.js @@ -0,0 +1 @@ +return !args.weapons; \ No newline at end of file diff --git a/effects/lJvf6AVjmuHoddQV.js b/effects/lJvf6AVjmuHoddQV.js new file mode 100644 index 0000000..d4cb21c --- /dev/null +++ b/effects/lJvf6AVjmuHoddQV.js @@ -0,0 +1 @@ +return args.fields.distance > 12; \ No newline at end of file diff --git a/effects/lXnUDQrXmieYYUfb.js b/effects/lXnUDQrXmieYYUfb.js new file mode 100644 index 0000000..87cb46e --- /dev/null +++ b/effects/lXnUDQrXmieYYUfb.js @@ -0,0 +1 @@ +return args.targets[0].name == this.effect.specifier \ No newline at end of file diff --git a/effects/lYrTbmezOxjtpUHd.js b/effects/lYrTbmezOxjtpUHd.js new file mode 100644 index 0000000..3f0cd1e --- /dev/null +++ b/effects/lYrTbmezOxjtpUHd.js @@ -0,0 +1 @@ +args.fields.ed += args.target.system.advances.tier; \ No newline at end of file diff --git a/effects/lbIWEbtpdbsgjxSQ.js b/effects/lbIWEbtpdbsgjxSQ.js new file mode 100644 index 0000000..ee36667 --- /dev/null +++ b/effects/lbIWEbtpdbsgjxSQ.js @@ -0,0 +1,4 @@ +if (args.test.result.test) +{ + args.test.result.test.dn += this.actor.system.advances.rank; +} \ No newline at end of file diff --git a/effects/lgVM7wAPaBYEwwIP.js b/effects/lgVM7wAPaBYEwwIP.js new file mode 100644 index 0000000..5acac40 --- /dev/null +++ b/effects/lgVM7wAPaBYEwwIP.js @@ -0,0 +1 @@ +return true; \ No newline at end of file diff --git a/effects/lpYvIQske0dpQMW5.js b/effects/lpYvIQske0dpQMW5.js new file mode 100644 index 0000000..17fb837 --- /dev/null +++ b/effects/lpYvIQske0dpQMW5.js @@ -0,0 +1 @@ +return args.target.system.mob?.value > 1; \ No newline at end of file diff --git a/effects/m9TL25I0TQQiXXou.js b/effects/m9TL25I0TQQiXXou.js new file mode 100644 index 0000000..b500060 --- /dev/null +++ b/effects/m9TL25I0TQQiXXou.js @@ -0,0 +1 @@ +return args.weapon.isRanged && args.fields.distance > 18; \ No newline at end of file diff --git a/effects/mCmXZR7irAzGdOVF.js b/effects/mCmXZR7irAzGdOVF.js new file mode 100644 index 0000000..31b1867 --- /dev/null +++ b/effects/mCmXZR7irAzGdOVF.js @@ -0,0 +1 @@ +return args.target.statuses.has("halfCover") || args.target.statuses.has("fullCover"); \ No newline at end of file diff --git a/effects/mJymsW6BtEvjJYCB.js b/effects/mJymsW6BtEvjJYCB.js new file mode 100644 index 0000000..39b542d --- /dev/null +++ b/effects/mJymsW6BtEvjJYCB.js @@ -0,0 +1,5 @@ +if (args.item.type == "weapon" && args.item.hasKeyword(["BOLT", "MELTA", "FIRE"])) +{ + // See https://github.com/foundryvtt/foundryvtt/issues/7987 + args.item.system.damage.bonus += this.actor.system.advances.rank / 2 +} \ No newline at end of file diff --git a/effects/miuWXyBThpx2nwgi.js b/effects/miuWXyBThpx2nwgi.js new file mode 100644 index 0000000..1430963 --- /dev/null +++ b/effects/miuWXyBThpx2nwgi.js @@ -0,0 +1 @@ +args.fields.pool += (args.actor.system.advances.rank * 2) \ No newline at end of file diff --git a/effects/nRzPe8J9HBSo8Ouv.js b/effects/nRzPe8J9HBSo8Ouv.js new file mode 100644 index 0000000..a48ce6d --- /dev/null +++ b/effects/nRzPe8J9HBSo8Ouv.js @@ -0,0 +1 @@ +return args.data.skill !== "athletics"; \ No newline at end of file diff --git a/effects/nqlrIfrjMNqm9rPu.js b/effects/nqlrIfrjMNqm9rPu.js new file mode 100644 index 0000000..98b252d --- /dev/null +++ b/effects/nqlrIfrjMNqm9rPu.js @@ -0,0 +1,4 @@ +if (args.wounds || args.mortal) +{ + this.item.effects.getName("Flensing Fury").update({disabled: false}); +} \ No newline at end of file diff --git a/effects/o53o6uRxwzd2zD7o.js b/effects/o53o6uRxwzd2zD7o.js new file mode 100644 index 0000000..645ad8f --- /dev/null +++ b/effects/o53o6uRxwzd2zD7o.js @@ -0,0 +1 @@ +args.fields.ed.value += args.actor.system.combat.stealth \ No newline at end of file diff --git a/effects/oOJIFfnYm8FKSsrR.js b/effects/oOJIFfnYm8FKSsrR.js new file mode 100644 index 0000000..7802c98 --- /dev/null +++ b/effects/oOJIFfnYm8FKSsrR.js @@ -0,0 +1 @@ +args.fields.difficulty -= args.actor.system.advances.rank * 2 \ No newline at end of file diff --git a/effects/ogLfE7uslg3NOAw1.js b/effects/ogLfE7uslg3NOAw1.js new file mode 100644 index 0000000..0322531 --- /dev/null +++ b/effects/ogLfE7uslg3NOAw1.js @@ -0,0 +1 @@ +args.fields.difficulty += 1 \ No newline at end of file diff --git a/effects/ooSIRNctWCRYawhZ.js b/effects/ooSIRNctWCRYawhZ.js new file mode 100644 index 0000000..58b178f --- /dev/null +++ b/effects/ooSIRNctWCRYawhZ.js @@ -0,0 +1,3 @@ +RuinGloryCounter.changeCounter(1, "glory"); + +this.script.notification("1 Glory Added"); \ No newline at end of file diff --git a/effects/oolhxEgOc3mFsBwJ.js b/effects/oolhxEgOc3mFsBwJ.js new file mode 100644 index 0000000..491b7c0 --- /dev/null +++ b/effects/oolhxEgOc3mFsBwJ.js @@ -0,0 +1 @@ +return !args.weapon?.isMelee; \ No newline at end of file diff --git a/effects/osnCvMgQ8yz26om9.js b/effects/osnCvMgQ8yz26om9.js new file mode 100644 index 0000000..4f75a4a --- /dev/null +++ b/effects/osnCvMgQ8yz26om9.js @@ -0,0 +1 @@ +args.fields.damage.bonus += (args.actor.system.advances.rank) \ No newline at end of file diff --git a/effects/oueyTSpTbi8zzrcq.js b/effects/oueyTSpTbi8zzrcq.js new file mode 100644 index 0000000..aade302 --- /dev/null +++ b/effects/oueyTSpTbi8zzrcq.js @@ -0,0 +1,6 @@ +let item = args.test?.item; + +if (item && item.hasKeyword(["MELTA", "FIRE"])) +{ + args.abort = this.effect.name; +} \ No newline at end of file diff --git a/effects/p9y4Td4ZLYcVHC3X.js b/effects/p9y4Td4ZLYcVHC3X.js new file mode 100644 index 0000000..e7e17d7 --- /dev/null +++ b/effects/p9y4Td4ZLYcVHC3X.js @@ -0,0 +1,5 @@ +if (args.isSuccess && args.targetTokens.map(i => i.actor).filter(i => i).some(a => a.system.mob?.value)) +{ + args.result.success += this.actor.system.advances.rank + args.result.text[this.effect.id] = {label : this.effect.name, description : `Added ${this.actor.system.advances.rank} Icons`} +} \ No newline at end of file diff --git a/effects/pDRZ5DMEdCw9W4C7.js b/effects/pDRZ5DMEdCw9W4C7.js new file mode 100644 index 0000000..d7b5573 --- /dev/null +++ b/effects/pDRZ5DMEdCw9W4C7.js @@ -0,0 +1 @@ +return args.skill != "pilot" \ No newline at end of file diff --git a/effects/pFJ8cQaMJRs4KnCP.js b/effects/pFJ8cQaMJRs4KnCP.js new file mode 100644 index 0000000..513ee4c --- /dev/null +++ b/effects/pFJ8cQaMJRs4KnCP.js @@ -0,0 +1,2 @@ +args.fields.damage += 1; +args.fields.pool += 4; \ No newline at end of file diff --git a/effects/pOhKN1s9y1RTy89J.js b/effects/pOhKN1s9y1RTy89J.js new file mode 100644 index 0000000..c6be62d --- /dev/null +++ b/effects/pOhKN1s9y1RTy89J.js @@ -0,0 +1 @@ +args.fields.ed.value += 4; \ No newline at end of file diff --git a/effects/pRxvTPAoTozwcbjj.js b/effects/pRxvTPAoTozwcbjj.js new file mode 100644 index 0000000..6ce8b49 --- /dev/null +++ b/effects/pRxvTPAoTozwcbjj.js @@ -0,0 +1 @@ +return args.options.multi > 1; \ No newline at end of file diff --git a/effects/pX5gXopi2ldlzKgb.js b/effects/pX5gXopi2ldlzKgb.js new file mode 100644 index 0000000..8c6ef31 --- /dev/null +++ b/effects/pX5gXopi2ldlzKgb.js @@ -0,0 +1 @@ +this.actor.removeCondition("restrained") \ No newline at end of file diff --git a/effects/pb0Z1LMiekkRrTJQ.js b/effects/pb0Z1LMiekkRrTJQ.js new file mode 100644 index 0000000..ca5c1d8 --- /dev/null +++ b/effects/pb0Z1LMiekkRrTJQ.js @@ -0,0 +1 @@ +return args.skill == "psychicMastery" \ No newline at end of file diff --git a/effects/q1lg7gMIadtty31V.js b/effects/q1lg7gMIadtty31V.js new file mode 100644 index 0000000..8190213 --- /dev/null +++ b/effects/q1lg7gMIadtty31V.js @@ -0,0 +1 @@ +return args.skill == "stealth"; \ No newline at end of file diff --git a/effects/q9qCgYfhjGfABnJG.js b/effects/q9qCgYfhjGfABnJG.js new file mode 100644 index 0000000..98126d6 --- /dev/null +++ b/effects/q9qCgYfhjGfABnJG.js @@ -0,0 +1,9 @@ +if (this.item.name.includes("Any")) +{ + let choice = await ValueDialog.create({text: "Enter Hatred Keyword", title : this.effect.name}); + if (choice) + { + this.item.updateSource({name : this.item.name.replace("Any", choice.toUpperCase())}); + this.effect.updateSource({name : this.item.name}); + } +} \ No newline at end of file diff --git a/effects/qNIDztrDVsmYDvTr.js b/effects/qNIDztrDVsmYDvTr.js new file mode 100644 index 0000000..0b6b67d --- /dev/null +++ b/effects/qNIDztrDVsmYDvTr.js @@ -0,0 +1 @@ +return args.weapon?.id != this.effect.getFlag(game.system.id, "trademarkId") \ No newline at end of file diff --git a/effects/qPoO0dnxeLUbrMAa.js b/effects/qPoO0dnxeLUbrMAa.js new file mode 100644 index 0000000..9077a5e --- /dev/null +++ b/effects/qPoO0dnxeLUbrMAa.js @@ -0,0 +1 @@ +args.fields.pool += (this.effect.sourceActor.system.advances.rank * 2) \ No newline at end of file diff --git a/effects/qjs3Ub0DWJ4Zo0Rq.js b/effects/qjs3Ub0DWJ4Zo0Rq.js new file mode 100644 index 0000000..af1bbcf --- /dev/null +++ b/effects/qjs3Ub0DWJ4Zo0Rq.js @@ -0,0 +1 @@ +return args.weapon.isRanged; \ No newline at end of file diff --git a/effects/qpF5cnBJLq2DGbVJ.js b/effects/qpF5cnBJLq2DGbVJ.js new file mode 100644 index 0000000..43ef8ec --- /dev/null +++ b/effects/qpF5cnBJLq2DGbVJ.js @@ -0,0 +1 @@ +return args.weapon || args.power || ["fellowship", "intellect"].includes(args.skill) \ No newline at end of file diff --git a/effects/qrko05ksnkafSuLH.js b/effects/qrko05ksnkafSuLH.js new file mode 100644 index 0000000..8c1a9e4 --- /dev/null +++ b/effects/qrko05ksnkafSuLH.js @@ -0,0 +1,3 @@ +await this.actor.addCondition("hindered", {[game.system.id] : {value : 2}}) + +await this.actor.addCondition("staggered") \ No newline at end of file diff --git a/effects/qwZ6OTEbAXNZJ9yX.js b/effects/qwZ6OTEbAXNZJ9yX.js new file mode 100644 index 0000000..45650fa --- /dev/null +++ b/effects/qwZ6OTEbAXNZJ9yX.js @@ -0,0 +1 @@ +return args.skill != "scholar" \ No newline at end of file diff --git a/effects/r2yuM4c339EFvQVt.js b/effects/r2yuM4c339EFvQVt.js new file mode 100644 index 0000000..c7d1547 --- /dev/null +++ b/effects/r2yuM4c339EFvQVt.js @@ -0,0 +1,11 @@ +let effects = this.item.effects.contents.filter(i => i.id != this.effect.id); + +effects.forEach(e => { + e.update({disabled : true}) +}) + +let e = effects.find(i => i.id == "MGiuyToigSluPOE5"); + +e.update({disabled : false}); + +this.script.notification(`${e.name} (+1 Defence) Activated`) \ No newline at end of file diff --git a/effects/r6Akxtto05ADYOrs.js b/effects/r6Akxtto05ADYOrs.js new file mode 100644 index 0000000..79f3492 --- /dev/null +++ b/effects/r6Akxtto05ADYOrs.js @@ -0,0 +1 @@ +return args.attribute == "fellowship" || args.skill == "intimidation" \ No newline at end of file diff --git a/effects/rEyARRVbIC24gond.js b/effects/rEyARRVbIC24gond.js new file mode 100644 index 0000000..205bb8d --- /dev/null +++ b/effects/rEyARRVbIC24gond.js @@ -0,0 +1 @@ +return args.fields.range == "long" \ No newline at end of file diff --git a/effects/rFS1jHvsucUNBwez.js b/effects/rFS1jHvsucUNBwez.js new file mode 100644 index 0000000..c2ce40f --- /dev/null +++ b/effects/rFS1jHvsucUNBwez.js @@ -0,0 +1,2 @@ +args.fields.pool += 2; +args.fields.ed.value += 2; \ No newline at end of file diff --git a/effects/rSgP5FedH8BCMgER.js b/effects/rSgP5FedH8BCMgER.js new file mode 100644 index 0000000..169f9b3 --- /dev/null +++ b/effects/rSgP5FedH8BCMgER.js @@ -0,0 +1 @@ +args.fields.pool -= (this.effect.sourceTest.result.WSPenalty) \ No newline at end of file diff --git a/effects/rm96unQpe10RFKad.js b/effects/rm96unQpe10RFKad.js new file mode 100644 index 0000000..893629b --- /dev/null +++ b/effects/rm96unQpe10RFKad.js @@ -0,0 +1 @@ +return args.options.multi \ No newline at end of file diff --git a/effects/rrQQLpoZ74X6V866.js b/effects/rrQQLpoZ74X6V866.js new file mode 100644 index 0000000..b717cbb --- /dev/null +++ b/effects/rrQQLpoZ74X6V866.js @@ -0,0 +1,2 @@ +// https://github.com/foundryvtt/foundryvtt/issues/7987 +this.item.system.salvo += 0.5; \ No newline at end of file diff --git a/effects/ry6TRb3XOnZMSNtZ.js b/effects/ry6TRb3XOnZMSNtZ.js new file mode 100644 index 0000000..36a0b4c --- /dev/null +++ b/effects/ry6TRb3XOnZMSNtZ.js @@ -0,0 +1 @@ +args.fields.ed.value += (this.effect.sourceTest.result.edPenalty) \ No newline at end of file diff --git a/effects/s3VJqcRi2aAoPBxo.js b/effects/s3VJqcRi2aAoPBxo.js new file mode 100644 index 0000000..19197be --- /dev/null +++ b/effects/s3VJqcRi2aAoPBxo.js @@ -0,0 +1 @@ +return !args.options.determination && args.skill != "tech" \ No newline at end of file diff --git a/effects/s8gRnNiND2DAlbQm.js b/effects/s8gRnNiND2DAlbQm.js new file mode 100644 index 0000000..e7bf7dd --- /dev/null +++ b/effects/s8gRnNiND2DAlbQm.js @@ -0,0 +1 @@ +return !args.weapon.system.isMelee; \ No newline at end of file diff --git a/effects/sB7sGAK1sB3FCZPU.js b/effects/sB7sGAK1sB3FCZPU.js new file mode 100644 index 0000000..54a11bc --- /dev/null +++ b/effects/sB7sGAK1sB3FCZPU.js @@ -0,0 +1 @@ +args.fields.pool += 3; \ No newline at end of file diff --git a/effects/sKu1EkyvtKjzP2ND.js b/effects/sKu1EkyvtKjzP2ND.js new file mode 100644 index 0000000..3203b9b --- /dev/null +++ b/effects/sKu1EkyvtKjzP2ND.js @@ -0,0 +1 @@ +return !args.weapon || args.weapon.isRanged; \ No newline at end of file diff --git a/effects/sPGM5PQudnBtx7f3.js b/effects/sPGM5PQudnBtx7f3.js new file mode 100644 index 0000000..00927e7 --- /dev/null +++ b/effects/sPGM5PQudnBtx7f3.js @@ -0,0 +1 @@ +return !args.options.resolve; \ No newline at end of file diff --git a/effects/sfx6toL0h2qZqOL1.js b/effects/sfx6toL0h2qZqOL1.js new file mode 100644 index 0000000..24a56fe --- /dev/null +++ b/effects/sfx6toL0h2qZqOL1.js @@ -0,0 +1 @@ +return args.options.resist?.includes("psychicPower"); \ No newline at end of file diff --git a/effects/st9bGbW1bDs3gVtg.js b/effects/st9bGbW1bDs3gVtg.js new file mode 100644 index 0000000..6189625 --- /dev/null +++ b/effects/st9bGbW1bDs3gVtg.js @@ -0,0 +1 @@ +args.fields.ap.value += (-args.actor.system.advances.rank) \ No newline at end of file diff --git a/effects/tNdYTVOLLNwsv6rp.js b/effects/tNdYTVOLLNwsv6rp.js new file mode 100644 index 0000000..ea70c4a --- /dev/null +++ b/effects/tNdYTVOLLNwsv6rp.js @@ -0,0 +1,13 @@ +if (args.item.system.isEquipped) +{ +if (args.item._source.system.traits.list.find(i => i.name == "brutal")) +{ + args.item.flags.hasBrutal = true; +} +else +{ + args.item.system.traits.list.push({name : "brutal"}) +} + + +} \ No newline at end of file diff --git a/effects/tOnMd9D7MHn4eXFp.js b/effects/tOnMd9D7MHn4eXFp.js new file mode 100644 index 0000000..28b7859 --- /dev/null +++ b/effects/tOnMd9D7MHn4eXFp.js @@ -0,0 +1 @@ +return args.skill == "persuasion" \ No newline at end of file diff --git a/effects/tPwJOmN2seFJyCUV.js b/effects/tPwJOmN2seFJyCUV.js new file mode 100644 index 0000000..718d168 --- /dev/null +++ b/effects/tPwJOmN2seFJyCUV.js @@ -0,0 +1 @@ +args.fields.pool += (this.effect.sourceActor.system.advances.rank) * 2 \ No newline at end of file diff --git a/effects/tSkQICmV6Rb46lcO.js b/effects/tSkQICmV6Rb46lcO.js new file mode 100644 index 0000000..ad62ee1 --- /dev/null +++ b/effects/tSkQICmV6Rb46lcO.js @@ -0,0 +1 @@ +return !args.options.multi \ No newline at end of file diff --git a/effects/ti7VF62RlG5IZcEy.js b/effects/ti7VF62RlG5IZcEy.js new file mode 100644 index 0000000..79e11f5 --- /dev/null +++ b/effects/ti7VF62RlG5IZcEy.js @@ -0,0 +1 @@ +return args.skill != "intimidation" || args.actor.itemTypes.armour.filter(i => i.system.isEquipped && i.hasKeyword("HEAVY")).length == 0 \ No newline at end of file diff --git a/effects/tyFTdIGFK74yF3hK.js b/effects/tyFTdIGFK74yF3hK.js new file mode 100644 index 0000000..fde6bbc --- /dev/null +++ b/effects/tyFTdIGFK74yF3hK.js @@ -0,0 +1 @@ +args.fields.difficulty--; \ No newline at end of file diff --git a/effects/tzhERsZsFHmeLp10.js b/effects/tzhERsZsFHmeLp10.js new file mode 100644 index 0000000..5d4e7a0 --- /dev/null +++ b/effects/tzhERsZsFHmeLp10.js @@ -0,0 +1,8 @@ +let roll = await new Roll("dp").roll(); + +if (roll.dice[0].results[0].value >= 1) +{ + this.actor.addCondition("frenzied"); +} + +roll.toMessage(this.script.getChatData()); \ No newline at end of file diff --git a/effects/uCSQMb5MzJvpBynd.js b/effects/uCSQMb5MzJvpBynd.js new file mode 100644 index 0000000..41bdf63 --- /dev/null +++ b/effects/uCSQMb5MzJvpBynd.js @@ -0,0 +1,3 @@ +let bonus = args.target.statuses.has("fullCover")?2:1; + +args.fields.difficulty += bonus; \ No newline at end of file diff --git a/effects/uDMSAlABh4jqg69V.js b/effects/uDMSAlABh4jqg69V.js new file mode 100644 index 0000000..52f75e4 --- /dev/null +++ b/effects/uDMSAlABh4jqg69V.js @@ -0,0 +1 @@ +args.fields.pool += (1) \ No newline at end of file diff --git a/effects/uXgr5K68WSR7dGS8.js b/effects/uXgr5K68WSR7dGS8.js new file mode 100644 index 0000000..cec3862 --- /dev/null +++ b/effects/uXgr5K68WSR7dGS8.js @@ -0,0 +1 @@ +return args.attribute == "weaponSkill" \ No newline at end of file diff --git a/effects/unSFRiuQRqN7cTcM.js b/effects/unSFRiuQRqN7cTcM.js new file mode 100644 index 0000000..bea3b88 --- /dev/null +++ b/effects/unSFRiuQRqN7cTcM.js @@ -0,0 +1,4 @@ +if (args.test.testData.shifted.armourbane) +{ + args.modifiers.ap.push({label : this.effect.label, value : -1 * args.test.testData.shifted.armourbane.dice.length}) +} \ No newline at end of file diff --git a/effects/uqsOhE2qxCz7oOJl.js b/effects/uqsOhE2qxCz7oOJl.js new file mode 100644 index 0000000..4dd8ca2 --- /dev/null +++ b/effects/uqsOhE2qxCz7oOJl.js @@ -0,0 +1 @@ +return !args.weapon || args.weapon.isRanged \ No newline at end of file diff --git a/effects/vCwJgU7eJnlq1WzL.js b/effects/vCwJgU7eJnlq1WzL.js new file mode 100644 index 0000000..c9257bc --- /dev/null +++ b/effects/vCwJgU7eJnlq1WzL.js @@ -0,0 +1,6 @@ +let roll = await new Roll("10dp").roll(); +let icons = roll.dice[0].results.reduce((total, die) => total + die.value, 0); + +await this.actor.applyHealing({wounds: icons, shock: 0}, {messageData : this.script.getChatData()}); + +roll.toMessage(this.script.getChatData()); \ No newline at end of file diff --git a/effects/vHPsLvYNqhcF7R6Y.js b/effects/vHPsLvYNqhcF7R6Y.js new file mode 100644 index 0000000..3ada236 --- /dev/null +++ b/effects/vHPsLvYNqhcF7R6Y.js @@ -0,0 +1 @@ +return arg.skill == "intimidation" \ No newline at end of file diff --git a/effects/vJy1GbGNsq9DKLBh.js b/effects/vJy1GbGNsq9DKLBh.js new file mode 100644 index 0000000..fa9f22c --- /dev/null +++ b/effects/vJy1GbGNsq9DKLBh.js @@ -0,0 +1 @@ +return !args.weapon || args.weapon.isRanged || !this.actor.items.filter(i => i.system.isEquipped).some(i => i.flags.hasParry) \ No newline at end of file diff --git a/effects/vOM3FbAlKu8B5v7Q.js b/effects/vOM3FbAlKu8B5v7Q.js new file mode 100644 index 0000000..68f88b7 --- /dev/null +++ b/effects/vOM3FbAlKu8B5v7Q.js @@ -0,0 +1 @@ +this.actor.setupAttributeTest("willpower", {appendTitle : ` - ${this.effect.sourceItem.name}`}); \ No newline at end of file diff --git a/effects/vT9eJ7E8wianEjYe.js b/effects/vT9eJ7E8wianEjYe.js new file mode 100644 index 0000000..7ebd2f9 --- /dev/null +++ b/effects/vT9eJ7E8wianEjYe.js @@ -0,0 +1 @@ +return !args.weapon?.isMelee \ No newline at end of file diff --git a/effects/vjjs6BT6Net1NMIa.js b/effects/vjjs6BT6Net1NMIa.js new file mode 100644 index 0000000..384259f --- /dev/null +++ b/effects/vjjs6BT6Net1NMIa.js @@ -0,0 +1 @@ +return args.skill != "persuasion" && !args.options.influence \ No newline at end of file diff --git a/effects/vvNiRZSXslLMxCIW.js b/effects/vvNiRZSXslLMxCIW.js new file mode 100644 index 0000000..d1301af --- /dev/null +++ b/effects/vvNiRZSXslLMxCIW.js @@ -0,0 +1 @@ +return !args.options.resolve && !args.options.corruption \ No newline at end of file diff --git a/effects/vvQ5OklTChNlEex0.js b/effects/vvQ5OklTChNlEex0.js new file mode 100644 index 0000000..bacf708 --- /dev/null +++ b/effects/vvQ5OklTChNlEex0.js @@ -0,0 +1 @@ +return args.weapon && args.weapon.isRanged; \ No newline at end of file diff --git a/effects/w4Tk1CJll8XO8B1M.js b/effects/w4Tk1CJll8XO8B1M.js new file mode 100644 index 0000000..ce6eb8d --- /dev/null +++ b/effects/w4Tk1CJll8XO8B1M.js @@ -0,0 +1 @@ +return args.skill == "investigation" \ No newline at end of file diff --git a/effects/w7qqGlzwGOzoRtvi.js b/effects/w7qqGlzwGOzoRtvi.js new file mode 100644 index 0000000..7a90d19 --- /dev/null +++ b/effects/w7qqGlzwGOzoRtvi.js @@ -0,0 +1 @@ +return args.options.corruption \ No newline at end of file diff --git a/effects/wE70SJJI6hZibemp.js b/effects/wE70SJJI6hZibemp.js new file mode 100644 index 0000000..a9edd1e --- /dev/null +++ b/effects/wE70SJJI6hZibemp.js @@ -0,0 +1 @@ +args.fields.pool += (2 * args.actor.system.advances.rank) \ No newline at end of file diff --git a/effects/wK3Lgd7N4ZRApgKH.js b/effects/wK3Lgd7N4ZRApgKH.js new file mode 100644 index 0000000..675d825 --- /dev/null +++ b/effects/wK3Lgd7N4ZRApgKH.js @@ -0,0 +1,5 @@ +if (args.options.fear) +{ + args.abort = true; + this.script.notification("Automatically succeed Fear Tests") +} \ No newline at end of file diff --git a/effects/wKRySrfwHmXmNv0L.js b/effects/wKRySrfwHmXmNv0L.js new file mode 100644 index 0000000..4377443 --- /dev/null +++ b/effects/wKRySrfwHmXmNv0L.js @@ -0,0 +1,8 @@ +let actor = this.effect.sourceActor; + +let hatred = actor?.items.find(i => i.baseName == "Hatred"); + +if (hatred) +{ + this.effect.updateSource({"name" : hatred.name}) +} \ No newline at end of file diff --git a/effects/wPEffMHvctRv8rvT.js b/effects/wPEffMHvctRv8rvT.js new file mode 100644 index 0000000..19d5fa4 --- /dev/null +++ b/effects/wPEffMHvctRv8rvT.js @@ -0,0 +1 @@ +this.actor.addCondition("frenzied"); \ No newline at end of file diff --git a/effects/wYYMkQr4urxjuGoH.js b/effects/wYYMkQr4urxjuGoH.js new file mode 100644 index 0000000..9d794b2 --- /dev/null +++ b/effects/wYYMkQr4urxjuGoH.js @@ -0,0 +1 @@ +return args.attribute != "toughness" \ No newline at end of file diff --git a/effects/wZ4Mnb1Rvta5jfeI.js b/effects/wZ4Mnb1Rvta5jfeI.js new file mode 100644 index 0000000..f26144b --- /dev/null +++ b/effects/wZ4Mnb1Rvta5jfeI.js @@ -0,0 +1,2 @@ +let socials = ["cunning", "deception", "insight", "persuasion", "intimidation", "leadership"] +return !args.options.influence && !socials.includes(args.skill) \ No newline at end of file diff --git a/effects/wgn804Rr9pTBZy9y.js b/effects/wgn804Rr9pTBZy9y.js new file mode 100644 index 0000000..8552806 --- /dev/null +++ b/effects/wgn804Rr9pTBZy9y.js @@ -0,0 +1 @@ +args.fields.pool -= (this.effect.sourceTest.result.penalty) \ No newline at end of file diff --git a/effects/wnLz905L9fGRgOOO.js b/effects/wnLz905L9fGRgOOO.js new file mode 100644 index 0000000..6662967 --- /dev/null +++ b/effects/wnLz905L9fGRgOOO.js @@ -0,0 +1 @@ +args.fields.ap.value -= (args.actor.system.advances.rank) \ No newline at end of file diff --git a/effects/wt6FKxokrDb27nYD.js b/effects/wt6FKxokrDb27nYD.js new file mode 100644 index 0000000..2e79d48 --- /dev/null +++ b/effects/wt6FKxokrDb27nYD.js @@ -0,0 +1 @@ +return args.skill != this.effect.getFlag(game.system.id, "skill") \ No newline at end of file diff --git a/effects/x4TjQeYRdoCQB77M.js b/effects/x4TjQeYRdoCQB77M.js new file mode 100644 index 0000000..e1bdf32 --- /dev/null +++ b/effects/x4TjQeYRdoCQB77M.js @@ -0,0 +1 @@ +return args.options.influence; \ No newline at end of file diff --git a/effects/x6tJeIHYjtqdrP2n.js b/effects/x6tJeIHYjtqdrP2n.js new file mode 100644 index 0000000..043c6cd --- /dev/null +++ b/effects/x6tJeIHYjtqdrP2n.js @@ -0,0 +1,11 @@ +let shock = Math.ceil(CONFIG.Dice.randomUniform() * 6); +let wounds = Math.ceil(CONFIG.Dice.randomUniform() * 3); + +let healedShock = Math.floor(shock / 2); +let healedWounds = Math.floor(wounds / 2); + +let report = await this.actor.applyDamage(wounds, {shock}, {allowDetermination : false}); + +this.script.message(` Received ${report.wounds} Wounds and ${report.shock} Shock`) + +this.effect.sourceActor.applyHealing({shock : healedShock, wounds : healedWounds}, {messageData : this.script.getChatData()}) \ No newline at end of file diff --git a/effects/x7egaio7kd51yznb.js b/effects/x7egaio7kd51yznb.js new file mode 100644 index 0000000..e52767b --- /dev/null +++ b/effects/x7egaio7kd51yznb.js @@ -0,0 +1 @@ +args.fields.ed.value += (args.actor.system.test.result.edBonus) \ No newline at end of file diff --git a/effects/xY6bpcsYSWfYJGD2.js b/effects/xY6bpcsYSWfYJGD2.js new file mode 100644 index 0000000..4072ef3 --- /dev/null +++ b/effects/xY6bpcsYSWfYJGD2.js @@ -0,0 +1 @@ +return args.options.fear || args.options.resolve \ No newline at end of file diff --git a/effects/xhmaZFufaDuw5WhC.js b/effects/xhmaZFufaDuw5WhC.js new file mode 100644 index 0000000..39a9bca --- /dev/null +++ b/effects/xhmaZFufaDuw5WhC.js @@ -0,0 +1,4 @@ +if (args.test.result.isWrathCritical) +{ + args.actor.addCondition('bleeding'); +} \ No newline at end of file diff --git a/effects/xikjJXgmbcre6jIC.js b/effects/xikjJXgmbcre6jIC.js new file mode 100644 index 0000000..beaae8d --- /dev/null +++ b/effects/xikjJXgmbcre6jIC.js @@ -0,0 +1 @@ +args.fields.difficulty += parseInt(this.effect.specifier) || 1 \ No newline at end of file diff --git a/effects/xkeWd7NAWWrW9WkX.js b/effects/xkeWd7NAWWrW9WkX.js new file mode 100644 index 0000000..2fcca32 --- /dev/null +++ b/effects/xkeWd7NAWWrW9WkX.js @@ -0,0 +1 @@ +return args.targets[0]?.document.elevation > 0; \ No newline at end of file diff --git a/effects/xpl1K8zUzYlgJ8YN.js b/effects/xpl1K8zUzYlgJ8YN.js new file mode 100644 index 0000000..b7a85b7 --- /dev/null +++ b/effects/xpl1K8zUzYlgJ8YN.js @@ -0,0 +1 @@ +return !args.weapon || args.weapon?.system.isRanged \ No newline at end of file diff --git a/effects/xtv4RmAhiRMLPOae.js b/effects/xtv4RmAhiRMLPOae.js new file mode 100644 index 0000000..02ed014 --- /dev/null +++ b/effects/xtv4RmAhiRMLPOae.js @@ -0,0 +1 @@ +this.actor.addCondition("hindered"); \ No newline at end of file diff --git a/effects/xuWe1g9gmBQl8rQ5.js b/effects/xuWe1g9gmBQl8rQ5.js new file mode 100644 index 0000000..752063f --- /dev/null +++ b/effects/xuWe1g9gmBQl8rQ5.js @@ -0,0 +1 @@ +return args.options.determination \ No newline at end of file diff --git a/effects/xzHcRwl7ttJdNtXu.js b/effects/xzHcRwl7ttJdNtXu.js new file mode 100644 index 0000000..72903b8 --- /dev/null +++ b/effects/xzHcRwl7ttJdNtXu.js @@ -0,0 +1,3 @@ +let wounds = Math.ceil(CONFIG.Dice.randomUniform() * 3); + +await this.actor.applyHealing({wounds, shock: 0}, {messageData : this.script.getChatData()}); \ No newline at end of file diff --git a/effects/y0Ws5ayXVNY7TL76.js b/effects/y0Ws5ayXVNY7TL76.js new file mode 100644 index 0000000..8ee1ede --- /dev/null +++ b/effects/y0Ws5ayXVNY7TL76.js @@ -0,0 +1,11 @@ +let shock = Math.ceil(CONFIG.Dice.randomUniform() * 3) + +let add = 1 - this.effect.sourceTest.result.shock; + +shock += add; + +let tooltip = `1d3 (${shock}) + ${add}` + +let report = await this.actor.applyDamage(0, {shock}); + +this.script.message(`Received ${report.shock} Shock`); \ No newline at end of file diff --git a/effects/y491iKlFpYBFsDEY.js b/effects/y491iKlFpYBFsDEY.js new file mode 100644 index 0000000..2413fec --- /dev/null +++ b/effects/y491iKlFpYBFsDEY.js @@ -0,0 +1 @@ +return args.target && (args.target.hasKeyword("BEAST") || args.target.hasKeyword("SQUIG")); \ No newline at end of file diff --git a/effects/y6O5MpU4HSFhoKnr.js b/effects/y6O5MpU4HSFhoKnr.js new file mode 100644 index 0000000..656fd30 --- /dev/null +++ b/effects/y6O5MpU4HSFhoKnr.js @@ -0,0 +1,2 @@ +let report = await this.actor.applyDamage(0, {mortal: 1}); +this.script.message(`Received ${report.wounds} Wound`); \ No newline at end of file diff --git a/effects/yCpSKxuwkwdRmmNd.js b/effects/yCpSKxuwkwdRmmNd.js new file mode 100644 index 0000000..8060376 --- /dev/null +++ b/effects/yCpSKxuwkwdRmmNd.js @@ -0,0 +1 @@ +args.fields.pool += 8; \ No newline at end of file diff --git a/effects/yN4OM8UtNqAq2Dfy.js b/effects/yN4OM8UtNqAq2Dfy.js new file mode 100644 index 0000000..68c8560 --- /dev/null +++ b/effects/yN4OM8UtNqAq2Dfy.js @@ -0,0 +1,4 @@ +let value = await ValueDialog.create({text : this.script.label, title : this.effect.name}) + +this.effect.updateSource({name : this.effect.setSpecifier(value)}) +this.item.updateSource({name : this.item.setSpecifier(value)}) \ No newline at end of file diff --git a/effects/yUSIDl1k44HVWZpq.js b/effects/yUSIDl1k44HVWZpq.js new file mode 100644 index 0000000..71aa0b9 --- /dev/null +++ b/effects/yUSIDl1k44HVWZpq.js @@ -0,0 +1 @@ +return !args.data.weapon; \ No newline at end of file diff --git a/effects/yXbCqxGPkQilEqbY.js b/effects/yXbCqxGPkQilEqbY.js new file mode 100644 index 0000000..03c81a0 --- /dev/null +++ b/effects/yXbCqxGPkQilEqbY.js @@ -0,0 +1 @@ +return !args.options.multi; \ No newline at end of file diff --git a/effects/yjspaw14CPu5KOTK.js b/effects/yjspaw14CPu5KOTK.js new file mode 100644 index 0000000..ee13b71 --- /dev/null +++ b/effects/yjspaw14CPu5KOTK.js @@ -0,0 +1,2 @@ +let maxTargets = Math.min(args.options.multi, 6); +args.fields.difficulty -= 2 * (maxTargets - 1); \ No newline at end of file diff --git a/effects/ylHXSuC15gtMQM6U.js b/effects/ylHXSuC15gtMQM6U.js new file mode 100644 index 0000000..08bd70c --- /dev/null +++ b/effects/ylHXSuC15gtMQM6U.js @@ -0,0 +1,5 @@ +if (args.options.conviction || args.options.resolve) +{ + args.abort = true; + this.script.notification("Automatically succeed Resolve or Conviction Tests") +} \ No newline at end of file diff --git a/effects/yo50TP9ocyy5EkzQ.js b/effects/yo50TP9ocyy5EkzQ.js new file mode 100644 index 0000000..a6bbe3f --- /dev/null +++ b/effects/yo50TP9ocyy5EkzQ.js @@ -0,0 +1 @@ +return args.skill != "athletics" \ No newline at end of file diff --git a/effects/z0gTZtf2b4ZBaChd.js b/effects/z0gTZtf2b4ZBaChd.js new file mode 100644 index 0000000..ea8aff9 --- /dev/null +++ b/effects/z0gTZtf2b4ZBaChd.js @@ -0,0 +1 @@ +await this.actor.addEffectItems("Compendium.wng-core.items.Item.JVz6FoVEc7p1DJUj", this.effect); \ No newline at end of file diff --git a/effects/zRozYzzKaAXc4j5G.js b/effects/zRozYzzKaAXc4j5G.js new file mode 100644 index 0000000..ba29b23 --- /dev/null +++ b/effects/zRozYzzKaAXc4j5G.js @@ -0,0 +1 @@ +return !args.weapon?.system.isMelee; \ No newline at end of file diff --git a/effects/zZKaz4lu1seX4XTD.js b/effects/zZKaz4lu1seX4XTD.js new file mode 100644 index 0000000..92b4e92 --- /dev/null +++ b/effects/zZKaz4lu1seX4XTD.js @@ -0,0 +1 @@ +return false; \ No newline at end of file diff --git a/package.json b/package.json index 032156e..13a4358 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "description": "The **official** system for playing Warhammer 40k: Wrath & Glory on [Foundry VTT](https://foundryvtt.com/). Created by Moo Man.", "main": "wrath-and-glory.js", "scripts": { - "build": "cross-env NODE_ENV=development rollup --config rollup.config.js --watch", - "release": "cross-env NODE_ENV=production rollup --config rollup.config.js" + "build": "node scriptPacker.js&& cross-env NODE_ENV=development rollup --config rollup.config.js --watch", + "release": "node scriptPacker.js&& cross-env NODE_ENV=production rollup --config rollup.config.js" }, "repository": { "type": "git", diff --git a/scriptPacker.js b/scriptPacker.js new file mode 100644 index 0000000..d00ab5d --- /dev/null +++ b/scriptPacker.js @@ -0,0 +1,24 @@ +const fs = require("fs"); + +let path = "./effects/" +let scripts = fs.readdirSync(path); +let count = 0; +let scriptObj = {}; +for(let file of scripts) +{ + let script = fs.readFileSync(path + file, {encoding:"utf8"}); + scriptObj[file.split(".")[0]] = script; + count++; +} + +let scriptLoader = `export default function() +{ + Hooks.on("init", () => + { + foundry.utils.mergeObject(game.wng.config.effectScripts, ${JSON.stringify(scriptObj)}); + }); + +}` + +fs.writeFileSync("./scripts/loadEffects.js", scriptLoader) +console.log(`Packed ${count} scripts`); \ No newline at end of file diff --git a/scripts/apps/active-effect-config.js b/scripts/apps/active-effect-config.js deleted file mode 100644 index 2970427..0000000 --- a/scripts/apps/active-effect-config.js +++ /dev/null @@ -1,84 +0,0 @@ - -import EffectScriptConfig from "./effect-script.js" - -export default class WrathAndGloryEffectSheet extends ActiveEffectConfig { - async getData() { - let data = await super.getData() - data.modes[6] = "Dialog Effect" - data.modes[7] = "Targeter's Dialog Effect" - return data - } - - - activateListeners(html) { - - - html.find(".changes-list .effect-controls").each((i, element) => { - if (this.object.changes[i].mode > 5) - { - element.append($(``)[0]) - } - }) - - super.activateListeners(html) - html.find(".effect-script-config").click(ev => { - let index = parseInt($(ev.currentTarget).parents(".effect-change").attr("data-index")) - new EffectScriptConfig({effect : this.object, index}).render(true) - }) - - html.find(".mode select").change(ev => { - this.submit({preventClose: true}) - }) - } - - /** - * Handle adding a new change to the changes array. - * @private - */ - async _addEffectChange() { - const idx = this.document.changes.length; - super._addEffectChange().then(sheet => { - this.document.update({[`flags.wrath-and-glory.changeCondition.${idx}`] : {script : "", description : "", hide : ""}}) - }) - } - - /** - * When deleting an active effect, make sure its change condition is deleted too - */ - _onEffectControl(event) { - event.preventDefault(); - if (event.currentTarget.dataset.action == "delete") - { - - let index = $(event.currentTarget).parents(".effect-change")[0]?.dataset.index; - let newConditionals = this.deleteChangeCondition(index); - // Call normal operation, once done, delete change condition for deleted index - super._onEffectControl(event).then(() => { - this.document.update({"flags.wrath-and-glory.changeCondition" : null}).then(() => { // Delete previous object so data doesn't get merged and produce duplicates - this.document.update({"flags.wrath-and-glory.changeCondition" : newConditionals}) - }) - }) - } - else - { - return super._onEffectControl(event); - } - } - - /** - *When deleting a change condition, all indices after must be adjusted - * - * @param {Number} index Index of change being deleted - * @returns - */ - deleteChangeCondition(index) - { - let newConditionals = {}; - let conditionals = foundry.utils.deepClone(this.document.changeConditionals); - delete conditionals[index]; - Object.values(conditionals).forEach((value, index) => { - newConditionals[index] = value; - }) - return newConditionals; - } -} \ No newline at end of file diff --git a/scripts/apps/archetype-generic.js b/scripts/apps/archetype-generic.js deleted file mode 100644 index 890a926..0000000 --- a/scripts/apps/archetype-generic.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Interface for creating a generic object stored in an archetype's wargear. - * These generic objects are used when the archetype refers to an item that doesn't exist officially. - * This object could simply be a description of the item, or could include filters (to accomodate for - * some archetypes specifying a range of items e.g. "Any Common Weapon") - */ - -export default class ArchetypeGeneric extends FormApplication { - - static get defaultOptions() { - let options = super.defaultOptions; - options.classes.push("archetype-generic"); - options.template = "systems/wrath-and-glory/template/apps/archetype-generic.hbs"; - options.height = "auto"; - options.width = 285; - options.title = "Archetype Item Generic"; - options.resizable = true; - return options; - } - - getData() { - let data = super.getData(); - let generic = {} - if (Number.isNumeric(this.object.index)) - { - generic.property = this.object.item.wargear[this.object.index]?.property - generic.name = this.object.item.wargear[this.object.index]?.name - generic.filters = this.object.item.wargear[this.object.index]?.filters - } - - data.property = generic.property; - data.name = generic.name; - data.filters = generic.filters || [{test : "", property: "", value : ""}] - - return data - } - - async _updateObject(event, formData) { - let wargear = duplicate(this.object.item.wargear) - - // Create filter array with - let filters = Array.from($(event.target).find(".test")).map(t => { return {test : t.value}}) - - // Add Property to each element in the filter array - Array.from($(event.target).find(".property")).map((p, i) => filters[i].property = p.value) - - // Add value to each element in the filter array - Array.from($(event.target).find(".value")).map((p, i) => filters[i].value = p.value) - - filters = filters.filter(f => f.property) - - let generic = {type: "generic", name : formData.name, filters} - let groups = this.object.item.groups - if (Number.isNumeric(this.object.index)) - wargear[this.object.index] = generic - else - { - wargear.push(generic) - // Add new index to groups (last index + 1) - groups = this.object.item.addToGroup({type : "item", index : (wargear.length - 1 || 0)}) - - } - - this.object.item.update({"system.wargear" : wargear, "system.groups" : groups}) - } - - - activateListeners(html) - { - super.activateListeners(html) - - html.find(".add-filter").click(async ev => { - await this._updateObject(ev, new FormDataExtended(this.form)) - let wargear = duplicate(this.object.item.wargear) - let generic = wargear[this.object.index || 0] - generic.filters.push({test : "", property: "", value: ""}) - - // // Add new index to groups (last index + 1) - // let groups = this.object.item.addToGroup({type : "item", index : (wargear.length - 1 || 0)}) - - await this.object.item.update({"system.wargear" : wargear}) - this.render(true); - }) - } - - -} \ No newline at end of file diff --git a/scripts/apps/archetype-groups.js b/scripts/apps/archetype-groups.js deleted file mode 100644 index 97c9161..0000000 --- a/scripts/apps/archetype-groups.js +++ /dev/null @@ -1,302 +0,0 @@ -/** - * Welcome to my incredibly over-engineered concept for archetype wargear - * - * "groups" is the concept to convey how an archetype gets wargear A, B, C, and D (such as (A or B) and (C or D)) - * - * An archetype's wargear list is flat, however their "groups" object stores the instructions on how to distribute those items - * - * Within the groups object are objects of type "and", "or", "item". - * - * "and/or" objects have an "items" property that can store "and/or/item" type objects - * "item" type objects exist at the bottom of the structure, and they store the index of the item in the wargear array - * - * So this structure can go arbitraritly deep (ands storing ors storing ands storing ors ... to finally storing items). Absolutely overkill, but whatever - * - * Example: - * (0 AND 1 AND 2 AND (3 OR 4)) AND (5 OR 6 OR (7 AND 8)) - * { - type: "and", - items : [ - {type : 'and', items : [ - {type: 'item', index: 0}, - {type: 'item', index: 1}, - {type: 'item', index: 2}, - {type: 'or', items: [ - {type: 'item', index: 3}, - {type: 'item', index: 4}, - ]} - ]}, - {type: "or", items : [ - {type: 'item', index: 5}, - {type: 'item', index: 6}, - {type: "and", items : [ - {type: 'item', index: 7}, - {type: 'item', index: 8} - ]} - ]} - ] - } - - * - */ - - -export default class ArchetypeGroups extends Application { - - constructor(object) { - super() - this.object = object - } - - static get defaultOptions() { - return mergeObject(super.defaultOptions, { - id: "archetype-groups", - template: "systems/wrath-and-glory/template/apps/archetype-groups.hbs", - height: "auto", - width: 285, - title: "Archetype Groups", - resizable: true, - dragDrop: [{ dragSelector: ".wargear", dropSelector: ".group", permissions: { dragstart: true, drop: true } }] - }) - } - - getData() { - let data = super.getData(); - - data.groupHtml = this._constructHTML() - return data - } - - - _groupIndexToObjects() { - return ArchetypeGroups.groupIndexToObjects(this.object.groups, this.object) - } - - _constructHTML() - { - return ArchetypeGroups.constructHTML(this.object) - } - - - - // Recursive function to convert group index arrays into their corresponding objects objects - // Also assigns a temporary ID to easily handle moving groups around - static groupIndexToObjects(groupObject, item) { - if (["and", "or"].includes(groupObject.type)) - { - return { - type: groupObject.type, - items : groupObject.items.map(i => this.groupIndexToObjects(i, item)), - groupId: groupObject.groupId - } - } - - // Base case - else if (["item", "generic"].includes(groupObject.type)) - { - return mergeObject(item.wargear[groupObject.index], {index : groupObject.index, groupId : groupObject.groupId}) - } - } - - /** - * Construct html to display the groups in a readable format - * - * @param {Object} displayGroups Group object that has been processed with actual items (gone through groupIndexToObjects) - * @returns - */ - static constructHTML(item, {parentheses=false, commas=false, draggable=true}={}) { - let displayGroups = this.groupIndexToObjects(item.groups, item) - let html = ` -
If (and only if) you are updating from Wrath & Glory version 5.1.7 (or earlier), effects have been vastly improved with the integration of th Warhammer Library. However, this means that your Actors/Items in the world are out of date and don't utilize these new features.
+It is recommended that your important Actors (notably player characters) replace their Talents, Powers, Upgrades, etc. fresh from the Compendium. Note: Implementing these effects is an ongoing process, while a great many Items from the preimum modules have been updated, there may be some that have not received attention and haven't been updated.
+If you have questions, please utilize the Discord channels where I or other community members will be happy to answer your questions. Thanks!
+ `}) + game.wng.migration.migrateWorld(true, true); } - return html; - } - catch (e) - { - console.error("Error replacing links: " + e); - } -} \ No newline at end of file +}); \ No newline at end of file diff --git a/scripts/common/overrides.js b/scripts/common/overrides.js index 6e0b98b..aec5427 100644 --- a/scripts/common/overrides.js +++ b/scripts/common/overrides.js @@ -1,36 +1,6 @@ export default function() { - // Convert functions that move data between world and compendium to retain ID - Actors.prototype.fromCompendium = keepID(Actors.prototype.fromCompendium); - Items.prototype.fromCompendium = keepID(Items.prototype.fromCompendium); - Journal.prototype.fromCompendium = keepID(Journal.prototype.fromCompendium); - Scenes.prototype.fromCompendium = keepID(Scenes.prototype.fromCompendium); - RollTables.prototype.fromCompendium = keepID(RollTables.prototype.fromCompendium); - - Actor.implementation.prototype.toCompendium = keepID(Actor.implementation.prototype.toCompendium); - Item.implementation.prototype.toCompendium = keepID(Item.implementation.prototype.toCompendium); - JournalEntry.implementation.prototype.toCompendium = keepID(JournalEntry.implementation.prototype.toCompendium); - Scene.implementation.prototype.toCompendium = keepID(Scene.implementation.prototype.toCompendium); - RollTable.implementation.prototype.toCompendium = keepID(RollTable.implementation.prototype.toCompendium); - - - - function keepID(orig) - { - return function(...args) - { - try { - args[1].keepId = true; - } - catch(e) - { - console.error("Error setting keepId: " + e); - } - return orig.bind(this)(...args); - } - } - // Since IDs are maintained in WNG, we have to clean actor imports from their IDs function WNGImportFromJson(json) { const data = JSON.parse(json); diff --git a/scripts/common/tag-manager.js b/scripts/common/tag-manager.js deleted file mode 100644 index a146939..0000000 --- a/scripts/common/tag-manager.js +++ /dev/null @@ -1,38 +0,0 @@ - -export default class TagManager { - createTags() - { - this.tags = {} - Array.from(game.packs.keys()).forEach(packKey => { - this.tags[packKey] = this.findTagsFromIndex(game.packs.get(packKey).index) - }) - } - - findTagsFromIndex(index) - { - let tags = [] - index.forEach(i => { - if (!tags.includes(i.type)) - tags.push(i.type) - }) - return tags - } - - getPacksWithTag(tags) - { - if (!tags) - return Object.keys(this.tags).map(k => game.packs.get(k)) - - if (!Array.isArray(tags)) - tags = [tags] - - let keys = [] - - for(let key in this.tags) - if (this.tags[key].some(t => tags.includes(t))) - keys.push(key) - - return keys.map(k => game.packs.get(k)) - } - -} diff --git a/scripts/common/tests/ability-roll.js b/scripts/common/tests/ability-roll.js index 12366f2..2c3e097 100644 --- a/scripts/common/tests/ability-roll.js +++ b/scripts/common/tests/ability-roll.js @@ -4,61 +4,79 @@ import { WNGTest } from "./test.js" export default class AbilityRoll extends WNGTest { constructor(data = {}) { - super(data) - if (!data) - return + if (foundry.utils.isEmpty(data)) + { + // Recreated test + super(data) + return; + } + else + { + // New Test + data.targets = Array.from(game.user.targets).map(t => t.actor?.speakerData(t.document)); + super(data) + } - this.data.testData.ed = data.ed || {} - this.data.testData.ap = data.ap || {} - this.data.testData.damage= data.damage || {} + this.testData.itemId = data.item?.uuid; + + let item = data.item; - this.data.testData.otherDamage = data.otherDamage || {} + if (item.system.test.self) + { + this.testSelf = true; + } - this.testData.itemId = data.itemId + this.data.context.title = data.title; } get template() { - return "systems/wrath-and-glory/template/chat/roll/damage/ability-roll.hbs" + return "systems/wrath-and-glory/template/chat/roll/ability/ability-use.hbs" } - get damageTemplate() { - return "systems/wrath-and-glory/template/chat/roll/damage/ability-roll.hbs" - } async rollTest() { this._computeResult(); + this.result.enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {secrets: false, relativeTo: this.item}) } _computeResult() { this.data.result = {} if (this.item.hasTest) this.result.test = duplicate(this.item.test); - this.computeDamage() - this.rollDamage() + this.result.isSuccess = true; + if (this.testData.damage) + { + this.computeDamage() + } } - sendToChat() { - this.sendDamageToChat() - } - - get testEffects() { - if(this.item) - return this.item.effects.filter(e => !e.transfer) - else - return [] - } + async sendToChat({ newMessage = null, chatDataMerge = {} } = {}) { - get showEffects() { - return this.testEffects.length - } + const html = await renderTemplate(this.template, this); + let chatData = { + _id : randomID(), + type: "test", + rolls: [], + system: this.data, + user: game.user.id, + rollMode: this.context.rollMode, + content: html, + speaker: this.context.speaker + }; + chatData.speaker.alias = this.actor.token ? this.actor.token.name : this.actor.prototypeToken.name + ChatMessage.applyRollMode(chatData, chatData.rollMode); - get showTest() { - return this.item && this.item.hasTest + if (newMessage || !this.message) + { + this.context.messageId = chatData._id + await ChatMessage.create(chatData, {keepId : true}); + } + else { + delete chatData.roll + return this.message.update(chatData) + } } - get ability() {return true} - - - + get ability() {return true} } diff --git a/scripts/common/tests/corruption-test.js b/scripts/common/tests/corruption-test.js index 8efce0b..95b5be1 100644 --- a/scripts/common/tests/corruption-test.js +++ b/scripts/common/tests/corruption-test.js @@ -1,11 +1,6 @@ import { WNGTest } from "./test.js" export default class CorruptionTest extends WNGTest { - constructor(data = {}) - { - super(data) - } - get template() { return "systems/wrath-and-glory/template/chat/roll/corruption/corruption-roll.hbs" } @@ -45,9 +40,8 @@ export default class CorruptionTest extends WNGTest { if (prevLevel < newLevel) { ui.notifications.notify(game.i18n.localize("ROLL.NewCorruptionLevel")) - this.actor.setupGenericTest("mutation").then(async mutationTest => { - await mutationTest.rollTest(); - mutationTest.sendToChat(); + this.actor.setupGenericTest("mutation").then(test => { + test.rollTest(); }) } } diff --git a/scripts/common/tests/damage.js b/scripts/common/tests/damage.js new file mode 100644 index 0000000..96ec331 --- /dev/null +++ b/scripts/common/tests/damage.js @@ -0,0 +1,345 @@ +import { PoolDie } from "./test"; + +export class DamageRoll { + constructor(data) { + this.data = data + if (this.result.roll) + this.roll = Roll.fromData(this.result.roll) + this.rerolledDamage = this.rerollData.rerolls.map(i => Roll.fromData(i)); + } + + static DEFAULT_DAMAGE = { + damage : 0, + ed : {value : 0}, + ap : {value : 0}, + damageDice : { + values : { + 1 : 0, + 2 : 0, + 3 : 0, + 4 : 1, + 5 : 1, + 6 : 2, + }, + addValue : 0 + }, + other : { + mortal: "", + wounds: "", + shock: "", + } + } + + static fromTest(test) + { + return new this({ + damageData : foundry.utils.mergeObject(foundry.utils.deepClone(this.DEFAULT_DAMAGE), test.result.damage), + context : { + title : test.context.title, + targets : test.context.targets, + speaker : test.context.speaker, + source : test.message?.id, + itemId : test.testData.itemId + }, + rerollData : { + indices : [], + rerolls : [] + }, + result : { + + } + }) + } + + get template() { + return "systems/wrath-and-glory/template/chat/roll/damage/damage-roll.hbs" + } + + async rollTest() { + // Total dice in the test + let result = { + base: this.damageData.damage, + ed: this.damageData.ed.value, + ap: this.damageData.ap.value, + total: this.damageData.damage, + other : { + mortal : 0, + wounds: 0, + shock : 0 + } + } + + let modifiers = { + damage : [], + ed : [], + ap : [], + wounds : [], + mortal : [], + shock: [] + } + + await Promise.all(this.actor.runScripts("preComputeDamage", {damage : this.data.result, roll : this, test : this.source?.system.test, modifiers}) || []); + await Promise.all(this.item?.runScripts("preComputeDamage", {damage : this.data.result, roll : this, test : this.source?.system.test, modifiers}) || []); + + this.result.ed += modifiers.ed.reduce((acc, mod) => acc + mod.value, 0); + + if (this.damageData.ed.dice) + { + result.edDice = (await new Roll(this.damageData.ed.dice || "0").roll()).total; + result.ed += result.edDice; + } + + if (this.damageData.ap.dice) + { + result.apDice = (await new Roll(this.damageData.ap.dice || "0").roll()).total; + result.ap += result.apDice; + } + + this.roll = Roll.fromTerms([ + new PoolDie({ number: result.ed || 0, faces: 6, options: { values: this.damageData.damageDice.values, add : this.damageData.damageDice.addValue } }), + ]) + + await this.roll.evaluate(); + + this.damageData.roll = this.roll.toJSON(); + this.damageData.dice = this.roll.dice.reduce((prev, current) => prev.concat(current.results), []); + + // Set dice indices before filtering out shifted + this.damageData.dice.forEach((die, index) => die.index = index); + + result.other.mortal = (await new Roll(this.damageData.other.mortal?.toString() || "0").roll()).total + result.other.wounds = (await new Roll(this.damageData.other.wounds?.toString() || "0").roll()).total + result.other.shock = (await new Roll(this.damageData.other.shock?.toString() || "0").roll()).total + + + this.data.result = result; + await Promise.all(this.actor.runScripts("computeDamage", {damage : this.data.result, roll : this, test : this.source?.system.test, modifiers}) || []); + await Promise.all(this.item?.runScripts("computeDamage", {damage : this.data.result, roll : this, test : this.source?.system.test, modifiers}) || []); + this.result.base += modifiers.damage.reduce((acc, mod) => acc + mod.value, 0); + this.result.ap += modifiers.ap.reduce((acc, mod) => acc + mod.value, 0); + this.result.other.mortal += modifiers.mortal.reduce((acc, mod) => acc + mod.value, 0); + this.result.other.shock += modifiers.shock.reduce((acc, mod) => acc + mod.value, 0); + + this.computeDamage(); + + let getModifierBreakdown = (modifiers) => { + // modifiers[type].map(mod => `${mod.label}: ${HandlebarsHelpers.numberFormat(mod.value, { hash: { sign: true } })}
${this.damageData.damage} (Base) + ${result.rolledValue} (ED) ${getModifierBreakdown(modifiers.damage)}
`, + mortal : `${this.damageData.other.mortal} (@DICE) ${getModifierBreakdown(modifiers.mortal)}`, + wounds : `
${this.damageData.other.wounds} (@DICE) ${getModifierBreakdown(modifiers.wounds)}`, + shock : `
${this.damageData.other.shock} (@DICE) ${getModifierBreakdown(modifiers.shock)}`, + } + + + if ((this.damageData.other.mortal?.toString() || "").includes("d")) + { this.result.breakdown.mortal = this.result.breakdown.mortal.replace("@DICE", result.other.mortal)} + else + {this.result.breakdown.mortal = this.result.breakdown.mortal.replace("(@DICE)", "")} + + if ((this.damageData.other.wounds?.toString() || "").includes("d")) + { this.result.breakdown.wounds = this.result.breakdown.wounds.replace("@DICE", result.other.wounds)} + else + {this.result.breakdown.wounds = this.result.breakdown.wounds.replace("(@DICE)", "")} + + if ((this.damageData.other.shock?.toString() || "").includes("d")) + { this.result.breakdown.shock = this.result.breakdown.shock.replace("@DICE", result.other.shock)} + else + {this.result.breakdown.shock = this.result.breakdown.shock.replace("(@DICE)", "")} + + + if (this.result.ap) + { + this.result.breakdown.ap = `
${this.damageData.ap.value} (Base) ${getModifierBreakdown(modifiers.ap)}
` + } + + if (this.result.ed) + { + this.result.breakdown.ed = `ED: ${this.damageData.ed.value} (Base) ${getModifierBreakdown(modifiers.ed)}
`; + } + await this.sendToChat(); + } + + computeDamage() + { + + this.result.roll = foundry.utils.deepClone(this.damageData.roll); + this.result.dice = foundry.utils.deepClone(this.damageData.dice); + + if (this.rerollData.indices?.length) { + this._computeReroll(); + } + this.result.total = this.result.base; + this.result.rolledValue = 0; + this.result.dice.forEach((die) => { + this.result.rolledValue += die.value; + this.result.total += die.value; + }); + + + + } + + + _computeReroll() { + let rerolledResults = []; + for (let reroll of this.rerolledDamage) + rerolledResults.push(reroll.dice.reduce((prev, current) => prev.concat(current.results.map(i => { + i.rerolled = true; + return i; + })), [])) + + // Merge rerolls and roll - For each reroll set, take the corresponding reroll indices and keep the dice that the indices indicate + for (let i = 0; i < rerolledResults.length; i++) { + let rerollResult = rerolledResults[i]; + let shouldRerollSet = this.rerollData.indices[i]; + this.result.dice = this.result.dice.reduce((prev, current, i) => { + if (shouldRerollSet.includes(i)) { + prev.push(rerollResult[i]); + } else { + prev.push(current); + } + return prev; + }, []) + } + } + + async reroll(diceIndices) { + + this.rerollData.indices.push(diceIndices) + + let reroll = await this.roll.reroll({async: true}); + this.rerollData.rerolls.push(reroll.toJSON()) + this.rerolledDamage.push(reroll) + + this.computeDamage(); + + if (game.dice3d) { + let rerollShow = reroll.toJSON(); + rerollShow.terms = rerollShow.terms.map((term, t) => { + if (term.results) { + term.results = term.results.map((die, i) => { + if (diceIndices.includes(this.roll.terms[t].results[i]?.index)) + return die + }).filter(i => i) + } + return term + }) + await game.dice3d.showForRoll(Roll.fromData(rerollShow)) + } + + this.sendToChat() + } + + + clearRerolls() { + this.rerollData.indices = [] + this.rerollData.rerolls = []; + this.computeDamage(); + this.sendToChat() + } + + + async sendToChat({ newMessage = null} = {}) { + const html = await renderTemplate(this.template, this); + let chatData = { + _id : randomID(), + type: "damage", + rolls: [this.roll], + system: this.data, + user: game.user.id, + rollMode: game.settings.get("core", "rollMode"), + content: html, + speaker: this.context.speaker + }; + chatData.speaker.alias = this.actor.token ? this.actor.token.name : this.actor.prototypeToken.name + ChatMessage.applyRollMode(chatData, chatData.rollMode); + + if (newMessage || !this.message) + { + this.context.messageId = chatData._id + await ChatMessage.create(chatData, {keepId : true}); + } + else { + delete chatData.roll + return this.message.update(chatData) + } + } + + // Update message data without rerendering the message content + updateMessageFlags() { + if (this.message) + return this.message.update({ system: this.data }) + } + + addReport(reports, replace=false) + { + let newReports = reports.map(r => `${r.resisted ? '' : ''} ${r.message}
`).join("") + + this.context.appliedReport = replace ? newReports : ((this.context.appliedReport || "") + newReports) + this.sendToChat() + } + + async applyToTargets() + { + let tokens = (game.user.targets.size ? Array.from(game.user.targets).map(t => t.document) : this.targetTokens); + let reports = await Promise.all(tokens.map(t => t.actor?.applyDamage(this.result.total + this.result.other.wounds, {ap : this.result.ap, shock : this.result.other.shock, mortal : this.result.other.mortal}, {test : this.source?.system.test, damageRoll: this, token : t}))); + this.addReport(reports); + } + + get hasRerolled() + { + return this.rerollData.indices.length + } + + + get damageData() + { + return this.data.damageData; + } + + get rerollData() + { + return this.data.rerollData; + } + + + get context() + { + return this.data.context; + } + + get result() + { + return this.data.result; + } + + get message() + { + return game.messages.get(this.context.messageId) + } + + get source() + { + return game.messages.get(this.context.source) + } + + get targetTokens() + { + // Ability rolls aren't sourced from a Test, they roll damage directly + return this.source ? this.source.system.test.targetTokens : this.context.targets.map(i => game.scenes.get(i.scene)?.tokens.get(i.token)); + } + + get actor() { return game.wng.utility.getSpeaker(this.context.speaker) } + + get item() + { + return this.source?.system.test?.item || fromUuidSync(this.context.itemId); + } +} \ No newline at end of file diff --git a/scripts/common/tests/determination.js b/scripts/common/tests/determination.js index c482eec..183e45e 100644 --- a/scripts/common/tests/determination.js +++ b/scripts/common/tests/determination.js @@ -3,10 +3,12 @@ import { PoolDie, WNGTest } from "./test.js"; export default class DeterminationRoll extends WNGTest { constructor(data = {}) { super(data) - if (data) - { - this.testData.wounds = data.wounds - } + if (foundry.utils.isEmpty(data)) + return + + + this.testData.wounds = data.wounds; + this.testData.ignoreShock = data.ignoreShock; this.testData.useDN = false } @@ -14,25 +16,13 @@ export default class DeterminationRoll extends WNGTest { get template() { return "systems/wrath-and-glory/template/chat/roll/determination/determination-roll.hbs" } - - async rollTest() { - this.result.poolSize = this.testData.pool.size + this.testData.pool.bonus + this.getRankNum(this.testData.pool.rank); - await this._rollDice() - this._computeResult(); - } - - async _rollDice() { - - this.roll = Roll.fromTerms([ - new PoolDie({ number: this.result.poolSize, faces: 6 }), - ]) - - await this.roll.evaluate({ async: true }); - } - _computeResult() { - super._computeResult(false,false); - this.result.shock = this.result.success >= this.result.wounds ? this.result.wounds : Math.min(this.result.success, this.testData.wounds) + super._computeResult(); + // Convert number of successes to shock (but no more than the original wounds value) + this.result.converted = this.result.success >= this.result.wounds ? this.result.wounds : Math.min(this.result.success, this.testData.wounds) + this.result.shock = this.testData.ignoreShock ? 0 : this.result.converted; + this.result.shockIgnored = this.testData.ignoreShock; + // Reduce Wounds by successes rolled this.result.wounds = this.testData.wounds >= this.result.success ? this.testData.wounds - this.result.success : 0 } diff --git a/scripts/common/tests/initiative.js b/scripts/common/tests/initiative.js index ce1be26..944a525 100644 --- a/scripts/common/tests/initiative.js +++ b/scripts/common/tests/initiative.js @@ -3,6 +3,8 @@ import { PoolDie, WNGTest } from "./test.js"; export default class InitiativeRoll extends WNGTest { constructor(data = {}) { super(data) + if (foundry.utils.isEmpty(data)) + return this.testData.useDN = false } diff --git a/scripts/common/tests/mutation-test.js b/scripts/common/tests/mutation-test.js index baf5de4..6ed80fa 100644 --- a/scripts/common/tests/mutation-test.js +++ b/scripts/common/tests/mutation-test.js @@ -1,10 +1,6 @@ import { WNGTest } from "./test.js" export default class MutationTest extends WNGTest { - constructor(data = {}) - { - super(data) - } get template() { return "systems/wrath-and-glory/template/chat/roll/mutation/mutation-roll.hbs" diff --git a/scripts/common/tests/power-test.js b/scripts/common/tests/power-test.js index 713c3e5..ca12273 100644 --- a/scripts/common/tests/power-test.js +++ b/scripts/common/tests/power-test.js @@ -4,38 +4,43 @@ export default class PowerTest extends WNGTest { constructor(data) { super(data) - if (!data) + if (foundry.utils.isEmpty(data)) return - - this.data.testData.ed = data.ed || {} - this.data.testData.ap = data.ap || {} - this.data.testData.damage= data.damage || {} - this.data.testData.itemId = data.itemId + this.data.testData.potency = foundry.utils.deepClone(this.item.potency.list) + this.data.testData.potency.forEach(p => p.allocation = 0) + this.data.testData.edit.potency = 0; - // TODO: add to dialog - this.data.testData.otherDamage = { - "mortalWounds": { value: this.item.otherDamage.mortalWounds, bonus : 0 }, - "wounds": { value: this.item.otherDamage.wounds, bonus : 0 }, - "shock": { value: this.item.otherDamage.shock, bonus : 0 }, + if (this.item.system.damage?.enabled) + { + this.addDamageData(data); } - - this.data.testData.potency = duplicate(this.item.potency) - this.data.testData.potency.forEach(p => p.allocation = 0) - this.data.context.edit.potency = 0; + } get template() { return "systems/wrath-and-glory/template/chat/roll/power/power-roll.hbs" } + async runPreScripts() + { + await super.runPreScripts(); + await Promise.all(this.actor.runScripts("preRollPowerTest", this)); + await Promise.all(this.item.runScripts("preRollPowerTest", this)); + } + + async runPostScripts() + { + await super.runPostScripts(); + await Promise.all(this.actor.runScripts("rollPowerTest", this)); + await Promise.all(this.item.runScripts("rollPowerTest", this)); + } + _computeResult() { super._computeResult() - if (this.item.hasTest) this.result.test = duplicate(this.item.test); - this.computeDamage() if (this.result.isSuccess) { this.result.range = this.item.range @@ -46,7 +51,7 @@ export default class PowerTest extends WNGTest { computePotencies() { - this.result.potency = {spent : 0, options : duplicate(this.testData.potency), available : this.testData.shifted.potency.length + this.context.edit.potency} + this.result.potency = {spent : 0, options : duplicate(this.testData.potency), available : this.testData.shifted.potency.dice.length + this.testData.edit.potency} this.result.potency.options.forEach(p => { // Set initial potency values (before potency allocation) @@ -64,7 +69,7 @@ export default class PowerTest extends WNGTest { newValue = propValue.replace(propValueNum, propValueNum + addToValue) // Replace the number with the potency value added } else - newValue = propValue + addToValue // If numeric property, just add the potency value + newValue = parseInt(propValue) + addToValue // If numeric property, just add the potency value if (p.property) @@ -94,10 +99,10 @@ export default class PowerTest extends WNGTest { async edit({pool=0, wrath=0, icons=0, damage=0, ed=0, ap=0, potency=0}={}) { - this.data.context.edit.damage += damage; - this.data.context.edit.ed += ed; - this.data.context.edit.ap += ap; - this.data.context.edit.potency += potency; + this.data.testData.edit.damage += damage; + this.data.testData.edit.ed += ed; + this.data.testData.edit.ap += ap; + this.data.testData.edit.potency += potency; await super.edit({pool, wrath, icons}) } diff --git a/scripts/common/tests/resolve-test.js b/scripts/common/tests/resolve-test.js index 328bb8d..c4df696 100644 --- a/scripts/common/tests/resolve-test.js +++ b/scripts/common/tests/resolve-test.js @@ -4,7 +4,7 @@ export default class ResolveTest extends WNGTest { constructor(data = {}) { super(data) - if (!data) + if (foundry.utils.isEmpty(data)) return this.testData.type = data.type diff --git a/scripts/common/tests/stealth.js b/scripts/common/tests/stealth.js index 638bf7c..b2e5c53 100644 --- a/scripts/common/tests/stealth.js +++ b/scripts/common/tests/stealth.js @@ -3,6 +3,8 @@ import { PoolDie, WNGTest } from "./test.js"; export default class StealthRoll extends WNGTest { constructor(data = {}) { super(data) + if (foundry.utils.isEmpty(data)) + return this.testData.useDN = false } @@ -10,20 +12,6 @@ export default class StealthRoll extends WNGTest { return "systems/wrath-and-glory/template/chat/roll/stealth/stealth-roll.hbs" } - async rollTest() { - this.result.poolSize = this.testData.pool.size + this.testData.pool.bonus + this.getRankNum(this.testData.pool.rank); - await this._rollDice() - this._computeResult(); - } - - async _rollDice() { - this.roll = Roll.fromTerms([ - new PoolDie({ number: this.result.poolSize, faces: 6 }), - ]) - - await this.roll.evaluate({ async: true }); - } - _computeResult() { super._computeResult(); this.result.stealth = this.result.success; diff --git a/scripts/common/tests/test.js b/scripts/common/tests/test.js index e5a500d..5143627 100644 --- a/scripts/common/tests/test.js +++ b/scripts/common/tests/test.js @@ -1,5 +1,11 @@ -export class WNGTest { +import { DamageModel } from "../../model/item/components/damage"; +import { DamageRoll } from "./damage"; + +export class WNGTest extends WarhammerTestBase { + static rollFunction = "rollTest"; + constructor(data = {}) { + super(); this.data = { testData: { difficulty: data.difficulty, @@ -7,20 +13,50 @@ export class WNGTest { attribute: data.attribute, skill: data.skill, wrath: data.wrath, - shifted: data.shifted || { damage: [], glory: [], other: [], potency: [] }, + shifted: data.shifted || { damage: { + label : game.i18n.localize("SHIFT.DAMAGE"), + dice : [], + letter : "D" + }, glory: { + label : game.i18n.localize("SHIFT.GLORY"), + dice : [], + letter : "G" + }, other: { + label : game.i18n.localize("SHIFT.OTHER"), + dice : [], + letter : "?" + }, potency: { + label : game.i18n.localize("SHIFT.POTENCY"), + dice : [], + letter : "P" + }}, + // shifted: data.shifted || { damage: [], glory: [], other: [], potency: [], added: {} }, rerolls: [], // Indices of reroll sets, - useDN: true + useDN: true, + itemId : data.item?.uuid, + edit: { pool: 0, wrath: 0, icons: 0, damage: 0, ed: 0, ap: 0 }, }, context: { - title: data.title, - targets: data.targets ? data.targets.map(i => i.document.toObject()) || [] : [], + title: data.options?.title, + targets: data.targets || [], type: data.type, + breakdown : data.context?.breakdown, speaker: data.speaker, rollClass: this.constructor.name, + rollMode : data.rollMode, rerolled: data.rerolled || false, - edit: { pool: 0, wrath: 0, icons: 0, damage: 0, ed: 0, ap: 0 } }, - result: {} + result: { + text : { + + } + }, + class: this.constructor.name + } + + if (this.item?.system.damage?.enabled) + { + this.addDamageData(this.item.system.damage); } } @@ -28,10 +64,6 @@ export class WNGTest { return "systems/wrath-and-glory/template/chat/roll/common/common-roll.hbs" } - get damageTemplate() { - return "systems/wrath-and-glory/template/chat/roll/damage/damage-roll.hbs" - } - static recreate(data) { if (!data.context) { return; @@ -48,12 +80,54 @@ export class WNGTest { return test } + async runPreScripts() + { + await super.runPreScripts(); + await Promise.all(this.item?.runScripts("preRollTest", this) || []); + } + + async runPostScripts() + { + await super.runPostScripts(); + await Promise.all(this.item?.runScripts("rollTest", this) || []); + } + + addDamageData(data) + { + if (data instanceof DamageModel) + { + this.testData.damage = { + base : data.base, + ed : {value : data.ed.base + data.ed.bonus + (data.ed.rank * (this.actor.system.advances?.rank || 0)), dice : data.ed.dice}, + ap : {value : data.ap.base + data.ed.bonus + (data.ap.rank * (this.actor.system.advances?.rank || 0)), dice : data.ap.dice}, + damageDice : data.damageDice, + other : data.otherDamage + } + } + else // From a Dialog + { + this.testData.damage = { + base : data.damage, + ed : data.ed, + ap : data.ap, + damageDice : data.damageDice, + other : this.item.system.damage.otherDamage + } + } + } + + static fromData(data) + { + return new this(data); + } + async rollTest() { + await this.runPreScripts() // Total dice in the test - let diceNum = this.testData.pool.size + this.testData.pool.bonus + this.getRankNum(this.testData.pool.rank); + let diceNum = this.testData.pool // Wrath = wrath value inputted, but can't be above total number of dice, and can't be negative - this.result.wrathSize = this.testData.wrath.base < 0 ? 0 : Math.min(this.testData.wrath.base, diceNum); + this.result.wrathSize = this.testData.wrath < 0 ? 0 : Math.min(this.testData.wrath, diceNum); // Leftover, if any, is pool dice this.result.poolSize = Math.max(diceNum - this.result.wrathSize, 0) @@ -62,6 +136,7 @@ export class WNGTest { this._computeResult(); this.handleCounters(); + await this.runPostScripts(); return this @@ -79,8 +154,8 @@ export class WNGTest { } _computeResult() { - this.data.result = {} - this.result.dn = (this.testData.useDN) ? this.testData.difficulty.target + this.testData.difficulty.penalty - this.getRankNum(this.testData.difficulty.rank) : 0; + this.data.result = {text : {}} + this.result.dn = (this.testData.useDN) && this.testData.difficulty this.result.roll = this.roll.toJSON(); this.result.dice = this.roll.dice.reduce((prev, current) => prev.concat(current.results), []); @@ -99,12 +174,18 @@ export class WNGTest { this.result.allDice = duplicate(this.result.dice); this.result.dice = this.result.dice.filter(die => !this.isShifted(die.index)); - this.result.success = this.result.dice.reduce((prev, current) => prev + current.value, 0) + this.context.edit.icons; + this.result.success = this.result.dice.reduce((prev, current) => prev + current.value, 0) + this.testData.edit.icons; this.result.failure = this.result.dice.reduce((prev, current) => prev + (current.value === 0 ? 1 : 0), 0); this.result.shiftsPossible = (this.isShiftable) ? this._countShifting() : 0; this.result.isSuccess = this.result.success >= this.result.dn; if (this.result.isWrathCritical) this.result.isWrathCritical = this.result.isWrathCritical && this.result.isSuccess // Only critical if test is successful + + if (this.result.isSuccess) + this.computeDamage() + + if (this.item?.hasTest && !this.item.system.test.self) this.result.test = duplicate(this.item.test); + } _computeReroll() { @@ -131,6 +212,24 @@ export class WNGTest { } } + /** + * Set Base values for damage + */ + computeDamage() { + if (this.testData.damage) + { + + this.result.damage = foundry.utils.deepClone({ + damage : this.testData.damage.base + this.testData.edit.damage, + ed : { value : this.testData.damage.ed.value + this.testData.shifted.damage.dice.length + this.testData.edit.ed, dice : this.testData.damage.ed.dice}, + ap : { value : this.testData.damage.ap.value + this.testData.edit.ap, dice : this.testData.damage.ap.dice}, + damageDice : this.testData.damage.damageDice, + other : this.testData.damage.other || this.item?.system?.damage.otherDamage + }) + } + } + + _handleWrath() { this.result.isWrathComplication = this.result.dice.some(r => r.isWrath && r.result === 1); @@ -146,14 +245,14 @@ export class WNGTest { _computeShifted() { this.result.shifted = this.result.dice.filter(die => this.isShifted(die.index)); this.result.shifted.forEach(die => { - if (this.testData.shifted.damage.includes(die.index)) - die.shift = "damage"; - else if (this.testData.shifted.glory.includes(die.index)) - die.shift = "glory"; - else if (this.testData.shifted.potency.includes(die.index)) - die.shift = "potency" - else - die.shift = "other"; + + for(let type in this.testData.shifted) + { + if (this.testData.shifted[type].dice.includes(die.index)) + { + die.shifted = this.testData.shifted[type]; + } + } }) } @@ -170,7 +269,7 @@ export class WNGTest { rerollShow.terms = rerollShow.terms.map((term, t) => { if (term.results) { term.results = term.results.map((die, i) => { - if (diceIndices.includes(this.roll.terms[t].results[i]?.index)) + if (diceIndices.includes(this.roll.terms[t].results?.[i]?.index)) return die }).filter(i => i) } @@ -208,11 +307,15 @@ export class WNGTest { wrathDice = new WrathDie({ number: wrath, faces: 6 }) let added - if (poolDice || wrathDice) { + if (poolDice && wrathDice) { added = Roll.fromTerms([ - poolDice, wrathDice + poolDice, new OperatorTerm({operator : "+"}), wrathDice ].filter(d => d)) } + else + { + added = Roll.fromTerms([poolDice || wrathDice]); + } if (pool < 0) { removePool = Math.abs(pool); @@ -225,6 +328,8 @@ export class WNGTest { let oldTerms = foundry.utils.deepClone(this.roll.terms).filter(t => t instanceof OperatorTerm || t.results.length > 0); + + // Find the last term of what is being deleted, and delete dice from that term // Example: Normal dice rolls will look like [PoolDieTerm, Operator, WrathDieTerm] // But, the user previously added dice, it will look like [PoolDieTerm, Operator, WrathDieTerm, PoolDieTerm] @@ -264,14 +369,22 @@ export class WNGTest { newRoll.splice(newRoll.length - 1, 1); } + // For some reason operator terms aren't evaluated but they are required to be to use fromTerms? + for(let term of newRoll) + { + if (!term._evaluated) + { + await term.evaluate(); + } + } this.roll = Roll.fromTerms(newRoll) } async edit({ pool = 0, wrath = 0, icons = 0 } = {}) { - this.context.edit.icons += icons; - this.context.edit.pool += pool; - this.context.edit.wrath += wrath; + this.testData.edit.icons += icons; + this.testData.edit.pool += pool; + this.testData.edit.wrath += wrath; if (pool || wrath) await this._addDice({ pool, wrath }) @@ -279,6 +392,11 @@ export class WNGTest { this.sendToChat(); } + addShiftOption(key, label, letter) + { + this.testData.shifted[key] = {dice : [], letter, label} + } + handleCounters() { if (this.result.isWrathCritical && !this.context.counterChanged && this.actor.getFlag("wrath-and-glory", "generateMetaCurrencies")) { @@ -299,9 +417,14 @@ export class WNGTest { } - shift(shift, type) { + async shift(shift, type) + { + if (type == "other" && Object.keys(this.testData.shifted).length > 4) + { + type = await this.promptShiftType() + } - this.testData.shifted[type] = this.testData.shifted[type].concat(shift) + this.testData.shifted[type].dice = this.testData.shifted[type].dice.concat(shift) this._computeResult() this.sendToChat() } @@ -314,10 +437,10 @@ export class WNGTest { ui.notifications.notify(game.i18n.format("COUNTER.GLORY_CHANGED", { change: glorySubtract })) }) //this.result.allDice.filter(die => die.shift).forEach(die => die.shift = "") - this.testData.shifted.other = [] - this.testData.shifted.damage = [] - this.testData.shifted.glory = [] - this.testData.shifted.potency = [] + for(let option of Object.values(this.testData.shifted)) + { + option.dice = []; + } this._computeResult() this.sendToChat() } @@ -327,24 +450,37 @@ export class WNGTest { return true } + async promptShiftType() + { + let options = Object.keys(this.testData.shifted).filter(i => !["damage", "potency", "glory"].includes(i)).map(id => { + return { + id, + name : this.testData.shifted[id].label, + img : "modules/wng-core/assets/dice/die-pool-6.webp" + } + }) + return (await ItemDialog.create(options, 1, {title : "Shift Options"}))[0].id + } + async sendToChat({ newMessage = null, chatDataMerge = {} } = {}) { const html = await renderTemplate(this.template, this); let chatData = { - type: CONST.CHAT_MESSAGE_TYPES.ROLL, + _id : randomID(), + type: "test", rolls: [this.roll], - flags: { "wrath-and-glory.testData": this.data }, + system: this.data, user: game.user.id, - rollMode: game.settings.get("core", "rollMode"), + rollMode: this.context.rollMode, content: html, speaker: this.context.speaker }; chatData.speaker.alias = this.actor.token ? this.actor.token.name : this.actor.prototypeToken.name ChatMessage.applyRollMode(chatData, chatData.rollMode); - if (newMessage || !this.message) { - return ChatMessage.create(chatData).then(msg => { - msg.update({ "flags.wrath-and-glory.testData.context.messageId": msg.id }) - }); + if (newMessage || !this.message) + { + this.context.messageId = chatData._id + await ChatMessage.create(chatData, {keepId : true}); } else { delete chatData.roll @@ -355,7 +491,7 @@ export class WNGTest { // Update message data without rerendering the message content updateMessageFlags() { if (this.message) - return this.message.update({ "flags.wrath-and-glory.testData": this.data }) + return this.message.update({ system: this.data }) } _countShifting() { @@ -371,16 +507,7 @@ export class WNGTest { } isShifted(dieIndex) { - if (this.testData.shifted.damage.includes(dieIndex)) - return true - if (this.testData.shifted.glory.includes(dieIndex)) - return true - if (this.testData.shifted.potency.includes(dieIndex)) - return true - if (this.testData.shifted.other.includes(dieIndex)) - return true - - return false + return Object.values(this.testData.shifted).some(option => option.dice.includes(dieIndex)); } getRankNum(rank) { @@ -400,132 +527,41 @@ export class WNGTest { } } - /** - * Set Base values for damage, before any rolling - */ - computeDamage() { - this.result.damage = { - ed: {}, - ap: (this.testData.ap.base + this.testData.ap.bonus + this.getRankNum(this.testData.ap.rank) + this.context.edit.ap) || 0, - dice: [], - flat: this.testData.damage.base + this.testData.damage.bonus + this.getRankNum(this.testData.damage.rank), - total: 0, - other: duplicate(this.testData.otherDamage || {}) - } - this.result.damage.total = this.result.damage.flat + this.context.edit.damage - this.result.damage.ed = { number: this.testData.ed.base + this.testData.ed.bonus + this.getRankNum(this.testData.ed.rank) + this.testData.shifted.damage.length + this.context.edit.ed}; - this.result.damage.ed.values = this.testData.ed.damageValues - } - async rollDamage() { - - this.result.damage.total = this.result.damage.flat + this.context.edit.damage - this.result.damage.dice = []; - - let add = 0 - if (this.weapon && this.weapon.traitList.rad) - add = Number(this.weapon.traitList.rad.rating) || 0; - - - let damage = this.result.damage - - - // Don't like this but will work for now - if (this.weapon && this.weapon.traitList.melta && this.result.range == "short") { - damage.ed.values = { - 1: 0, - 2: 0, - 3: 1, - 4: 1, - 5: 2, - 6: 2 - } - if (game.actors.get(this.data.context.targets[0]?.actorId)?.type == "vehicle") - { - damage.ed.values = { - 1: 1, - 2: 1, - 3: 1, - 4: 2, - 5: 2, - 6: 2 - } - } - } - - let r = Roll.fromTerms([ - new PoolDie({ number: damage.ed.number, faces: 6, options: { values: damage.ed.values, add } }), - ]) - - await r.evaluate({ async: true }); - r.terms.forEach((term) => { - if (typeof term === 'object' && term !== null) { - term.results.forEach(die => { - this.result.damage.total += die.value; - this.result.damage.dice.push(die); - }); - } - }); - - // Other Damage - for (let damage in this.result.damage.other) { - if (this.result.damage.other[damage].value) - this.result.damage.other[damage].total = (await new Roll(this.result.damage.other[damage].value).evaluate({ async: true })).total + this.result.damage.other[damage].bonus - else if (this.result.damage.other[damage].bonus) - this.result.damage.other[damage].total = this.result.damage.other[damage].bonus - - } - - this.damageRoll = r; - this.result.damage.roll = r.toJSON() + let damage = DamageRoll.fromTest(this); + await damage.rollTest(); + this.result.damageRoll = damage.context.messageId; this.updateMessageFlags() - this.sendDamageToChat() } - - async sendDamageToChat() { - const html = await renderTemplate(this.damageTemplate, this); - let chatData = { - type: CONST.CHAT_MESSAGE_TYPES.ROLL, - roll: this.damageRoll, - flags: { "wrath-and-glory.testData": this.data }, - user: game.user.id, - rollMode: game.settings.get("core", "rollMode"), - content: html, - speaker: this.context.speaker - }; - - ChatMessage.applyRollMode(chatData, chatData.rollMode); - return ChatMessage.create(chatData); + get hasRerolled() + { + return this.testData.rerolls?.length } - // Need a specialized function to account for both item and ammo effects - getEffect(effectId) { - return this.testEffects.find(e => e.id == effectId) + _formatBreakdown(breakdown) + { + breakdown.modifiersBreakdown = `${game.i18n.localize("DIALOG.MODIFIER_BREAKDOWN")}
${breakdown.modifiersBreakdown}`; + return Object.values(breakdown).join(""); } get doesDamage() { - return (this.testData.damage && (this.testData.damage.base || this.testData.damage.bonus || this.testData.damage.rank != "none")) || (this.testData.ed && (this.testData.ed.base || this.testData.ed.bonus || this.testData.ed.rank != "none")) + return this.testData.damage; } - get testEffects() { - if (this.item) { - let effects = this.item.effects.filter(e => !e.transfer) - if (this.item.isRanged && this.item.Ammo) - effects = effects.concat(this.item.Ammo.ammoEffects) - return effects + get showTest() { + let effects = this.targetEffects.concat(this.damageEffects).concat(this.areaEffects) + + // Effects already prompt a test + if (effects.some(e => e.system.transferData.avoidTest.value == "item")) + { + return false; } else - return [] - } - - get showEffects() { - return this.testEffects.length && this.result.isSuccess - } - - get showTest() { - return this.result.isSuccess && this.result.test + { + return this.result.isSuccess && this.result.test + } } get testDisplay() { diff --git a/scripts/common/tests/weapon-test.js b/scripts/common/tests/weapon-test.js index 4fc3e59..61f4483 100644 --- a/scripts/common/tests/weapon-test.js +++ b/scripts/common/tests/weapon-test.js @@ -4,16 +4,14 @@ export default class WeaponTest extends WNGTest { constructor(data = {}) { super(data) - if (!data) + if (foundry.utils.isEmpty(data)) return - this.data.testData.ed = data.ed - this.data.testData.ap = data.ap - this.data.testData.damage= data.damage this.data.testData.range = data.range this.data.testData.aim = data.aim - this.testData.itemId = data.itemId + this.addDamageData(data); + //this.data.context.edit = mergeObject(this.data.context.edit, {damage : 0, ed : 0, ap : 0}) } @@ -21,12 +19,23 @@ export default class WeaponTest extends WNGTest { return "systems/wrath-and-glory/template/chat/roll/weapon/weapon-roll.hbs" } + async runPreScripts() + { + await super.runPreScripts(); + await Promise.all(this.actor.runScripts("preRollWeaponTest", this)); + } + + async runPostScripts() + { + await super.runPostScripts(); + await Promise.all(this.actor.runScripts("rollWeaponTest", this)); + } async edit({pool=0, wrath=0, icons=0, damage=0, ed=0, ap=0}={}) { - this.data.context.edit.damage += damage; - this.data.context.edit.ed += ed; - this.data.context.edit.ap += ap; + this.data.testData.edit.damage += damage; + this.data.testData.edit.ed += ed; + this.data.testData.edit.ap += ap; await super.edit({pool, wrath, icons}) } @@ -36,9 +45,6 @@ export default class WeaponTest extends WNGTest { this.result.range = this.testData.range this.result.aim = this.testData.aim - if (this.item.hasTest) this.result.test = duplicate(this.item.test); - if (this.result.isSuccess) - this.computeDamage() } get weapon() {return fromUuidSync(this.testData.itemId)} diff --git a/scripts/common/utility.js b/scripts/common/utility.js index e2b881d..15b8426 100644 --- a/scripts/common/utility.js +++ b/scripts/common/utility.js @@ -1,30 +1,6 @@ import { WrathAndGloryItem } from "../document/item.js"; export default class WNGUtility { - /** - * Searches an object for a key that matches the given value. - * - * @param {String} value value whose key is being searched for - * @param {Object} obj object to be searched in - */ - static findKey(value, obj, options = {}) { - if (!value || !obj) - return undefined; - - if (options.caseInsensitive) { - for (let key in obj) { - if (obj[key].toLowerCase() == value.toLowerCase()) - return key; - } - } - else { - for (let key in obj) { - if (obj[key] == value) - return key; - } - } - } - static getAttributeCostTotal(rating, base = 0) { let total = 0 @@ -71,9 +47,9 @@ export default class WNGUtility { let item = game.items.contents.find(i => i.type == "keyword" && i.name.toLowerCase() == name.toLowerCase()) if (!item) { - let packs = game.wng.tags.getPacksWithTag("keyword") - for (let pack of packs) { - let i = pack.index.contents.find(i => i.name == name) + for (let pack of game.packs) { + + let i = pack.index.contents.find(i => i.name == name && i.type == "keyword") if (i) { // If item is in pack item = await pack.getDocument(i._id) } @@ -87,31 +63,6 @@ export default class WNGUtility { return new WrathAndGloryItem({ name, type: "keyword", img: "modules/wng-core/assets/ui/aquila-white.webp" }) } - static _keepID(id, document) { - try { - let compendium = !!document.pack - let world = !compendium - let collection - - if (compendium) { - let pack = game.packs.get(document.pack) - collection = pack.index - } - else if (world) - collection = document.collection - - if (collection.has(id)) { - ui.notifications.notify(`${game.i18n.format("ERROR.ID", { name: document.name })}`) - return false - } - else return true - } - catch (e) { - console.error(e) - return false - } - } - static _getTargetDefence() { const targets = game.user.targets.size; if (0 >= targets) { @@ -156,32 +107,6 @@ export default class WNGUtility { } } - static highlightToken(ev) { - if (!canvas.ready) return; - const li = ev.target; - let tokenId = li.dataset.tokenId - const token = canvas.tokens.get(tokenId); - if (token?.isVisible) { - if (!token._controlled) token._onHoverIn(ev); - this._highlighted = token; - } - } - - static unhighlightToken(ev) { - const li = ev.target; - let tokenId = li.dataset.tokenId - if (this._highlighted) this._highlighted._onHoverOut(ev); - this._highlighted = null; - } - - - static focusToken(ev) { - const li = ev.target; - let tokenId = li.dataset.tokenId - const token = canvas.tokens.get(tokenId); - canvas.animatePan({ x: token.center.x, y: token.center.y, duration: 250 }); - } - static async tableToHTML(table, label, options=[]) { let noCenter = options.includes("no-center"); @@ -235,29 +160,25 @@ export default class WNGUtility { // Trigger the item roll switch (itemType) { case "attribute": - test = await actor.setupAttributeTest(itemName) + actor.setupAttributeTest(itemName) break; case "skill": - test = await actor.setupSkill(itemName) + actor.setupSkill(itemName) break; case "weapon": - test = await actor.setupWeaponTest(item) + actor.setupWeaponTest(item) break; case "psychicPower": - test = await actor.setupPowerTest(item) + actor.setupPowerTest(item) break; case "ability": - test = await actor.setupAbilityRoll(item) + actor.setupAbilityRoll(item) break; default: - test = await actor.setupGenericTest(itemType) + actor.setupGenericTest(itemType) break; } - return Array.isArray(test) - ? test.forEach(t => t.rollTest().then(roll => roll.sendToChat())) - : test.rollTest().then(roll => roll.sendToChat()) - } } diff --git a/scripts/document/actor.js b/scripts/document/actor.js index 0c9deb3..096fe69 100644 --- a/scripts/document/actor.js +++ b/scripts/document/actor.js @@ -1,4 +1,3 @@ -import WNGDocumentMixin from "./mixin.js"; import { WNGTest } from "../common/tests/test.js"; import WeaponTest from "../common/tests/weapon-test.js"; import PowerTest from "../common/tests/power-test.js"; @@ -7,41 +6,28 @@ import MutationTest from "../common/tests/mutation-test.js"; import ResolveTest from "../common/tests/resolve-test.js"; import DeterminationRoll from "../common/tests/determination.js"; import AbilityRoll from "../common/tests/ability-roll.js"; -import WNGUtility from "../common/utility.js"; import StealthRoll from "../common/tests/stealth.js"; import CharacterCreation from "../apps/character-creation.js"; import { RollDialog } from "../common/dialogs/base-dialog.js"; import { WeaponDialog } from "../common/dialogs/weapon-dialog.js"; import { PowerDialog } from "../common/dialogs/power-dialog.js"; +import { CommonDialog } from "../common/dialogs/common-dialog.js"; -export class WrathAndGloryActor extends WNGDocumentMixin(Actor) { +export class WrathAndGloryActor extends WarhammerActor { prepareBaseData() { - // this.propagateDataModels(this.system, "runScripts", this.runScripts.bind(this)); - this._itemTypes = null; - this.derivedEffects = [] - this.system.computeBase(); - // this.runScripts("prepareBaseData", this); + this.derivedEffects = []; + super.prepareBaseData(); + this.keywords = new Set(this.itemTypes.keyword.map(i => i.name)); } prepareDerivedData() { - this.runScripts("prePrepareDerivedData", this); - this.system.computeDerived(); - this.items.forEach(i => i.prepareOwnedData()); - } - - - prepareDerivedData() { - // this.runScripts("prePrepareDerivedData", this); - this._applyDerivedEffects() - this.system.computeDerived(); - this.items.forEach(i => i.prepareOwnedData()); - // this.runScripts("prepareOwnedItems", this); - // this.system.computeDerived(); - // this.runScripts("postPrepareDerivedData", this); + this._applyDerivedEffects(); + super.prepareDerivedData(); } + _applyDerivedEffects() { this.derivedEffects.forEach(change => { change.effect.fillDerivedData(this, change) @@ -49,395 +35,210 @@ export class WrathAndGloryActor extends WNGDocumentMixin(Actor) { }) } + async _onUpdate(data, options, user) + { + await super._onUpdate(data, options, user); + if (options.deltaWounds > 0) + { + TokenHelpers.displayScrollingText("+" + options.deltaWounds, this, {fill: "0xFF0000", direction : CONST.TEXT_ANCHOR_POINTS.TOP}); + } + else if (options.deltaWounds < 0) + { + TokenHelpers.displayScrollingText(options.deltaWounds, this, {fill: "0x00FF00", direction : CONST.TEXT_ANCHOR_POINTS.BOTTOM}); + } + + if (options.deltaShock > 0) + { + TokenHelpers.displayScrollingText("+" + options.deltaShock, this, {fill: "0x6666FF", direction : CONST.TEXT_ANCHOR_POINTS.TOP}); + } + else if (options.deltaShock < 0) + { + TokenHelpers.displayScrollingText(options.deltaShock, this, {fill: "0x6666FF", direction : CONST.TEXT_ANCHOR_POINTS.BOTTOM}); + } + } + //#region Rolling async setupAttributeTest(attribute, options = {}) { - let attributeObject = this.attributes[attribute] - - let dialogData = this._baseDialogData(); - dialogData.title = `${game.i18n.localize(attributeObject.label)} Test` - dialogData.pool.size = attributeObject.total - this._addOptions(dialogData, options) - dialogData.type = "attribute" - dialogData.attribute = attribute - let testData = await RollDialog.create(dialogData) - testData.targets = dialogData.targets - testData.title = dialogData.title - testData.speaker = this.speakerData(); - testData.attribute = attribute; - return new WNGTest(testData) + return this._setupTest(CommonDialog, WNGTest, {attribute}, options) } async setupSkillTest(skill, options = {}) { - let skillObject = this.skills[skill] - - let dialogData = this._baseDialogData(); - dialogData.title = `${game.i18n.localize(skillObject.label)} Test` - dialogData.pool.size = skillObject.total - this._addOptions(dialogData, options) - dialogData.type = "skill" - dialogData.skill = skill - let testData = await RollDialog.create(dialogData) - testData.targets = dialogData.targets - testData.title = dialogData.title - testData.speaker = this.speakerData(); - testData.skill = skill - testData.attribute = skillObject.attribute - return new WNGTest(testData) + return this._setupTest(CommonDialog, WNGTest, {skill}, options) } async setupGenericTest(type, options = {}) { - let dialogData = this._baseDialogData(); - let testClass = WNGTest + options = foundry.utils.mergeObject(options, {fields : {}, [type] : true}) + + if (type == "conviction") + { + type = await Dialog.wait({ + title : game.i18n.localize(`ROLL.CONVICTION`), + buttons : { + corruption : { + label : game.i18n.localize(`ROLL.CORRUPTION`) + }, + mutation : { + label : game.i18n.localize(`ROLL.MUTATION`) + } + }}) + } + switch (type) { case "stealth": - dialogData.pool.size = this.skills.stealth.total; - dialogData.title = game.i18n.localize(`ROLL.STEALTH`); - dialogData.noDn = true; - testClass = StealthRoll; - break; + options.title = game.i18n.localize(`ROLL.STEALTH`); + options.noDn = true; + options.noWrath = true; + return this._setupTest(CommonDialog, StealthRoll, {skill: "stealth"}, options) case "determination": - dialogData.pool.size = this.combat.determination.total - dialogData.title = game.i18n.localize(`ROLL.DETERMINATION`) - dialogData.determination = true; - dialogData.noDn = true; - testClass = DeterminationRoll; - break; - case "conviction": - dialogData.pool.size = this.combat.conviction.total - dialogData.title = game.i18n.localize(`ROLL.CONVICTION`) - break; + options.title = game.i18n.localize(`ROLL.DETERMINATION`) + options.noDn = true; + options.noWrath = true; + return this._setupTest(RollDialog, DeterminationRoll, {pool : this.combat.determination.total,}, options) case "corruption": - dialogData.pool.size = this.combat.conviction.total - dialogData.title = game.i18n.localize(`ROLL.CORRUPTION`) - this._addCorruptionData(dialogData) - testClass = CorruptionTest; - break; + options.title = game.i18n.localize(`ROLL.CORRUPTION`) + options.conviction = true; + return this._setupTest(RollDialog, CorruptionTest, {pool : this.combat.conviction.total}, options) case "mutation": - dialogData.pool.size = this.combat.conviction.total - dialogData.title = game.i18n.localize(`ROLL.MUTATION`) - dialogData.difficulty.target = 3 - testClass = MutationTest; - break; + options.title = game.i18n.localize(`ROLL.MUTATION`) + options.conviction = true; + return this._setupTest(RollDialog, MutationTest, {pool : this.combat.conviction.total}, options) case "fear": - dialogData.pool.size = this.combat.resolve.total - dialogData.title = game.i18n.localize(`ROLL.FEAR`) - dialogData.type == "fear" - testClass = ResolveTest - break; + options.title = game.i18n.localize(`ROLL.FEAR`) + options.resolve = true; + options.noWrath = true; + return this._setupTest(RollDialog, ResolveTest, {pool : this.combat.resolve.total}, options) case "terror": - dialogData.pool.size = this.combat.resolve.total - dialogData.title = game.i18n.localize(`ROLL.TERROR`) - dialogData.type == "terror" - testClass = ResolveTest - break; + options.title = game.i18n.localize(`ROLL.TERROR`) + options.resolve = true; + options.noWrath = true; + return this._setupTest(RollDialog, ResolveTest, {pool : this.combat.resolve.total}, options) case "influence": - dialogData.pool.size = this.resources.influence - dialogData.title = game.i18n.localize(`ROLL.INFLUENCE`) - break; + options.fields.pool = this.resources.influence + options.title = game.i18n.localize(`ROLL.INFLUENCE`) + options.noWrath = true; + return this._setupTest(RollDialog, ResolveTest, {pool : this.combat.resolve.total}, options) default: throw new Error("Unknown roll type: " + type) } - this._addOptions(dialogData, options) - dialogData.type = type - let testData = await RollDialog.create(dialogData) - testData.title = dialogData.title - testData.speaker = this.speakerData(); - testData.type = type - ui.sidebar.activateTab("chat") - return new testClass(testData) } - - async setupWeaponTest(weapon, options={}) { - if (typeof weapon == "string") - weapon = this.items.get(weapon) || await fromUuid(weapon) - - options.combi = weapon.system.combi.document ? await Dialog.confirm({title : "Combi-Weapons", content : "Fire both Combi-Weapons?"}) : false - - let tests = [] - let multi = options.combi ? 2 : 0; - - // If targets, call this function again with single target option - if (game.user.targets.size) + if (game.user.targets.size > 1) { - let targets = Array.from(game.user.targets) - game.user.updateTokenTargets([]) - options.multi = targets.length + multi; - // Function needs to return an array of WeaponTests so need to do some funky stuff to convert - targets.forEach(target => { - options.target = target; - tests.push(this._promptWeaponDialog(weapon, options)) - if (options.combi) - { - tests.push(this._promptWeaponDialog(weapon.system.combi.document, options)) - } - }) - tests = await Promise.all(tests) + return Promise.all(game.user.targets.map(i => { + let optionsCopy = foundry.utils.deepClone(options); + optionsCopy.targets = [i]; + optionsCopy.multi = game.user.targets.size; + return this._setupTest(WeaponDialog, WeaponTest, weapon, optionsCopy); + })) } else { - options.multi = multi; - tests = [await this._promptWeaponDialog(weapon, options)]; - if (options.combi) - { - tests.push(await this._promptWeaponDialog(weapon.system.combi.document, options)) - } + return this._setupTest(WeaponDialog, WeaponTest, weapon, options); } - - - return tests - } - - async _promptWeaponDialog(weapon, options) - { - let dialogData = this._weaponDialogData(weapon, {multi : options.multi, targets : [options.target].filter(t => t)}); - dialogData.title = `${weapon.name} Test` - this._addOptions(dialogData, options) - dialogData.type = "weapon" - dialogData.skill = weapon.isMelee ? "weaponSkill" : "ballisticSkill" - dialogData.attribute = weapon.getSkillFor(this).attribute - let testData = await WeaponDialog.create(dialogData) - testData.targets = dialogData.targets - testData.title = dialogData.title - testData.speaker = this.speakerData(); - testData.itemId = weapon.uuid - testData.skill = dialogData.skill - testData.attribute = dialogData.attribute - return new WeaponTest(testData); } async setupPowerTest(power, options = {}) { - if (typeof power == "string") - power = this.items.get(power) || await fromUuid(power) - - let dialogData = this._powerDialogData(power); - dialogData.title = `${power.name}` - this._addOptions(dialogData, options) - dialogData.type = "power" - dialogData.skill = "psychicMastery" - dialogData.attribute = power.skill.attribute - let testData = await PowerDialog.create(dialogData) - testData.targets = dialogData.targets - testData.title = dialogData.title - testData.speaker = this.speakerData(); - testData.itemId = power.uuid - testData.skill = dialogData.skill - testData.attribute = dialogData.attribute - ui.sidebar.activateTab("chat") - return new PowerTest(testData) + return this._setupTest(PowerDialog, PowerTest, power, options) } async setupAbilityRoll(ability, options = {}) { let testData = { title: ability.name, speaker: this.speakerData(), - itemId: ability.uuid, - damage: {}, - ed: {}, - ap: {} - } - if (ability.hasDamage) { - testData.damage.base = ability.damage.base - testData.damage.bonus = ability.damage.bonus - testData.damage.rank = ability.damage.rank - testData.ed.base = ability.ed.base - testData.ed.bonus = ability.ed.bonus - testData.ed.rank = ability.ed.rank - testData.ap.base = ability.ap.base - testData.ap.bonus = ability.ap.bonus - testData.ap.rank = ability.ap.rank - testData.otherDamage = { - mortalWounds: { value: ability.otherDamage.mortalWounds, bonus : 0 }, - wounds: { value: ability.otherDamage.wounds, bonus : 0 }, - shock: { value: ability.otherDamage.shock, bonus : 0 }, - } - + item: ability, } - ui.sidebar.activateTab("chat") - return new AbilityRoll(testData) - } - _baseDialogData() { - return { - difficulty: { - target: 3, - penalty: 0, - rank: "none" - }, - pool: { - size: 1, - bonus: 0, - rank: "none" - }, - wrath: { - base: this.hasCondition("dying") ? 1 + this.itemTypes["traumaticInjury"].length : 1 - }, - changes: this.allDialogChanges( {targets : Array.from(game.user.targets).map(t => t.actor)}), - actor: this, - targets: Array.from(game.user.targets) - }; - } - - - _weaponDialogData(weapon, options={}) { - - let dialogData = this._baseDialogData() - if (options.targets) + if (ability.system.test.self) { - dialogData.targets = options.targets; - dialogData.changes = this.allDialogChanges({targets: options.targets.map(i => i.actor), vehicle : weapon.actor?.type == "vehicle" ? weapon.actor : null}); - // Weapon dialogs need to get dialog changes separately because of special target handling - } - - if (weapon.Ammo) { - // Add ammo dialog changes if any exist - weapon.Ammo.effects.forEach(e => { - mergeObject(dialogData.changes, e.getDialogChanges()) - }) + return this.setupTestFromItem(ability, {item : ability}); } - dialogData.weapon = weapon - dialogData.skill = weapon.getSkillFor(this) - dialogData.pool.size = dialogData.skill.total; - dialogData.pool.bonus = weapon.attack.base + weapon.attack.bonus; - if (this.isMob) - dialogData.pool.bonus += Math.ceil(this.mob / 2) - dialogData.pool.rank = weapon.attack.rank; - dialogData.damageValues = weapon.damageValues - dialogData.damage = duplicate(weapon.system.damage) - dialogData.ed = duplicate(weapon.system.damage.ed) - dialogData.ap = duplicate(weapon.system.damage.ap) - - if (weapon.isMelee) { - dialogData.damage.base += this.attributes.strength.total - } - - if (weapon.traitList.force) { - if (this.hasKeyword("PSYKER")) - dialogData.damage.bonus += Math.ceil(this.attributes.willpower.total / 2) - else - dialogData.damage.bonus -= 2 - } - - if (dialogData.targets[0]) + if (this.type == "threat" && ability.type == "ability" && ability.system.cost) { - let target = dialogData.targets[0] - let token - dialogData.difficulty.target = target.actor.combat.defence.total - - if (this.isToken) - token = this.token - else - token = this.getActiveTokens()[0]?.document - - if (token) - dialogData.distance = canvas.grid.measureDistances([{ ray: new Ray({ x: token.x, y: token.y }, { x: target.x, y: target.y }) }], { gridSpaces: true })[0] - - if (target.actor.system.combat.size == "large") + if (!(await this.spend("system.resources.ruin", ability.system.cost || 0))) { - dialogData.pool.bonus += 1; - } - else if (target.actor.system.combat.size == "huge") - { - dialogData.pool.bonus += 2; + if (game.counter.ruin > 0) + { + game.wng.RuinGloryCounter.changeCounter(-1, "ruin"); + ui.notifications.notify(`${ability.name}: Spent ${ability.system.cost} Ruin (Counter)`) + } + else + { + ui.notifications.error(`${ability.name}: Not enough Ruin!`) + return; + } } - else if (target.actor.system.combat.size == "gargantuan") + else { - dialogData.pool.bonus += 3; + ui.notifications.notify(`${ability.name}: Spent ${ability.system.cost} Ruin (Personal)`) } - - - // If using melee and target has parry weapon equipped, increase difficulty - if (weapon.system.category == "melee" && target.actor.itemTypes.weapon.find(i => i.equipped && i.traitList["parry"])) - { - dialogData.difficulty.penalty += 1; } + + ui.sidebar.activateTab("chat") + let roll = new AbilityRoll(testData) + await roll.rollTest(); + roll.sendToChat(); + } - } - dialogData.difficulty.penalty += weapon.traitList.unwieldy ? parseInt(weapon.traitList.unwieldy.rating) : 0 - - if (this.hasKeyword("ORK") && weapon.traitList["waaagh!"]) + async setupTestFromItem(item, options) + { + if (typeof item == "string") { - dialogData.pool.bonus += 1; - if (this.combat.wounds.value > 0) - dialogData.ed.bonus += 1 + item = await fromUuid(item); } - if (options.multi > 1) + if (item) { - dialogData.difficulty.penalty += (options.multi - 1) * 2; - dialogData.multi = options.multi + options.appendTitle = ` - ${item.name}`; + return this.setupTestFromData(item.system.test, options); } - - return dialogData } - _powerDialogData(power) { - let dialogData = this._baseDialogData() - dialogData.power = power - dialogData.difficulty.target = power.system.DN - if (!Number.isNumeric(dialogData.difficulty.target)) { - ui.notifications.warn(game.i18n.localize("DIALOG.TARGET_DEFENSE_WARNING")) + async setupTestFromData(data, options={}) + { + let dn = data.dn; + let type = data.type; + let specification = data.specification; + foundry.utils.setProperty(options, "fields.difficulty", dn); + + if (type == "attribute") + { + return this.setupAttributeTest(specification, options) } - dialogData.pool.size = power.skill.total; - return dialogData - } - - _addOptions(dialogData, options) { - dialogData.difficulty.target = options.dn || dialogData.difficulty.target - dialogData.pool.size = options.pool || dialogData.pool.size - dialogData.title = options.title || dialogData.title - delete options.title; - delete options.pool; - delete options.dn; - - mergeObject(dialogData, options); - } - - _addCorruptionData(dialogData) { - let level = game.wng.config.corruptionLevels[this.corruptionLevel] - dialogData.difficulty.penalty += level.dn - } - - speakerData() { - if (this.isToken) { - return { - token: this.token.id, - scene: this.token.parent.id - } + else if (type == "skill") + { + return this.setupSkillTest(specification, options) } - else { - return { - actor: this.id - } + else if (type == "resolve") + { + return this.setupGenericTest(specification, options) + } + else if (type == "corruption") + { + return this.setupGenericTest(specification, options) } } - allDialogChanges({targets=[], vehicle} = {}) { - let effects = this.effects.contents.concat(vehicle?.effects.contents || []); - // Aggregate dialog changes from each effect - let changes = effects.filter(e => !e.disabled).reduce((prev, current) => mergeObject(prev, current.getDialogChanges()), {}) - - if (targets.length) { - let target = targets[0] - let targetChanges = target.effects.filter(e => !e.disabled).reduce((prev, current) => mergeObject(prev, current.getDialogChanges({target : true})), {}) - mergeObject(changes, targetChanges); + async rollDetermination(wounds, message) + { + if (this.statuses.has("exhausted")) + { + return; } - - return changes + let test = await this.setupGenericTest("determination", {message, fields: {wounds}, resolveClose: true}) + return test; } - characterCreation(archetype) { new Dialog({ title: "Character Creation", content: "Begin Character Creation?
", yes: () => new CharacterCreation({ actor: this, archetype }).render(true), no: async () => { - let species = await game.wng.utility.findItem(archetype.species.id, "species") - let faction = await game.wng.utility.findItem(archetype.faction.id, "faction") + let species = await warhammer.utility.findItemId(archetype.species.id, "species") + let faction = await warhammer.utility.findItemId(archetype.faction.id, "faction") this.createEmbeddedDocuments("Item", [archetype.toObject(), faction?.toObject(), species?.toObject()].filter(i => i)) } }).render(true) @@ -451,7 +252,7 @@ export class WrathAndGloryActor extends WNGDocumentMixin(Actor) { } else if (this.type == "threat" && apply) // If threat, apply archetype statistics { - ui.notifications.notify(`Applying ${archetype.name} Archetype`) + message.push(`Applying ${archetype.name} Archetype`) let actorData = this.toObject(); let items = await archetype.GetArchetypeItems() @@ -498,6 +299,248 @@ export class WrathAndGloryActor extends WNGDocumentMixin(Actor) { } } + async applyDamage(damage=0, {ap=0, shock=0, mortal=0}, {test, damageRoll, token, allowDetermination=true}={}) { + + let resilience = foundry.utils.deepClone(this.system.combat.resilience) + let res = resilience.total || 1 + ap = Math.abs(ap); + + token = token || this.prototypeToken; + + // label, value, description + let modifiers = { + damage : [], + ap : [], + shock: [], + mortal: [], + resilience : [], + wounds : [], + }; + + let addModifierBreakdown = (type, label) => { + for(let mod of modifiers[type]) + { + report.breakdown.push(`${mod.label}: ${HandlebarsHelpers.numberFormat(mod.value, { hash: { sign: true } })} ${label}` + (mod.description ? ` (${mod.description})` : "")) + } + } + + let mortalDetermination = false; + let args = {damage, ap, shock, mortal, test, damageRoll, modifiers, resilience, actor: this} + this.runScripts("preTakeDamage", args) + test?.actor?.runScripts("preApplyDamage", args) + test?.item?.runScripts("preApplyDamage", args) + damage = args.damage; + ap = args.ap; + shock = args.shock; + mortal = args.mortal; + mortalDetermination = args.mortalDetermination; + + let invuln = resilience.invulnerable + if (resilience.forceField) + { + mortalDetermination = true; + } + + let wounds = 0 + + let report = { + message : null, + breakdown : [], + uuid : token?.uuid + } + + if (args.abort) + { + report.message = game.i18n.format(`${token?.name} received no damage`); + report.breakdown = `${args.abort}
` + return report; + } + + damage += modifiers.damage.reduce((acc, mod) => acc + mod.value, 0); + ap += modifiers.ap.reduce((acc, mod) => acc + mod.value, 0); + mortal += modifiers.mortal.reduce((acc, mod) => acc + mod.value, 0); + + if (invuln) + { + ap = 0; + } + + if (ap) + { + let resilienceReduction = ap + if (game.settings.get('wrath-and-glory', 'advancedArmour')) + { + resilienceReduction = Math.min(ap, target.system.combat.resilience.armour) + } + addModifierBreakdown("ap", "AP"); + report.breakdown.push(`AP: Reduced Resilience to ${Math.max(0, res - resilienceReduction)} (${res} - ${resilienceReduction})`) + res = Math.max(0, res - resilienceReduction); + } + else if (invuln) + { + report.breakdown.push(`Invulnerable: Ignore AP`); + } + + if (res <= 0) + res = 1 + + if (damage) + { + addModifierBreakdown("damage", "Damage"); + if (res > damage) + { + report.message = game.i18n.format("NOTE.APPLY_DAMAGE_RESIST", {name : token?.name}) + report.breakdown.push(`Resilience: Resisted ${damage} Damage`) + report.resisted = true; + } + + if (res == damage) + { + report.breakdown.push(`Resilience: Suffered 1 Shock (${res} vs. ${damage} Damage)`) + shock++ + } + if (res < damage) + { + wounds = damage - res + report.breakdown.push(`Resilience: ${damage} Damage reduced to ${wounds} Wounds (-${res})`) + } + } + + if (mortal) + { + addModifierBreakdown("mortal", "Mortal Wounds"); + report.breakdown.push(`Mortal Wounds: ${mortal}`) + if (mortalDetermination) + { + report.breakdown.push(`Mortal Wounds: ${mortal} converted to Wounds (${wounds + mortal})`); + wounds += mortal; + mortal = 0; + } + } + + if (wounds && allowDetermination) + { + let determination = await this.rollDetermination(wounds, damageRoll?.message?.id) + if (determination) + { + wounds = determination.result.wounds; + shock += determination.result.shock; + if (determination.result.shockIgnored) + { + report.breakdown.push(`Determination: Ignored ${determination.result.converted} Wounds`) + } + else + { + report.breakdown.push(`Determination: Converted ${determination.result.converted} Wounds to Shock`) + } + report.determination = determination; + } + } + + if (shock && (this.hasCondition("exhausted"))) + { + mortal += shock; + shock = 0; + report.breakdown.push(`Exhausted: ${shock} Shock converted to Mortal Wounds (${mortal})`); + } + + + let updateObj = {} + args = {wounds, shock, mortal, report, updateObj, actor: this, test, damageRoll} + this.runScripts("takeDamage", args) + test?.actor?.runScripts("applyDamage", args) + test?.item?.runScripts("applyDamage", args) + + // If you want to modify wounds before determination, use damage modifier + // modifier.wounds is for modifying wounds after determination + wounds += modifiers.wounds.reduce((acc, mod) => acc + mod.value, 0); + shock += modifiers.shock.reduce((acc, mod) => acc + mod.value, 0); + addModifierBreakdown("shock", "Shock"); + addModifierBreakdown("wounds", "Wounds"); + + + shock = Math.max(shock, 0); + wounds = Math.max(wounds, 0); + mortal = Math.max(mortal, 0); + + if (shock > 0) + { + let newShock = this.system.combat.shock.value + shock + updateObj["system.combat.shock.value"] = newShock; + if (newShock >= this.system.combat.shock.max) + { + await this.addCondition("exhausted") + } + } + if (wounds > 0 || mortal > 0) + { + let newWounds = this.system.combat.wounds.value + wounds + mortal; + updateObj["system.combat.wounds.value"] = newWounds; + if (newWounds >= this.system.combat.wounds.max) + { + await this.addCondition("dying") + } + } + let applyDamageEffects = false + if (shock + wounds + mortal > 0 && !args.abort) // if shock or wounds or mortal + { + report.breakdown.push(game.i18n.format("NOTE.APPLY_DAMAGE", {wounds : wounds + mortal, shock, name : token?.name})); + report.message = game.i18n.format(`${token?.name} received damage`); + applyDamageEffects = true; + } + else + { + report.message = game.i18n.format(`${token?.name} received no damage`); + } + + if (args.abort) + { + report.breakdown = `${args.abort}
` + } + else + { + report.breakdown = `${report.breakdown.join(`
`)}
{{localize "GRIEVANCE.Warning1"}}{{localize "GRIEVANCE.Warning2"}} - -
{{localize "GRIEVANCE.Warning3"}} {{localize "GRIEVANCE.Warning4"}}
- -Drag and Drop Items from the Actor to designate them as Mob Abilities.
+{{localize "CHAT.SUCCESS"}}: {{result.success}}
{{localize "CHAT.FAILURE"}}: {{result.failure}}
{{#if isShiftable}}{{localize "CHAT.SHIFTING"}}: {{result.shiftsPossible}}
- {{/if}} \ No newline at end of file + {{/if}} + + {{#each result.text}} +{{this.label}}: {{this.description}}
+ {{/each}} \ No newline at end of file diff --git a/static/template/chat/roll/base/base-roll.hbs b/static/template/chat/roll/base/base-roll.hbs index e40ff83..a5da9ff 100644 --- a/static/template/chat/roll/base/base-roll.hbs +++ b/static/template/chat/roll/base/base-roll.hbs @@ -1,6 +1,5 @@{{localize "WEAPON.DAMAGE"}}: {{result.damage.total}}
- {{/if}} - {{#if result.damage.ap}} -{{localize "WEAPON.AP"}}: {{result.damage.ap}}
- {{/if}} - - {{#if result.damage.other.mortalWounds.total}} -{{localize "CHAT.MORTAL"}}: {{result.damage.other.mortalWounds.total}}
- {{/if}} - - {{#if result.damage.other.wounds.total}} -{{localize "CHAT.WOUNDS"}}: {{result.damage.other.wounds.total}}
- {{/if}} - - {{#if result.damage.other.shock.total}} -{{localize "CHAT.SHOCK"}}: {{result.damage.other.shock.total}}
- {{/if}} - - {{#if item.system.traits}} -{{localize "WEAPON.TRAITS"}}: {{item.system.traits.formatted}}
- {{/if}} -{{localize "WEAPON.DAMAGE"}}: {{result.damage.total}}
- {{#if result.damage.ap}} -{{localize "WEAPON.AP"}}: {{result.damage.ap}}
+ {{#if targetTokens.length}} +{{localize "WEAPON.DAMAGE"}}: {{result.total}}
+ {{#if result.ap}} +{{localize "WEAPON.AP"}}: {{result.ap}}
{{/if}} - {{#if result.damage.other.mortalWounds.total}} -{{localize "CHAT.MORTAL"}}: {{result.damage.other.mortalWounds.total}}
+ {{#if result.other.mortal}} +{{localize "CHAT.MORTAL"}}: {{result.other.mortal}}
{{/if}} - {{#if result.damage.other.wounds.total}} -{{localize "CHAT.WOUNDS"}}: {{result.damage.other.wounds.total}}
+ {{#if result.other.wounds}} +{{localize "CHAT.WOUNDS"}}: {{result.other.wounds}}
{{/if}} - {{#if result.damage.other.shock.total}} -{{localize "CHAT.SHOCK"}}: {{result.damage.other.shock.total}}
+ {{#if result.other.shock}} +{{localize "CHAT.SHOCK"}}: {{result.other.shock}}
{{/if}} - {{#if item.system.traits}} -{{localize "WEAPON.TRAITS"}}: {{item.system.traits.formatted}}
+ {{#if item.system.traits.list.length}} +{{localize "WEAPON.TRAITS"}}: {{item.system.traits.formatted}}
{{/if}}{{localize "CHAT.DETERMINATION"}}: {{localize "CHAT.DETERMINATION_RESULT" wounds=result.wounds shock=result.shock}}
+{{#if result.shockIgnored}} +{{localize "CHAT.DETERMINATION_RESULT_IGNORE_SHOCK" wounds=result.wounds shock=result.converted}}
+{{else}} +{{localize "CHAT.DETERMINATION_RESULT" wounds=result.wounds shock=result.converted}}
+{{/if}} diff --git a/static/template/dialog/attack-roll.hbs b/static/template/dialog/attack-roll.hbs new file mode 100644 index 0000000..506b537 --- /dev/null +++ b/static/template/dialog/attack-roll.hbs @@ -0,0 +1,67 @@ +