diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 1b58e35..e5413d7 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -42,7 +42,7 @@ module.exports = { { // Unique ID of current classification id: 'monster', - // Meta title for spell list page + // Meta title for monster list page title: 'Bestiaire', // Target directory dirname: 'bestiaire', diff --git a/docs/.vuepress/data/monsters.js b/docs/.vuepress/data/monsters.js index 819c55f..5469b92 100644 --- a/docs/.vuepress/data/monsters.js +++ b/docs/.vuepress/data/monsters.js @@ -25,40 +25,40 @@ export const MONSTERSIZES = [ ] export const CHALLENGES = [ - { label: "0", value:'0', xp: "0 ou 10" }, - { label: "1/8", value:'0.125', xp: 25 }, - { label: "1/4", value:'0.25', xp: 50 }, - { label: "1/2", value:'0.5', xp: 100 }, - { label: "1", value:'1', xp: 200 }, - { label: "2", value:'2', xp: 450 }, - { label: "3", value:'3', xp: 700 }, - { label: "4", value:'4', xp: 1100 }, - { label: "5", value:'5', xp: 1800 }, - { label: "6", value:'6', xp: 2300 }, - { label: "7", value:'7', xp: 2900 }, - { label: "8", value:'8', xp: 3900 }, - { label: "9", value:'9', xp: 5000 }, - { label: "10", value:'10', xp: 5900 }, - { label: "11", value:'11', xp: 7200 }, - { label: "12", value:'12', xp: 8400 }, - { label: "13", value:'13', xp: 10000 }, - { label: "14", value:'14', xp: 11500 }, - { label: "15", value:'15', xp: 13000 }, - { label: "16", value:'16', xp: 15000 }, - { label: "17", value:'17', xp: 18000 }, - { label: "18", value:'18', xp: 20000 }, - { label: "19", value:'19', xp: 22000 }, - { label: "20", value:'20', xp: 25000 }, - { label: "21", value:'21', xp: 33000 }, - { label: "22", value:'22', xp: 41000 }, - { label: "23", value:'23', xp: 50000 }, - { label: "24", value:'24', xp: 62000 }, - { label: "25", value:'25', xp: 75000 }, - { label: "26", value:'26', xp: 90000 }, - { label: "27", value:'27', xp: 105000 }, - { label: "28", value:'28', xp: 120000 }, - { label: "29", value:'29', xp: 135000 }, - { label: "30", value:'30', xp: 155000 }, + { label: "0", value:'0', xp: "0 ou 10", pc: 1 }, + { label: "1/8", value:'0.125', xp: 25, pc: 5 }, + { label: "1/4", value:'0.25', xp: 50, pc: 9 }, + { label: "1/2", value:'0.5', xp: 100, pc: 15 }, + { label: "1", value:'1', xp: 200, pc: 25 }, + { label: "2", value:'2', xp: 450, pc: 40 }, + { label: "3", value:'3', xp: 700, pc: 60 }, + { label: "4", value:'4', xp: 1100, pc: 85 }, + { label: "5", value:'5', xp: 1800, pc: 110 }, + { label: "6", value:'6', xp: 2300, pc: 135 }, + { label: "7", value:'7', xp: 2900, pc: 160 }, + { label: "8", value:'8', xp: 3900, pc: 185 }, + { label: "9", value:'9', xp: 5000, pc: 210 }, + { label: "10", value:'10', xp: 5900, pc: 230 }, + { label: "11", value:'11', xp: 7200, pc: 265 }, + { label: "12", value:'12', xp: 8400, pc: 300 }, + { label: "13", value:'13', xp: 10000, pc: 330 }, + { label: "14", value:'14', xp: 11500, pc: 370 }, + { label: "15", value:'15', xp: 13000, pc: 420 }, + { label: "16", value:'16', xp: 15000, pc: 475 }, + { label: "17", value:'17', xp: 18000, pc: 525 }, + { label: "18", value:'18', xp: 20000, pc: 620 }, + { label: "19", value:'19', xp: 22000, pc: 675 }, + { label: "20", value:'20', xp: 25000, pc: 770 }, + { label: "21", value:'21', xp: 33000, pc: 870 }, + { label: "22", value:'22', xp: 41000, pc: 995 }, + { label: "23", value:'23', xp: 50000, pc: 1100 }, + { label: "24", value:'24', xp: 62000, pc: 1240 }, + { label: "25", value:'25', xp: 75000, pc: 1450 }, + { label: "26", value:'26', xp: 90000, pc: 1700 }, + { label: "27", value:'27', xp: 105000, pc: 1950 }, + { label: "28", value:'28', xp: 120000, pc: 2200 }, + { label: "29", value:'29', xp: 135000, pc: 2450 }, + { label: "30", value:'30', xp: 155000, pc: 2700 }, ] export const ABILITIES = [ @@ -90,3 +90,26 @@ export const SKILLS = [ { label: "Supercherie", value:"supercherie", ability: "cha" }, { label: "Survie", value:"survie", ability: "sag" }, ] + +export const ENCOUNTERLEVELS = [ + { level: 1, easy: 15, normal: 25, hard: 33, deadly: 40}, + { level: 2, easy: 25, normal: 40, hard: 55, deadly: 70}, + { level: 3, easy: 32, normal: 60, hard: 80, deadly: 100}, + { level: 4, easy: 45, normal: 80, hard: 100, deadly: 120}, + { level: 5, easy: 70, normal: 120, hard: 160, deadly: 200}, + { level: 6, easy: 90, normal: 140, hard: 185, deadly: 230}, + { level: 7, easy: 105, normal: 160, hard: 210, deadly: 260}, + { level: 8, easy: 130, normal: 180, hard: 240, deadly: 300}, + { level: 9, easy: 135, normal: 200, hard: 265, deadly: 330}, + { level: 10, easy: 140, normal: 210, hard: 280, deadly: 350}, + { level: 11, easy: 160, normal: 240, hard: 350, deadly: 460}, + { level: 12, easy: 180, normal: 270, hard: 395, deadly: 520}, + { level: 13, easy: 200, normal: 310, hard: 465, deadly: 620}, + { level: 14, easy: 210, normal: 330, hard: 515, deadly: 700}, + { level: 15, easy: 225, normal: 360, hard: 565, deadly: 770}, + { level: 16, easy: 240, normal: 400, hard: 610, deadly: 820}, + { level: 17, easy: 285, normal: 480, hard: 695, deadly: 910}, + { level: 18, easy: 300, normal: 510, hard: 730, deadly: 950}, + { level: 19, easy: 330, normal: 600, hard: 800, deadly: 1000}, + { level: 20, easy: 370, normal: 700, hard: 900, deadly: 1100}, +] diff --git a/docs/.vuepress/store/index.js b/docs/.vuepress/store/index.js index e350488..4a793bd 100644 --- a/docs/.vuepress/store/index.js +++ b/docs/.vuepress/store/index.js @@ -9,6 +9,8 @@ import mySpells from './modules/mySpells' import myMonsters from './modules/myMonsters' import myMagicItems from './modules/myMagicItems' +import encounterCalculator from './modules/encounterCalculator' + Vue.use(Vuex) import Cookies from 'js-cookie' @@ -20,7 +22,8 @@ export default new Vuex.Store({ monsterFilters, mySpells, myMonsters, - myMagicItems + myMagicItems, + encounterCalculator, }, state: { diff --git a/docs/.vuepress/store/modules/encounterCalculator.js b/docs/.vuepress/store/modules/encounterCalculator.js new file mode 100644 index 0000000..cf83219 --- /dev/null +++ b/docs/.vuepress/store/modules/encounterCalculator.js @@ -0,0 +1,87 @@ +import {sortByString} from '@theme/util/filterHelpers' +import { getResourceIndexInLibrary } from '@theme/util' +import { ENCOUNTERLEVELS } from '../../data/monsters' +import { getPCbyChallenge } from '@theme/util/monsterHelpers' + +export default { + namespaced: true, + + state: { + creatures: [], + pc: 4, + level: ENCOUNTERLEVELS[0].level, + }, + + getters: { + creatures: state => state.creatures, + pc: state => state.pc, + level: state => state.level, + }, + + actions: { + reset: ({ commit }) => { + commit('resetCreatures') + }, + updateCreatures: ({ commit }, payload) => { + commit('setCreatures', payload) + }, + resetCreatures: ({ commit }) => { + commit('resetCreatures') + }, + addCreature: ({ commit }, payload) => { + commit('addCreature', payload) + }, + removeCreature: ({ commit }, payload) => { + commit('removeCreature', payload) + }, + setCreatureQty: ({ commit }, payload) => { + commit('setCreatureQty', payload) + }, + }, + + mutations: { + setCreatures: (state, payload) => { + state.creatures = payload + }, + resetCreatures: (state) => { + state.creatures = [] + }, + addCreature: (state, payload) => { + payload.qty = 1 + state.creatures.push(payload) + state.creatures.sort((a, b) => { return sortByString(a.title, b.title) }) + }, + updateCreatures: (state, payload) => { + let creatureIndex = getResourceIndexInLibrary(payload, state.creatures) + if (creatureIndex >= 0) { + state.creatures[creatureIndex] = payload + } + }, + removeCreature: (state, payload) => { + let creatureIndex = getResourceIndexInLibrary(payload, state.creatures) + if (creatureIndex >= 0) { + state.creatures.splice(creatureIndex, 1) + } + }, + setCreatureQty: (state, payload) => { + let creatureIndex = getResourceIndexInLibrary(payload.creature, state.creatures) + if (creatureIndex >= 0) { + if (Number(payload.qty) > 0) { + state.creatures[creatureIndex].qty = Number(payload.qty) + } else { + let creatureIndex = getResourceIndexInLibrary(payload.creature, state.creatures) + if (creatureIndex >= 0) { + state.creatures.splice(creatureIndex, 1) + } + } + } + }, + setPC: (state, payload) => { + state.pc = payload + }, + setLevel: (state, payload) => { + state.level = payload + }, + } + +} diff --git a/docs/.vuepress/theme/components/Breadcrumb.vue b/docs/.vuepress/theme/components/Breadcrumb.vue index 5457efb..6668624 100644 --- a/docs/.vuepress/theme/components/Breadcrumb.vue +++ b/docs/.vuepress/theme/components/Breadcrumb.vue @@ -57,6 +57,8 @@ crumbs.push({to: page.path, disabled: disabled, text: 'Création de monstre ou PNJ'}) } else if (page.path == '/calculateur-de-caracteristiques/') { crumbs.push({to: page.path, disabled: disabled, text: 'Calculateur de caractéristiques'}) + } else if (page.path == '/calculateur-de-rencontres/') { + crumbs.push({to: page.path, disabled: disabled, text: 'Calculateur de rencontres'}) } else { crumbs.push({to: page.path, disabled: disabled, text: page.frontmatter.breadcrumb || page.title}) } diff --git a/docs/.vuepress/theme/components/EncounterCalculator.vue b/docs/.vuepress/theme/components/EncounterCalculator.vue new file mode 100644 index 0000000..396e2c2 --- /dev/null +++ b/docs/.vuepress/theme/components/EncounterCalculator.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/docs/.vuepress/theme/components/RightDrawer.vue b/docs/.vuepress/theme/components/RightDrawer.vue index 603a966..33779ca 100644 --- a/docs/.vuepress/theme/components/RightDrawer.vue +++ b/docs/.vuepress/theme/components/RightDrawer.vue @@ -4,6 +4,7 @@ + @@ -12,6 +13,7 @@ import PageToc from '@theme/components/PageToc' import SpellFilters from '@theme/components/SpellFilters' import MagicItemFilters from '@theme/components/MagicItemFilters' import MonsterFilters from '@theme/components/MonsterFilters' +import EncounterCalculator from '@theme/components/EncounterCalculator' export default { name: 'RightDrawer', @@ -20,6 +22,7 @@ export default { SpellFilters, MagicItemFilters, MonsterFilters, + EncounterCalculator, PageToc }, diff --git a/docs/.vuepress/theme/enhanceApp.js b/docs/.vuepress/theme/enhanceApp.js index b02e5c6..09a3eea 100644 --- a/docs/.vuepress/theme/enhanceApp.js +++ b/docs/.vuepress/theme/enhanceApp.js @@ -39,11 +39,13 @@ export default ({ primary: '#4c6477', // Dragons (Bleu) navbar: '#435a3f', // Héros (Vert) accent: '#435a3f', // Héros + gold: "#bab468", }, dark: { primary: '#6c8599', // Dragons (Bleu) navbar: '#435a3f', // Héros (Vert) accent: '#6c8599', // Dragons + gold: "#bab468", } } }, diff --git a/docs/.vuepress/theme/layouts/MonstersLayout.vue b/docs/.vuepress/theme/layouts/MonstersLayout.vue index 044c2e8..bb7d2c5 100644 --- a/docs/.vuepress/theme/layouts/MonstersLayout.vue +++ b/docs/.vuepress/theme/layouts/MonstersLayout.vue @@ -12,6 +12,52 @@

Bestiaire

+
+
Colonnes affichées :
+ + + + + + +
+
Indice de dangerosité entre {{ challenges[challengeRange[0]].label }} et {{ challenges[challengeRange[1]].label }} @@ -74,6 +120,12 @@ {{ displayList(item.frontmatter.dungeonTypes) }} + + @@ -96,6 +148,7 @@ import { isResourceInLibrary } from '@theme/util' import Monster from '@theme/components/Monster' import MyMonstersButton from '@theme/global-components/MyMonstersButton' import { CHALLENGES } from '../../data/monsters' +import Cookies from 'js-cookie' export default { components: { Breadcrumb, Monster, MyMonstersButton }, @@ -116,9 +169,10 @@ export default { showColumn: { type: true, size: true, - subtype: true, - environments: true, - dungeonTypes: true, + subtype: false, + environments: false, + dungeonTypes: false, + encounter: true, }, challenges: CHALLENGES } @@ -138,7 +192,7 @@ export default { let headers = [ { text: "", align: 'center', sortable: false, value: 'isInBestiary' }, { text: "Nom", align: 'start', sortable: true, value: 'title' }, - { text: "ID", align: 'center', sortable: true, value: 'frontmatter.challenge' } + { text: "ID", align: 'center', sortable: true, value: 'frontmatter.challenge' }, ] if (this.showColumn.type && this.$vuetify.breakpoint.mdAndUp) { headers.push({ text: "Type", align: 'start', sortable: false, value: 'frontmatter.type' }) @@ -155,6 +209,9 @@ export default { if (this.showColumn.dungeonTypes && this.$vuetify.breakpoint.mdAndUp) { headers.push({ text: "Type de donjons", align: 'start', sortable: false, value: 'frontmatter.dungeonTypes' }) } + if (this.showColumn.encounter && this.$vuetify.breakpoint.mdAndUp) { + headers.push({ text: "Rencontre", align: 'center', sortable: false, value: 'isInEncounter' }) + } return headers }, @@ -306,6 +363,13 @@ export default { } }, + isCreatureInEncounter (creature) { + return isResourceInLibrary(creature, this.$store.state.encounterCalculator.creatures) + }, + addCreatureInEncounter (creature) { + this.$store.commit('encounterCalculator/addCreature', creature) + }, + selectItemPerPage (value) { setUrlParams("lignes", [value]) }, @@ -317,7 +381,11 @@ export default { onClickRow (row, item) { item.expand(!item.isExpanded) - } + }, + + setShowColumn () { + Cookies.set('5e-drs-bestiaire-colonnes', this.showColumn, { expires: 365 }) + }, }, mounted () { @@ -333,6 +401,11 @@ export default { if (page) { this.page = page } + + const showColumn = Cookies.get('5e-drs-bestiaire-colonnes') + if (showColumn) { + this.showColumn = JSON.parse(showColumn) + } } } diff --git a/docs/.vuepress/theme/util/monsterHelpers.js b/docs/.vuepress/theme/util/monsterHelpers.js index 13da754..37afb4b 100644 --- a/docs/.vuepress/theme/util/monsterHelpers.js +++ b/docs/.vuepress/theme/util/monsterHelpers.js @@ -1,4 +1,5 @@ import {stats} from '../../data/stats' +import {CHALLENGES} from '../../data/monsters' // Calcul du modificateur de caractéristique export function getModifier (score) { @@ -68,3 +69,12 @@ export function displayMonsterTypeSizeAlignment (monster, hideAlignment = false, } return result } + +// Retourne le nombre de points de combat pour un indice de dangerosité +export function getPCbyChallenge(challenge) { + let challengeIndex = CHALLENGES.findIndex(item => item.value == challenge) + if (challengeIndex > -1) { + return CHALLENGES[challengeIndex].pc + } + return false +}