Skip to content

Commit

Permalink
Add weapon attack details on not executed attacks
Browse files Browse the repository at this point in the history
Closes #111
  • Loading branch information
kmoschcau committed Jan 8, 2022
1 parent f015bf7 commit 3216d71
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 242 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- notifications for errors in weapon macros created from source
- a value replacing rule element
([#95](https://github.com/Wasteland-Ventures-Group/WV-VTT-module/issues/95))
- weapon attack details on not executed attacks
([#111](https://github.com/Wasteland-Ventures-Group/WV-VTT-module/issues/111))

### Changed

Expand Down
129 changes: 65 additions & 64 deletions src/main/handlebars/chatMessages/weaponAttack.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,76 +4,77 @@
<h3>{{template.raw.mainHeading}}</h3>
<h4>{{template.raw.subHeading}}</h4>

{{#if executed}}
{{#if weaponSystemData.notes}}
<p>{{weaponSystemData.notes}}</p>
{{/if}}
{{#if weaponSystemData.notes}}
<p>{{weaponSystemData.notes}}</p>
{{/if}}

{{!attack details}}
<div class="detail-section">
<span>{{localize "wv.weapons.attacks.details"}}</span>
<div class="detail-content hide">
<div class="spacing-bottom">{{localize "wv.weapons.attacks.ranges"}}: {{template.raw.displayRanges}}</div>
{{#if details}} {{!backward compatibility}}
<div class="spacing-bottom">{{localize "wv.weapons.modifiers.hit.range"}}: {{localize template.keys.rangeBracket}} ({{details.range.distance}})</div>
<div class="spacing-bottom">
<div>{{localize "wv.sheets.actor.secondary.criticals.title"}}</div>
<ul class="no-margin">
<li>{{localize "wv.sheets.actor.secondary.criticals.success"}}: {{details.criticals.success}}</li>
<li>{{localize "wv.sheets.actor.secondary.criticals.failure"}}: {{details.criticals.failure}}</li>
</ul>
{{!attack details}}
<div class="detail-section">
<span>{{localize "wv.weapons.attacks.details"}}</span>
<div class="detail-content hide">
<div class="spacing-bottom">{{localize "wv.weapons.attacks.ranges"}}: {{template.raw.displayRanges}}</div>
{{#if details}} {{!backward compatibility}}
<div class="spacing-bottom">{{localize "wv.weapons.modifiers.hit.range"}}: {{localize template.keys.rangeBracket}} ({{details.range.distance}})</div>
<div class="spacing-bottom">
<div>{{localize "wv.sheets.actor.secondary.criticals.title"}}</div>
<ul class="no-margin">
<li>{{localize "wv.sheets.actor.secondary.criticals.success"}}: {{details.criticals.success}}</li>
<li>{{localize "wv.sheets.actor.secondary.criticals.failure"}}: {{details.criticals.failure}}</li>
</ul>
</div>
<div class="modifier-listing">
<div class="listing-heading">
<span>{{localize "wv.weapons.modifiers.listingTitles.hit"}}</span>
<hr />
</div>
<div class="modifier-listing">
<div class="listing-heading">
<span>{{localize "wv.weapons.modifiers.listingTitles.hit"}}</span>
<hr />
</div>
<div class="listing-table grid-2cols">
<span>{{localize "wv.weapons.modifiers.base"}}</span>
<span class="number-display">{{details.hit.base}}</span>
{{#each details.hit.modifiers as |modifier|}}
<span>{{localize modifier.key}}</span>
<span class="number-display">{{modifier.amount}}</span>
{{/each}}
<span class="listing-total">{{localize "wv.weapons.modifiers.total"}}</span>
<span class="listing-total number-display">{{details.hit.total}}</span>
</div>
<div class="listing-table grid-2cols">
<span>{{localize "wv.weapons.modifiers.base"}}</span>
<span class="number-display">{{details.hit.base}}</span>
{{#each details.hit.modifiers as |modifier|}}
<span>{{localize modifier.key}}</span>
<span class="number-display">{{modifier.amount}}</span>
{{/each}}
<span class="listing-total">{{localize "wv.weapons.modifiers.total"}}</span>
<span class="listing-total number-display">{{details.hit.total}}</span>
</div>
<div class="modifier-listing">
<div class="listing-heading">
<span>{{localize "wv.weapons.modifiers.listingTitles.damageBase"}}</span>
<hr />
</div>
<div class="listing-table grid-2cols">
<span>{{localize "wv.weapons.modifiers.base"}}</span>
<span class="number-display">{{details.damage.base.base}}</span>
{{#each details.damage.base.modifiers as |modifier|}}
<span>{{localize modifier.key}}</span>
<span class="number-display">{{modifier.amount}}</span>
{{/each}}
<span class="listing-total">{{localize "wv.weapons.modifiers.total"}}</span>
<span class="listing-total number-display">{{details.damage.base.total}}</span>
</div>
</div>
<div class="modifier-listing">
<div class="listing-heading">
<span>{{localize "wv.weapons.modifiers.listingTitles.damageBase"}}</span>
<hr />
</div>
<div class="modifier-listing">
<div class="listing-heading">
<span>{{localize "wv.weapons.modifiers.listingTitles.damageDice"}}</span>
<hr />
</div>
<div class="listing-table grid-2cols">
<span>{{localize "wv.weapons.modifiers.base"}}</span>
<span class="number-display">{{details.damage.dice.base}}</span>
{{#each details.damage.dice.modifiers as |modifier|}}
<span>{{localize modifier.key}}</span>
<span class="number-display">{{modifier.amount}}</span>
{{/each}}
<span class="listing-total">{{localize "wv.weapons.modifiers.total"}}</span>
<span class="listing-total number-display">{{details.damage.dice.total}}</span>
</div>
<div class="listing-table grid-2cols">
<span>{{localize "wv.weapons.modifiers.base"}}</span>
<span class="number-display">{{details.damage.base.base}}</span>
{{#each details.damage.base.modifiers as |modifier|}}
<span>{{localize modifier.key}}</span>
<span class="number-display">{{modifier.amount}}</span>
{{/each}}
<span class="listing-total">{{localize "wv.weapons.modifiers.total"}}</span>
<span class="listing-total number-display">{{details.damage.base.total}}</span>
</div>
{{/if}}
</div>
</div>
<div class="modifier-listing">
<div class="listing-heading">
<span>{{localize "wv.weapons.modifiers.listingTitles.damageDice"}}</span>
<hr />
</div>
<div class="listing-table grid-2cols">
<span>{{localize "wv.weapons.modifiers.base"}}</span>
<span class="number-display">{{details.damage.dice.base}}</span>
{{#each details.damage.dice.modifiers as |modifier|}}
<span>{{localize modifier.key}}</span>
<span class="number-display">{{modifier.amount}}</span>
{{/each}}
<span class="listing-total">{{localize "wv.weapons.modifiers.total"}}</span>
<span class="listing-total number-display">{{details.damage.dice.total}}</span>
</div>
</div>
{{/if}}
</div>
</div>

{{#if executed}}

{{!hit roll}}
<div class="detail-section">
Expand Down
1 change: 1 addition & 0 deletions src/main/lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@
},
"ranges": {
"brackets": {
"outOfRange": "Außer Reichweite",
"long": "Weit",
"medium": "Mittel",
"short": "Kurz",
Expand Down
1 change: 1 addition & 0 deletions src/main/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@
},
"ranges": {
"brackets": {
"outOfRange": "Out of range",
"long": "Long",
"medium": "Medium",
"short": "Short",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,37 @@ export default async function decorateWeaponAttack(

const content = getContentElement(html);

const commonData: CommonWeaponAttackTemplateData = {
...flags,
template: {
keys: {
rangeBracket: getRangeBracketKey(flags)
},
raw: {
displayRanges: getDisplayRanges(
flags.weaponSystemData,
flags.ownerSpecials
),
mainHeading:
flags.weaponName !== flags.weaponSystemData.name
? flags.weaponName
: flags.weaponSystemData.name,
subHeading:
flags.weaponName !== flags.weaponSystemData.name
? `${flags.weaponSystemData.name} - ${flags.attackName}`
: flags.attackName
}
}
};

if (!flags.executed) {
const data: NotExecutedAttackTemplateData = {
...flags,
...commonData,
template: {
...commonData.template,
keys: {
...commonData.template.keys,
notExecutedReason: getNotExecutedReasonKey(flags)
}
}
Expand All @@ -32,7 +58,9 @@ export default async function decorateWeaponAttack(

const data: ExecutedAttackTemplateData = {
...flags,
...commonData,
template: {
...commonData.template,
damage: {
results: flags.rolls.damage.results.map((result) => {
return {
Expand All @@ -42,22 +70,8 @@ export default async function decorateWeaponAttack(
})
},
keys: {
hit: getHitResultKey(flags),
rangeBracket: getRangeBracketKey(flags)
},
raw: {
displayRanges: getDisplayRanges(
flags.weaponSystemData,
flags.ownerSpecials
),
mainHeading:
flags.weaponName !== flags.weaponSystemData.name
? flags.weaponName
: flags.weaponSystemData.name,
subHeading:
flags.weaponName !== flags.weaponSystemData.name
? `${flags.weaponSystemData.name} - ${flags.attackName}`
: flags.attackName
...commonData.template.keys,
hit: getHitResultKey(flags)
}
}
};
Expand Down Expand Up @@ -87,8 +101,12 @@ function getHitResultKey(flags: ExecutedAttackFlags): string {
}

/** Get the i18n key for the range bracket. */
function getRangeBracketKey(flags: ExecutedAttackFlags): string | undefined {
function getRangeBracketKey(
flags: CommonWeaponAttackFlags
): string | undefined {
switch (flags.details?.range.bracket) {
case RangeBracket.OUT_OF_RANGE:
return "wv.weapons.ranges.brackets.outOfRange";
case RangeBracket.LONG:
return "wv.weapons.ranges.brackets.long";
case RangeBracket.MEDIUM:
Expand All @@ -104,24 +122,9 @@ function getRangeBracketKey(flags: ExecutedAttackFlags): string | undefined {
export type WeaponAttackFlags = NotExecutedAttackFlags | ExecutedAttackFlags;

/** The common weapon attack chat message flags */
interface CommonWeaponAttackFlags {
export interface CommonWeaponAttackFlags {
type: "weaponAttack";
weaponName: string;
weaponImage: string | null;
weaponSystemData: WeaponDataProperties["data"];
attackName: string;
}

/** The attack chat message flags for a unexecuted attack */
export interface NotExecutedAttackFlags extends CommonWeaponAttackFlags {
executed: false;
reason?: "insufficientAp" | "outOfRange";
}

/** The attack chat message flags for an executed attack */
export interface ExecutedAttackFlags extends CommonWeaponAttackFlags {
executed: true;
ownerSpecials?: Partial<Specials> | undefined;
details?: {
criticals: {
failure: number;
Expand All @@ -137,6 +140,21 @@ export interface ExecutedAttackFlags extends CommonWeaponAttackFlags {
distance: number;
};
};
ownerSpecials?: Partial<Specials> | undefined;
weaponImage: string | null;
weaponName: string;
weaponSystemData: WeaponDataProperties["data"];
}

/** The attack chat message flags for a unexecuted attack */
export type NotExecutedAttackFlags = CommonWeaponAttackFlags & {
executed: false;
reason?: "insufficientAp" | "outOfRange";
};

/** The attack chat message flags for an executed attack */
export type ExecutedAttackFlags = CommonWeaponAttackFlags & {
executed: true;
rolls: {
damage: {
formula: string;
Expand All @@ -150,7 +168,7 @@ export interface ExecutedAttackFlags extends CommonWeaponAttackFlags {
total: number;
};
};
}
};

export interface ModifierFlags {
amount: number;
Expand All @@ -163,26 +181,10 @@ interface DetailsListingInfo {
total: number;
}

/** The data for rendering the not executed weapon attack template */
interface NotExecutedAttackTemplateData extends NotExecutedAttackFlags {
/** The template data common for both executed and not executed attacks. */
type CommonWeaponAttackTemplateData = CommonWeaponAttackFlags & {
template: {
keys: {
notExecutedReason: string;
};
};
}

/** The data for rendering the executed weapon attack template */
interface ExecutedAttackTemplateData extends ExecutedAttackFlags {
template: {
damage: {
results: {
class: string;
value: number;
}[];
};
keys: {
hit: string;
rangeBracket: string | undefined;
};
raw: {
Expand All @@ -191,4 +193,30 @@ interface ExecutedAttackTemplateData extends ExecutedAttackFlags {
subHeading: string;
};
};
}
};

/** The data for rendering the not executed weapon attack template */
type NotExecutedAttackTemplateData = CommonWeaponAttackTemplateData &
NotExecutedAttackFlags & {
template: {
keys: {
notExecutedReason: string;
};
};
};

/** The data for rendering the executed weapon attack template */
type ExecutedAttackTemplateData = CommonWeaponAttackTemplateData &
ExecutedAttackFlags & {
template: {
damage: {
results: {
class: string;
value: number;
}[];
};
keys: {
hit: string;
};
};
};
Loading

0 comments on commit 3216d71

Please sign in to comment.