Skip to content

Commit f63aec5

Browse files
authored
Merge pull request #1023 from ben/ben/moves-from-index
Indexed moves
2 parents b5268a2 + fbb2a18 commit f63aec5

File tree

10 files changed

+161
-70
lines changed

10 files changed

+161
-70
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Next Release
44

5+
- Brought back support for the "Custom Moves" folder ([#1023](https://github.com/ben/foundry-ironsworn/pull/1023))
6+
57
## 1.24.0
68

79
This is a major update that includes Sundered Isles content, but also brings along a host of changes:

src/module/datasworn2/finding.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,13 @@ interface PackAndIndex {
6262

6363
export async function getPackAndIndexForCompendiumKey(
6464
ruleset: DataswornRulesetKey,
65-
type: keyof typeof COMPENDIUM_KEY_MAP
65+
type: keyof typeof COMPENDIUM_KEY_MAP,
66+
additionalFields?: string[]
6667
): Promise<PackAndIndex> {
6768
const pack = game.packs.get(COMPENDIUM_KEY_MAP[type][ruleset])
68-
const index = await pack?.getIndex({ fields: ['flags'] })
69+
const index = await pack?.getIndex({
70+
fields: ['flags', ...((additionalFields ?? []) as any[])]
71+
})
6972
return { pack, index }
7073
}
7174

src/module/features/custommoves.ts

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import {
55
} from '../datasworn2'
66
import { DataswornRulesetKey, IronswornSettings } from '../helpers/settings'
77
import type { Move, MoveCategory } from '@datasworn/core/dist/Datasworn'
8+
import { moveTriggerIsRollable } from '../rolls/preroll-dialog'
9+
import { compact } from 'lodash-es'
10+
import { IronswornItem } from '../item/item'
11+
import { SFMoveModel } from '../item/subtypes/sfmove'
812

913
interface DisplayMoveRuleset {
1014
displayName: string
@@ -22,14 +26,20 @@ export interface DisplayMove {
2226
color: string | null
2327
displayName: string
2428
uuid: string
29+
triggerText?: string
30+
isRollable: boolean
31+
oracles: string[]
2532
ds?: Move
2633
}
2734

2835
const INDEXES: Record<string, any> = {}
2936
async function ensureIndex(rsKey: DataswornRulesetKey) {
3037
const compendiumKey = COMPENDIUM_KEY_MAP.move[rsKey]
3138
if (INDEXES[compendiumKey] == null) {
32-
const { index } = await getPackAndIndexForCompendiumKey(rsKey, 'move')
39+
const { index } = await getPackAndIndexForCompendiumKey(rsKey, 'move', [
40+
'system.Trigger',
41+
'system.dsOracleIds'
42+
])
3343
INDEXES[compendiumKey] = index
3444
}
3545
}
@@ -55,19 +65,58 @@ export async function createMoveTreeForRuleset(
5565
color: move.color ?? null,
5666
displayName: move.name,
5767
uuid: indexEntry.uuid, // TODO: move.uuid
68+
triggerText: indexEntry.system?.Trigger?.Text,
69+
isRollable: moveTriggerIsRollable(indexEntry?.system?.Trigger),
70+
oracles: indexEntry.system?.dsOracleIds ?? [],
5871
ds: move
5972
}
6073
})
6174
}))
6275
}
6376
}
6477

78+
function customFolderMoveCategory(): DisplayMoveRuleset | undefined {
79+
const name = game.i18n.localize('IRONSWORN.MOVES.Custom Moves')
80+
const rootFolder = game.items?.directory?.folders.find((x) => x.name === name)
81+
if (!rootFolder) return undefined
82+
83+
const category: DisplayMoveCategory = {
84+
displayName: name,
85+
color: (rootFolder as any).color?.css ?? null,
86+
moves: []
87+
}
88+
89+
for (const item of rootFolder.contents) {
90+
if (!(item instanceof IronswornItem)) continue
91+
if (item.type !== 'sfmove') continue
92+
const system = item.system as SFMoveModel
93+
94+
category.moves.push({
95+
displayName: item.name ?? '(unnamed)',
96+
uuid: item.uuid,
97+
color: null,
98+
isRollable: moveTriggerIsRollable(system.Trigger),
99+
oracles: system.dsOracleIds ?? [],
100+
triggerText: system.Trigger?.Text
101+
})
102+
}
103+
if (category.moves.length === 0) return undefined
104+
105+
return {
106+
displayName: name,
107+
categories: [category]
108+
}
109+
}
110+
65111
export async function createMergedMoveTree(): Promise<DisplayMoveRuleset[]> {
66112
// Pre-load compendium indexes
67113
await Promise.all(IronswornSettings.enabledRulesets.map(ensureIndex))
68-
return await Promise.all(
69-
IronswornSettings.enabledRulesets.map(createMoveTreeForRuleset)
70-
)
114+
return compact([
115+
...(await Promise.all(
116+
IronswornSettings.enabledRulesets.map(createMoveTreeForRuleset)
117+
)),
118+
customFolderMoveCategory()
119+
])
71120
}
72121

73122
// TODO dataforged has a key for move colours...., but they appear to have changed significantly since the last time i updated them! they'll be fixed for 2.0, but until then, here's a workaround.

src/module/rolls/preroll-dialog.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,8 @@ function rollableOptions(trigger: SFMoveTrigger) {
5858
)
5959
}
6060

61-
export function moveHasRollableOptions(move: IronswornItem<'sfmove'>) {
62-
if (!move.assert('sfmove')) return false
63-
const options = rollableOptions(move.system.Trigger)
64-
return options.length > 0
61+
export function moveTriggerIsRollable(trigger?: SFMoveTrigger) : boolean {
62+
return !!trigger && rollableOptions(trigger).length > 0
6563
}
6664

6765
export function getStatData(

src/module/vue/components/buttons/btn-sendmovetochat.vue

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,22 @@
1313
</template>
1414

1515
<script setup lang="ts">
16-
import { inject } from 'vue'
1716
import { createSfMoveChatMessage } from '../../../chat/sf-move-chat-message'
1817
import type { DisplayMove } from '../../../features/custommoves'
19-
import { $ItemKey } from '../../provisions.js'
2018
import IronBtn from './iron-btn.vue'
19+
import { IronswornItem } from '../../../item/item'
2120
2221
interface Props
2322
extends /* @vue-ignore */ Omit<PropsOf<typeof IronBtn>, 'tooltip'> {
2423
move: DisplayMove
2524
}
2625
27-
defineProps<Props>()
26+
const props = defineProps<Props>()
2827
29-
const $item = inject($ItemKey)
30-
31-
function sendToChat(e) {
32-
if ($item) createSfMoveChatMessage($item)
28+
async function sendToChat(e) {
29+
const foundryMove = (await fromUuid(
30+
props.move.uuid
31+
)) as IronswornItem<'sfmove'>
32+
if (foundryMove) createSfMoveChatMessage(foundryMove)
3333
}
3434
</script>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<template>
2+
<RulesTextMove
3+
:data="moveObj"
4+
:is-progress-move="foundryMove.system.isProgressMove"
5+
:class="$style.summary"
6+
>
7+
<template #after-footer>
8+
<OracleTreeNode
9+
v-for="node of oracleNodes"
10+
:key="node.displayName"
11+
:class="$style.oracle"
12+
:node="node"
13+
/>
14+
</template>
15+
</RulesTextMove>
16+
</template>
17+
18+
<script setup lang="ts">
19+
import { ref, provide } from 'vue'
20+
import { uniq, compact } from 'lodash-es'
21+
import { IronswornItem } from '../../../item/item'
22+
import { OracleTable } from '../../../roll-table/oracle-table'
23+
import { ItemKey, $ItemKey } from '../../provisions.js'
24+
import type { DisplayMove } from '../../../features/custommoves'
25+
import type { IOracleTreeNode } from '../../../features/customoracles'
26+
27+
import RulesTextMove from '../rules-text/rules-text-move.vue'
28+
import OracleTreeNode from '../oracle-tree-node.vue'
29+
30+
const props = defineProps<{
31+
move: DisplayMove
32+
}>()
33+
34+
const foundryMove = (await fromUuid(props.move.uuid)) as IronswornItem<'sfmove'>
35+
const moveObj = ref(foundryMove.toObject())
36+
provide(ItemKey, moveObj as any)
37+
provide($ItemKey, foundryMove)
38+
39+
const oracleDsIds = uniq([
40+
...(foundryMove?.system?.dsOracleIds ?? []),
41+
...Object.values(props.move.ds?.oracles ?? {}).map((x) => x._id)
42+
])
43+
const oracleNodes: IOracleTreeNode[] = await Promise.all(
44+
oracleDsIds.map(async (oid) => {
45+
const t = await OracleTable.getByDsId(oid)
46+
return {
47+
displayName: t?.name ?? '(missing)',
48+
tables: compact([t?.uuid]),
49+
children: []
50+
}
51+
})
52+
)
53+
</script>
54+
55+
<style lang="scss" module>
56+
.oracle {
57+
border-width: var(--ironsworn-border-width-md);
58+
border-style: solid;
59+
border-radius: var(--ironsworn-border-radius-sm);
60+
border-color: var(--ironsworn-color-border);
61+
padding: 0;
62+
63+
h4 {
64+
font-size: var(--font-size-16);
65+
66+
button.icon-button {
67+
height: inherit;
68+
}
69+
}
70+
}
71+
</style>

src/module/vue/components/sf-moverow.vue renamed to src/module/vue/components/move/sf-moverow.vue

Lines changed: 18 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
class="movesheet-row"
66
:class="$style.wrapper"
77
data-tooltip-direction="LEFT"
8-
:base-id="`move_row_${item._id}`"
8+
:base-id="`move_row_${move.uuid}`"
99
:content-wrapper-class="$style.contentWrapper"
1010
:toggle-wrapper-is="`h${headingLevel}`"
1111
:toggle-section-class="[$style.toggleSection, toggleSectionClass]"
@@ -15,8 +15,7 @@
1515
:toggle-wrapper-class="$style.toggleWrapper"
1616
:toggle-label="move?.displayName"
1717
:data-highlighted="dataHighlight"
18-
:data-move-id="item._id"
19-
:data-move-uuid="$item.uuid"
18+
:data-move-uuid="move.uuid"
2019
>
2120
<template #after-toggle>
2221
<section
@@ -28,10 +27,10 @@
2827
<slot name="controls">
2928
<slot
3029
name="btn-roll-move"
31-
v-bind="{ disabled: !canRoll, move, class: $style.btn }"
30+
v-bind="{ disabled: !move.isRollable, move, class: $style.btn }"
3231
>
3332
<BtnRollmove
34-
:disabled="!canRoll"
33+
:disabled="!move.isRollable"
3534
:move="move"
3635
:class="$style.btn"
3736
/>
@@ -57,40 +56,23 @@
5756
</section>
5857
</template>
5958
<template #default>
60-
<RulesTextMove
61-
:data="item"
62-
:is-progress-move="$item.system.isProgressMove"
63-
:class="$style.summary"
64-
>
65-
<template #after-footer>
66-
<OracleTreeNode
67-
v-for="node of oracleNodes"
68-
:key="node.displayName"
69-
:class="$style.oracle"
70-
:node="node"
71-
/>
72-
</template>
73-
</RulesTextMove>
59+
<MoveContent :move="move" />
7460
</template>
7561
</Collapsible>
7662
</template>
7763

7864
<script setup lang="ts">
79-
import { computed, onMounted, provide, ref, watch } from 'vue'
80-
import type { DisplayMove } from '../../features/custommoves'
81-
import type { IOracleTreeNode } from '../../features/customoracles'
82-
import type { IronswornItem } from '../../item/item'
83-
import { moveHasRollableOptions } from '../../rolls/preroll-dialog'
84-
import BtnRollmove from './buttons/btn-rollmove.vue'
85-
import BtnSendmovetochat from './buttons/btn-sendmovetochat.vue'
86-
import OracleTreeNode from './oracle-tree-node.vue'
87-
import RulesTextMove from './rules-text/rules-text-move.vue'
88-
import Collapsible from './collapsible/collapsible.vue'
89-
import BtnOracle from './buttons/btn-oracle.vue'
90-
import { ItemKey, $ItemKey } from '../provisions.js'
91-
import { enrichMarkdown } from '../vue-plugin.js'
92-
import { compact, uniq } from 'lodash-es'
93-
import { OracleTable } from '../../roll-table/oracle-table'
65+
import { computed, onMounted, ref, watch } from 'vue'
66+
import type { DisplayMove } from '../../../features/custommoves'
67+
import type { IOracleTreeNode } from '../../../features/customoracles'
68+
import { compact } from 'lodash-es'
69+
import { OracleTable } from '../../../roll-table/oracle-table'
70+
71+
import BtnRollmove from '../buttons/btn-rollmove.vue'
72+
import BtnSendmovetochat from '../buttons/btn-sendmovetochat.vue'
73+
import Collapsible from '../collapsible/collapsible.vue'
74+
import BtnOracle from '../buttons/btn-oracle.vue'
75+
import MoveContent from './move-content.vue'
9476
9577
const props = withDefaults(
9678
defineProps<{
@@ -125,20 +107,10 @@ const props = withDefaults(
125107
}
126108
)
127109
128-
const $item = (await fromUuid(props.move.uuid)) as IronswornItem<'sfmove'>
129-
const item = ref($item.toObject())
130-
131-
provide(ItemKey, item as any)
132-
provide($ItemKey, $item)
133-
134110
const $collapsible = ref<typeof Collapsible>()
135111
136-
const oracleDsIds = uniq([
137-
...($item?.system?.dsOracleIds ?? []),
138-
...Object.values(props.move.ds?.oracles ?? {}).map((x) => x._id)
139-
])
140112
const oracleNodes: IOracleTreeNode[] = await Promise.all(
141-
oracleDsIds.map(async (oid) => {
113+
props.move.oracles.map(async (oid) => {
142114
const t = await OracleTable.getByDsId(oid)
143115
return {
144116
displayName: t?.name ?? '(missing)',
@@ -148,15 +120,11 @@ const oracleNodes: IOracleTreeNode[] = await Promise.all(
148120
})
149121
)
150122
151-
const canRoll = computed(() => {
152-
return moveHasRollableOptions($item)
153-
})
154123
const preventOracle = computed(() => {
155124
return oracleNodes.length !== 1
156125
})
157126
158-
const toggleTooltip = ref($item.system.Trigger?.Text)
159-
enrichMarkdown(toggleTooltip.value).then((x) => (toggleTooltip.value = x))
127+
const toggleTooltip = props.move.triggerText
160128
161129
const dataHighlight = ref(false)
162130
async function flashHighlight() {

src/module/vue/components/sf-move-category-rows.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<script setup lang="ts">
4040
import { computed, ref } from 'vue'
4141
import type { DisplayMoveCategory } from '../../features/custommoves.js'
42-
import SfMoverow from './sf-moverow.vue'
42+
import SfMoverow from './move/sf-moverow.vue'
4343
import Collapsible from './collapsible/collapsible.vue'
4444
import { snakeCase } from 'lodash-es'
4545
import { enrichMarkdown } from '../vue-plugin'

src/module/vue/components/sf-movesheetmoves.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ import { computed, nextTick, provide, reactive, ref } from 'vue'
6060
import type { DisplayMoveCategory } from '../../features/custommoves'
6161
import { createMergedMoveTree } from '../../features/custommoves'
6262
import SfMoveCategoryRows from './sf-move-category-rows.vue'
63-
import SfMoverow from './sf-moverow.vue'
63+
import SfMoverow from './move/sf-moverow.vue'
6464
import IronBtn from './buttons/iron-btn.vue'
6565
6666
const state = reactive({

src/module/vue/components/site/site-moves.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ import { $ActorKey, ActorKey } from '../../provisions'
8383
import BtnOracle from '../buttons/btn-oracle.vue'
8484
import BtnRollmove from '../buttons/btn-rollmove.vue'
8585
86-
import SfMoverow from '../sf-moverow.vue'
86+
import SfMoverow from '../move/sf-moverow.vue'
8787
8888
const site = inject(ActorKey) as Ref<ActorSource<'site'>>
8989
const $site = inject($ActorKey) as IronswornActor<'site'>

0 commit comments

Comments
 (0)