Skip to content

Commit

Permalink
closes #952
Browse files Browse the repository at this point in the history
  • Loading branch information
Muttley committed Nov 18, 2024
1 parent 674b661 commit 5dfffe4
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 118 deletions.
2 changes: 1 addition & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* [#930] Class Abilities can't be used if they have no associated skill roll
* [#936] Character Generator: Don't display empty alignment for Deities that don't have one
* [#938] Unecessary line breaks in Farsight talent descriptions
* [#952] NPC Special Attacks always posted to chat in public
* [#953] Dice So Nice not honouring roll modes in Shadowdark
* [#955] Chat message icon missing on hovering over Ancestry and Level talents on character sheet

Expand All @@ -40,7 +41,6 @@

*Many thanks to **AdamsGH** for contributing **Russian** translation data.*


---

# v3.1.3
Expand Down
2 changes: 1 addition & 1 deletion i18n/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ SHADOWDARK.chat.spell_learn.failure: "{name} failed to learn anything from the s
SHADOWDARK.chat.spell_learn.success: "{name} successfully learnt the {spellName} spell"
SHADOWDARK.chat.spell_learn.title: Learning Spell
SHADOWDARK.chat.spell_roll.title: "{name}, DC {spellDC}"
SHADOWDARK.chat.use_ability.failure: "{name} failed to used the {ability} ability"
SHADOWDARK.chat.use_ability.failure: "{name} failed to use the {ability} ability"
SHADOWDARK.chat.use_ability.success: "{name} successfully used the {ability} ability"
SHADOWDARK.chat.use_ability.title: "Using Ability"
SHADOWDARK.chat.welcome_message.arcane_library_button: Shop Shadowdark RPG
Expand Down
6 changes: 4 additions & 2 deletions system/src/apps/RequestCheckSD.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ export default class RequestCheckSD extends FormApplication {
shadowdark.chat.renderRollRequestMessage(
await shadowdark.utils.getCurrentActor(),
{
title: game.i18n.localize("SHADOWDARK.check.requesting"),
body: `[[check ${dc} ${stat}]]`,
templateData: {
title: game.i18n.localize("SHADOWDARK.check.requesting"),
body: `[[check ${dc} ${stat}]]`,
},
},
CONST.DICE_ROLL_MODES.PUBLIC
);
Expand Down
112 changes: 39 additions & 73 deletions system/src/documents/ActorSD.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1412,6 +1412,26 @@ export default class ActorSD extends Actor {

async useAbility(itemId, options={}) {
const item = this.items.get(itemId);

if (item.type === "NPC Feature") item.displayCard();

// If the ability has limited uses, handle that first
if (item.system.limitedUses) {
if (item.system.uses.available <= 0) {
return ui.notifications.error(
game.i18n.format("SHADOWDARK.error.class_ability.no-uses-remaining"),
{permanent: false}
);
}
else {
const newUsesAvailable = item.system.uses.available - 1;

item.update({
"system.uses.available": Math.max(0, newUsesAvailable),
});
}
}

const abilityDescription = await TextEditor.enrichHTML(
item.system.description,
{
Expand All @@ -1420,86 +1440,32 @@ export default class ActorSD extends Actor {
relativeTo: this,
}
);
// Default message values
let title = "";
let message = "";
let success = true;

// NPC features - no title or checks required
if (item.type === "NPC Feature") {
message = `${abilityDescription}`;
}
else {
title = game.i18n.localize("SHADOWDARK.chat.use_ability.title");

// does ability use on a roll check?
if (item.system.ability) {
options = foundry.utils.mergeObject({target: item.system.dc}, options);
const result = await this.rollAbility(
item.system.ability,
options
);

success = result?.rolls?.main?.success ?? false;
}

// does ability have limited uses?
if (item.system.limitedUses) {
if (item.system.uses.available > 0) {
item.update({
"system.uses.available": item.system.uses.available - 1,
});
}
else {
success = false;
ui.notifications.error(
game.i18n.format("SHADOWDARK.error.class_ability.no-uses-remaining"),
{permanent: false}
);
}
}

const messageType = success
? "SHADOWDARK.chat.use_ability.success"
: "SHADOWDARK.chat.use_ability.failure";

message = game.i18n.format(
messageType,
{
name: this.name,
ability: item.name,
}
let success = true;
// does ability use on a roll check?
if (item.system.ability) {
options = foundry.utils.mergeObject({target: item.system.dc}, options);
const result = await this.rollAbility(
item.system.ability,
options
);

if (success) {
message = `<p>${message}</p>${abilityDescription}`;
success = result?.rolls?.main?.success ?? false;

if (!success && item.system.loseOnFailure) {
item.update({"system.lost": true});
}
}

// construct and create chat message
const cardData = {
actor: this,
item: item,
message,
};

let template = "systems/shadowdark/templates/chat/use-ability.hbs";

const content = await renderTemplate(template, cardData);

await ChatMessage.create({
title,
content,
flags: { "core.canPopout": true },
flavor: title,
speaker: ChatMessage.getSpeaker({actor: this, token: this.token}),
type: CONST.CHAT_MESSAGE_STYLES.OTHER,
user: game.user.id,
return shadowdark.chat.renderUseAbilityMessage(this.actor, {
flavor: game.i18n.localize("SHADOWDARK.chat.use_ability.title"),
templateData: {
abilityDescription,
actor: this,
item: item,
success,
},
});

if (!success && item.system.loseOnFailure) {
item.update({"system.lost": true});
}
}


Expand Down
62 changes: 26 additions & 36 deletions system/src/documents/ItemSD.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ export default class ItemSD extends Item {
].includes(this.type);
}


get typeSlug() {
return this.type.slugify();
}


get usesAmmunition() {
return (game.settings.get("shadowdark", "autoConsumeAmmunition")
&& this.isOwned
Expand Down Expand Up @@ -55,12 +57,14 @@ export default class ItemSD extends Item {
}
}


availableAmmunition() {
if (this.usesAmmunition) {
return this.actor.ammunitionItems(this.system.ammoClass);
}
}


async getChatData(htmlOptions={}) {
const description = await this.getEnrichedDescription();

Expand All @@ -87,33 +91,15 @@ export default class ItemSD extends Item {
return data;
}

async displayCard(options={}) {
// Render the chat card template
const token = this.actor.token;

const templateData = await this.getChatData();

const template = this.getItemTemplate("systems/shadowdark/templates/chat/item");

const html = await renderTemplate(template, templateData);

const chatData = {
user: game.user.id,
type: CONST.CHAT_MESSAGE_STYLES.OTHER,
content: html,
flavor: this.name,
speaker: ChatMessage.getSpeaker({actor: this.actor, token}),
flags: { "core.canPopout": true },
};

ChatMessage.applyRollMode(chatData, options.rollMode ?? game.settings.get("core", "rollMode"));

const card = (options.createMessage !== false)
? await ChatMessage.create(chatData) : chatData;

return card;
async displayCard(options={}) {
shadowdark.chat.renderItemCardMessage(this.actor, {
template: this.getItemTemplate("systems/shadowdark/templates/chat/item"),
templateData: await this.getChatData(),
});
}


async getBaseItemName() {
if (this.type === "Armor") {
if (this.system.baseArmor === "") return "";
Expand Down Expand Up @@ -159,6 +145,7 @@ export default class ItemSD extends Item {
return await renderTemplate(templatePath, data);
}


async getEnrichedDescription() {
return await TextEditor.enrichHTML(
this.system.description,
Expand All @@ -168,6 +155,7 @@ export default class ItemSD extends Item {
);
}


getItemTemplate(basePath) {
switch (this.type) {
case "Armor":
Expand All @@ -185,51 +173,57 @@ export default class ItemSD extends Item {
}
}


lightRemainingString() {
if (this.type !== "Basic" && !this.system.light.isSource) return;

const timeRemaining = Math.ceil(
this.system.light.remainingSecs / 60
);

if (this.system.light.remainingSecs < 60) {
this.lightSourceTimeRemaining = game.i18n.localize(
"SHADOWDARK.inventory.item.light_seconds_remaining"
);
}
else {
const timeRemaining = Math.ceil(
this.system.light.remainingSecs / 60
);

this.lightSourceTimeRemaining = game.i18n.format(
"SHADOWDARK.inventory.item.light_remaining",
{ timeRemaining }
);
}
}


async reduceAmmunition(amount) {
const newAmount = Math.max(0, this.system.quantity - amount);
this.update({"system.quantity": newAmount});
}


setLightRemaining(remainingSeconds) {
this.update({"system.light.remainingSecs": remainingSeconds});
}


/* -------------------------------------------- */
/* Roll Methods */
/* -------------------------------------------- */

async rollNpcAttack(parts, data, options={}) {
options.dialogTemplate = "systems/shadowdark/templates/dialog/roll-npc-attack-dialog.hbs";
async rollItem(parts, data, options={}) {
options.dialogTemplate = "systems/shadowdark/templates/dialog/roll-item-dialog.hbs";
options.chatCardTemplate = "systems/shadowdark/templates/chat/item-card.hbs";
await CONFIG.DiceSD.RollDialog(parts, data, options);
}

async rollItem(parts, data, options={}) {
options.dialogTemplate = "systems/shadowdark/templates/dialog/roll-item-dialog.hbs";

async rollNpcAttack(parts, data, options={}) {
options.dialogTemplate = "systems/shadowdark/templates/dialog/roll-npc-attack-dialog.hbs";
options.chatCardTemplate = "systems/shadowdark/templates/chat/item-card.hbs";
await CONFIG.DiceSD.RollDialog(parts, data, options);
}


async rollSpell(parts, data, options={}) {
options.dialogTemplate = "systems/shadowdark/templates/dialog/roll-spell-dialog.hbs";
options.chatCardTemplate = "systems/shadowdark/templates/chat/item-card.hbs";
Expand All @@ -250,9 +244,6 @@ export default class ItemSD extends Item {
return roll;
}

/* -------------------------------------------- */
/* Methods */
/* -------------------------------------------- */

async hasProperty(property) {
property = property.slugify();
Expand Down Expand Up @@ -364,7 +355,6 @@ export default class ItemSD extends Item {
return propertyItems;
}

// Duration getters

/**
* Returns the total duration depending on the type
Expand Down
16 changes: 14 additions & 2 deletions system/src/system/ChatSD.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default class ChatSD {
template,
mode
) {
const html = await renderTemplate(template, data);
const html = await renderTemplate(template, data.templateData);

if (!mode) {
mode = game.settings.get("core", "rollMode");
Expand All @@ -15,11 +15,12 @@ export default class ChatSD {
const chatData = {
content: html,
flags: { "core.canPopout": true },
flavor: data.flavor ?? undefined,
rollMode: mode,
speaker: ChatMessage.getSpeaker({
actor: actor,
}),
type: CONST.CHAT_MESSAGE_STYLES.OTHER,
type: data.type ?? CONST.CHAT_MESSAGE_STYLES.OTHER,
user: game.user.id,
};

Expand All @@ -35,10 +36,21 @@ export default class ChatSD {
);
}

static async renderItemCardMessage(actor, data, mode) {
this._renderChatMessage(actor, data, data.template, mode);
}

static async renderRollRequestMessage(actor, data, mode) {
this._renderChatMessage(actor, data,
"systems/shadowdark/templates/chat/roll-request.hbs",
mode
);
}

static async renderUseAbilityMessage(actor, data, mode) {
this._renderChatMessage(actor, data,
"systems/shadowdark/templates/chat/use-ability.hbs",
mode
);
}
}
Loading

0 comments on commit 5dfffe4

Please sign in to comment.