Skip to content

Commit

Permalink
Add fate reroll button to chat messages
Browse files Browse the repository at this point in the history
Add fate reroll button to chat messages, allowing for using fate to
open the skill (rerolling any 6's)
Hide fate reroll button for all but the owner of the character that
performed the roll.
  • Loading branch information
StasTserk committed Jul 22, 2020
1 parent 1ec342d commit 2a7377f
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 9 deletions.
5 changes: 5 additions & 0 deletions module/burningwheel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
RegisterItemSheets
} from "./items/item.js";

import { hideChatButtonsIfNotOwner, onChatLogRender } from "./chat.js";
import { slugify } from "./helpers.js";
import { preloadHandlebarsTemplates } from "./templates.js";

Expand Down Expand Up @@ -77,3 +78,7 @@ function registerHelpers() {
return slugify(value.toLowerCase());
});
}


Hooks.on("renderChatLog", (_app, html: JQuery, _data) => onChatLogRender(html));
Hooks.on("renderChatMessage", (app, html, data) => hideChatButtonsIfNotOwner(app, html, data));
23 changes: 23 additions & 0 deletions module/chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Chat message helpers
*/
import { handleFateReroll } from "./rolls.js";

/**
* Binds buttons in chat log to perform actions
* @param html rendered html of the chat long
*/
export function onChatLogRender(html: JQuery) {
html.on('click', 'button.chat-fate-button', (e) => handleFateReroll(e.target));
}

export function hideChatButtonsIfNotOwner(_message: unknown, html: JQuery, data: any) {
const message = html.find("div.chat-message");
if (message.length > 0) {
const actor = game.actors.get(data.message.speaker.actor);
if (actor && actor.owner) {
return; // we are the owner of the message and shouldn't hide the buttons
}
message.find('div.chat-fate-reroll').each((i, b) => { b.style.display = "none"; });
}
}
63 changes: 59 additions & 4 deletions module/rolls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ export async function handleRollable(
}
}

export async function handleFateReroll(target: HTMLButtonElement): Promise<unknown> {
return null;
}


/* ================================================= */
/* Private Roll Handlers */
/* ================================================= */
async function handleShrugRoll(target: HTMLButtonElement, sheet: BWActorSheet): Promise<unknown> {
return handlePtgsRoll(target, sheet, true);
}
Expand Down Expand Up @@ -157,7 +165,7 @@ async function handleAttrRoll(target: HTMLButtonElement, sheet: BWActorSheet): P
woundDice: attrName === "Steel" ? actor.data.data.ptgs.woundDice : undefined,
obPenalty: actor.data.data.ptgs.obPenalty,
tax,
stat
stat,
};

const html = await renderTemplate(templates.attrDialog, data);
Expand Down Expand Up @@ -194,6 +202,7 @@ async function attrRollCallback(

const isSuccessful = parseInt(roll.result, 10) >= (baseData.diff + baseData.obPenalty);

const fateReroll = buildFateRerollData(sheet.actor, roll, accessor);
const data: RollChatMessageData = {
name: `${name} Test`,
successes: roll.result,
Expand All @@ -204,7 +213,8 @@ async function attrRollCallback(
rolls: roll.dice[0].rolls,
difficultyGroup: dg,
penaltySources: baseData.penaltySources,
dieSources
dieSources,
fateReroll
};

sheet.actor.addAttributeTest(stat, name, accessor, dg, isSuccessful);
Expand Down Expand Up @@ -275,6 +285,8 @@ async function circlesRollCallback(
const roll = rollDice(exp + baseData.bDice + baseData.aDice + bonusData.sum, stat.open, stat.shade);
if (!roll) { return; }

const fateReroll = buildFateRerollData(sheet.actor, roll, "data.circles");

baseData.obstacleTotal += penaltyData.sum;
const data: RollChatMessageData = {
name: `Circles Test`,
Expand All @@ -286,7 +298,8 @@ async function circlesRollCallback(
rolls: roll.dice[0].rolls,
difficultyGroup: dg,
dieSources,
penaltySources: { ...baseData.penaltySources, ...penaltyData.bonuses }
penaltySources: { ...baseData.penaltySources, ...penaltyData.bonuses },
fateReroll
};
const messageHtml = await renderTemplate(templates.circlesMessage, data);

Expand Down Expand Up @@ -351,6 +364,7 @@ async function learningRollCallback(
);
if (!roll) { return; }
const isSuccessful = parseInt(roll.result, 10) >= baseData.obstacleTotal;
const fateReroll = buildFateRerollData(sheet.actor, roll, undefined, skill._id);

const data: RollChatMessageData = {
name: `Beginner's Luck ${skill.data.name} Test`,
Expand All @@ -363,6 +377,7 @@ async function learningRollCallback(
difficultyGroup: dg,
penaltySources: baseData.penaltySources,
dieSources,
fateReroll
};
const messageHtml = await renderTemplate(templates.learnMessage, data);
advanceLearning(skill, sheet.actor, dg, isSuccessful);
Expand Down Expand Up @@ -428,6 +443,8 @@ async function statRollCallback(
if (!roll) { return; }
const isSuccessful = parseInt(roll.result, 10) >= baseData.obstacleTotal;

const fateReroll = buildFateRerollData(sheet.actor, roll, accessor);

const data: RollChatMessageData = {
name: `${name} Test`,
successes: roll.result,
Expand All @@ -439,6 +456,7 @@ async function statRollCallback(
difficultyGroup: dg,
penaltySources: baseData.penaltySources,
dieSources,
fateReroll
};

sheet.actor.addStatTest(stat, name, accessor, dg, isSuccessful);
Expand Down Expand Up @@ -494,6 +512,7 @@ async function skillRollCallback(
skill.data.data.open,
skill.data.data.shade);
if (!roll) { return; }
const fateReroll = buildFateRerollData(sheet.actor, roll, undefined, skill._id);

const data: RollChatMessageData = {
name: `${skill.name} Test`,
Expand All @@ -506,6 +525,7 @@ async function skillRollCallback(
difficultyGroup: dg,
penaltySources: baseData.penaltySources,
dieSources,
fateReroll
};

await helpers.addTestToSkill(skill, dg);
Expand All @@ -528,6 +548,10 @@ async function skillRollCallback(
});
}


/* ================================================= */
/* Helper functions */
/* ================================================= */
function buildDiceSourceObject(
exp: number,
aDice: number,
Expand All @@ -546,7 +570,29 @@ function buildDiceSourceObject(
return dieSources;
}

/* ======== Helper functions ======================= */
function buildFateRerollData(actor: BWActor, roll: Roll, accessor?: string, itemId?: string):
FateRerollData | undefined {
if (!parseInt(actor.data.data.fate, 10)) {
return;
}
const coreData: FateRerollData = {
dice: roll.dice[0].rolls.map(r => r.roll).join(","),
type: "stat",
actorId: actor._id,
};
if (accessor) {
return {
accessor,
...coreData
};
} else {
return {
itemId,
...coreData
};
}
}

function extractBaseData(html: JQuery<HTMLElement>, sheet: BWActorSheet ) {
const actorData = sheet.actor.data;
const woundDice = extractNumber(html, "woundDice") || 0;
Expand Down Expand Up @@ -808,4 +854,13 @@ export interface RollChatMessageData {

dieSources?: { [i: string]: string };
penaltySources?: { [i: string]: string };
fateReroll?: FateRerollData;
}

export interface FateRerollData {
dice: string;
actorId: string;
type: "stat" | "skill";
itemId?: string;
accessor?: string;
}
12 changes: 8 additions & 4 deletions styles/chat/roll.scss
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
.chat-message {
display: flex;

hr {
width: 100%;
}

.message-title {
font-size: 1.5em;
font-weight: bold;

&.open-roll {
color: gold;
}

&.shade-grey {
background-color: rgba(black, 0.35);
}
Expand All @@ -22,6 +22,10 @@
background-color: rgba(white, .75);
color: black;
}

&.open-roll {
color: gold;
}
}

div {
Expand Down
16 changes: 15 additions & 1 deletion templates/chat/roll-message.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,18 @@
Failure!
</div>
{{/if}}
</div>
{{#if fateReroll}}
<div class="chat-fate-reroll roll-full-width">
<hr/>
<button class="chat-fate-button"
data-actor-id="{{fateReroll.actorId}}"
data-reroll-type="{{fateReroll.type}}"
data-dice="{{fateReroll.dice}}"
{{#if fateReroll.itemId}} data-item-id="{{fateReroll.itemId}}" {{/if}}
{{#if fateReroll.accessor}} data-accessor="{{fateReroll.accessor}}" {{/if}}
data-difficulty="{{obstacleTotal}}"
data-successes="{{successes}}"
data-difficulty-group="{{difficultyGroup}}">Reroll with Fate</button>
</div>
{{/if}}
</div>

0 comments on commit 2a7377f

Please sign in to comment.