Skip to content

Commit

Permalink
Merge pull request #134 from ebshimizu/mm2024
Browse files Browse the repository at this point in the history
2024 Stat Block Update
  • Loading branch information
ebshimizu authored Dec 21, 2024
2 parents e499caa + 2cc27d5 commit e3b8de5
Show file tree
Hide file tree
Showing 26 changed files with 1,445 additions and 631 deletions.
560 changes: 11 additions & 549 deletions package-lock.json

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "5e-monster-maker",
"version": "2.2.11",
"version": "2.3.0",
"description": "A monster builder and generator for 5th Edition Dungeons and Dragons. Effortlessly create a monster with tools for automatically computing CR, formatting a statblock, and managing your monster actions and traits.",
"productName": "Falindrith's D&D Monster Maker",
"author": "Evan Shimizu <ebshimizu@gmail.com>",
Expand All @@ -11,19 +11,19 @@
"test": "echo \"No test specified\" && exit 0"
},
"dependencies": {
"@quasar/extras": "^1.15.11",
"@quasar/extras": "^1.16.12",
"@vueuse/core": "^8.6.0",
"copy-to-clipboard": "^3.3.2",
"core-js": "^3.6.5",
"fs-extra": "^10.1.0",
"html-to-image": "^1.11.11",
"dom-to-image-more": "^3.5.0",
"json-url": "^3.0.0",
"jsonschema": "^1.4.1",
"lodash": "^4.17.21",
"number-to-words": "^1.2.4",
"pinia": "^2.0.11",
"pinia-plugin-persistedstate": "^3.0.0",
"quasar": "^2.11.8",
"quasar": "^2.16.11",
"slugify": "^1.6.5",
"url": "^0.11.0",
"uuid": "^8.3.2",
Expand All @@ -33,7 +33,7 @@
},
"devDependencies": {
"@intlify/vite-plugin-vue-i18n": "^3.3.1",
"@quasar/app-vite": "^1.2.1",
"@quasar/app-vite": "^1.9.5",
"@types/dom-to-image": "^2.6.4",
"@types/lodash": "^4.14.182",
"@types/node": "^12.20.21",
Expand All @@ -51,8 +51,9 @@
"typescript": "^4.5.4"
},
"engines": {
"node": "^20 || ^18",
"node": "^22 || ^20 || ^18",
"npm": ">= 6.13.4",
"yarn": ">= 1.21.1"
}
},
"packageManager": "pnpm@9.12.3+sha512.cce0f9de9c5a7c95bef944169cc5dfe8741abfb145078c0d508b868056848a87c81e626246cb60967cbd7fd29a6c062ef73ff840d96b3c86c40ac92cf4a813ee"
}
16 changes: 9 additions & 7 deletions src/components/AppDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@
<q-card-section class="scroll">
<q-markup-table>
<thead>
<th>{{ $t('monster.cr') }}</th>
<th>{{ $t('editor.cr.prof') }}</th>
<th>{{ $t('editor.cr.ac') }}</th>
<th>{{ $t('editor.cr.hp') }}</th>
<th>{{ $t('editor.cr.attack') }}</th>
<th>{{ $t('editor.cr.damage') }}</th>
<th>{{ $t('editor.cr.save') }}</th>
<tr>
<th>{{ $t('monster.cr') }}</th>
<th>{{ $t('editor.cr.prof') }}</th>
<th>{{ $t('editor.cr.ac') }}</th>
<th>{{ $t('editor.cr.hp') }}</th>
<th>{{ $t('editor.cr.attack') }}</th>
<th>{{ $t('editor.cr.damage') }}</th>
<th>{{ $t('editor.cr.save') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="(cr, idx) in crData" :key="cr.numeric">
Expand Down
63 changes: 63 additions & 0 deletions src/components/ChangelogContent.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,68 @@
<template>
<q-timeline color="secondary">
<q-timeline-entry
title="v2.3.0"
subtitle="Major Update - 12/20/2023"
icon="update"
color="positive"
>
<div class="text-body1 q-mb-sm">
This update is a bit in advance of the full 2024 Monster Manual release,
and lays the foundation for anticipated stat block updates in the 2024
rules. These updates are based on changes observed in the 2024 Player's
Handbook. I anticipate a (hopefully) small update once the full Monster
Manual is released to catch the remainder of the formatting updates,
probably as they relate to Legendary Actions.
</div>
<q-separator class="q-my-sm" />
<div class="text-overline text-uppercase q-mb-sm">New Features</div>
<div class="text-body2">
<ul>
<li>
<github-issue-link :issue="128" /> The web renderer stat block can
now toggle between the 2014 stat block style and the new 2024 stat
block style. New data fields have been added to the monster stat
block format to accommodate the new style. The data fields are fully
backwards compatible.
</li>
<li>
<github-issue-link :issue="131" />Actions that utilize saving throws
have been overhauled in the 2024 format. Save-based actions can now
indicate the stat used for the DC (with an optional override), the
range of the action, and can now explicitly list out the results for
succeeding, failing, or satisfying some other more complex condition
on the save (e.g. failing by more than 5). The stat block renderer
will format this for you. If you do not wish to use this new
formatting, just leave the save stat as 'none'. This formatting can
be used in both 2014 and 2024 styles.
</li>
<li>
<github-issue-link :issue="132" /> Reactions now have an explicit
"Trigger" and a "Response." They can also now have limited uses
(like normal actions). This formatting will only appear if the
"Trigger" field has text in it, so to keep using the 2014
formatting, leave that field blank. This formatting can be used in
both 2014 and 2024 styles.
</li>
<li>
<github-issue-link :issue="130" /> The 2024 style for the stat block
has been added. Toggle between 2024 and 2014 styles with the
settings menu (gear icon, top right). The 2024 style primarily
affects the header, which has a new table for displaying stats and
saves, and removes some of the dividers in there. Exports to other
formats (markdown, LaTeX) should function as they did before.
</li>
<li>
Added Initiative as a skill. Due to the 2024 stat block explicitly
showing Initiative in the top right of the stat block, Initiative is
now a skill you can add, give proficiency for, and override as with
any other skill. In the 2014 stat block, this will appear in the
Skills section. In the 2024 stat block, this will be omitted from
the Skills section, as it has its own dedicated location.
</li>
</ul>
</div>
</q-timeline-entry>
<q-timeline-entry
title="v2.2.11"
subtitle="Bugfix - 12/19/2024"
Expand Down
2 changes: 1 addition & 1 deletion src/components/GenericFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ import { useEditorStore } from 'src/stores/editor-store'
// TODO: don't forget to change the target changelog when the app has an update
// that should trigger a notice
const TARGET_CHANGELOG = 'v2.2.0'
const TARGET_CHANGELOG = 'v2.3.0'
export default defineComponent({
name: 'GenericFooter',
Expand Down
188 changes: 185 additions & 3 deletions src/components/editor/ActionsEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,176 @@
:label="$t('monster.trait.limitedUse.rate')"
class="col-4 q-pa-sm"
/>
<q-select
v-model="action.stat"
:options="statOptions"
:label="$t('monster.action.savingThrowStat')"
class="col-2 q-pa-sm"
@update:model-value="(stat: string) => {
action.stat = stat as DndStat | 'none'
autoUpdateCr(action.description, action.crAnnotation, action)
}"
/>
<q-input
:model-value="saveThrowValueForAction(action)"
:label="$t('monster.action.saveDc')"
type="number"
:disable="!action.save.override"
class="col-2 q-pa-sm"
@update:model-value="(v: string | number | null) => {
action.save.overrideValue = parseInt(`${v}`)
autoUpdateCr(action.description, action.crAnnotation, action)
}"
>
<template #after>
<lock-toggle-button
:locked="!action.save.override"
:lock-tooltip="$t('monster.action.lockSave')"
:unlock-tooltip="$t('monster.action.unlockSave')"
@click="
() => {
action.save.override = !action.save.override
autoUpdateCr(
action.description,
action.crAnnotation,
action
)
}
"
/>
</template>
</q-input>
<q-input
v-model="action.range"
class="col-8 q-pa-sm"
:label="$t('monster.action.range')"
>
<template #after>
<q-btn-dropdown
:label="$t('editor.action.addEffect')"
color="green"
:disable="action.stat === 'none'"
>
<q-list>
<q-item
v-close-popup
clickable
@click="
action.effects.push({
case: $t('editor.action.effectCase.failure'),
effect: '',
})
"
>
<q-item-section>
<q-item-label>{{
$t('editor.action.effectCase.failure')
}}</q-item-label>
</q-item-section>
</q-item>
<q-item
v-close-popup
clickable
@click="
action.effects.push({
case: $t('editor.action.effectCase.failByFive'),
effect: '',
})
"
>
<q-item-section>
<q-item-label>{{
$t('editor.action.effectCase.failByFive')
}}</q-item-label>
</q-item-section>
</q-item>
<q-item
v-close-popup
clickable
@click="
action.effects.push({
case: $t('editor.action.effectCase.success'),
effect: $t(
'editor.action.effectTemplate.halfDamage'
),
})
"
>
<q-item-section>
<q-item-label
>{{ $t('editor.action.effectCase.success') }}:
{{
$t('editor.action.effectTemplate.halfDamage')
}}</q-item-label
>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</template>
</q-input>
<q-card
v-if="action.stat !== 'none'"
bordered
class="row q-ma-sm full-width"
>
<q-card-section class="bg-orange-10 full-width">
<div class="text-overline text-uppercase">
{{ $t('editor.action.saveDescription') }}
</div>
<div class="text-caption">
{{ $t('editor.action.saveHelp') }}
</div>
</q-card-section>
<q-card-section class="row full-width">
<template
v-for="(effect, idx) of action.effects"

Check warning on line 223 in src/components/editor/ActionsEditor.vue

View workflow job for this annotation

GitHub Actions / build

Variable 'idx' is already declared in the upper scope
:key="idx"
>
<q-input
v-model="effect.case"
:label="$t('editor.action.condition')"
class="col-3 q-pa-sm"
/>
<q-input
v-model="effect.effect"
:label="$t('editor.action.effect')"
class="col-9 q-pa-sm"
@update:model-value="(value: string | number | null) => {
effect.effect = `${value}`
autoUpdateCr(action.description, action.crAnnotation, action)
}"
>
<template #after>
<q-btn
round
color="negative"
icon="delete"
class="q-mx-sm"
@click="
() => {
action.effects.splice(idx, 1)
autoUpdateCr(
action.description,
action.crAnnotation,
action
)
}
"
/>
</template>
</q-input>
</template>
</q-card-section>
</q-card>
<monster-text-editor
:field="action.description"
i18n-label-key="monster.trait.description"
token-category="action"
@update:model-value="
(value: string) => {
action.description = value
autoUpdateCr(action.description, action.crAnnotation)
autoUpdateCr(action.description, action.crAnnotation, action)
}
"
/>
Expand Down Expand Up @@ -143,18 +305,26 @@ import MonsterTextEditor from './MonsterTextEditor.vue'
import { useAutoUpdateCr } from './useAutoUpdateCr'
import CrAnnotationCard from './CrAnnotationCard.vue'
import { useQuasar } from 'quasar'
import { MonsterAction } from '../models'
import { DndStat, MonsterAction } from '../models'

Check warning on line 308 in src/components/editor/ActionsEditor.vue

View workflow job for this annotation

GitHub Actions / build

'DndStat' is defined but never used
import NewTemplateDialog from './widgets/NewTemplateDialog.vue'
import { useTemplatesStore } from 'src/stores/templates-store'
import { useI18n } from 'vue-i18n'
import { validateNumber } from './numberInput'
import SwapButtons from './widgets/SwapButtons.vue'
import { useStats } from 'src/data/STAT'
import LockToggleButton from '../LockToggleButton.vue'
export default defineComponent({
name: 'ActionsEditor',
components: { MonsterTextEditor, CrAnnotationCard, SwapButtons },
components: {
MonsterTextEditor,
CrAnnotationCard,
SwapButtons,
LockToggleButton,
},
setup() {
const monster = useMonsterStore()
const { statOptionsShort } = useStats()
const { rechargeTimeOptions } = useRechargeTimes()
const { autoUpdateCr, printCrSummary } = useAutoUpdateCr()
const $q = useQuasar()
Expand All @@ -177,14 +347,26 @@ export default defineComponent({
})
}
const saveThrowValueForAction = (action: MonsterAction) => {
if (action.stat !== 'none') {
return action.save.override
? action.save.overrideValue
: monster.defaultSpellSave(action.stat)
}
return 0
}
return {
monster,
actions: computed(() => monster.actions),
rechargeTimeOptions,
autoUpdateCr,
printCrSummary,
addTemplate,
statOptions: ['none', ...statOptionsShort],
validateNumber: validateNumber,
saveThrowValueForAction,
}
},
})
Expand Down
Loading

0 comments on commit e3b8de5

Please sign in to comment.