Skip to content

Commit

Permalink
Merge pull request #352 from FoxLee/card-atk-bonus
Browse files Browse the repository at this point in the history
Option to display calculated attack bonus in auto power cards
  • Loading branch information
EndlesNights authored Apr 2, 2024
2 parents 3969ba1 + 71870d6 commit 9e5d1a3
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 32 deletions.
12 changes: 10 additions & 2 deletions lang/en-au.json
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@
"DND4E.gains": "gains",
"DND4E.Gaze": "Gaze",
"DND4E.Gender": "Gender",
"DND4E.GMNotesAdd": "Add GM Notes",
"DND4E.GrantedAbilities": "Granted Abilities",
"DND4E.HalfLVL": "1/2 LVL",
"DND4E.HalfProficient": "Half Proficient",
Expand Down Expand Up @@ -1126,8 +1127,8 @@
"DND4E.TargetEnemy": "Enemy",
"DND4E.TargetEnemyAdjacent": "Adjacent Enemy",
"DND4E.TargetLine": "Line",
"DND4E.TargetObject": "Object",
"DND4E.TargetMisc": "Misc",
"DND4E.TargetObject": "Object",
"DND4E.TargetPersonal": "Personal",
"DND4E.TargetRadius": "Radius",
"DND4E.TargetSpace": "Space",
Expand All @@ -1139,6 +1140,7 @@
"DND4E.TempHP": "Temp HP",
"DND4E.TempHPTip": "Temporary Hit Points",
"DND4E.Theme": "Theme",
"DND4E.Tier": "Tier",
"DND4E.TimeDay": "Days",
"DND4E.TimeHour": "Hours",
"DND4E.TimeInst": "Instantaneous",
Expand Down Expand Up @@ -1480,7 +1482,9 @@
"DND4EUI.UnknownCondition.Tip": "No match was found for this id in the current status conditions configuration.",
"DND4EUI.Yes": "Yes",
"SETTINGS.4eApplyEffectsToSelectionN": "Buttons to apply effects should apply to SELECTED tokens",
"SETTINGS.4eApplyEffectsToSelectionL": "If checked, apply effect buttons will work over targets that are SELECTED. Otherwise will work over tokens that are TARGETED",
"SETTINGS.4eApplyEffectsToSelectionL": "If checked, apply effect buttons will work over targets that are SELECTED. Otherwise will work over tokens that are TARGETED",
"SETTINGS.4eAutoApplyEffectsL": "Determin if a powers effects/conditions will be autmaticly appled to valid selected targets when a power is used or when an attack roll is made.",
"SETTINGS.4eAutoApplyEffectsN": "Automaticly Apply Effetcs",
"SETTINGS.4eAutoCollapseCardL": "Automatically collapse Item Card descriptions in the Chat Log",
"SETTINGS.4eAutoCollapseCardN": "Collapse Item Cards in Chat",
"SETTINGS.4eAutoDoTsApply": "Apply automatically",
Expand All @@ -1496,6 +1500,10 @@
"SETTINGS.4eAutomationCombatL": "Determine whether the Attack Rolls hits or misses.",
"SETTINGS.4eAutoSpellTemplateL": "When a spell is cast, defaults to begin the process to create the corresponding Measured Template if any (requires TRUSTED or higher player role)",
"SETTINGS.4eAutoSpellTemplateN": "Always place Spell Template",
"SETTINGS.4eCardAtkDisplayL": "When an attack has an associated ability score, how should the auto power card show the name and attack bonus value?",
"SETTINGS.4eCardAtkDisplayN": "Power card attack display",
"SETTINGS.4eCardAtkDisplayBonus": "Display bonus (name/formula in tooltip)",
"SETTINGS.4eCardAtkDisplayStat": "Display name (bonus/formula in tooltip)",
"SETTINGS.4eCollapseSituationalBonusL": "If checked: all common situational modifiers will be computed and added as a single modifier to @bonus. Otherwise each will be displayed individually in the resulting formula",
"SETTINGS.4eCollapseSituationalBonusN": "Collapse Common Attack Mods",
"SETTINGS.4eCurWtL": "Carried currency affects character encumbrance following the rules on PHB pg. 212.",
Expand Down
5 changes: 5 additions & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,7 @@
"DND4E.TempHP": "Temp HP",
"DND4E.TempHPTip": "Temporary Hit Points",
"DND4E.Theme": "Theme",
"DND4E.Tier": "Tier",
"DND4E.TimeDay": "Days",
"DND4E.TimeHour": "Hours",
"DND4E.TimeInst": "Instantaneous",
Expand Down Expand Up @@ -1499,6 +1500,10 @@
"SETTINGS.4eAutomationCombatL": "Determine whether the Attack Rolls hits or misses.",
"SETTINGS.4eAutoSpellTemplateL": "When a spell is cast, defaults to begin the process to create the corresponding Measured Template if any (requires TRUSTED or higher player role)",
"SETTINGS.4eAutoSpellTemplateN": "Always place Spell Template",
"SETTINGS.4eCardAtkDisplayL": "When an attack has an associated ability score, how should the auto power card show the name and attack bonus value?",
"SETTINGS.4eCardAtkDisplayN": "Power card attack display",
"SETTINGS.4eCardAtkDisplayBonus": "Display bonus (name/formula in tooltip)",
"SETTINGS.4eCardAtkDisplayStat": "Display name (bonus/formula in tooltip)",
"SETTINGS.4eCollapseSituationalBonusL": "If checked: all common situational modifiers will be computed and added as a single modifier to @bonus. Otherwise each will be displayed individually in the resulting formula",
"SETTINGS.4eCollapseSituationalBonusN": "Collapse Common Attack Mods",
"SETTINGS.4eCurWtL": "Carried currency affects character encumbrance following the rules on PHB pg. 212.",
Expand Down
6 changes: 5 additions & 1 deletion module/actor/actor-sheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,11 @@ ${parseInt(data.system.movement.walk.value)} ${game.i18n.localize("DND4E.Movemen

if(item.system.autoGenChatPowerCard){
// let details = $(`<div class="item-details">${Helper._preparePowerCardData(chatData, CONFIG, this.actor.toObject(false))}</div>`);
let details = $(`<div class="item-details">${Helper._preparePowerCardData(chatData, CONFIG, this.actor)}</div>`);
let attackBonus = null;
if(item.hasAttack){
attackBonus = await item.getAttackBonus();
}
let details = $(`<div class="item-details">${Helper._preparePowerCardData(chatData, CONFIG, this.actor, attackBonus)}</div>`);
div.append(details);
}

Expand Down
60 changes: 33 additions & 27 deletions module/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,7 @@ export class Helper {
}
}

static _preparePowerCardData(chatData, CONFIG, actorData=null) {
static _preparePowerCardData(chatData, CONFIG, actorData=null, attackTotal=null) {
let powerSource = (chatData.powersource && chatData.powersource !== "") ? `${CONFIG.DND4E.powerSource[`${chatData.powersource}`]}` : "";
let powerDetail = `<span class="basics"><span class="usage">${CONFIG.DND4E.powerUseType[`${chatData.useType}`]}</span>`;
let tag = [];
Expand Down Expand Up @@ -952,27 +952,35 @@ export class Helper {
}

if(chatData.attack.isAttack) {
if(chatData.attack.ability === "form"){
//if does not srtart with a number sign add one

let attackForm = this.commonReplace(chatData.attack.formula, actorData);
try {
attackForm = Roll.safeEval(attackForm).toString();
} catch (e) { /* noop */ }


let trimmedForm = attackForm.trim()
if(!(trimmedForm.startsWith("+") || trimmedForm.startsWith("-"))) {
trimmedForm = '+' + trimmedForm;
let attackForm = chatData.attack.formula;
attackForm = chatData.attack.formula.replaceAll('@powerMod',`@${chatData.attack?.ability}Mod`);
const attackValues = this.commonReplace(attackForm, actorData);
if(attackTotal){
//if does not start with a number sign add one
attackTotal = attackTotal.toString();
if(!(attackTotal.startsWith("+") || attackTotal.startsWith("-"))) {
attackTotal = '+' + attackTotal;
}
powerDetail += `<p class="attack"><strong>${game.i18n.localize("DND4E.Attack")}:</strong> ${trimmedForm} ${game.i18n.localize("DND4E.VS")} ${CONFIG.DND4E.def[chatData.attack.def]}</p>`;
}else if(chatData.attack.ability){
attackTotal = CONFIG.DND4E.abilities[chatData.attack.ability];
}else{
attackTotal = game.i18n.localize("DND4E.Attack");
}

if(chatData.attack.ability === "form"){
powerDetail += `<p class="attack"><strong>${game.i18n.localize("DND4E.Attack")}:</strong> <a class="attack-bonus" data-tooltip="${attackValues}">${attackTotal}</a>`;
}
else if(chatData.attack.ability){
powerDetail += `<p class="attack"><strong>${game.i18n.localize("DND4E.Attack")}</strong>: ${CONFIG.DND4E.abilities[chatData.attack.ability]} ${game.i18n.localize("DND4E.VS")} ${CONFIG.DND4E.def[chatData.attack.def]}</p>`;
powerDetail += `<p class="attack"><strong>${game.i18n.localize("DND4E.Attack")}</strong>: <a class="attack-bonus" data-tooltip="`;
if(game.settings.get("dnd4e","cardAtkDisplay")=="bonus"){
powerDetail += `${CONFIG.DND4E.abilities[chatData.attack.ability]} (${attackValues})">${attackTotal}</a>`;
}else{
powerDetail += `${attackTotal} (${attackValues})">${CONFIG.DND4E.abilities[chatData.attack.ability]}</a>`;
}
} else {
powerDetail += `<p class="attack"><strong>${game.i18n.localize("DND4E.Attack")}</strong>: ${game.i18n.localize("DND4E.Attack")} ${game.i18n.localize("DND4E.VS")} ${CONFIG.DND4E.def[chatData.attack.def]}</p>`;
powerDetail += `<p class="attack"><strong>${game.i18n.localize("DND4E.Attack")}</strong>: ${game.i18n.localize("DND4E.Attack")}`;
}
// powerDetail += `<p class="attack"><strong>${game.i18n.localize("DND4E.Attack")}</strong>: ${CONFIG.DND4E.abilities[chatData.attack.ability] || "Attack"} ${game.i18n.localize("DND4E.VS")} ${CONFIG.DND4E.def[chatData.attack.def]}</p>`;
powerDetail += ` ${game.i18n.localize("DND4E.VS")} ${CONFIG.DND4E.def[chatData.attack.def]}</p>`;
}

let highlight = true;
Expand Down Expand Up @@ -1209,13 +1217,12 @@ export class Helper {
return ( idOnly ? firstGM.id : firstGM );
}


/**
/* Function to return the sum of the highest positive value
/* and the lowest negative value in a given set.
/* Intended for getting the correct value from multiple
/* resistances and vulnerabilities.
/* */
* Function to return the sum of the highest positive value
* and the lowest negative value in a given set.
* Intended for getting the correct value from multiple
* resistances and vulnerabilities.
*/
static sumExtremes(values = []){
if (!values.length) return;
let negatives = [0], positives = [0];
Expand All @@ -1232,7 +1239,6 @@ export class Helper {
return Math.max(...positives) + Math.min(...negatives);
}


/**
* Determine if a fastForward key was held during the given click event.
*
Expand All @@ -1259,7 +1265,7 @@ export class Helper {
const foundEffects = power.item.effects.contents.filter(e => effects.includes(e.flags.dnd4e.effectData.powerEffectTypes));
return foundEffects.length > 0;
}

/**
* Use to find the value in a given scale
*
Expand Down Expand Up @@ -1293,7 +1299,7 @@ export class Helper {
}
return result;
}

}

export async function handleApplyEffectToToken(data){
Expand Down Expand Up @@ -1384,4 +1390,4 @@ Handlebars.registerHelper("needsHitOrMissEffectButton", function(power){

Handlebars.registerHelper("applyEffectsToSelection", function(){
return game.settings.get("dnd4e","applyEffectsToSelection")
});
});
8 changes: 6 additions & 2 deletions module/item/item-document.js
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,11 @@ export default class Item4e extends Item {
const cardData = await ( async () => {
if ((this.type === "power" || this.type === "consumable") && this.system.autoGenChatPowerCard) {
let weaponUse = Helper.getWeaponUse(this.system, this.actor);
let cardString = Helper._preparePowerCardData(await this.getChatData(), CONFIG, this.actor);
let attackBonus = null;
if(this.hasAttack){
attackBonus = await this.getAttackBonus();
}
let cardString = Helper._preparePowerCardData(await this.getChatData(), CONFIG, this.actor, attackBonus);
return Helper.commonReplace(cardString, this.actor, this, weaponUse? weaponUse.system : null, 1);
} else {
return null;
Expand Down Expand Up @@ -1309,7 +1313,7 @@ export default class Item4e extends Item {
rollConfig.options.powerEffects = this.effects;
rollConfig.options.parent = this.parent;
}

// Get the bonus
const bonus = getAttackRollBonus(rollConfig);

Expand Down
13 changes: 13 additions & 0 deletions module/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -342,4 +342,17 @@ export const registerSystemSettings = function() {
// ],
// precedence: CONST.KEYBINDING_PRECEDENCE.NORMAL,
// });

game.settings.register("dnd4e", "cardAtkDisplay",{
name: "SETTINGS.4eCardAtkDisplayN",
hint: "SETTINGS.4eCardAtkDisplayL",
scope: "client",
config: true,
default: "stat",
type: String,
choices: {
"bonus": "SETTINGS.4eCardAtkDisplayBonus",
"stat": "SETTINGS.4eCardAtkDisplayStat"
}
});
};

0 comments on commit 9e5d1a3

Please sign in to comment.