Skip to content

Commit 2141a62

Browse files
authored
Release v0.0.22 (#160)
* Apply Duval font to headings on dialogs with .sheet class. * Limit Duval headings to journals. * Set correct primary/secondary token attributes. Set default max for abilities. * Support registration of default critical hit/disapproval compendiums or fumble tables by modules (with the system settings acting as an override or addition to the settings as appropriate). * Add a 'dcc.ready' hook to let modules know when the DCC system is initialised. * Fix criticialHitsPack hook name. * Implement rollable mercurial magic effects on the spell sheet. Closes #125. * Support Inherit Action Die config variable on spells. * Update manifest and download URLs. * Default icons for actors and items. (#141) * Add a Hook that executes after an actor is imported. * Apply default icons for Items on imported actors. * Implement entity creation hooks to set themed default icons. * Unify default image selection and apply to the parser and embedded entities. * Add placeholder spell image. * Only assign an image for actors/items with no existing image. * Only try to apply the Pop Out flag as GM. Remove spurious call to hexExistingMercurialEffect before rolling a Treasure item's value. * Update download link for v0.0.22-preview.3 * Minor and cosmetic fixes (#157) * Add fields and dependency for the bug-reporter module. Closes #152. * Reorder saves on upper level sheets. Closes #151. * Rework Halfling two weapon fighting description on the sheet. Closes #149. * Remove actor name from damage and healing chat cards since the token name is at the top of the card. Closes #146. * Fix Skill sheet description size and other item sheet issues. Replaced item header fields with flexrows (grid caused some layout problems). Spell Mercurial Magic and Description now both resize if necessary. Closes #143. * Update download link to be v0.0.22-preview-4. * Remove unnecessary overflow: scroll style on item sheet descriptions. This created a second scrollbar on Firefox. Closes #159. * Update manifest for v0.0.22 release. * Add a single author node and expand the contributors node. * Fix download and manifest URLs.
1 parent 12decc8 commit 2141a62

28 files changed

+575
-110
lines changed

lang/en.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,10 @@
268268
"DCC.HalflingAbilities": "Halfling Skills",
269269
"DCC.HalflingTwoWeaponActionDie": "Action dice d16+d16",
270270
"DCC.HalflingTwoWeaponCrit": "Crit on nat 16",
271-
"DCC.HalflingTwoWeaponFumble": "Fumble only on 2x 1",
272-
"DCC.HalflingTwoWeaponHighAg": "If Agi > 16 use normal rules",
271+
"DCC.HalflingTwoWeaponFumble": "Fumble only on double 1",
272+
"DCC.HalflingTwoWeaponHighAg": "If Agi > 16 use normal rules",
273273
"DCC.HandlePoison": "Handle Poison",
274-
"DCC.HealDamage": "{target} is healed for {damage} HP.",
274+
"DCC.HealDamage": "Healed for {damage} HP.",
275275
"DCC.Healing": "Healing",
276276
"DCC.Health": "Health",
277277
"DCC.HealthFormula": "Health Formula",
@@ -375,6 +375,9 @@
375375
"DCC.MercurialEffect": "Mercurial Effect",
376376
"DCC.MercurialEffectSummary": "Summary",
377377
"DCC.MercurialEffectValue": "Roll",
378+
"DCC.MercurialMagicRoll": "Mercurial Magic Roll",
379+
"DCC.MercurialMagicRerollPrompt": "Re-roll Mercurial Magic Roll?",
380+
"DCC.MercurialMagicRerollExplain": "Discard previous Mercurial Magic roll and re-roll?",
378381
"DCC.MightyDeedsOfArms": "Mighty Deeds of Arms",
379382
"DCC.MigrationComplete": "Finished migration to DCC System version {systemVersion}!",
380383
"DCC.MigrationInfo": "Beginning DCC System Migration to version {systemVersion}. Please be patient and do not close your game or shut down your server.",
@@ -447,6 +450,8 @@
447450
"DCC.SettingDisapprovalTablesCompendiumHint": "Compendium to look in for critical hit tables. The specific table to use is selectable from the Cleric sheet.",
448451
"DCC.SettingFumbleTable": "Fumble Table",
449452
"DCC.SettingFumbleTableHint": "Roll Table to use for fumbles - must be in a compendium pack",
453+
"DCC.SettingMercurialMagicTable": "Mercurial Magic Table",
454+
"DCC.SettingMercurialMagicTableHint": "Roll Table to use for Mercurial Magic effects - must be in a compendium pack",
450455
"DCC.SettingStandardDiceRoller": "Use standard chat cards for dice rolls",
451456
"DCC.SettingStandardDiceRollerHint": "Use Foundry's standard cards to display attack, damage, crit, and fumble rolls instead of the custom card.",
452457
"DCC.SheetConfig": "Sheet Configuration",
@@ -532,7 +537,7 @@
532537
"DCC.SkillUseDie": "Use Die",
533538
"DCC.SkillUseValue": "Use Modifier",
534539
"DCC.SkillValue": "Modifier",
535-
"DCC.TakeDamage": "{target} takes {damage} HP of damage.",
540+
"DCC.TakeDamage": "Takes {damage} HP of damage.",
536541
"DCC.Target": "Target",
537542
"DCC.TargetAlly": "Ally",
538543
"DCC.TargetCone": "Cone",

module/actor-sheet.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* global ActorSheet, CONFIG, duplicate, Dialog, game, mergeObject, expandObject, $, ENTITY_PERMISSIONS */
22

33
import DCCActorConfig from './actor-config.js'
4+
import EntityImages from './entity-images.js'
45

56
/**
67
* Extend the basic ActorSheet
@@ -72,6 +73,15 @@ class DCCActorSheet extends ActorSheet {
7273
this.options.template = 'systems/dcc/templates/actor-sheet-npc.html'
7374
} else {
7475
this.options.template = 'systems/dcc/templates/actor-sheet-zero-level.html'
76+
77+
if (!data.isZero) {
78+
// Reorder saves on upper level sheet to define tabbing order
79+
data.data.saves = {
80+
ref: data.data.saves.ref,
81+
frt: data.data.saves.frt,
82+
wil: data.data.saves.wil
83+
}
84+
}
7585
}
7686

7787
// Prepare item lists by type
@@ -688,6 +698,7 @@ class DCCActorSheet extends ActorSheet {
688698
// Prepare the item object.
689699
const itemData = {
690700
name: name,
701+
img: EntityImages.imageForItem(type),
691702
type: type,
692703
data: data
693704
}

module/actor.js

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -622,16 +622,17 @@ class DCCActor extends Actor {
622622

623623
// Lookup the crit table if available
624624
let critResult = null
625-
const critsPackName = game.settings.get('dcc', 'critsCompendium')
626-
if (critsPackName) {
627-
const pack = game.packs.get(critsPackName)
628-
if (pack) {
629-
await pack.getIndex() // Load the compendium index
630-
const critTableFilter = `Crit Table ${this.data.data.attributes.critical.table}`
631-
const entry = pack.index.find((entity) => entity.name.startsWith(critTableFilter))
632-
if (entry) {
633-
const table = await pack.getEntity(entry._id)
634-
critResult = await table.draw({ roll, displayChat: options.displayStandardCards })
625+
for (const criticalHitPackName of CONFIG.DCC.criticalHitPacks.packs) {
626+
if (criticalHitPackName) {
627+
const pack = game.packs.get(criticalHitPackName)
628+
if (pack) {
629+
await pack.getIndex() // Load the compendium index
630+
const critTableFilter = `Crit Table ${this.data.data.attributes.critical.table}`
631+
const entry = pack.index.find((entity) => entity.name.startsWith(critTableFilter))
632+
if (entry) {
633+
const table = await pack.getEntity(entry._id)
634+
critResult = await table.draw({ roll, displayChat: options.displayStandardCards })
635+
}
635636
}
636637
}
637638
}
@@ -681,7 +682,7 @@ class DCCActor extends Actor {
681682

682683
// Lookup the fumble table if available
683684
let fumbleResult = null
684-
const fumbleTableName = game.settings.get('dcc', 'fumbleTable')
685+
const fumbleTableName = CONFIG.DCC.fumbleTable
685686
if (fumbleTableName) {
686687
const fumbleTablePath = fumbleTableName.split('.')
687688
let pack
@@ -853,15 +854,16 @@ class DCCActor extends Actor {
853854

854855
// Lookup the disapproval table if available
855856
let disapprovalTable = null
856-
const disapprovalPackName = game.settings.get('dcc', 'disapprovalCompendium')
857-
const disapprovalTableName = this.data.data.class.disapprovalTable
858-
if (disapprovalPackName && disapprovalTableName) {
859-
const pack = game.packs.get(disapprovalPackName)
860-
if (pack) {
861-
await pack.getIndex() // Load the compendium index
862-
const entry = pack.index.find((entity) => entity.name === disapprovalTableName)
863-
if (entry) {
864-
disapprovalTable = await pack.getEntity(entry._id)
857+
for (const disapprovalPackName of CONFIG.DCC.disapprovalPacks.packs) {
858+
const disapprovalTableName = this.data.data.class.disapprovalTable
859+
if (disapprovalPackName && disapprovalTableName) {
860+
const pack = game.packs.get(disapprovalPackName)
861+
if (pack) {
862+
await pack.getIndex() // Load the compendium index
863+
const entry = pack.index.find((entity) => `${disapprovalPackName}.${entity.name}` === disapprovalTableName)
864+
if (entry) {
865+
disapprovalTable = await pack.getEntity(entry._id)
866+
}
865867
}
866868
}
867869
}

module/config.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,28 @@ DCC.DICE_CHAIN = [
350350
3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 30
351351
]
352352

353-
// Disapproval tables - updated at runtime from compendiums
353+
// Critical Hit and Disapproval Compendiums, Fumble table, and Mercurial Magic table
354+
// Updated at runtime from settings
355+
DCC.criticalHitPacks = null
356+
DCC.disapprovalPacks = null
357+
DCC.fumbleTable = null
358+
DCC.mercurialMagicTable = null
359+
360+
// List of available disapproval tables for the cleric sheet, generated from disapprovalPacks
354361
DCC.disapprovalTables = {}
355362

363+
// Default actor images
364+
DCC.defaultActorImages = {
365+
default: 'systems/dcc/styles/images/actor.webp'
366+
}
367+
368+
// Default item tokens
369+
DCC.defaultItemImages = {
370+
default: 'systems/dcc/styles/images/item.webp',
371+
armor: 'systems/dcc/styles/images/armor.webp',
372+
spell: 'systems/dcc/styles/images/spell.webp',
373+
treasure: 'systems/dcc/styles/images/coins.webp',
374+
weapon: 'systems/dcc/styles/images/weapon.webp'
375+
}
376+
356377
export default DCC

module/dcc.js

Lines changed: 106 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import * as chat from './chat.js'
1414
import * as migrations from './migrations.js'
1515
import DiceChain from './dice-chain.js'
1616
import parser from './parser.js'
17+
import TablePackManager from './tablePackManager.js'
18+
import EntityImages from './entity-images.js'
1719

1820
import { registerSystemSettings } from './settings.js'
1921

@@ -117,25 +119,55 @@ Hooks.once('ready', async function () {
117119

118120
// Determine whether a system migration is required and feasible
119121
const currentVersion = game.settings.get('dcc', 'systemMigrationVersion')
120-
const NEEDS_MIGRATION_VERSION = 0.16
122+
const NEEDS_MIGRATION_VERSION = 0.21
121123
const needMigration = (currentVersion <= NEEDS_MIGRATION_VERSION) || (currentVersion === null)
122124

123125
// Perform the migration
124126
if (needMigration && game.user.isGM) {
125127
migrations.migrateWorld()
126128
}
127129

128-
// Load the list of disapproval tables
129-
const disapprovalTablesPackName = game.settings.get('dcc', 'disapprovalCompendium')
130-
if (disapprovalTablesPackName) {
131-
const pack = game.packs.get(disapprovalTablesPackName)
132-
if (pack) {
133-
await pack.getIndex()
134-
pack.index.forEach(function (value, key, map) {
135-
CONFIG.DCC.disapprovalTables[key] = value
136-
})
130+
// Create manager for disapproval tables and register the system setting
131+
CONFIG.DCC.disapprovalPacks = new TablePackManager({
132+
updateHook: async (manager) => {
133+
// Clear disapproval tables
134+
CONFIG.DCC.disapprovalTables = {}
135+
136+
// For each valid pack, update the list of disapproval tables available to a cleric
137+
for (const packName of manager.packs) {
138+
const pack = game.packs.get(packName)
139+
if (pack) {
140+
await pack.getIndex()
141+
pack.index.forEach(function (value, key, map) {
142+
CONFIG.DCC.disapprovalTables[key] = {
143+
name: value.name,
144+
path: `${packName}.${value.name}`
145+
}
146+
})
147+
}
148+
}
137149
}
150+
})
151+
CONFIG.DCC.disapprovalPacks.addPack(game.settings.get('dcc', 'disapprovalCompendium'), true)
152+
153+
// Create manager for critical hit table packs and register the system setting
154+
CONFIG.DCC.criticalHitPacks = new TablePackManager()
155+
CONFIG.DCC.criticalHitPacks.addPack(game.settings.get('dcc', 'critsCompendium'), true)
156+
157+
// Set fumble table from the system setting
158+
const fumbleTable = game.settings.get('dcc', 'fumbleTable')
159+
if (fumbleTable) {
160+
CONFIG.DCC.fumbleTable = fumbleTable
138161
}
162+
163+
// Set mercurial magic table from the system setting
164+
const mercurialMagicTable = game.settings.get('dcc', 'mercurialMagicTable')
165+
if (mercurialMagicTable) {
166+
CONFIG.DCC.mercurialMagicTable = mercurialMagicTable
167+
}
168+
169+
// Let modules know the DCC system is ready
170+
Hooks.callAll('dcc.ready')
139171
})
140172

141173
/* -------------------------------------------- */
@@ -145,8 +177,11 @@ Hooks.once('ready', async function () {
145177
Hooks.on('hotbarDrop', (bar, data, slot) => createDCCMacro(data, slot))
146178

147179
// Highlight 1's and 20's for all regular rolls
148-
Hooks.on('renderChatMessage', (app, html, data) => {
149-
chat.highlightCriticalSuccessFailure(app, html, data)
180+
Hooks.on('renderChatMessage', (message, html, data) => {
181+
if (game.user.isGM) {
182+
message.setFlag('core', 'canPopout', true)
183+
}
184+
chat.highlightCriticalSuccessFailure(message, html, data)
150185
})
151186

152187
// Support context menu on chat cards
@@ -157,9 +192,67 @@ Hooks.on('renderActorDirectory', (app, html) => {
157192
parser.onRenderActorDirectory(app, html)
158193
})
159194

195+
// Disapproval table packs
196+
Hooks.on('dcc.registerDisapprovalPack', (value, fromSystemSetting) => {
197+
const disapprovalPacks = CONFIG.DCC.disapprovalPacks
198+
199+
if (disapprovalPacks) {
200+
disapprovalPacks.addPack(value, fromSystemSetting)
201+
}
202+
})
203+
204+
// Critical hit table packs
205+
Hooks.on('dcc.registerCriticalHitsPack', (value, fromSystemSetting) => {
206+
const criticalHitPacks = CONFIG.DCC.criticalHitPacks
207+
208+
if (criticalHitPacks) {
209+
criticalHitPacks.addPack(value, fromSystemSetting)
210+
}
211+
})
212+
213+
// Fumble table
214+
Hooks.on('dcc.setFumbleTable', (value, fromSystemSetting = false) => {
215+
// Set fumble table if unset, or if applying the system setting (which takes precedence)
216+
if (fromSystemSetting || !CONFIG.DCC.fumbleTable) {
217+
CONFIG.DCC.fumbleTable = value
218+
}
219+
})
220+
221+
// Mercurial Magic mable
222+
Hooks.on('dcc.setMercurialMagicTable', (value, fromSystemSetting = false) => {
223+
// Set mercurial magic table if unset, or if applying the system setting (which takes precedence)
224+
if (fromSystemSetting || !CONFIG.DCC.mercurialMagicTable) {
225+
CONFIG.DCC.mercurialMagicTable = value
226+
}
227+
})
228+
229+
// Entity creation hook
230+
Hooks.on('createActor', (entity, options, userId) => {
231+
if (!game.user.isGM || entity.data.img) { return }
232+
233+
// Assign an appropriate DCC actor image
234+
const img = EntityImages.imageForActor(entity.type)
235+
if (img) {
236+
entity.update({
237+
img
238+
})
239+
}
240+
})
241+
242+
Hooks.on('createItem', (entity, options, userId) => {
243+
if (!game.user.isGM || entity.data.img) { return }
244+
245+
// Assign an appropriate DCC item image
246+
const img = EntityImages.imageForItem(entity.type)
247+
if (img) {
248+
entity.update({
249+
img
250+
})
251+
}
252+
})
253+
160254
/* -------------------------------------------- */
161255
/* Hotbar Macros */
162-
163256
/* -------------------------------------------- */
164257

165258
/**

module/entity-images.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* global CONFIG */
2+
3+
class EntityImages {
4+
/**
5+
* Select an appropriate image from a map
6+
* @param {Object} map The map of entity types (or default) to image paths
7+
* @param {String} type The entity type
8+
* @returns {String} The image to use
9+
*/
10+
static _selectImage (map, type) {
11+
// Grab the default image if available
12+
let img = map.default
13+
14+
// Check for a more specialised image based on actor type
15+
if (map[type]) {
16+
img = map[type]
17+
}
18+
19+
return img
20+
}
21+
22+
/**
23+
* Select an appropriate image for an actor
24+
* @param {String} type The actor type
25+
* @returns {String} The image to use
26+
*/
27+
static imageForActor (type) {
28+
return this._selectImage(CONFIG.DCC.defaultActorImages, type)
29+
}
30+
31+
/**
32+
* Select an appropriate image for an item
33+
* @param {String} type The item type
34+
* @returns {String} The image to use
35+
*/
36+
static imageForItem (type) {
37+
return this._selectImage(CONFIG.DCC.defaultItemImages, type)
38+
}
39+
}
40+
41+
export default EntityImages

0 commit comments

Comments
 (0)