Skip to content

Commit

Permalink
add rollable class abilities to character sheet
Browse files Browse the repository at this point in the history
  • Loading branch information
Muttley committed Oct 3, 2023
1 parent e9d6e40 commit ada8b1c
Show file tree
Hide file tree
Showing 22 changed files with 400 additions and 70 deletions.
15 changes: 13 additions & 2 deletions i18n/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,20 @@ 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.success: "{name} successfully used the {ability} ability"
SHADOWDARK.chat.use_ability.title: "Using Ability"
SHADOWDARK.chat.welcome_message.intro: "To quickly get familiar with the system, check out the provided guided tours by clicking on the following button:"
SHADOWDARK.chat.welcome_message.issue_tracker_button: Issue Tracker
SHADOWDARK.chat.welcome_message.issues: "If you find any issues or have ideas for new features for the system. Check out our issue tracker:"
SHADOWDARK.chat.welcome_message.title: Shadowdark RPG for Foundry
SHADOWDARK.chat.welcome_message.tour_button: Shadowdark RPG Tours
SHADOWDARK.chatcard.default: Roll
SHADOWDARK.class-ability.ability.label: Ability
SHADOWDARK.class-ability.dc.label: DC
SHADOWDARK.class-ability.group.label: Ability Group
SHADOWDARK.class-ability.lose_on_failure.label: Lose on Failure?
SHADOWDARK.class-ability.lost.label: Lost
SHADOWDARK.class.armor.all.label: All Armor
SHADOWDARK.class.armor.label: Armor
SHADOWDARK.class.armor.prompt: Select Armor...
Expand Down Expand Up @@ -478,6 +486,8 @@ SHADOWDARK.settings.track_light_sources.pause_with_game.hint: If checked the Rea
SHADOWDARK.settings.track_light_sources.pause_with_game.name: Pause Light Tracking
SHADOWDARK.settings.track_light_sources.realtime_tracking.hint: If checked the Light Tracking will follow real time. Disable if an external time/calendar module is used.
SHADOWDARK.settings.track_light_sources.realtime_tracking.name: Realtime Light Tracking
SHADOWDARK.sheet.abilities.label: Abilities
SHADOWDARK.sheet.abilities.ungrouped.label: Miscellaneous
SHADOWDARK.sheet.actor.ac: AC
SHADOWDARK.sheet.actor.alignment: Alignment
SHADOWDARK.sheet.actor.hp_max: Max
Expand Down Expand Up @@ -518,24 +528,25 @@ SHADOWDARK.sheet.player.deity.tooltip: Your character’s cosmic link to the opp
SHADOWDARK.sheet.player.languages: Languages
SHADOWDARK.sheet.player.luck: Luck
SHADOWDARK.sheet.player.melee_attacks: Melee Attacks
SHADOWDARK.sheet.player.tab.notes: Notes
SHADOWDARK.sheet.player.ranged_attacks: Ranged Attacks
SHADOWDARK.sheet.player.roll_initiative: Roll Initiative
SHADOWDARK.sheet.player.spells_tier: Tier
SHADOWDARK.sheet.player.spells: Spells
SHADOWDARK.sheet.abilities.label: Abilities
SHADOWDARK.sheet.player.tab.abilities: Abilities
SHADOWDARK.sheet.player.tab.background: Background
SHADOWDARK.sheet.player.tab.inventory: Inventory
SHADOWDARK.sheet.player.tab.notes: Notes
SHADOWDARK.sheet.player.tab.spells: Spells
SHADOWDARK.sheet.player.tab.talents: Talents
SHADOWDARK.sheet.player.talents_level: Level
SHADOWDARK.sheet.player.talents_name: Name
SHADOWDARK.sheet.player.talents: Talents
SHADOWDARK.sheet.player.title: Title
SHADOWDARK.sheet.player.toggle_ability_lost: Toggle Ability Lost
SHADOWDARK.sheet.player.toggle_spell_lost: Toggle Spell Lost
SHADOWDARK.sheet.player.tooltip.cast_spell: Cast Spell
SHADOWDARK.sheet.player.tooltip.learn_spell: Learn Spell
SHADOWDARK.sheet.player.tooltip.use_class_ability: Use Class Ability
SHADOWDARK.sheet.player.tooltip.use_potion: Use Potion
SHADOWDARK.sheet.player.tooltip.use_scroll: Use Scroll
SHADOWDARK.sheet.player.tooltip.use_wand: Use Wand
Expand Down
57 changes: 56 additions & 1 deletion scss/sheets/actors/_player.scss
Original file line number Diff line number Diff line change
Expand Up @@ -561,10 +561,11 @@
}
}

.spell-lost {
.strike-through {
text-decoration: line-through;
}

.class-abilities-body,
.spells-body {
@include p-reset;
margin: 4px;
Expand Down Expand Up @@ -641,6 +642,60 @@
}
}

.class-abilities-list {
margin-bottom: 8px;

table {
@include p-reset;
font-family: "Montserrat-Medium";
font-size: 14px;
text-align: left;
border: none;

& td:first-child {
padding-left: 8px;
}

& th:first-child {
text-align: left;
padding-left: 4px;
}

& th:last-child {
text-align: right;
padding-right: 4px;
}

& td:last-child {
text-align: center;
padding-right: 4px;
}

// & tr:first-child {
// // background-color: #00000020;

// & td {
// @include p-reset;
// }
// }

// Only highlight on hover rows that have actual items in them,
// not the section headers or header/footer rows
//
& tr:not(
:first-child,
.spell-tier-header,
.item-details
) {
&:hover {
cursor: pointer;
background-color: var(--secondary);
color: white;
}
}
}
}

.talents-body {
@include p-reset;
margin: 4px;
Expand Down
4 changes: 2 additions & 2 deletions scss/sheets/items/_item.scss
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@
}
}

.class-details{
.class-details {
grid-column: span 3;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 4px;
}

.class-equipment-details{
.class-equipment-details {
grid-column: span 3;
display: grid;
grid-template-columns: 1.5fr 1.5fr 1fr;
Expand Down
35 changes: 19 additions & 16 deletions system/src/config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -63,33 +63,36 @@ SHADOWDARK.DICE = {
d20: "d20",
};

/* eslint-disable quote-props */
SHADOWDARK.DEFAULTS = {
BASE_ARMOR_CLASS: 10,
GEAR_SLOTS: 10,
FREE_COIN_CARRY: 100,
LEARN_SPELL_DC: 15,
LIGHT_TRACKER_UPDATE_INTERVAL_SECS: 30,
ITEM_IMAGES: {
Ancestry: "icons/environment/people/group.webp",
Armor: "icons/equipment/chest/breastplate-banded-steel-gold.webp",
Background: "icons/environment/people/commoner.webp",
Basic: "icons/containers/bags/pouch-simple-brown.webp",
Class: "icons/sundries/documents/document-sealed-brown-red.webp",
Deity: "icons/magic/holy/yin-yang-balance-symbol.webp",
Effect: "icons/commodities/tech/cog-brass.webp",
Gem: "icons/commodities/gems/gem-faceted-navette-red.webp",
Language: "icons/tools/scribal/ink-quill-pink.webp",
"Ancestry": "icons/environment/people/group.webp",
"Armor": "icons/equipment/chest/breastplate-banded-steel-gold.webp",
"Background": "icons/environment/people/commoner.webp",
"Basic": "icons/containers/bags/pouch-simple-brown.webp",
"Class Ability": "icons/tools/navigation/map-chart-tan.webp",
"Class": "icons/sundries/documents/document-sealed-brown-red.webp",
"Deity": "icons/magic/holy/yin-yang-balance-symbol.webp",
"Effect": "icons/commodities/tech/cog-brass.webp",
"Gem": "icons/commodities/gems/gem-faceted-navette-red.webp",
"Language": "icons/tools/scribal/ink-quill-pink.webp",
"NPC Attack": "icons/skills/melee/weapons-crossed-swords-yellow.webp",
"NPC Feature": "icons/creatures/abilities/dragon-breath-purple.webp",
Potion: "icons/consumables/potions/bottle-corked-red.webp",
Property: "icons/sundries/documents/document-torn-diagram-tan.webp",
Scroll: "icons/sundries/scrolls/scroll-runed-brown-purple.webp",
Spell: "icons/magic/symbols/runes-star-blue.webp",
Talent: "icons/sundries/books/book-worn-brown-grey.webp",
Wand: "icons/weapons/wands/wand-gem-violet.webp",
Weapon: "icons/weapons/swords/swords-short.webp",
"Potion": "icons/consumables/potions/bottle-corked-red.webp",
"Property": "icons/sundries/documents/document-torn-diagram-tan.webp",
"Scroll": "icons/sundries/scrolls/scroll-runed-brown-purple.webp",
"Spell": "icons/magic/symbols/runes-star-blue.webp",
"Talent": "icons/sundries/books/book-worn-brown-grey.webp",
"Wand": "icons/weapons/wands/wand-gem-violet.webp",
"Weapon": "icons/weapons/swords/swords-short.webp",
},
};
/* eslint-enable quote-props */

SHADOWDARK.INVENTORY = {
GEMS_PER_SLOT: 10,
Expand Down
1 change: 1 addition & 0 deletions system/src/dice/RollSD.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ export default class RollSD extends Roll {
isVersatile: false,
isRoll: true,
isNPC: data.actor?.type === "NPC",
targetDC: options.target ?? false,
};
if (data.rolls.main) {
templateData._formula = data.rolls.main.roll._formula;
Expand Down
72 changes: 68 additions & 4 deletions system/src/documents/ActorSD.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ export default class ActorSD extends Actor {
itemId,
});
}
if (item.hasProperty("thrown")) {
if (await item.hasProperty("thrown")) {
weaponOptions.attackBonus = baseAttackBonus
+ parseInt(this.system.bonuses.rangedAttackBonus, 10)
+ parseInt(item.system.bonuses.attackBonus, 10)
Expand Down Expand Up @@ -503,9 +503,12 @@ export default class ActorSD extends Actor {

async isSpellcaster() {
const characterClass = this.backgroundItems.class;
const spellcastingAbility = characterClass?.system?.spellcasting?.ability ?? "";
const spellcastingAbility =
characterClass?.system?.spellcasting?.class ?? "__not_spellcaster__";

return characterClass && spellcastingAbility !== "" ? true : false;
return characterClass && spellcastingAbility !== "__not_spellcaster__"
? true
: false;
}

/** @inheritDoc */
Expand Down Expand Up @@ -904,6 +907,68 @@ export default class ActorSD extends Actor {
return newArmorClass;
}

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

const result = await this.rollAbility(
item.system.ability,
{target: item.system.dc}
);

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

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

let message = game.i18n.format(
messageType,
{
name: this.name,
ability: item.name,
}
);

const abilityDescription = await TextEditor.enrichHTML(
item.system.description,
{
secrets: this.isOwner,
async: true,
relativeTo: this,
}
);

if (success) {
message = `<p>${message}</p>${abilityDescription}`;
}

const cardData = {
actor: this,
item: item,
message,
};

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

const content = await renderTemplate(template, cardData);

const title = game.i18n.localize("SHADOWDARK.chat.use_ability.title");

await ChatMessage.create({
title,
content,
flags: { "core.canPopout": true },
flavor: title,
speaker: ChatMessage.getSpeaker({actor: this, token: this.token}),
type: CONST.CHAT_MESSAGE_TYPES.OTHER,
user: game.user.id,
});

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

async usePotion(itemId) {
const item = this.items.get(itemId);

Expand Down Expand Up @@ -990,7 +1055,6 @@ export default class ActorSD extends Actor {
}

_preparePlayerData() {
this._populateBackgroundItems();
this._populatePlayerModifiers();
}

Expand Down
1 change: 1 addition & 0 deletions system/src/documents/CompendiumsSD.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ export default class CompendiumsSD {

const filteredDocuments = documents.filter(
document => document.system.spellcasting.ability !== ""
&& document.system.spellcasting.class !== "NONE"
);

// re-create the collection from the filtered Items
Expand Down
3 changes: 2 additions & 1 deletion system/src/documents/ItemSD.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ export default class ItemSD extends Item {
async hasProperty(property) {
property = property.slugify();

const propertyItem = (await this.propertyItems()).find(
const propertyItems = await this.propertyItems();
const propertyItem = propertyItems.find(
p => p.name.slugify() === property
);

Expand Down
15 changes: 1 addition & 14 deletions system/src/sheets/ActorSheetSD.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -386,19 +386,6 @@ export default class ActorSheetSD extends ActorSheet {
_sortAllItems(context) {
// Pre-sort all items so that when they are filtered into their relevant
// categories they are already sorted alphabetically (case-sensitive)
const allItems = [];
(context.items ?? []).forEach(item => allItems.push(item));

allItems.sort((a, b) => {
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});

return allItems;
return (context.items ?? []).sort((a, b) => a.name.localeCompare(b.name));
}
}
9 changes: 8 additions & 1 deletion system/src/sheets/ItemSheetSD.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ export default class ItemSheetSD extends ItemSheet {
return "systems/shadowdark/templates/items/item.hbs";
}

/** @inheritdoc */
get title() {
return `[${this.item.type}] ${this.item.name}`;
}

/** @inheritdoc */
activateListeners(html) {

Expand Down Expand Up @@ -198,6 +203,7 @@ export default class ItemSheetSD extends ItemSheet {

context.spellcastingClasses = {};
for (const spellcastingClass of spellcastingClasses) {
if (spellcastingClass.name === this.item.name) continue;
context.spellcastingClasses[spellcastingClass.uuid] =
spellcastingClass.name;
}
Expand Down Expand Up @@ -249,10 +255,11 @@ export default class ItemSheetSD extends ItemSheet {
"Ancestry",
"Armor",
"Basic",
"Class Ability",
"Class",
"Deity",
"Gem",
"Effect",
"Gem",
"Language",
"NPC Attack",
"Potion",
Expand Down
Loading

0 comments on commit ada8b1c

Please sign in to comment.