Skip to content

Commit

Permalink
Merge pull request #55 from ben/ben/shared-sheet
Browse files Browse the repository at this point in the history
Shared sheet
  • Loading branch information
ben authored Jul 1, 2021
2 parents d043cb3 + 6594f83 commit 904f4a2
Show file tree
Hide file tree
Showing 12 changed files with 240 additions and 39 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## In progress

- Add a shared sheet ([#55](https://github.com/ben/foundry-ironsworn/pull/55))

## 0.4.7

- Fix the move sheet's description ([#54](https://github.com/ben/foundry-ironsworn/pull/54))
Expand Down
5 changes: 5 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { IRONSWORN } from './config'
import { IronswornActor } from './module/actor/actor'
import { IronswornCharacterSheet } from './module/actor/sheets/charactersheet'
import { IronswornCompactCharacterSheet } from './module/actor/sheets/compactsheet'
import { IronswornSharedSheet } from './module/actor/sheets/sharedsheet'
import { IronswornHandlebarsHelpers } from './module/helpers/handlebars'
import { IronswornSettings } from './module/helpers/settings'
import { TemplatePreloader } from './module/helpers/templatepreloader'
Expand Down Expand Up @@ -45,6 +46,10 @@ Hooks.once('init', async () => {
Actors.registerSheet('ironsworn', IronswornCompactCharacterSheet, {
types: ['character'],
})
Actors.registerSheet('ironsworn', IronswornSharedSheet, {
types: ['shared'],
makeDefault: true,
})

Items.registerSheet('ironsworn', AssetSheet, {
types: ['asset'],
Expand Down
22 changes: 6 additions & 16 deletions src/module/actor/actor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,19 @@ import { CharacterMoveSheet } from './sheets/charactermovesheet'
export class IronswornActor extends Actor<IronswornActorData, IronswornItem> {
moveSheet?: CharacterMoveSheet

/** @override */
getRollData() {
const data = super.getRollData()
return data
}

/** @override */
prepareDerivedData() {
// Calculate momentum max/reset from debilities
const data = this.data.data as any
const numDebilitiesMarked = Object.values(data.debility).filter((x) => x).length
data.momentumMax = 10 - numDebilitiesMarked
data.momentumReset = Math.max(0, 2 - numDebilitiesMarked)
}

async addDefaultItems() {
// Every character needs a bondset
await this.createOwnedItem({ type: 'bondset', name: 'bonds' })
if (this.data.type === 'character') {
const numDebilitiesMarked = Object.values(data.debility).filter((x) => x).length
data.momentumMax = 10 - numDebilitiesMarked
data.momentumReset = Math.max(0, 2 - numDebilitiesMarked)
}
}
}

Hooks.on('createActor', async (actor) => {
if (actor.data.type === 'character') {
await actor.addDefaultItems()
}
await actor.createOwnedItem({ type: 'bondset', name: 'bonds' })
})
3 changes: 3 additions & 0 deletions src/module/actor/sheets/charactersheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ export class IronswornCharacterSheet extends ActorSheet<ActorSheet.Data<Ironswor
if (resource !== 'momentum' || newValue <= momentumMax) {
this.actor.update({ data: { [resource]: newValue } })
}
if (resource === 'supply') {
IronswornSettings.maybeSetGlobalSupply(newValue)
}
}
}
}
3 changes: 3 additions & 0 deletions src/module/actor/sheets/compactsheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ export class IronswornCompactCharacterSheet extends ActorSheet<ActorSheet.Data<I
value += amt
if (value >= min && value <= max) {
this.actor.update({ data: { [stat]: value } })
if (stat === 'supply') {
IronswornSettings.maybeSetGlobalSupply(value)
}
}
}

Expand Down
79 changes: 79 additions & 0 deletions src/module/actor/sheets/sharedsheet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { IronswornRollDialog } from '../../helpers/roll'
import { IronswornSettings } from '../../helpers/settings'
import { IronswornActor } from '../actor'

export class IronswornSharedSheet extends ActorSheet<ActorSheet.Data<IronswornActor>, IronswornActor> {
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
classes: ['ironsworn', 'sheet', 'shared', `theme-${IronswornSettings.theme}`],
width: 350,
height: 700,
template: 'systems/foundry-ironsworn/templates/actor/shared.hbs',
} as BaseEntitySheet.Options)
}

activateListeners(html: JQuery) {
super.activateListeners(html)

html.find('.ironsworn__supply__roll').on('click', (e) => this._onSupplyRoll.call(this, e))
html.find('.ironsworn__supply__value').on('click', (e) => this._onSupplySet.call(this, e))

// Custom sheet listeners for every ItemType
for (const itemClass of CONFIG.IRONSWORN.itemClasses) {
itemClass.activateActorSheetListeners(html, this)
}
}

getData() {
let data: any = super.getData()

data.vows = this.actor.items.filter((x) => x.type === 'vow')
data.progresses = this.actor.items.filter((x) => x.type === 'progress')
data.bonds = this.actor.items.find((x) => x.type === 'bondset')

// Allow every itemtype to add data to the actorsheet
for (const itemType of CONFIG.IRONSWORN.itemClasses) {
data = itemType.getActorSheetData(data, this)
}

return data
}

_getHeaderButtons() {
return [
{
class: 'ironsworn-toggle-edit-mode',
label: 'Edit',
icon: 'fas fa-edit',
onclick: (e) => this._toggleEditMode(e),
},
...super._getHeaderButtons(),
]
}

_toggleEditMode(e: JQuery.ClickEvent) {
e.preventDefault()

const currentValue = this.actor.getFlag('foundry-ironsworn', 'edit-mode')
this.actor.setFlag('foundry-ironsworn', 'edit-mode', !currentValue)
}

_onSupplyRoll(ev: JQuery.ClickEvent) {
ev.preventDefault()

const rollText = game.i18n.localize('IRONSWORN.Roll')
const statText = game.i18n.localize('IRONSWORN.Supply')
IronswornRollDialog.showDialog(this.actor.data.data, 'supply', `${rollText} +${statText}`)
}

_onSupplySet(ev: JQuery.ClickEvent) {
ev.preventDefault()

const el = ev.currentTarget
const { value } = el.dataset
// Clicked a value in momentum/health/etc, set the value
const newValue = parseInt(value)
this.actor.update({ data: { supply: newValue } })
IronswornSettings.maybeSetGlobalSupply(newValue)
}
}
19 changes: 19 additions & 0 deletions src/module/helpers/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,28 @@ export class IronswornSettings {
window.location.reload()
},
})

game.settings.register('foundry-ironsworn', 'shared-supply', {
name: 'IRONSWORN.Settings.SharedSupply.Name',
hint: 'IRONSWORN.Settings.SharedSupply.Hint',
scope: 'world',
config: true,
type: Boolean,
default: true,
})
}

static get theme(): string {
return game.settings.get('foundry-ironsworn', 'theme') as string
}

static async maybeSetGlobalSupply(value: number) {
if (!game.settings.get('foundry-ironsworn', 'shared-supply')) return

// TODO: use game.actors.contents instead when types update
const actorsToUpdate = game.actors?.entities?.filter((x) => ['character', 'shared'].includes(x.data.type)) || []
for (const actor of actorsToUpdate) {
await actor.update({ data: { supply: value } })
}
}
}
44 changes: 23 additions & 21 deletions src/styles/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -257,33 +257,35 @@
}

.compact {
h3, h4, h5 {
h3,
h4,
h5 {
margin: 3px 0;
}
}

.boxgroup {
border: 1px solid;
border-radius: 5px;
.boxgroup {
border: 1px solid;
border-radius: 5px;

.boxrow {
border-top: 1px solid;
&:first-child {
border-top: none;
}

&.small {
flex-basis: 25px;
line-height: 25px;
flex-grow: 0;
}
.boxrow {
border-top: 1px solid;
&:first-child {
border-top: none;
}

.box {
text-align: center;
border-left: 1px solid;
&:first-child {
border-left: none;
}
&.small {
flex-basis: 25px;
line-height: 25px;
flex-grow: 0;
}
}

.box {
text-align: center;
border-left: 1px solid;
&:first-child {
border-left: none;
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions system/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,10 @@
"Hint": "Select the visual look for this game. Requires a reload.",
"Ironsworn": "Ironsworn Classic",
"Starforged": "Starforged (experimental)"
},
"SharedSupply": {
"Name": "Shared Supply Tracker",
"Hint": "If on, changing any character/shared supply tracker changes all other actors' supply trackers as well."
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion system/template.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
},
"xp": 0
},
"shared": {}
"shared": {
"supply": 5
}
},
"Item": {
"types": [
Expand Down
2 changes: 1 addition & 1 deletion system/templates/actor/character.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@
<div class="block clickable ironsworn__vow__add">
<i class="fas fa-plus"></i>
</div>

</section>

<section class="sheet-area progresses">
<h2 style="text-align:center">{{localize 'IRONSWORN.Progress'}}</h2>
{{#each progresses}}
Expand Down
92 changes: 92 additions & 0 deletions system/templates/actor/shared.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{{#*inline "progress"}}
<div class="flexcol item-row" data-id="{{id}}">
<div class="flexcol">
<div class="flexrow">
<div class="flexrow">{{>rankHexes rank=data.data.rank id=id}}</div>

{{#if actor.data.flags.foundry-ironsworn.edit-mode}}
<div class="clickable block nogrow ironsworn__{{type}}__delete" data-item="{{id}}">
<i class="fas fa-trash"></i>
</div>
{{/if}}

<div class="clickable block nogrow ironsworn__{{type}}__settings" data-item="{{id}}">
<i class="fas fa-edit"></i>
</div>
<div class="clickable block nogrow ironsworn__progress__mark" {{! This works for vows too }}
title="{{localize 'IRONSWORN.MarkProgress'}}" data-item="{{id}}">
<i class="fas fa-play"></i>
</div>
<div class="clickable block ironsworn__progress__fulfill" title="{{localize 'IRONSWORN.FulfillVow'}}"
style="flex-grow: 0;" data-item="{{id}}">
<i class="fas fa-check"></i>
</div>
</div>
<h3>{{name}}</h3>
</div>
<div class="flexrow">
<div class="flexrow track">
{{#each (progressCharacters data.data.current)}}
<div class="track-box">{{{this}}}</div>
{{/each}}
</div>
</div>
</div>
{{/inline}}

<form class="{{cssClass}} flexcol" autocomplete="off">

<section class="sheet-area" style="flex-grow: 0;">
<h2 class="clickable text ironsworn__supply__roll">
{{localize 'IRONSWORN.Supply'}}
</h2>
<div class="boxgroup" style="line-height: 25px;">
<div class="flexrow boxrow">
{{#rangeEach from=0 to=5 current=data.data.supply}}
<div class="
box clickable block ironsworn__supply__value
{{#if isCurrent}} selected {{/if}}
" data-value="{{value}}">
{{valueStr}}
</div>
{{/rangeEach}}
</div>
</div>
</section>

<section class="sheet-area" style="flex-grow: 0;">
<h2>{{localize 'IRONSWORN.Bonds'}}</h2>
<div class="flexrow">
<div class="flexrow track">
{{#each (progressCharacters bonds.count)}}
<div class="track-box">{{{this}}}</div>
{{/each}}
</div>
<div data-item="{{bonds.id}}" class="ironsworn__bondset__settings block clickable"
style="flex-grow: 0; padding: 5px; margin: 2px;">
<i class="fas fa-edit"></i>
</div>
</div>
</section>

<section class="sheet-area progresses">
<h2>{{localize 'IRONSWORN.Vows'}}</h2>
{{#each vows}}
{{>progress}}
{{/each}}
<div class="block clickable ironsworn__vow__add">
<i class="fas fa-plus"></i>
</div>
</section>

<section class="sheet-area progresses">
<h2>{{localize 'IRONSWORN.Progress'}}</h2>
{{#each progresses}}
{{>progress}}
{{/each}}
<div class="block clickable ironsworn__progress__add">
<i class="fas fa-plus"></i>
</div>
</section>

</form>

0 comments on commit 904f4a2

Please sign in to comment.