diff --git a/modules/model/item/components/overcast.js b/modules/model/item/components/overcast.js index a3e841bc3..ea2e36a21 100644 --- a/modules/model/item/components/overcast.js +++ b/modules/model/item/components/overcast.js @@ -19,6 +19,7 @@ export class OvercastItemModel extends BaseItemModel { additional : new fields.StringField(), characteristic : new fields.StringField(), bonus : new fields.BooleanField(), + cost : new fields.StringField() }), initial : new fields.SchemaField({ type : new fields.StringField(), diff --git a/modules/system/config-wfrp4e.js b/modules/system/config-wfrp4e.js index 0d42ab301..905fe6718 100644 --- a/modules/system/config-wfrp4e.js +++ b/modules/system/config-wfrp4e.js @@ -993,29 +993,57 @@ WFRP4E.availabilityTable = { } } -WFRP4E.overCastTable = { - range: [ - {cost: 1, value: 2}, - {cost: 4, value: 3}, - {cost: 16, value: 4}], - target: [ - {cost: 1, value: 1}, - {cost: 4, value: 2}, - {cost: 16, value: 3}], - AoE: [ - {cost: 3, value: 2}, - {cost: 18, value: 3}], - duration: [ - {cost: 2, value: 2}, - {cost: 6, value: 3}], - damage: [ - {cost: 1, value: 1}, - {cost: 1, value: 2}, - {cost: 1, value: 3}, - {cost: 2, value: 4}, - {cost: 3, value: 5}, - {cost: 5, value: 6}, - {cost: 8, value: 7}] +WFRP4E.overCastTablesPerWind = { + "default": { + range: [ + {cost: 1, value: 2}, + {cost: 4, value: 3}, + {cost: 16, value: 4}], + target: [ + {cost: 1, value: 1}, + {cost: 4, value: 2}, + {cost: 16, value: 3}], + AoE: [ + {cost: 3, value: 2}, + {cost: 18, value: 3}], + duration: [ + {cost: 2, value: 2}, + {cost: 6, value: 3}], + damage: [ + {cost: 1, value: 1}, + {cost: 1, value: 2}, + {cost: 1, value: 3}, + {cost: 2, value: 4}, + {cost: 3, value: 5}, + {cost: 5, value: 6}, + {cost: 8, value: 7}], + other: [ + {cost: 2, value: 1}, + {cost: 2, value: 2}, + {cost: 2, value: 3}, + {cost: 2, value: 4}, + {cost: 2, value: 5}, + {cost: 2, value: 6}, + {cost: 2, value: 7}, + {cost: 2, value: 8}, + {cost: 2, value: 9}, + {cost: 2, value: 10}, + {cost: 2, value: 11}, + {cost: 2, value: 12}, + {cost: 2, value: 13}, + {cost: 2, value: 14}, + {cost: 2, value: 15}, + {cost: 2, value: 16}, + {cost: 2, value: 17}, + {cost: 2, value: 18}, + {cost: 2, value: 19}, + {cost: 2, value: 20} + ] + } +} + +WFRP4E.overCastTable = function(wind) { + return WFRP4E.overCastTablesPerWind[wind] || WFRP4E.overCastTablesPerWind["default"] } WFRP4E.species = {}; diff --git a/modules/system/rolls/wom-cast-test.js b/modules/system/rolls/wom-cast-test.js index e45269ade..1575ff982 100644 --- a/modules/system/rolls/wom-cast-test.js +++ b/modules/system/rolls/wom-cast-test.js @@ -10,25 +10,26 @@ export default class WomCastTest extends CastTest { this.result.overcasts = Math.max(0, slOver) + (this.result.totalPower ? parseInt(Math.floor(this.result.roll / 10)) : 0); this.result.overcast.total = this.result.overcasts; this.result.overcast.available = this.result.overcasts; + let overCastTable = game.wfrp4e.config.overCastTable(this.spell.lore.value); // Since SL is spent by overcasts, need to keep track of original this.result.overcast.originalSL = Number(this.result.SL) if (this.result.overcast.usage.range) { - this.result.overcast.usage.range.available = this.result.overcast.available >= game.wfrp4e.config.overCastTable.range[0].cost + this.result.overcast.usage.range.available = this.result.overcast.available >= overCastTable.range[0].cost } if (this.result.overcast.usage.target) { if(this.result.overcast.usage.target.AoE) { - this.result.overcast.usage.target.available = this.result.overcast.available >= game.wfrp4e.config.overCastTable.AoE[0].cost + this.result.overcast.usage.target.available = this.result.overcast.available >= overCastTable.AoE[0].cost } else { - this.result.overcast.usage.target.available = this.result.overcast.available >= game.wfrp4e.config.overCastTable.target[0].cost + this.result.overcast.usage.target.available = this.result.overcast.available >= overCastTable.target[0].cost } } if (this.result.overcast.usage.duration) { - this.result.overcast.usage.duration.available = this.result.overcast.available >= game.wfrp4e.config.overCastTable.duration[0].cost + this.result.overcast.usage.duration.available = this.result.overcast.available >= overCastTable.duration[0].cost } if (this.result.overcast.usage.damage) { - this.result.overcast.usage.damage.available = this.result.overcast.available >= game.wfrp4e.config.overCastTable.damage[0].cost + this.result.overcast.usage.damage.available = this.result.overcast.available >= overCastTable.damage[0].cost } if (this.result.overcast.usage.other) { this.result.overcast.usage.other.available = this.result.overcast.available >= 2 @@ -38,6 +39,7 @@ export default class WomCastTest extends CastTest { async calculateDamage() { let damageBreakdown = this.result.breakdown.damage; this.result.additionalDamage = this.preData.additionalDamage || 0 + let overCastTable = game.wfrp4e.config.overCastTable(this.spell.lore.value); // Calculate Damage if the this.item has it specified and succeeded in casting try { if (this.item.Damage && this.result.castOutcome == "success") { @@ -45,7 +47,7 @@ export default class WomCastTest extends CastTest { damageBreakdown.base = `${this.item.Damage} (${game.i18n.localize("Spell")})` if (this.result.overcast.usage.damage && this.result.overcast.usage.damage.count > 0) { - let overcastDamage = game.wfrp4e.config.overCastTable.damage[this.result.overcast.usage.damage.count - 1].value + let overcastDamage = overCastTable.damage[this.result.overcast.usage.damage.count - 1].value this.result.additionalDamage += overcastDamage damageBreakdown.other.push({label : game.i18n.localize("Overcast"), value : overcastDamage}); this.result.damage += this.result.additionalDamage @@ -71,6 +73,9 @@ export default class WomCastTest extends CastTest { if (!game.settings.get("wfrp4e", "useWoMOvercast")) { await super._overcast(choice); } else { + const overCastTable = game.wfrp4e.config.overCastTable(this.spell.lore.value); + + let otherCost = overCastTable.other[0].cost const overcastData = this.result.overcast if (!overcastData.available) @@ -79,21 +84,24 @@ export default class WomCastTest extends CastTest { if (typeof overcastData.usage[choice].initial != "number") return overcastData - const overCastTable = game.wfrp4e.config.overCastTable; const count = overcastData.usage[choice].count; - // If no table entry, or costs more than SL available, do nothing // AoE is separate column from target, so must be tested separately if (choice == "target" && overcastData.usage.target.AoE) { if (!overCastTable["AoE"][count] || overCastTable["AoE"][count].cost > overcastData.available) { return overcastData; } - } - // Other options are not in the table, so assume cost is 2 per original rules + } else if (choice == "other") { - if (2 > overcastData.available) + if (overcastData.valuePerOvercast.cost) { + otherCost = parseInt(eval(overcastData.valuePerOvercast.cost + .replace("{{current}}", overcastData.usage[choice].current) + .replace("{{count}}", overcastData.usage[choice].count))); + } + if (otherCost > overcastData.available) { return overcastData + } } else { if (!overCastTable[choice][count] || overCastTable[choice][count].cost > overcastData.available) { @@ -146,7 +154,7 @@ export default class WomCastTest extends CastTest { overcastData.available = overcastData.available - overCastTable["AoE"][count].cost } else if (choice == "other") { - overcastData.available = overcastData.available - 2 + overcastData.available = overcastData.available - otherCost } else { overcastData.available = overcastData.available - overCastTable[choice][count].cost @@ -188,6 +196,7 @@ export default class WomCastTest extends CastTest { } else { let overcastData = this.result.overcast overcastData.available = overcastData.total; + let overCastTable = game.wfrp4e.config.overCastTable(this.spell.lore.value); // For each usage option, set count to 0, reset current value to initial, and check availability for (let overcastType in overcastData.usage) { @@ -196,13 +205,20 @@ export default class WomCastTest extends CastTest { overcastData.usage[overcastType].current = overcastData.usage[overcastType].initial if (overcastType == "other") { - overcastData.usage[overcastType].available = overcastData.available >= 2 + if (overcastData.valuePerOvercast.cost) { + otherCost = parseInt(eval(overcastData.valuePerOvercast.cost + .replace("{{current}}", overcastData.usage["other"].current) + .replace("{{count}}", overcastData.usage["other"].count))); + overcastData.usage[overcastType].available = overcastData.available >= otherCost + } else { + overcastData.usage[overcastType].available = overcastData.available >= overcastType[overcastType][0].cost + } } else if(overcastType == "target" && overcastData.usage.target.AoE) { - overcastData.usage[overcastType].available = overcastData.available >= game.wfrp4e.config.overCastTable.AoE[0].cost + overcastData.usage[overcastType].available = overcastData.available >= overCastTable.AoE[0].cost } else { - overcastData.usage[overcastType].available = overcastData.available >= game.wfrp4e.config.overCastTable[overcastType][0].cost + overcastData.usage[overcastType].available = overcastData.available >= overCastTable[overcastType][0].cost } } } diff --git a/static/lang/en.json b/static/lang/en.json index 3e1a46df7..b8c2c103d 100644 --- a/static/lang/en.json +++ b/static/lang/en.json @@ -1434,6 +1434,8 @@ "SHEET.Target" : "Target", "SHEET.ToggleEffect" : "Toggle Effect", "SHEET.Additional" : "Additional", + "SHEET.OtherCost": "Other Cost", + "SHEET.OtherCostPlaceholder": "formula or number", "SHEET.ApplyEffect" : "Apply {effect}", "SHEET.InvokeEffect" : "Invoke {effect}", "SHEET.ExpChange" : "Spent / Total Change", diff --git a/static/templates/items/item-spell-sheet.hbs b/static/templates/items/item-spell-sheet.hbs index 7856a4c25..db68723c0 100644 --- a/static/templates/items/item-spell-sheet.hbs +++ b/static/templates/items/item-spell-sheet.hbs @@ -279,12 +279,18 @@ {{localize 'Bonus'}} {{/if}} + {{/if}} +
+ +
+ +
+
{{/if}} {{/if}} - {{/if}} - - {{> systems/wfrp4e/templates/items/item-effects.hbs}}