Skip to content

Commit 3b31b38

Browse files
authored
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.
1 parent a8ac507 commit 3b31b38

File tree

13 files changed

+102
-6
lines changed

13 files changed

+102
-6
lines changed

module/actor-sheet.js

Lines changed: 2 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
@@ -688,6 +689,7 @@ class DCCActorSheet extends ActorSheet {
688689
// Prepare the item object.
689690
const itemData = {
690691
name: name,
692+
img: EntityImages.imageForItem(type),
691693
type: type,
692694
data: data
693695
}

module/config.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,4 +360,18 @@ DCC.mercurialMagicTable = null
360360
// List of available disapproval tables for the cleric sheet, generated from disapprovalPacks
361361
DCC.disapprovalTables = {}
362362

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+
363377
export default DCC

module/dcc.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import * as migrations from './migrations.js'
1515
import DiceChain from './dice-chain.js'
1616
import parser from './parser.js'
1717
import TablePackManager from './tablePackManager.js'
18+
import EntityImages from './entity-images.js'
1819

1920
import { registerSystemSettings } from './settings.js'
2021

@@ -223,6 +224,31 @@ Hooks.on('dcc.setMercurialMagicTable', (value, fromSystemSetting = false) => {
223224
}
224225
})
225226

227+
// Entity creation hook
228+
Hooks.on('createActor', (entity, options, userId) => {
229+
if (!game.user.isGM || entity.data.img) { return }
230+
231+
// Assign an appropriate DCC actor image
232+
const img = EntityImages.imageForActor(entity.type)
233+
if (img) {
234+
entity.update({
235+
img
236+
})
237+
}
238+
})
239+
240+
Hooks.on('createItem', (entity, options, userId) => {
241+
if (!game.user.isGM || entity.data.img) { return }
242+
243+
// Assign an appropriate DCC item image
244+
const img = EntityImages.imageForItem(entity.type)
245+
if (img) {
246+
entity.update({
247+
img
248+
})
249+
}
250+
})
251+
226252
/* -------------------------------------------- */
227253
/* Hotbar Macros */
228254
/* -------------------------------------------- */

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

module/parser.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* global CONFIG, FormApplication, game, expandObject ui, $ */
1+
/* global CONFIG, expandObject, FormApplication, game, Hooks, ui, $ */
22

33
import DCCActor from './actor.js'
44
import parsePCs from './pc-parser.js'
@@ -126,6 +126,9 @@ async function createActors (type, folderId, actorData) {
126126
}
127127

128128
actors.push(actor)
129+
130+
// Call a hook for postprocessing of actors
131+
Hooks.callAll('dcc.postActorImport', { actor })
129132
}
130133

131134
return actors

module/pc-parser.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/* global game, ui */
22

3+
import EntityImages from './entity-images.js'
4+
35
/**
46
* Parses Player Stat Blocks (e.g. from Purple Sorceror) into an NPC sheet
57
*
@@ -136,28 +138,32 @@ function _parseJSONPCs (pcObject) {
136138
notes = notes + ' ' + pcObject.equipment + '<br/>'
137139
pc.items.push({
138140
name: pcObject.equipment,
139-
type: 'equipment'
141+
type: 'equipment',
142+
img: EntityImages.imageForItem('equipment')
140143
})
141144
}
142145
if (pcObject.equipment2) {
143146
notes = notes + ' ' + pcObject.equipment2 + '<br/>'
144147
pc.items.push({
145148
name: pcObject.equipment2,
146-
type: 'equipment'
149+
type: 'equipment',
150+
img: EntityImages.imageForItem('equipment')
147151
})
148152
}
149153
if (pcObject.equipment3) {
150154
notes = notes + ' ' + pcObject.equipment3 + '<br/>'
151155
pc.items.push({
152156
name: pcObject.equipment3,
153-
type: 'equipment'
157+
type: 'equipment',
158+
img: EntityImages.imageForItem('equipment')
154159
})
155160
}
156161
if (pcObject.tradeGood) {
157162
notes = notes + ' ' + pcObject.tradeGood + ' (' + game.i18n.localize('DCC.TradeGoods') + ')<br/>'
158163
pc.items.push({
159164
name: pcObject.tradeGood,
160-
type: 'equipment'
165+
type: 'equipment',
166+
img: EntityImages.imageForItem('equipment')
161167
})
162168
}
163169
notes = notes + '<br/>'
@@ -184,6 +190,7 @@ function _parseJSONPCs (pcObject) {
184190
notes = notes + spell.level + ') ' + spell.name + '<br/>'
185191
pc.items.push({
186192
name: spell.name,
193+
img: EntityImages.imageForItem('spell'),
187194
type: 'spell',
188195
data: {
189196
level: spell.level,
@@ -422,6 +429,7 @@ function _parseWeapon (weaponString) {
422429
const name = weaponData[1].replace(/\s+melee/, '').replace(/\s+ranged/, '')
423430
return {
424431
name: name,
432+
img: 'systems/dcc/styles/images/weapon.webp',
425433
attackMod: weaponData[2],
426434
attackDamage: damage,
427435
melee: melee
@@ -438,6 +446,7 @@ function _parseArmor (armorString) {
438446
return {
439447
name: armorFields[1],
440448
type: 'armor',
449+
img: EntityImages.imageForItem('armor'),
441450
data: {
442451
acBonus: armorFields[2],
443452
checkPenalty: armorFields[3],
@@ -458,6 +467,7 @@ function _parseStartingFunds (startingFundsString) {
458467
return {
459468
name: 'Coins',
460469
type: 'treasure',
470+
img: EntityImages.imageForItem('treasure'),
461471
data: {
462472
value: {
463473
pp,

styles/images/actor.webp

3.53 KB
Loading

styles/images/armor.webp

2.46 KB
Loading

styles/images/coins.webp

2.7 KB
Loading

styles/images/item.webp

2.01 KB
Loading

0 commit comments

Comments
 (0)