Skip to content

Commit

Permalink
feat(presence): allow striking appearance to affect presence attacks
Browse files Browse the repository at this point in the history
  • Loading branch information
phBalance authored and phBalance committed Nov 24, 2024
1 parent dd56585 commit 292593b
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 16 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Releases

## Version 4.0.8 [Hero System 6e (Unofficial) v2](https://github.com/dmdorman/hero6e-foundryvtt)
## Version 4.0.8 (So far...) [Hero System 6e (Unofficial) v2](https://github.com/dmdorman/hero6e-foundryvtt)

- Support striking appearance. Can be optionally enabled for presence and interaction skill rolls. [#1509](https://github.com/dmdorman/hero6e-foundryvtt/issues/1509)
- Improved DEADLYBLOW so it does not apply to adjustment powers, sense-affecting powers, or ENTANGLES. GM still has to confirm DEADLYBLOW with applicable powers. [#1493](https://github.com/dmdorman/hero6e-foundryvtt/issues/1493)

## Version 4.0.7
Expand Down
4 changes: 2 additions & 2 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,14 @@ Our support ratings:
| EIDETIC MEMORY | D | |
| ENVIRONMENTAL MOVEMENT | D | |
| LIGHTNING CALCULATOR | D | |
| LIGHTNING REFLEXES | B | A second token in the combat tracker is shown, but up to player/gm to determine when to use |
| LIGHTNING REFLEXES | B | A second token in the combat tracker is shown, but up to player/GM to determine when to use |
| LIGHTSLEEP | D | |
| OFF-HAND DEFENSE | D | |
| PERFECT PITCH | D | |
| RESISTANCE | D | |
| SIMULATE DEATH | D | |
| SPEED READING | D | |
| STRIKING APPEARANCE | D | |
| STRIKING APPEARANCE | B | Up to player/GM to determine when to use |
| UNIVERSAL TRANSLATOR | D | |
| WEAPONMASTER | B | |

Expand Down
1 change: 0 additions & 1 deletion module/item/skill.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ async function _renderSkillForm(item, actor, stateData) {
}
}

// Enhanced Perception + Skill Levels
const skillMods = [
...skillLevels,
...helperItems,
Expand Down
55 changes: 44 additions & 11 deletions module/utility/presence-attack.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,76 @@ import { HeroRoller } from "./dice.mjs";
async function _renderForm(actor, stateData) {
const token = actor.token;

// Certain skills/talents/powers may help or hinder this roll
const attackMods = [];
// Striking appearance may help
const strikingAppearance = actor.items.filter((item) => item.system.XMLID === "STRIKING_APPEARANCE");
for (const saTalent of strikingAppearance) {
saTalent.system.checked = false;
saTalent.system.active = true;
attackMods.push(saTalent);
}

const templateData = {
actor: actor.system,
tokenId: token?.uuid || null,
state: stateData,
preAttackMods: attackMods,
};

var path = `systems/${HEROSYS.module}/templates/pop-out/presence-attack-card.hbs`;

const path = `systems/${HEROSYS.module}/templates/pop-out/presence-attack-card.hbs`;
return await renderTemplate(path, templateData);
}

async function presenceAttackRoll(actor, html) {
const form = html[0].querySelector("form");
const rollModifier = parseFloat(form.mod.value);

const presence = parseInt(actor.system.characteristics.pre.value);
const presenceDice = presence / 5;
const partialDice = presenceDice % 1;

const heroRoller = new HeroRoller()
const preAttackRoller = new HeroRoller()
.makeBasicRoll()
.addDice(Math.trunc(presenceDice), "Presence Attack")
.addHalfDice(Math.sign(partialDice) * (Math.abs(partialDice) >= 0.5 ? 1 : 0), "Presence Attack")
.addHalfDice(Math.sign(partialDice) * (Math.abs(partialDice) >= 0.5 ? 1 : 0), "Presence Attack Half Dice")
.addDice(Math.trunc(rollModifier), "Roll Modifier")
.addHalfDice(Math.abs(rollModifier) % 1 >= 0.5 ? 1 : 0, "Roll Modifier");
await heroRoller.roll();

const cardHtml = await heroRoller.render("Presence Attack");
// Presence Attack Modifiers
const preAttackModInputs = form.querySelectorAll("INPUT:checked");
for (const preAttackInput of preAttackModInputs) {
const preAttack = actor.items.get(preAttackInput.id);
const levels = parseInt(preAttack.system.LEVELS || 0);
if (levels > 0) {
preAttackRoller.addDice(levels, preAttack.name);
}
}

await preAttackRoller.roll();

const rollHtml = await preAttackRoller.render("Presence Attack");
const tags = await preAttackRoller.tags();

// render card
const token = actor.token;
const speaker = ChatMessage.getSpeaker({ actor: actor, token });
speaker.alias = actor.name;

const cardData = {
tags: tags.map((tag) => {
return { ...tag, value: tag.value.signedString() };
}),
rolls: preAttackRoller.rawRolls(),
renderedRoll: rollHtml,
user: game.user._id,
speaker: speaker,
};
const template = `systems/${HEROSYS.module}/templates/chat/presence-attack-result-card.hbs`;
const cardHtml = await renderTemplate(template, cardData);

const chatData = {
style: CONST.CHAT_MESSAGE_STYLES.OOC,
rolls: heroRoller.rawRolls(),
rolls: preAttackRoller.rawRolls(),
author: game.user._id,
content: cardHtml,
speaker: speaker,
Expand All @@ -47,7 +82,7 @@ async function presenceAttackRoll(actor, html) {
return ChatMessage.create(chatData);
}

async function presenceAttackPopOut(actor) {
export async function presenceAttackPopOut(actor) {
const content = await _renderForm(actor, {});

// Attack Card as a Pop Out
Expand All @@ -72,5 +107,3 @@ async function presenceAttackPopOut(actor) {
new Dialog(data, options).render(true);
});
}

export { presenceAttackPopOut };
14 changes: 14 additions & 0 deletions templates/chat/presence-attack-result-card.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{{ log 'HEROSYS presence-attack-result-card' this }}
<div class="hero chat-card">
<div class="card-section tags">
{{#each tags as |tag id|}}
<span class="tag tag-transparent" {{#if tag.title}}title="{{tag.title}}"{{/if}}>{{tag.name}}
{{tag.value}}
</span>
{{/each}}
</div>

<div class="card-section">
<div class="damage-roll">{{{ renderedRoll }}}</div>
</div>
</div>
2 changes: 1 addition & 1 deletion templates/pop-out/item-skill-card.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

{{#if skillMods.length}}
<div class="form-group">
<label>Skill Mods</label>
<label>Skill Modifiers</label>
<table>
{{#each skillMods}}
{{#if this.system.active}}
Expand Down
30 changes: 30 additions & 0 deletions templates/pop-out/presence-attack-card.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,34 @@
<label>Roll Modifier</label>
<input type="number" name="mod" value="0"/>
</div>

{{#if preAttackMods.length}}
<div class="form-group">
<label>Attack Modifiers</label>
<table>
{{#each preAttackMods}}
{{#if this.system.active}}
<tr>
<td style="width:1%">
<input class="item-toggle" id="{{this.id}}" type="checkbox" {{checked
this.system.checked}} data-dtype="Boolean"/>
</td>
<td style="text-align:left">
{{this.system.description}}
</td>
</tr>
{{else}}
<tr title="This power is inactive" style="opacity:50%">
<td>
<i class="fas fa-ban"></i>
</td>
<td style="text-align:left">
{{this.system.description}}
</td>
</tr>
{{/if}}
{{/each}}
</table>
</div>
{{/if}}
</form>

0 comments on commit 292593b

Please sign in to comment.