Skip to content

Commit

Permalink
Merge pull request #62 from McGregor777/0.8.1
Browse files Browse the repository at this point in the history
0.8.1
  • Loading branch information
Grégory Soupé authored Mar 26, 2024
2 parents b6ceea4 + 84739d8 commit b1aa76f
Show file tree
Hide file tree
Showing 46 changed files with 1,645 additions and 1,281 deletions.
66 changes: 37 additions & 29 deletions lang/en-EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
"Details": "Details",

"ACTOR.GenerateACharacter": "Generate a Character",
"ACTOR.TypeCharacter": "Character",
"ACTOR.TypeCreature": "Creature",
"ACTOR.TypeGroup": "Group",
"ACTOR.TypeParty": "Party",

"ACTION.Art": "Art",
"ACTION.ChallengeDice": "Challenge Dice",
Expand Down Expand Up @@ -281,17 +285,21 @@
"INSANITY.Traits": "Traits",
"INSANITY.Description": "Description",

"ITEM.Career": "Career",
"ITEM.Skill": "Skill",
"ITEM.TrainingLevel": "Training Level",
"ITEM.Talent": "Talent",
"ITEM.Type": "Type",
"ITEM.Action": "Action",
"ITEM.Trapping": "Trapping",
"ITEM.Weapon": "Weapon",
"ITEM.Armour": "Armour",
"ITEM.Money": "Money",
"ITEM.Wound": "Wound",
"ITEM.TypeAbility": "Ability",
"ITEM.TypeAction": "Action",
"ITEM.TypeArmour": "Armour",
"ITEM.TypeCareer": "Career",
"ITEM.TypeCondition": "Condition",
"ITEM.TypeCriticalwound": "Critical Wound",
"ITEM.TypeDisease": "Disease",
"ITEM.TypeInsanity": "Insanity",
"ITEM.TypeMoney": "Money",
"ITEM.TypeMiscast": "Miscast",
"ITEM.TypeMutation": "Mutation",
"ITEM.TypeSkill": "Skill",
"ITEM.TypeTalent": "Talent",
"ITEM.TypeTrapping": "Trapping",
"ITEM.TypeWeapon": "Weapon",

"MONEY.Value": "Value",
"MONEY.Brass": "Brass",
Expand Down Expand Up @@ -348,7 +356,7 @@
"RACE.Human": "Human",
"RACE.WoodElf": "Wood Elf",

"ROLL.CheckBuilder": "Check Builder",
"ROLL.DicePoolBuilder": "Dice Pool Builder",
"ROLL.ActionCheckBuilder": "{action} Check Builder",
"ROLL.InitiativeCheckBuilder": "Initiative Check Builder",
"ROLL.SkillCheckBuilder": "{skill} Check Builder",
Expand Down Expand Up @@ -392,23 +400,23 @@
"ROLL.CHALLENGELEVEL.Hard": "Hard",
"ROLL.CHALLENGELEVEL.Daunting": "Daunting",
"ROLL.CHALLENGELEVEL.Heroic": "Heroic",
"ROLL.CHECKBUILDER.AggressionDice": "Aggression Dice",
"ROLL.CHECKBUILDER.ChallengeLevel": "Challenge Level",
"ROLL.CHECKBUILDER.Characteristic": "Characteristic",
"ROLL.CHECKBUILDER.ConvertConservative": "Convert to conservative die",
"ROLL.CHECKBUILDER.ConvertReckless": "Convert to reckless die",
"ROLL.CHECKBUILDER.ConvertWarning": "There is no {type} die left to convert.",
"ROLL.CHECKBUILDER.ConvertBackWarning": "There is no {type} die left to convert back.",
"ROLL.CHECKBUILDER.CunningDice": "Cunning Dice",
"ROLL.CHECKBUILDER.DicePool": "Dice Pool",
"ROLL.CHECKBUILDER.EncounterType": "Encounter Type",
"ROLL.CHECKBUILDER.ExpertiseDice": "Expertise Dice",
"ROLL.CHECKBUILDER.Hint": "Left click to increase dice, right click to decrease.",
"ROLL.CHECKBUILDER.Options": "Options",
"ROLL.CHECKBUILDER.RollCheck": "Roll check",
"ROLL.CHECKBUILDER.Skill": "Skill",
"ROLL.CHECKBUILDER.StartingResults": "Starting results",
"ROLL.CHECKBUILDER.Weapon": "Weapon",
"ROLL.DICEPOOLBUILDER.AggressionDice": "Aggression Dice",
"ROLL.DICEPOOLBUILDER.ChallengeLevel": "Challenge Level",
"ROLL.DICEPOOLBUILDER.Characteristic": "Characteristic",
"ROLL.DICEPOOLBUILDER.ConvertConservative": "Convert to conservative die",
"ROLL.DICEPOOLBUILDER.ConvertReckless": "Convert to reckless die",
"ROLL.DICEPOOLBUILDER.ConvertWarning": "There is no {type} die to convert.",
"ROLL.DICEPOOLBUILDER.ConvertBackWarning": "There is no {type} die left to convert back.",
"ROLL.DICEPOOLBUILDER.CunningDice": "Cunning Dice",
"ROLL.DICEPOOLBUILDER.DicePool": "Dice Pool",
"ROLL.DICEPOOLBUILDER.EncounterType": "Encounter Type",
"ROLL.DICEPOOLBUILDER.ExpertiseDice": "Expertise Dice",
"ROLL.DICEPOOLBUILDER.Hint": "Left click to increase dice, right click to decrease.",
"ROLL.DICEPOOLBUILDER.Options": "Options",
"ROLL.DICEPOOLBUILDER.RollCheck": "Roll check",
"ROLL.DICEPOOLBUILDER.Skill": "Skill",
"ROLL.DICEPOOLBUILDER.StartingResults": "Starting results",
"ROLL.DICEPOOLBUILDER.Weapon": "Weapon",
"ROLL.DIE.ChallengeDice": "challenge dice",
"ROLL.DIE.CharacteristicDice": "characteristic dice",
"ROLL.DIE.ConservativeDice": "conservative dice",
Expand Down
66 changes: 37 additions & 29 deletions lang/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
"Details": "Détails",

"ACTOR.GenerateACharacter": "Générer un Personnage",
"ACTOR.TypeCharacter": "Personnage",
"ACTOR.TypeCreature": "Créature",
"ACTOR.TypeGroup": "Bande",
"ACTOR.TypeParty": "Groupe",

"ACTION.Art": "Illustration",
"ACTION.ChallengeDice": "Dés de Défi",
Expand Down Expand Up @@ -281,17 +285,21 @@
"INSANITY.Traits": "Traits",
"INSANITY.Description": "Description",

"ITEM.Career": "Carrière",
"ITEM.Skill": "Compétence",
"ITEM.TrainingLevel": "Niveau de formation",
"ITEM.Talent": "Talent",
"ITEM.Type": "Type",
"ITEM.Action": "Action",
"ITEM.Trapping": "Dotation",
"ITEM.Weapon": "Arme",
"ITEM.Armour": "Armure",
"ITEM.Money": "Monnaie",
"ITEM.Wound": "Blessure",
"ITEM.TypeAbility": "Aptitude",
"ITEM.TypeAction": "Action",
"ITEM.TypeArmour": "Armure",
"ITEM.TypeCareer": "Carrière",
"ITEM.TypeCondition": "État",
"ITEM.TypeCriticalwound": "Blessure",
"ITEM.TypeDisease": "Maladie",
"ITEM.TypeInsanity": "Folie",
"ITEM.TypeMoney": "Monnaie",
"ITEM.TypeMiscast": "Revers Magique",
"ITEM.TypeMutation": "Mutation",
"ITEM.TypeSkill": "Compétence",
"ITEM.TypeTalent": "Talent",
"ITEM.TypeTrapping": "Dotation",
"ITEM.TypeWeapon": "Arme",

"MONEY.Value": "Valeur",
"MONEY.Brass": "Brass",
Expand Down Expand Up @@ -348,7 +356,7 @@
"RACE.Human": "Humain",
"RACE.WoodElf": "Elfe Sylvain",

"ROLL.CheckBuilder": "Préparateur de test",
"ROLL.DicePoolBuilder": "Préparateur de réserve de dés",
"ROLL.ActionCheckBuilder": "Préparateur du test de {action}",
"ROLL.InitiativeCheckBuilder": "Préparateur du test d'initiative",
"ROLL.SkillCheckBuilder": "Préparateur du test de {skill}",
Expand Down Expand Up @@ -392,23 +400,23 @@
"ROLL.CHALLENGELEVEL.Hard": "Hard",
"ROLL.CHALLENGELEVEL.Daunting": "Daunting",
"ROLL.CHALLENGELEVEL.Heroic": "Heroic",
"ROLL.CHECKBUILDER.AggressionDice": "Aggression Dice",
"ROLL.CHECKBUILDER.ChallengeLevel": "Challenge Level",
"ROLL.CHECKBUILDER.Characteristic": "Caractéristique",
"ROLL.CHECKBUILDER.ConvertConservative": "Convertir en dé de prudence",
"ROLL.CHECKBUILDER.ConvertReckless": "Convertir en dé de témérité",
"ROLL.CHECKBUILDER.ConvertWarning": "Il n'y a plus de dé de {type} à convertir.",
"ROLL.CHECKBUILDER.ConvertBackWarning": "Il n'y a plus de dé de {type} à reconvertir.",
"ROLL.CHECKBUILDER.CunningDice": "Cunning Dice",
"ROLL.CHECKBUILDER.DicePool": "Réserve de dés",
"ROLL.CHECKBUILDER.EncounterType": "Type de rencontre",
"ROLL.CHECKBUILDER.ExpertiseDice": "Expertise Dice",
"ROLL.CHECKBUILDER.Hint": "Clic gauche pour ajouter des dés, clic droit pour en retirer.",
"ROLL.CHECKBUILDER.Options": "Options",
"ROLL.CHECKBUILDER.RollCheck": "Lancer le test",
"ROLL.CHECKBUILDER.Skill": "Skill",
"ROLL.CHECKBUILDER.StartingResults": "Pictogrammes de départ",
"ROLL.CHECKBUILDER.Weapon": "Arme",
"ROLL.DICEPOOLBUILDER.AggressionDice": "Aggression Dice",
"ROLL.DICEPOOLBUILDER.ChallengeLevel": "Challenge Level",
"ROLL.DICEPOOLBUILDER.Characteristic": "Caractéristique",
"ROLL.DICEPOOLBUILDER.ConvertConservative": "Convertir en dé de prudence",
"ROLL.DICEPOOLBUILDER.ConvertReckless": "Convertir en dé de témérité",
"ROLL.DICEPOOLBUILDER.ConvertWarning": "Il n'y a pas de dé de {type} à convertir.",
"ROLL.DICEPOOLBUILDER.ConvertBackWarning": "Il n'y a plus de dé de {type} à reconvertir.",
"ROLL.DICEPOOLBUILDER.CunningDice": "Cunning Dice",
"ROLL.DICEPOOLBUILDER.DicePool": "Réserve de dés",
"ROLL.DICEPOOLBUILDER.EncounterType": "Type de rencontre",
"ROLL.DICEPOOLBUILDER.ExpertiseDice": "Expertise Dice",
"ROLL.DICEPOOLBUILDER.Hint": "Clic gauche pour ajouter des dés, clic droit pour en retirer.",
"ROLL.DICEPOOLBUILDER.Options": "Options",
"ROLL.DICEPOOLBUILDER.RollCheck": "Lancer le test",
"ROLL.DICEPOOLBUILDER.Skill": "Skill",
"ROLL.DICEPOOLBUILDER.StartingResults": "Pictogrammes de départ",
"ROLL.DICEPOOLBUILDER.Weapon": "Arme",
"ROLL.DIE.ChallengeDice": "dés de défi",
"ROLL.DIE.CharacteristicDice": "dés de caractéristique",
"ROLL.DIE.ConservativeDice": "dés de prudence",
Expand Down
134 changes: 77 additions & 57 deletions modules/CheckHelper.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import CheckBuilder from "./applications/CheckBuilder.js";
import DicePoolBuilder from "./applications/DicePoolBuilder.js";
import DicePool from "./DicePool.js";

/**
Expand All @@ -7,42 +7,49 @@ import DicePool from "./DicePool.js";
export default class CheckHelper
{
/**
* Prepares a Skill check then opens the CheckBuilder dialog afterwards.
* @param {WFRP3eActor} actor The Character using the Action.
* Prepares a Skill check then opens the Dice Pool Builder afterwards.
* @param {WFRP3eActor} actor The Character using the Action.
* @param {WFRP3eItem} skill The Skill check has been triggered.
* @param {string} [rollFlavor] Some flavor text to add to the Skill check's outcome description.
* @param {string} [rollSound] Some sound to play after the Skill check completion.
* @param {Object} [options]
* @param {String} [options.flavor] Some flavor text to add to the Skill check's outcome description.
* @param {String} [options.sound] Some sound to play after the Skill check completion.
* @returns {Promise<void>}
*/
static async prepareSkillCheck(actor, skill, rollFlavor = null, rollSound = null)
static async prepareSkillCheck(actor, skill, {flavor = null, sound = null} = {})
{
const characteristic = actor.system.characteristics[skill.system.characteristic];
const stance = actor.system.stance.current;

await new CheckBuilder(
await new DicePoolBuilder(
new DicePool({
characteristicDice: characteristic.rating - Math.abs(stance),
fortuneDice: characteristic.fortune,
expertiseDice: skill.system.trainingLevel,
conservativeDice: stance < 0 ? Math.abs(stance) : 0,
recklessDice: stance > 0 ? stance : 0
}),
game.i18n.format("ROLL.SkillCheck", {skill: skill.name}),
{actor: actor, skill: skill, characteristic: skill.system.characteristic},
rollFlavor,
rollSound
dice: {
characteristic: characteristic.rating - Math.abs(stance),
fortune: characteristic.fortune,
expertise: skill.system.trainingLevel,
conservative: stance < 0 ? Math.abs(stance) : 0,
reckless: stance > 0 ? stance : 0
}
}, {
name: game.i18n.format("ROLL.SkillCheck", {skill: skill.name}),
checkData: {actor: actor, skill: skill, characteristic: skill.system.characteristic},
flavor,
sound
})
).render(true);
}

/**
* Prepares an Action check then opens the CheckBuilder dialog afterwards.
* Prepares an Action check then opens the Dice Pool Builder afterwards.
* @param {WFRP3eActor} actor The Character using the Action.
* @param {WFRP3eItem} action The Action that is used.
* @param {string} face The Action face.
* @param {Object} [options].
* @param {Object} [options]
* @param {WFRP3eItem} [options.weapon] The weapon used alongside the Action.
* @param {String} [options.flavor] Some flavor text to add to the Action check's outcome description.
* @param {String} [options.sound] Some sound to play after the Action check completion.
* @returns {Promise<void>}
*/
static async prepareActionCheck(actor, action, face, options = {})
static async prepareActionCheck(actor, action, face, {weapon = null, flavor = null, sound = null} = {})
{
const match = action.system[face].check.match(new RegExp(/(([\w\s]+) \((\w+)\))( vs\.? ([\w\s]+))?/));
let skill = actor.itemTypes.skill[0] ?? null;
Expand All @@ -57,56 +64,69 @@ export default class CheckHelper
}

const characteristic = actor.system.characteristics[characteristicName];
const rollData = {actor: actor, action: action, face: face, skill: skill, characteristic: characteristicName};
const checkData = {actor: actor, action: action, face: face, skill: skill, characteristic: characteristicName};
let stance = 0;

if(actor.type === "character")
stance = actor.system.stance.current
else if(actor.type === "creature")
stance = actor.system.stance

if(options.weapon)
rollData.weapon = options.weapon;
if(weapon)
checkData.weapon = weapon;

await new CheckBuilder(
await new DicePoolBuilder(
new DicePool({
characteristicDice: characteristic?.rating - Math.abs(stance) ?? 0,
fortuneDice: characteristic?.fortune ?? 0,
expertiseDice: skill?.system.trainingLevel ?? 0,
conservativeDice: stance < 0 ? Math.abs(stance) : 0,
recklessDice: stance > 0 ? stance : 0,
challengeDice: action.system[face].difficultyModifiers.challengeDice +
(["melee", "ranged"].includes(action.system.type)
? CONFIG.WFRP3e.challengeLevels.easy.challengeDice
: 0),
misfortuneDice: action.system[face].difficultyModifiers.misfortuneDice +
((match ? match[5] === game.i18n.localize("ACTION.CHECK.TargetDefence") : false)
? [...game.user.targets][0]?.actor.system.totalDefence ?? 0
: 0)
}),
game.i18n.format("ROLL.ActionCheck", {action: action.name}),
rollData,
options.rollFlavor,
options.rollSound
dice: {
characteristic: characteristic?.rating - Math.abs(stance) ?? 0,
fortune: characteristic?.fortune ?? 0,
expertise: skill?.system.trainingLevel ?? 0,
conservative: stance < 0 ? Math.abs(stance) : 0,
reckless: stance > 0 ? stance : 0,
challenge: action.system[face].difficultyModifiers.challengeDice +
(["melee", "ranged"].includes(action.system.type)
? CONFIG.WFRP3e.challengeLevels.easy.challengeDice
: 0),
misfortune: action.system[face].difficultyModifiers.misfortuneDice +
((match ? match[5] === game.i18n.localize("ACTION.CHECK.TargetDefence") : false)
? [...game.user.targets][0]?.actor.system.totalDefence ?? 0
: 0)
}
}, {
name: game.i18n.format("ROLL.ActionCheck", {action: action.name}),
checkData,
flavor,
sound
})
).render(true);
}

/**
* Prepares an initiative check.
* @param {WFRP3eActor} actor The Character making the initiative check.
* @param {string} characteristicName The Characteristic used for the initiative check.
* @returns {Promise<DicePool>}
* @param {WFRP3eCombat} combat The Combat document associated with the initiative check.
* @param {Object} [options]
* @param {String} [options.flavor] Some flavor text to add to the Skill check's outcome description.
* @param {String} [options.sound] Some sound to play after the Skill check completion.
* @returns {DicePool}
*/
static async prepareInitiativeCheck(actor, characteristicName)
static prepareInitiativeCheck(actor, combat, {flavor = null, sound = null} = {})
{
const characteristic = actor.system.characteristics[characteristicName];
const characteristic = actor.system.characteristics[combat.initiativeCharacteristic];
const stance = actor.system.stance.current ?? actor.system.stance;

return new DicePool({
characteristicDice: characteristic.rating - Math.abs(stance),
fortuneDice: characteristic.fortune,
conservativeDice: stance < 0 ? Math.abs(stance) : 0,
recklessDice: stance > 0 ? stance : 0
dice: {
characteristic: characteristic.rating - Math.abs(stance),
fortune: characteristic.fortune,
conservative: stance < 0 ? Math.abs(stance) : 0,
reckless: stance > 0 ? stance : 0
}
}, {
name: game.i18n.localize("ROLL.InitiativeCheckBuilder"),
checkData: {actor: actor, characteristic: characteristic, combat},
flavor,
sound
});
}

Expand Down Expand Up @@ -154,7 +174,7 @@ export default class CheckHelper
/**
* Get the universal Sigmar's comet effect.
*/
static getUniversalSigmarsCometEffect(isMental)
static getUniversalSigmarsCometEffect()
{
return {
symbolAmount: 1,
Expand All @@ -173,18 +193,18 @@ export default class CheckHelper
const chatMessage = game.messages.get(chatMessageId);
const changes = {rolls: chatMessage.rolls};

if(changes.rolls[0].data.effects[symbol][index].active === true)
changes.rolls[0].data.effects[symbol][index].active = false;
else if(changes.rolls[0].data.remainingSymbols[CONFIG.WFRP3e.symbols[symbol].plural] >= changes.rolls[0].data.effects[symbol][index].symbolAmount)
changes.rolls[0].data.effects[symbol][index].active = true;
if(changes.rolls[0].effects[symbol][index].active === true)
changes.rolls[0].effects[symbol][index].active = false;
else if(changes.rolls[0].remainingSymbols[CONFIG.WFRP3e.symbols[symbol].plural] >= changes.rolls[0].effects[symbol][index].symbolAmount)
changes.rolls[0].effects[symbol][index].active = true;
else
ui.notifications.warn(game.i18n.format("ROLL.NotEnoughSymbolToTriggerEffect", {symbol: game.i18n.localize(CONFIG.WFRP3e.symbols[symbol].name)}));

changes.rolls[0].data.remainingSymbols[CONFIG.WFRP3e.symbols[symbol].plural] = changes.rolls[0].data.effects[symbol].reduce((accumulator, effect) => {
changes.rolls[0].remainingSymbols[CONFIG.WFRP3e.symbols[symbol].plural] = changes.rolls[0].effects[symbol].reduce((accumulator, effect) => {
if(effect.active)
accumulator -= effect.symbolAmount;
return accumulator;
}, changes.rolls[0].symbols[CONFIG.WFRP3e.symbols[symbol].plural]);
}, changes.rolls[0].resultSymbols[CONFIG.WFRP3e.symbols[symbol].plural]);

chatMessage.update(changes);
}
Expand Down
Loading

0 comments on commit b1aa76f

Please sign in to comment.