mirror of
https://github.com/em-squared/5e-drs.git
synced 2025-10-30 13:14:20 +00:00
outils de création de sorts/monstres/objets
This commit is contained in:
parent
6237f0e6a2
commit
a6986c42c6
48 changed files with 2743 additions and 259 deletions
231
docs/.vuepress/theme/layouts/CreateMagicItemLayout.vue
Normal file
231
docs/.vuepress/theme/layouts/CreateMagicItemLayout.vue
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
<template>
|
||||
<div class="create-magic-item">
|
||||
<div class="d-flex align-center mb-4 d-print-none">
|
||||
<Breadcrumb class="mr-auto" />
|
||||
<v-btn color="primary" class="mr-4" depressed link to="/mes-objets-magiques/">Mes objets magiques</v-btn>
|
||||
<v-btn color="primary" depressed link to="/liste-objets-magiques/">Liste des objets magiques</v-btn>
|
||||
</div>
|
||||
|
||||
<h1 class="d-print-none">Création de sort</h1>
|
||||
|
||||
<div class="my-4 d-flex flex-wrap d-print-none">
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed @click="print"><v-icon>mdi-printer</v-icon> Imprimer</v-btn>
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed @click="download"><v-icon>mdi-file-download</v-icon> Sauvegarder</v-btn>
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed :loading="isUploading" @click="onUploadClick">
|
||||
<v-icon left>mdi-file-upload</v-icon> Charger
|
||||
</v-btn>
|
||||
<input ref="uploader" class="d-none" type="file" @change="upload">
|
||||
<v-btn :outlined="!isMagicItemInTreasureChest" color="accent" class="mr-1 mb-1" depressed @click="toggleMagicItemInTreasureChest"><v-icon>mdi-book</v-icon> {{ displayToggleMagicItemButton }}</v-btn>
|
||||
<v-btn :disabled="!isMagicItemInTreasureChest" outlined color="accent" class="mr-1 mb-1" depressed @click="updateMagicItemInTreasureChest"><v-icon>mdi-update</v-icon> MàJ dans le grimoire</v-btn>
|
||||
<v-btn outlined color="error" class="mb-1" depressed @click="reset"><v-icon>mdi-eraser</v-icon> Réinitialiser</v-btn>
|
||||
</div>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-print-none" :col="6">
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field label="Nom" outlined dense v-model="magicItem.title"></v-text-field>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-select :items="types" label="Type" outlined dense v-model="magicItem.frontmatter.type"></v-select>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-select :items="rarities" label="Rareté" outlined dense v-model="magicItem.frontmatter.rarity"></v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field label="Sous-type" outlined dense v-model="magicItem.frontmatter.subtype"></v-text-field>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-switch class="my-0" v-model="magicItem.hasAttunement" label="Harmonisation" @change="switchAttunement" dense></v-switch>
|
||||
</v-col>
|
||||
<v-col v-if="magicItem.hasAttunement">
|
||||
<v-text-field label="Type d'armonisation" outlined dense v-model="magicItem.frontmatter.attunement"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-textarea outlined label="Description" v-model="magicItem.content"></v-textarea>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
</v-col>
|
||||
|
||||
<v-col :col="6">
|
||||
<MagicItem :magicItem="magicItem" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Breadcrumb from '@theme/components/Breadcrumb'
|
||||
import MagicItem from '@theme/components/MagicItem'
|
||||
import { saveAs } from 'file-saver'
|
||||
import { MAGICITEMTYPES, RARITIES } from '../../data/magicItems'
|
||||
import { getUrlParameter } from '@theme/util/filterHelpers'
|
||||
|
||||
export default {
|
||||
name: 'CreateMagicItemLayout',
|
||||
|
||||
components: {
|
||||
Breadcrumb,
|
||||
MagicItem
|
||||
},
|
||||
|
||||
computed: {
|
||||
isMagicItemInTreasureChest () {
|
||||
let isInTreasureChest = false
|
||||
for (let s of this.$store.state.myMagicItems.magicItems) {
|
||||
if (s.key == this.magicItem.key) {
|
||||
isInTreasureChest = true
|
||||
}
|
||||
}
|
||||
return isInTreasureChest
|
||||
},
|
||||
|
||||
displayToggleMagicItemButton () {
|
||||
if (this.isMagicItemInTreasureChest) {
|
||||
return 'Supprimer de mes objets magiques'
|
||||
}
|
||||
return 'Ajouter à mes objets magiques'
|
||||
},
|
||||
|
||||
displayAttunement () {
|
||||
if (this.customAttunement !== "") {
|
||||
return this.customAttunement
|
||||
} else {
|
||||
return 'harmonisation requise'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
isUploading: false,
|
||||
types: MAGICITEMTYPES,
|
||||
rarities: RARITIES,
|
||||
customAttunement: '',
|
||||
magicItem: {
|
||||
custom: true,
|
||||
pid: 'magicItem',
|
||||
key: null,
|
||||
title: '',
|
||||
content: '',
|
||||
hasAttunement: false,
|
||||
frontmatter: {
|
||||
type: '',
|
||||
subtype: '',
|
||||
rarity: '',
|
||||
attunement: '',
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
download () {
|
||||
saveAs(new Blob([JSON.stringify(this.magicItem)], {
|
||||
type: "text/plain;charset=utf-8"
|
||||
}), "objet-magique.json")
|
||||
},
|
||||
|
||||
upload (e) {
|
||||
let file = e.target.files[0]
|
||||
let reader = new FileReader()
|
||||
let self = this
|
||||
|
||||
reader.onload = function() {
|
||||
let result = JSON.parse(reader.result)
|
||||
if (result.pid == 'magicItem') {
|
||||
self.magicItem = result
|
||||
}
|
||||
}
|
||||
|
||||
reader.readAsText(file)
|
||||
},
|
||||
|
||||
onUploadClick () {
|
||||
this.isUploading = true
|
||||
window.addEventListener('focus', () => {
|
||||
this.isUploading = false
|
||||
}, { once: true })
|
||||
|
||||
this.$refs.uploader.click()
|
||||
},
|
||||
|
||||
print () {
|
||||
window.print()
|
||||
},
|
||||
|
||||
toggleMagicItemInTreasureChest () {
|
||||
if (this.isMagicItemInTreasureChest) {
|
||||
this.$store.commit('myMagicItems/removeMagicItem', this.magicItem)
|
||||
} else {
|
||||
this.$store.commit('myMagicItems/addMagicItem', this.magicItem)
|
||||
}
|
||||
},
|
||||
|
||||
updateMagicItemInTreasureChest () {
|
||||
if (this.isMagicItemInTreasureChest) {
|
||||
this.$store.commit('myMagicItems/updateMagicItem', this.magicItem)
|
||||
}
|
||||
},
|
||||
|
||||
switchAttunement () {
|
||||
if (this.magicItem.hasAttunement) {
|
||||
this.magicItem.frontmatter.attunement = "harmonisation requise"
|
||||
} else {
|
||||
this.magicItem.frontmatter.attunement = ""
|
||||
}
|
||||
},
|
||||
|
||||
reset () {
|
||||
this.customAttunement = '',
|
||||
this.magicItem = {
|
||||
custom: true,
|
||||
pid: 'magicItem',
|
||||
key: Math.random().toString(36).substr(2, 9),
|
||||
title: '',
|
||||
content: '',
|
||||
hasAttunement: false,
|
||||
frontmatter: {
|
||||
type: '',
|
||||
subtype: '',
|
||||
rarity: '',
|
||||
attunement: '',
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$store.commit('setHasRightDrawer', false)
|
||||
this.$store.commit('setRightDrawer', this.$vuetify.breakpoint.lgAndUp)
|
||||
this.$store.commit('setInRightDrawer', null)
|
||||
|
||||
let magicItemKey = getUrlParameter(window.location.href, "key")
|
||||
|
||||
if (magicItemKey) {
|
||||
for (let magicItem of this.$store.state.myMagicItems.magicItems) {
|
||||
if (magicItem.key == magicItemKey) {
|
||||
this.magicItem = magicItem
|
||||
if (!this.magicItem.custom) {
|
||||
this.magicItem.content = magicItem.rawContent
|
||||
this.magicItem.custom = true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.magicItem.key = Math.random().toString(36).substr(2, 9)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
402
docs/.vuepress/theme/layouts/CreateMonsterLayout.vue
Normal file
402
docs/.vuepress/theme/layouts/CreateMonsterLayout.vue
Normal file
|
|
@ -0,0 +1,402 @@
|
|||
<template>
|
||||
<div class="create-monster">
|
||||
<div class="d-flex align-center mb-4 d-print-none">
|
||||
<Breadcrumb class="mr-auto" />
|
||||
<v-btn color="primary" class="mr-4" depressed link to="/mon-bestiaire/">Mon Bestiaire</v-btn>
|
||||
<v-btn color="primary" depressed link to="/bestiaire/">Bestiaire</v-btn>
|
||||
</div>
|
||||
|
||||
<h1 class="d-print-none">Création de monstre/PNJ</h1>
|
||||
|
||||
<div class="my-4 d-flex flex-wrap d-print-none">
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed @click="print"><v-icon>mdi-printer</v-icon> Imprimer</v-btn>
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed @click="download"><v-icon>mdi-file-download</v-icon> Sauvegarder</v-btn>
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed :loading="isUploading" @click="onUploadClick">
|
||||
<v-icon left>mdi-file-upload</v-icon> Charger
|
||||
</v-btn>
|
||||
<input ref="uploader" class="d-none" type="file" @change="upload">
|
||||
<v-btn :outlined="!isMonsterInBestiary" color="accent" class="mr-1 mb-1" depressed @click="toggleMonsterInBestiary"><v-icon>mdi-book</v-icon> {{ displayToggleMonsterButton }}</v-btn>
|
||||
<v-btn :disabled="!isMonsterInBestiary" outlined color="accent" class="mr-1 mb-1" depressed @click="updateMonsterInBestiary"><v-icon>mdi-update</v-icon> MàJ dans le bestiaire</v-btn>
|
||||
<v-btn outlined color="error" class="mb-1" depressed @click="reset"><v-icon>mdi-eraser</v-icon> Réinitialiser</v-btn>
|
||||
</div>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-print-none" :col="6">
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field label="Nom" placeholder="Elfe noir" outlined dense v-model="monster.title"></v-text-field>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-select :items="sizes" item-text="label" item-value="abbr" label="Taille" outlined dense v-model="monster.frontmatter.size" @change="selectMonsterSize"></v-select>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-select :items="challenges" item-text="label" item-value="value" label="Dangerosité" persistent-hint :hint="challengeHint" outlined dense v-model="monster.frontmatter.challenge"></v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-select :items="monsterTypes" label="Type" outlined dense v-model="monster.frontmatter.type"></v-select>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-text-field label="Sous-type" outlined dense v-model="monster.frontmatter.subtype"></v-text-field>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-text-field label="Alignement" placeholder="Chaotique mauvais" outlined dense v-model="monster.frontmatter.alignment"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-flex justify-space-between">
|
||||
<v-switch :disabled="!monster.frontmatter.type" class="my-0 mr-4" v-model="monster.frontmatter.isSwarm" label="Nuée" dense @change="switchIsSwarm"></v-switch>
|
||||
<v-select :disabled="!monster.frontmatter.isSwarm" :items="sizes" item-text="label" item-value="abbr" label="Taille des créatures" outlined dense v-model="monster.frontmatter.swarmSize"></v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-flex align-center">
|
||||
<v-text-field class="mr-1" label="Force" type="number" min="1" outlined dense v-model="monster.frontmatter.abilityScores.for"></v-text-field>
|
||||
<v-text-field class="mr-1" label="Dextérité" type="number" min="1" outlined dense v-model="monster.frontmatter.abilityScores.dex"></v-text-field>
|
||||
<v-text-field class="mr-1" label="Constitution" type="number" min="1" outlined dense v-model="monster.frontmatter.abilityScores.con"></v-text-field>
|
||||
<v-text-field class="mr-1" label="Intelligence" type="number" min="1" outlined dense v-model="monster.frontmatter.abilityScores.int"></v-text-field>
|
||||
<v-text-field class="mr-1" label="Sagesse" type="number" min="1" outlined dense v-model="monster.frontmatter.abilityScores.sag"></v-text-field>
|
||||
<v-text-field class="mr-0" label="Charisme" type="number" min="1" outlined dense v-model="monster.frontmatter.abilityScores.cha"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-flex align-center">
|
||||
<v-text-field label="Dés de vie" type="number" min="1" outlined dense v-model="monster.frontmatter.hitDiceCount"></v-text-field>
|
||||
<v-switch class="my-0 mx-1" v-model="customHitDieSize" label="Dé de vie personnalisé" dense @change="switchCustomHitDizeSize"></v-switch>
|
||||
<v-select :disabled="!customHitDieSize" :items="sizes" item-text="hitDie" item-value="hitDie" label="Taille du dé de vie" outlined dense v-model="monster.frontmatter.hitDieSize"></v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-flex align-center">
|
||||
<v-select class="mr-1" :items="armorTypes" item-text="label" item-value="value" label="Type d'armure" outlined dense v-model="monster.frontmatter.ac.armorType" @change="selectArmorType"></v-select>
|
||||
<v-text-field v-if="monster.frontmatter.ac.armorType == 'armure naturelle'" label="Armure naturelle" type="number" min="0" outlined dense v-model="monster.frontmatter.ac.value"></v-text-field>
|
||||
<v-text-field v-if="monster.frontmatter.ac.armorType == 'custom'" label="Armure personnalisée" outlined dense v-model="monster.frontmatter.ac.value"></v-text-field>
|
||||
<v-switch class="my-0 ml-1" v-if="monster.frontmatter.ac.armorType != 'custom'" v-model="monster.frontmatter.ac.hasShield" label="Bouclier" dense></v-switch>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-flex align-center">
|
||||
<v-select class="mr-1" multiple clearable :items="abilities" item-text="label" item-value="value" label="Jets de sauvegarde" outlined dense v-model="monster.frontmatter.savingThrows"></v-select>
|
||||
<v-select class="mr-1" multiple clearable return-object :items="skills" item-text="label" item-value="value" label="Compétences" outlined dense v-model="selectedSkillsProficient" @change="selectSkill"></v-select>
|
||||
<v-select class="mr-1" multiple clearable :items="selectedSkillsProficient" item-text="label" item-value="value" label="Compétences expert" outlined dense v-model="selectedSkillsExpert" @change="selectSkillExpert"></v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col class="d-flex align-center flex-wrap">
|
||||
<v-select class="mr-1" multiple clearable :items="conditions" label="Immunité états spéciaux" outlined dense v-model="monster.frontmatter.conditionImmunities"></v-select>
|
||||
<v-select class="mr-1" multiple clearable :items="damageTypes" label="Vulnérabilité au dégâts" outlined dense v-model="monster.frontmatter.damageTypeVulnerabilities"></v-select>
|
||||
<v-select class="mr-1" multiple clearable :items="damageTypes" label="Résistance au dégâts" outlined dense v-model="monster.frontmatter.damageTypeResistances"></v-select>
|
||||
<v-select class="mr-1" multiple clearable :items="damageTypes" label="Immunité au dégâts" outlined dense v-model="monster.frontmatter.damageTypeImmunities"></v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-flex align-center">
|
||||
<v-text-field class="mr-1" label="Au sol" type="number" min="0" outlined dense v-model="monster.frontmatter.movement.walk"></v-text-field>
|
||||
<v-text-field class="mr-1" label="Escalade" type="number" min="0" outlined dense v-model="monster.frontmatter.movement.climb"></v-text-field>
|
||||
<v-text-field class="mr-1" label="Fouissement" type="number" min="0" outlined dense v-model="monster.frontmatter.movement.burrow"></v-text-field>
|
||||
<v-text-field class="mr-1" label="Nage" type="number" min="0" outlined dense v-model="monster.frontmatter.movement.swim"></v-text-field>
|
||||
<v-text-field class="mr-1" label="Vol" type="number" min="0" outlined dense v-model="monster.frontmatter.movement.fly"></v-text-field>
|
||||
<v-switch class="my-0" v-model="monster.frontmatter.movement.hover" label="Vol stationnaire" dense></v-switch>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-flex align-center">
|
||||
<v-text-field class="mr-1" label="Perception des vibrations" type="number" min="0" outlined dense v-model="monster.frontmatter.senses.tremorsense"></v-text-field>
|
||||
<v-text-field class="mr-1" label="Vision aveugle" type="number" min="0" outlined dense v-model="monster.frontmatter.senses.blindsight"></v-text-field>
|
||||
<v-text-field class="mr-1" label="Vision dans le noir" type="number" min="0" outlined dense v-model="monster.frontmatter.senses.darkvision"></v-text-field>
|
||||
<v-text-field class="mr-0" label="Vision parfaite" type="number" min="0" outlined dense v-model="monster.frontmatter.senses.truesight"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-flex align-center">
|
||||
<v-select class="mr-1" multiple clearable :items="languages" label="Langues" outlined dense v-model="monster.frontmatter.languages"></v-select>
|
||||
<v-text-field class="mr-1" label="Langue personnalisée" outlined dense v-model="monster.frontmatter.customLanguage"></v-text-field>
|
||||
<v-text-field label="Télépathie" type="number" min="0" outlined dense v-model="monster.frontmatter.telepathy"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-textarea outlined label="Capacités, Actions, Réactions, Actions légendaires" v-model="monster.content"></v-textarea>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
</v-col>
|
||||
|
||||
<v-col :col="6">
|
||||
<Monster :monster="monster" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Breadcrumb from '@theme/components/Breadcrumb'
|
||||
import Monster from '@theme/components/Monster'
|
||||
import { saveAs } from 'file-saver'
|
||||
import { MONSTERTYPES, MONSTERSIZES, CHALLENGES, ABILITIES, SKILLS } from '../../data/monsters'
|
||||
import { stats } from '../../data/stats'
|
||||
import { ARMORTYPES } from '../../data/armorTypes'
|
||||
import { CONDITIONS } from '../../data/conditions'
|
||||
import { DAMAGETYPES } from '../../data/damageTypes'
|
||||
import { LANGUAGES } from '../../data/languages'
|
||||
import { getUrlParameter } from '@theme/util/filterHelpers'
|
||||
import { getProficiencyBonus, displayBonus } from '@theme/util/monsterHelpers'
|
||||
|
||||
export default {
|
||||
name: 'CreateMonsterLayout',
|
||||
|
||||
components: {
|
||||
Breadcrumb,
|
||||
Monster
|
||||
},
|
||||
|
||||
computed: {
|
||||
isMonsterInBestiary () {
|
||||
let isInBestiary = false
|
||||
for (let s of this.$store.state.myMonsters.monsters) {
|
||||
if (s.key == this.monster.key) {
|
||||
isInBestiary = true
|
||||
}
|
||||
}
|
||||
return isInBestiary
|
||||
},
|
||||
|
||||
displayToggleMonsterButton () {
|
||||
if (this.isMonsterInBestiary) {
|
||||
return 'Supprimer de mon bestiaire'
|
||||
}
|
||||
return 'Ajouter à mon bestiaire'
|
||||
},
|
||||
|
||||
challengeHint () {
|
||||
return 'Bonus de maîtrise : ' + displayBonus(getProficiencyBonus(this.monster.frontmatter.challenge))
|
||||
},
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
isUploading: false,
|
||||
monsterTypes: MONSTERTYPES,
|
||||
sizes: MONSTERSIZES,
|
||||
armorTypes: ARMORTYPES,
|
||||
abilities: ABILITIES,
|
||||
skills: SKILLS,
|
||||
skillObjects: stats.skills,
|
||||
conditions: CONDITIONS,
|
||||
damageTypes: DAMAGETYPES,
|
||||
challenges: CHALLENGES,
|
||||
languages: LANGUAGES,
|
||||
customHitDieSize: false,
|
||||
selectedSkillsProficient: [],
|
||||
selectedSkillsExpert: [],
|
||||
monster: {
|
||||
custom: true,
|
||||
pid: 'monster',
|
||||
key: null,
|
||||
title: '',
|
||||
content: '',
|
||||
frontmatter: {
|
||||
type: '',
|
||||
subtype: '',
|
||||
size: '',
|
||||
challenge: '0',
|
||||
alignment: '',
|
||||
isSwarm: false,
|
||||
swarmSize: '',
|
||||
hitDiceCount: 1,
|
||||
hitDieSize: '',
|
||||
abilityScores: {
|
||||
for: 10,
|
||||
dex: 10,
|
||||
con: 10,
|
||||
int: 10,
|
||||
sag: 10,
|
||||
cha: 10,
|
||||
},
|
||||
ac: {
|
||||
armorType: null,
|
||||
value: null, // Dans le cas du type d'armure "Armure naturelle"
|
||||
hasShield: false,
|
||||
},
|
||||
savingThrow: null,
|
||||
skills: null,
|
||||
movement: {
|
||||
walk: '',
|
||||
climb: '',
|
||||
burrow: '',
|
||||
swim: '',
|
||||
fly: '',
|
||||
hover: false,
|
||||
},
|
||||
senses: {
|
||||
tremorsense: '',
|
||||
blindsight: '',
|
||||
darkvision: '',
|
||||
truesight: '',
|
||||
},
|
||||
conditionImmunities: [],
|
||||
damageTypeVulnerabilities: [],
|
||||
damageTypeResistances: [],
|
||||
damageTypeImmunities: [],
|
||||
languages: [],
|
||||
customLanguage: '',
|
||||
telepathy: null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
download () {
|
||||
saveAs(new Blob([JSON.stringify(this.monster)], {
|
||||
type: "text/plain;charset=utf-8"
|
||||
}), "monstre.json")
|
||||
},
|
||||
|
||||
upload (e) {
|
||||
let file = e.target.files[0]
|
||||
let reader = new FileReader()
|
||||
let self = this
|
||||
|
||||
reader.onload = function() {
|
||||
let result = JSON.parse(reader.result)
|
||||
if (result.pid == 'monster') {
|
||||
self.monster = result
|
||||
}
|
||||
}
|
||||
|
||||
reader.readAsText(file)
|
||||
},
|
||||
|
||||
onUploadClick () {
|
||||
this.isUploading = true
|
||||
window.addEventListener('focus', () => {
|
||||
this.isUploading = false
|
||||
}, { once: true })
|
||||
|
||||
this.$refs.uploader.click()
|
||||
},
|
||||
|
||||
print () {
|
||||
window.print()
|
||||
},
|
||||
|
||||
toggleMonsterInBestiary () {
|
||||
if (this.isMonsterInBestiary) {
|
||||
this.$store.commit('myMonsters/removeMonster', this.monster)
|
||||
} else {
|
||||
this.$store.commit('myMonsters/addMonster', this.monster)
|
||||
}
|
||||
},
|
||||
|
||||
updateMonsterInBestiary () {
|
||||
if (this.isMonsterInBestiary) {
|
||||
this.$store.commit('myMonsters/updateMonster', this.monster)
|
||||
}
|
||||
},
|
||||
|
||||
reset () {
|
||||
this.monster = {
|
||||
custom: true,
|
||||
pid: 'monster',
|
||||
key: Math.random().toString(36).substr(2, 9),
|
||||
title: '',
|
||||
content: '',
|
||||
frontmatter: {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
switchIsSwarm () {
|
||||
if (!this.monster.frontmatter.isSwarm) {
|
||||
this.monster.frontmatter.swarmSize = ''
|
||||
}
|
||||
},
|
||||
|
||||
selectMonsterSize (selected) {
|
||||
|
||||
},
|
||||
|
||||
switchCustomHitDizeSize () {
|
||||
if (!this.customHitDieSize) {
|
||||
this.monster.frontmatter.hitDieSize = ''
|
||||
}
|
||||
},
|
||||
|
||||
selectArmorType () {
|
||||
if (this.monster.frontmatter.ac.armorType == 'armure naturelle' || this.monster.frontmatter.ac.armorType == 'custom') {
|
||||
this.monster.frontmatter.ac.value = null
|
||||
}
|
||||
},
|
||||
|
||||
selectSkill () {
|
||||
this.monster.frontmatter.skills = []
|
||||
this.selectedSkillsProficient.forEach((skill, idx) => {
|
||||
this.monster.frontmatter.skills.push({name: skill.value})
|
||||
})
|
||||
this.setSkillsExpert()
|
||||
},
|
||||
|
||||
selectSkillExpert () {
|
||||
this.selectSkill()
|
||||
this.setSkillsExpert()
|
||||
},
|
||||
|
||||
setSkillsExpert () {
|
||||
this.monster.frontmatter.skills.forEach((mskill, idx) => {
|
||||
this.monster.frontmatter.skills[idx].isExpert = this.selectedSkillsExpert.indexOf(mskill.name) >= 0
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$store.commit('setHasRightDrawer', false)
|
||||
this.$store.commit('setRightDrawer', this.$vuetify.breakpoint.lgAndUp)
|
||||
this.$store.commit('setInRightDrawer', null)
|
||||
|
||||
let monsterKey = getUrlParameter(window.location.href, "key")
|
||||
|
||||
if (monsterKey) {
|
||||
for (let monster of this.$store.state.myMonsters.monsters) {
|
||||
if (monster.key == monsterKey) {
|
||||
this.monster = monster
|
||||
if (!this.monster.custom) {
|
||||
this.monster.content = monster.rawContent
|
||||
this.monster.custom = true
|
||||
}
|
||||
if (this.monster.frontmatter.skills) {
|
||||
this.monster.frontmatter.skills.forEach((mskill, idx) => {
|
||||
SKILLS.forEach((skill, jdx) => {
|
||||
if (mskill.name == skill.value) {
|
||||
this.selectedSkillsProficient.push(skill)
|
||||
if (mskill.isExpert) {
|
||||
this.selectedSkillsExpert.push(skill.value)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.monster.key = Math.random().toString(36).substr(2, 9)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
276
docs/.vuepress/theme/layouts/CreateSpellLayout.vue
Normal file
276
docs/.vuepress/theme/layouts/CreateSpellLayout.vue
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
<template>
|
||||
<div class="create-spell">
|
||||
<div class="d-flex align-center mb-4 d-print-none">
|
||||
<Breadcrumb class="mr-auto" />
|
||||
<v-btn color="primary" class="mr-4" depressed link to="/mon-grimoire/">Mon Grimoire</v-btn>
|
||||
<v-btn color="primary" depressed link to="/grimoire/">Grimoire</v-btn>
|
||||
</div>
|
||||
|
||||
<h1 class="d-print-none">Création de sort</h1>
|
||||
|
||||
<div class="my-4 d-flex flex-wrap d-print-none">
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed @click="print"><v-icon>mdi-printer</v-icon> Imprimer</v-btn>
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed @click="download"><v-icon>mdi-file-download</v-icon> Sauvegarder</v-btn>
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed :loading="isUploading" @click="onUploadClick">
|
||||
<v-icon left>mdi-file-upload</v-icon> Charger
|
||||
</v-btn>
|
||||
<input ref="uploader" class="d-none" type="file" @change="upload">
|
||||
<v-btn :outlined="!isSpellInSpellBook" color="accent" class="mr-1 mb-1" depressed @click="toggleSpellInSpellBook"><v-icon>mdi-book</v-icon> {{ displayToggleSpellButton }}</v-btn>
|
||||
<v-btn :disabled="!isSpellInSpellBook" outlined color="accent" class="mr-1 mb-1" depressed @click="updateSpellInSpellBook"><v-icon>mdi-update</v-icon> MàJ dans le grimoire</v-btn>
|
||||
<v-btn outlined color="error" class="mb-1" depressed @click="reset"><v-icon>mdi-eraser</v-icon> Réinitialiser</v-btn>
|
||||
</div>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-print-none" :col="6">
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field label="Nom" placeholder="Projectile magique" outlined dense v-model="spell.title"></v-text-field>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-select :items="schools" label="École" outlined dense v-model="spell.frontmatter.school"></v-select>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-select :items="levels" item-text="label" item-value="value" label="Niveau" outlined dense v-model="spell.frontmatter.level"></v-select>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-switch class="my-0" v-model="spell.frontmatter.ritual" label="Rituel" dense></v-switch>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field label="Temps d'incantation" placeholder="1 action" outlined dense v-model="spell.frontmatter.casting_time"></v-text-field>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-text-field label="Portée" placeholder="36 m" outlined dense v-model="spell.frontmatter.range"></v-text-field>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-text-field label="Duration" placeholder="instantanée" outlined dense v-model="spell.frontmatter.duration"></v-text-field>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-switch class="my-0" v-model="spell.frontmatter.concentration" label="Concentration" dense></v-switch>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-switch class="my-0" v-model="spell.frontmatter.components.verbal" label="Verbale" dense></v-switch>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-switch class="my-0" v-model="spell.frontmatter.components.somatic" label="Somatique" dense></v-switch>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-switch class="my-0" v-model="spell.frontmatter.components.material" label="Matérielle" dense></v-switch>
|
||||
</v-col>
|
||||
<v-col v-if="spell.frontmatter.components.material">
|
||||
<v-text-field label="Composantes matérielles" outlined dense v-model="spell.frontmatter.components.materials"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-select :items="classes" multiple clearable label="Disponible pour les classes de :" outlined dense v-model="spell.frontmatter.classes"></v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field label="Classes personnalisées" placeholder="Forgesort" outlined dense v-model="spell.frontmatter.customClasses"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field outlined label="Résumé" v-model="spell.frontmatter.description"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-textarea outlined label="Description" v-model="spell.content"></v-textarea>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
</v-col>
|
||||
|
||||
<v-col :col="6">
|
||||
<Spell :spell="spell" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Breadcrumb from '@theme/components/Breadcrumb'
|
||||
import Spell from '@theme/components/Spell'
|
||||
import { saveAs } from 'file-saver'
|
||||
import { CLASSES } from '../../data/classes'
|
||||
import { SPELLSCHOOLS, SPELLLEVELS } from '../../data/spells'
|
||||
import { getUrlParameter } from '@theme/util/filterHelpers'
|
||||
|
||||
export default {
|
||||
name: 'CreateSpellLayout',
|
||||
|
||||
components: {
|
||||
Breadcrumb,
|
||||
Spell
|
||||
},
|
||||
|
||||
computed: {
|
||||
isSpellInSpellBook () {
|
||||
let isInSpellBook = false
|
||||
for (let s of this.$store.state.mySpells.spells) {
|
||||
if (s.key == this.spell.key) {
|
||||
isInSpellBook = true
|
||||
}
|
||||
}
|
||||
return isInSpellBook
|
||||
},
|
||||
|
||||
displayToggleSpellButton () {
|
||||
if (this.isSpellInSpellBook) {
|
||||
return 'Supprimer de mon grimoire'
|
||||
}
|
||||
return 'Ajouter à mon grimoire'
|
||||
}
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
isUploading: false,
|
||||
schools: SPELLSCHOOLS,
|
||||
levels: SPELLLEVELS,
|
||||
classes: CLASSES,
|
||||
spell: {
|
||||
custom: true,
|
||||
pid: 'spell',
|
||||
key: null,
|
||||
title: '',
|
||||
content: '',
|
||||
frontmatter: {
|
||||
description: '',
|
||||
classes: '',
|
||||
customClasses: '',
|
||||
school: '',
|
||||
level: '',
|
||||
ritual: false,
|
||||
casting_time: '',
|
||||
range: '',
|
||||
duration: '',
|
||||
concentration: false,
|
||||
components: {
|
||||
verbal: false,
|
||||
somatic: false,
|
||||
material: false,
|
||||
materials: null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
download () {
|
||||
saveAs(new Blob([JSON.stringify(this.spell)], {
|
||||
type: "text/plain;charset=utf-8"
|
||||
}), "sort.json")
|
||||
},
|
||||
|
||||
upload (e) {
|
||||
let file = e.target.files[0]
|
||||
let reader = new FileReader()
|
||||
let self = this
|
||||
|
||||
reader.onload = function() {
|
||||
let result = JSON.parse(reader.result)
|
||||
if (result.pid == 'spell') {
|
||||
self.spell = result
|
||||
}
|
||||
}
|
||||
|
||||
reader.readAsText(file)
|
||||
},
|
||||
|
||||
onUploadClick () {
|
||||
this.isUploading = true
|
||||
window.addEventListener('focus', () => {
|
||||
this.isUploading = false
|
||||
}, { once: true })
|
||||
|
||||
this.$refs.uploader.click()
|
||||
},
|
||||
|
||||
print () {
|
||||
window.print()
|
||||
},
|
||||
|
||||
toggleSpellInSpellBook () {
|
||||
if (this.isSpellInSpellBook) {
|
||||
this.$store.commit('mySpells/removeSpell', this.spell)
|
||||
} else {
|
||||
this.$store.commit('mySpells/addSpell', this.spell)
|
||||
}
|
||||
},
|
||||
|
||||
updateSpellInSpellBook () {
|
||||
if (this.isSpellInSpellBook) {
|
||||
this.$store.commit('mySpells/updateSpell', this.spell)
|
||||
}
|
||||
},
|
||||
|
||||
reset () {
|
||||
this.spell = {
|
||||
custom: true,
|
||||
pid: 'spell',
|
||||
key: Math.random().toString(36).substr(2, 9),
|
||||
title: '',
|
||||
content: '',
|
||||
frontmatter: {
|
||||
description: '',
|
||||
classes: '',
|
||||
customClasses: '',
|
||||
school: '',
|
||||
level: '',
|
||||
ritual: false,
|
||||
casting_time: '',
|
||||
range: '',
|
||||
duration: '',
|
||||
concentration: false,
|
||||
components: {
|
||||
verbal: false,
|
||||
somatic: false,
|
||||
material: false,
|
||||
materials: null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$store.commit('setHasRightDrawer', false)
|
||||
this.$store.commit('setRightDrawer', this.$vuetify.breakpoint.lgAndUp)
|
||||
this.$store.commit('setInRightDrawer', null)
|
||||
|
||||
let spellKey = getUrlParameter(window.location.href, "key")
|
||||
|
||||
if (spellKey) {
|
||||
for (let spell of this.$store.state.mySpells.spells) {
|
||||
if (spell.key == spellKey) {
|
||||
this.spell = spell
|
||||
if (!this.spell.custom) {
|
||||
this.spell.content = spell.rawContent
|
||||
this.spell.custom = true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.spell.key = Math.random().toString(36).substr(2, 9)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -101,6 +101,12 @@ export default {
|
|||
if (THEMEISDARK === 'true') {
|
||||
this.$vuetify.theme.dark = true
|
||||
}
|
||||
|
||||
// Chargement des donées utilisateur depuis le navigateur
|
||||
this.$store.commit('mySpells/initialiseStore')
|
||||
this.$store.commit('myMonsters/initialiseStore')
|
||||
this.$store.commit('myMagicItems/initialiseStore')
|
||||
|
||||
// this.$vuetify.theme.dark = this.$store.state.isThemeDark
|
||||
|
||||
// let conditionLinks = document.links
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
<template>
|
||||
<div class="magic-item">
|
||||
<Breadcrumb />
|
||||
<MagicItem />
|
||||
<div class="d-flex align-center mb-4 d-print-none">
|
||||
<Breadcrumb class="mr-auto" />
|
||||
<v-btn color="primary" class="mr-4" depressed link to="/creation-d-objet-magique/"><v-icon left>mdi-plus</v-icon> Créer un objet magique</v-btn>
|
||||
<v-btn :outlined="!isMagicItemInTreasureChest" color="accent" class="mr-4" depressed @click="toggleMagicItemInTreasureChest"><v-icon>mdi-book</v-icon> {{ displayToggleMagicItemButton }}</v-btn>
|
||||
<v-btn color="primary" class="mr-4" depressed link to="/mon-grimoire/">Mes objets magiques</v-btn>
|
||||
</div>
|
||||
<MagicItem :magicItem="$page" />
|
||||
<Edit />
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -20,6 +25,35 @@ export default {
|
|||
Edit
|
||||
},
|
||||
|
||||
computed: {
|
||||
isMagicItemInTreasureChest () {
|
||||
let isInTreasureChest = false
|
||||
for (let s of this.$store.state.myMagicItems.magicItems) {
|
||||
if (s.key == this.$page.key) {
|
||||
isInTreasureChest = true
|
||||
}
|
||||
}
|
||||
return isInTreasureChest
|
||||
},
|
||||
|
||||
displayToggleMagicItemButton () {
|
||||
if (this.isMagicItemInTreasureChest) {
|
||||
return 'Supprimer de mes objets magiques'
|
||||
}
|
||||
return 'Ajouter à mes objets magiques'
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleMagicItemInTreasureChest () {
|
||||
if (this.isMagicItemInTreasureChest) {
|
||||
this.$store.commit('myMagicItems/removeMagicItem', this.$page)
|
||||
} else {
|
||||
this.$store.commit('myMagicItems/addMagicItem', this.$page)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$store.commit('setHasRightDrawer', false)
|
||||
this.$store.commit('setRightDrawer', false)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
<template>
|
||||
<div class="magic-items">
|
||||
|
||||
<Breadcrumb />
|
||||
<div class="d-flex align-center mb-4">
|
||||
<Breadcrumb class="mr-auto" />
|
||||
<v-btn color="primary" class="mr-4" depressed link to="/creation-d-objet-magique/"><v-icon left>mdi-plus</v-icon> Créer un objet magique</v-btn>
|
||||
<v-btn color="primary" depressed link to="/mes-objets-magiques/">Mes objets magiques</v-btn>
|
||||
</div>
|
||||
|
||||
<h1>Liste des objets magiques</h1>
|
||||
|
||||
|
|
@ -16,6 +20,10 @@
|
|||
:search="search"
|
||||
>
|
||||
|
||||
<template v-slot:item.isInTreasureChest="{ item }">
|
||||
<v-simple-checkbox off-icon="mdi-bookmark-outline" on-icon="mdi-bookmark" @input="toggleItemInTreasureChest(item)" :value="isItemInTreasureChest(item)"></v-simple-checkbox>
|
||||
</template>
|
||||
|
||||
<template v-slot:item.title="{ item }">
|
||||
<router-link :to="{ path: item.path }" class="subtitle-2">{{ item.title }}</router-link>
|
||||
</template>
|
||||
|
|
@ -40,6 +48,7 @@ export default {
|
|||
sortBy: 'title',
|
||||
sortDesc: false,
|
||||
headers: [
|
||||
{ text: "", align: 'center', sortable: false, value: 'isInTreasureChest' },
|
||||
{ text: "Nom", align: 'start', sortable: true, value: 'title' },
|
||||
{ text: "Type", align: 'start', sortable: false, value: 'frontmatter.type' },
|
||||
{ text: "Rareté", align: 'start', sortable: false, value: 'frontmatter.rarity' },
|
||||
|
|
@ -102,6 +111,25 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
isItemInTreasureChest (magicItem) {
|
||||
let isInTreasureChest = false
|
||||
for (let mi of this.$store.state.myMagicItems.magicItems) {
|
||||
if (mi.key == magicItem.key) {
|
||||
isInTreasureChest = true
|
||||
}
|
||||
}
|
||||
return isInTreasureChest
|
||||
},
|
||||
toggleItemInTreasureChest (magicItem) {
|
||||
if (this.isItemInTreasureChest(magicItem)) {
|
||||
this.$store.commit('myMagicItems/removeMagicItem', magicItem)
|
||||
} else {
|
||||
this.$store.commit('myMagicItems/addMagicItem', magicItem)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$store.commit('setHasRightDrawer', true)
|
||||
this.$store.commit('setRightDrawer', this.$vuetify.breakpoint.lgAndUp)
|
||||
|
|
|
|||
|
|
@ -1,20 +1,57 @@
|
|||
<template>
|
||||
<div class="monster">
|
||||
<Breadcrumb />
|
||||
<Monster />
|
||||
<div class="d-flex align-center mb-4 d-print-none">
|
||||
<Breadcrumb class="mr-auto" />
|
||||
<v-btn color="primary" class="mr-4" depressed link to="/creation-de-monstre-pnj/"><v-icon left>mdi-plus</v-icon> Créer un monstre</v-btn>
|
||||
<v-btn :outlined="!isMonsterInBestiary" color="accent" class="mr-4" depressed @click="toggleMonsterInBestiary"><v-icon>mdi-book</v-icon> {{ displayToggleMonsterButton }}</v-btn>
|
||||
<v-btn color="primary" class="mr-4" depressed link to="/mon-bestiaire/">Mon Bestiaire</v-btn>
|
||||
</div>
|
||||
<Monster :monster="$page" />
|
||||
<Edit />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Breadcrumb from '@theme/components/Breadcrumb'
|
||||
import Monster from '@theme/components/Monster'
|
||||
import Edit from '@theme/components/Edit'
|
||||
|
||||
export default {
|
||||
name: 'MonsterLayout',
|
||||
|
||||
components: {
|
||||
Breadcrumb,
|
||||
Monster
|
||||
Monster,
|
||||
Edit
|
||||
},
|
||||
|
||||
computed: {
|
||||
isMonsterInBestiary () {
|
||||
let isInBestiary = false
|
||||
for (let s of this.$store.state.myMonsters.monsters) {
|
||||
if (s.key == this.$page.key) {
|
||||
isInBestiary = true
|
||||
}
|
||||
}
|
||||
return isInBestiary
|
||||
},
|
||||
|
||||
displayToggleMonsterButton () {
|
||||
if (this.isMonsterInBestiary) {
|
||||
return 'Supprimer de mon grimoire'
|
||||
}
|
||||
return 'Ajouter à mon grimoire'
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleMonsterInBestiary () {
|
||||
if (this.isMonsterInBestiary) {
|
||||
this.$store.commit('myMonsters/removeMonster', this.$page)
|
||||
} else {
|
||||
this.$store.commit('myMonsters/addMonster', this.$page)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
<template>
|
||||
<div class="monsters">
|
||||
|
||||
<Breadcrumb />
|
||||
<div class="d-flex align-center mb-4">
|
||||
<Breadcrumb class="mr-auto" />
|
||||
<v-btn color="primary" class="mr-4" depressed link to="/creation-de-monstre-pnj/"><v-icon left>mdi-plus</v-icon> Créer un monstre</v-btn>
|
||||
<v-btn color="primary" depressed link to="/mon-bestiaire/">Mon bestiaire</v-btn>
|
||||
</div>
|
||||
|
||||
<h1>Bestiaire</h1>
|
||||
|
||||
|
|
@ -16,6 +20,10 @@
|
|||
:search="search"
|
||||
>
|
||||
|
||||
<template v-slot:item.isInBestiary="{ item }">
|
||||
<v-simple-checkbox off-icon="mdi-bookmark-outline" on-icon="mdi-bookmark" @input="toggleMonsterInBestiary(item)" :value="isMonsterInBestiary(item)"></v-simple-checkbox>
|
||||
</template>
|
||||
|
||||
<template v-slot:item.title="{ item }">
|
||||
<router-link :to="{ path: item.path }" class="subtitle-2">{{ item.title }}</router-link>
|
||||
</template>
|
||||
|
|
@ -51,6 +59,7 @@ export default {
|
|||
sortBy: 'title',
|
||||
sortDesc: false,
|
||||
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: "Type", align: 'start', sortable: false, value: 'frontmatter.type' },
|
||||
|
|
@ -153,6 +162,22 @@ export default {
|
|||
methods: {
|
||||
displayList (list) { return list.join(', ') },
|
||||
displayChallenge (challenge) { return displayChallenge(challenge) },
|
||||
isMonsterInBestiary (monster) {
|
||||
let isInBestiary = false
|
||||
for (let m of this.$store.state.myMonsters.monsters) {
|
||||
if (m.key == monster.key) {
|
||||
isInBestiary = true
|
||||
}
|
||||
}
|
||||
return isInBestiary
|
||||
},
|
||||
toggleMonsterInBestiary (monster) {
|
||||
if (this.isMonsterInBestiary(monster)) {
|
||||
this.$store.commit('myMonsters/removeMonster', monster)
|
||||
} else {
|
||||
this.$store.commit('myMonsters/addMonster', monster)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
|
|
|
|||
96
docs/.vuepress/theme/layouts/MyMagicItemsLayout.vue
Normal file
96
docs/.vuepress/theme/layouts/MyMagicItemsLayout.vue
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<div class="my-magic-items">
|
||||
<div class="d-flex align-center mb-4 d-print-none">
|
||||
<Breadcrumb class="mr-auto" />
|
||||
<v-btn color="primary" depressed link to="/liste-objets-magiques/">Liste des objets magiques</v-btn>
|
||||
</div>
|
||||
|
||||
<h1>Mes objets magiques</h1>
|
||||
|
||||
<div class="my-4 d-flex flex-wrap d-print-none">
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed @click="print"><v-icon>mdi-printer</v-icon> Imprimer</v-btn>
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed @click="download"><v-icon>mdi-file-download</v-icon> Sauvegarder</v-btn>
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed :loading="isUploading" @click="onUploadClick">
|
||||
<v-icon left>mdi-file-upload</v-icon> Charger
|
||||
</v-btn>
|
||||
<input ref="uploader" class="d-none" type="file" @change="upload">
|
||||
<v-btn outlined color="error" class="mb-1" depressed @click="$store.commit('myMagicItems/resetMagicItems')"><v-icon>mdi-delete</v-icon> Effacer les objets magiques</v-btn>
|
||||
</div>
|
||||
|
||||
<MyMagicItems />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Breadcrumb from '@theme/components/Breadcrumb'
|
||||
import MyMagicItems from '@theme/components/MyMagicItems'
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
export default {
|
||||
name: 'MyMagicItemsLayout',
|
||||
|
||||
components: {
|
||||
Breadcrumb,
|
||||
MyMagicItems
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
isUploading: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
download () {
|
||||
saveAs(new Blob([JSON.stringify(this.$store.state.myMagicItems.magicItems)], {
|
||||
type: "text/plain;charset=utf-8"
|
||||
}), "objets-magiques.json")
|
||||
},
|
||||
|
||||
upload (e) {
|
||||
let file = e.target.files[0]
|
||||
let reader = new FileReader()
|
||||
let self = this
|
||||
|
||||
reader.onload = function() {
|
||||
let result = JSON.parse(reader.result)
|
||||
let isValid = true
|
||||
if (result.length >= 1) {
|
||||
for (var s of result) {
|
||||
if (s.pid !== 'magicItem') {
|
||||
isValid = false
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isValid) {
|
||||
self.$store.commit('myMagicItems/setMagicItems', result)
|
||||
}
|
||||
}
|
||||
|
||||
reader.readAsText(file)
|
||||
},
|
||||
|
||||
onUploadClick () {
|
||||
this.isUploading = true
|
||||
window.addEventListener('focus', () => {
|
||||
this.isUploading = false
|
||||
}, { once: true })
|
||||
|
||||
this.$refs.uploader.click()
|
||||
},
|
||||
|
||||
print () {
|
||||
window.print()
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$store.commit('setHasRightDrawer', false)
|
||||
this.$store.commit('setRightDrawer', this.$vuetify.breakpoint.lgAndUp)
|
||||
this.$store.commit('setInRightDrawer', null)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
96
docs/.vuepress/theme/layouts/MyMonstersLayout.vue
Normal file
96
docs/.vuepress/theme/layouts/MyMonstersLayout.vue
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<div class="my-monsters">
|
||||
<div class="d-flex align-center mb-4 d-print-none">
|
||||
<Breadcrumb class="mr-auto" />
|
||||
<v-btn color="primary" depressed link to="/bestiaire/">Bestiaire</v-btn>
|
||||
</div>
|
||||
|
||||
<h1>Mon bestiaire</h1>
|
||||
|
||||
<div class="my-4 d-flex flex-wrap d-print-none">
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed @click="print"><v-icon>mdi-printer</v-icon> Imprimer</v-btn>
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed @click="download"><v-icon>mdi-file-download</v-icon> Sauvegarder</v-btn>
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed :loading="isUploading" @click="onUploadClick">
|
||||
<v-icon left>mdi-file-upload</v-icon> Charger
|
||||
</v-btn>
|
||||
<input ref="uploader" class="d-none" type="file" @change="upload">
|
||||
<v-btn outlined color="error" class="mb-1" depressed @click="$store.commit('myMonsters/resetMonsters')"><v-icon>mdi-delete</v-icon> Effacer le bestiaire</v-btn>
|
||||
</div>
|
||||
|
||||
<MyMonsters />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Breadcrumb from '@theme/components/Breadcrumb'
|
||||
import MyMonsters from '@theme/components/MyMonsters'
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
export default {
|
||||
name: 'MyMonstersLayout',
|
||||
|
||||
components: {
|
||||
Breadcrumb,
|
||||
MyMonsters
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
isUploading: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
download () {
|
||||
saveAs(new Blob([JSON.stringify(this.$store.state.myMonsters.monsters)], {
|
||||
type: "text/plain;charset=utf-8"
|
||||
}), "bestiaire.json")
|
||||
},
|
||||
|
||||
upload (e) {
|
||||
let file = e.target.files[0]
|
||||
let reader = new FileReader()
|
||||
let self = this
|
||||
|
||||
reader.onload = function() {
|
||||
let result = JSON.parse(reader.result)
|
||||
let isValid = true
|
||||
if (result.length >= 1) {
|
||||
for (var s of result) {
|
||||
if (s.pid !== 'monster') {
|
||||
isValid = false
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isValid) {
|
||||
self.$store.commit('myMonsters/setMonsters', result)
|
||||
}
|
||||
}
|
||||
|
||||
reader.readAsText(file)
|
||||
},
|
||||
|
||||
onUploadClick () {
|
||||
this.isUploading = true
|
||||
window.addEventListener('focus', () => {
|
||||
this.isUploading = false
|
||||
}, { once: true })
|
||||
|
||||
this.$refs.uploader.click()
|
||||
},
|
||||
|
||||
print () {
|
||||
window.print()
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$store.commit('setHasRightDrawer', false)
|
||||
this.$store.commit('setRightDrawer', this.$vuetify.breakpoint.lgAndUp)
|
||||
this.$store.commit('setInRightDrawer', null)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
96
docs/.vuepress/theme/layouts/MySpellsLayout.vue
Normal file
96
docs/.vuepress/theme/layouts/MySpellsLayout.vue
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<div class="my-spells">
|
||||
<div class="d-flex align-center mb-4 d-print-none">
|
||||
<Breadcrumb class="mr-auto" />
|
||||
<v-btn color="primary" depressed link to="/grimoire/">Grimoire</v-btn>
|
||||
</div>
|
||||
|
||||
<h1>Mon grimoire</h1>
|
||||
|
||||
<div class="my-4 d-flex flex-wrap d-print-none">
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed @click="print"><v-icon>mdi-printer</v-icon> Imprimer</v-btn>
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed @click="download"><v-icon>mdi-file-download</v-icon> Sauvegarder</v-btn>
|
||||
<v-btn outlined color="accent" class="mr-1 mb-1" depressed :loading="isUploading" @click="onUploadClick">
|
||||
<v-icon left>mdi-file-upload</v-icon> Charger
|
||||
</v-btn>
|
||||
<input ref="uploader" class="d-none" type="file" @change="upload">
|
||||
<v-btn outlined color="error" class="mb-1" depressed @click="$store.commit('mySpells/resetSpells')"><v-icon>mdi-delete</v-icon> Effacer le grimoire</v-btn>
|
||||
</div>
|
||||
|
||||
<MySpells />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Breadcrumb from '@theme/components/Breadcrumb'
|
||||
import MySpells from '@theme/components/MySpells'
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
export default {
|
||||
name: 'MySpellsLayout',
|
||||
|
||||
components: {
|
||||
Breadcrumb,
|
||||
MySpells
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
isUploading: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
download () {
|
||||
saveAs(new Blob([JSON.stringify(this.$store.state.mySpells.spells)], {
|
||||
type: "text/plain;charset=utf-8"
|
||||
}), "grimoire.json")
|
||||
},
|
||||
|
||||
upload (e) {
|
||||
let file = e.target.files[0]
|
||||
let reader = new FileReader()
|
||||
let self = this
|
||||
|
||||
reader.onload = function() {
|
||||
let result = JSON.parse(reader.result)
|
||||
let isValid = true
|
||||
if (result.length >= 1) {
|
||||
for (var s of result) {
|
||||
if (s.pid !== 'spell') {
|
||||
isValid = false
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isValid) {
|
||||
self.$store.commit('mySpells/setSpells', result)
|
||||
}
|
||||
}
|
||||
|
||||
reader.readAsText(file)
|
||||
},
|
||||
|
||||
onUploadClick () {
|
||||
this.isUploading = true
|
||||
window.addEventListener('focus', () => {
|
||||
this.isUploading = false
|
||||
}, { once: true })
|
||||
|
||||
this.$refs.uploader.click()
|
||||
},
|
||||
|
||||
print () {
|
||||
window.print()
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$store.commit('setHasRightDrawer', false)
|
||||
this.$store.commit('setRightDrawer', this.$vuetify.breakpoint.lgAndUp)
|
||||
this.$store.commit('setInRightDrawer', null)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -1,7 +1,12 @@
|
|||
<template>
|
||||
<div class="spell">
|
||||
<Breadcrumb />
|
||||
<Spell />
|
||||
<div class="d-flex align-center mb-4 d-print-none">
|
||||
<Breadcrumb class="mr-auto" />
|
||||
<v-btn color="primary" class="mr-4" depressed link to="/creation-de-sort/"><v-icon left>mdi-plus</v-icon> Créer un sort</v-btn>
|
||||
<v-btn :outlined="!isSpellInSpellBook" color="accent" class="mr-4" depressed @click="toggleSpellInSpellBook"><v-icon>mdi-book</v-icon> {{ displayToggleSpellButton }}</v-btn>
|
||||
<v-btn color="primary" class="mr-4" depressed link to="/mon-grimoire/">Mon Grimoire</v-btn>
|
||||
</div>
|
||||
<Spell :spell="$page" />
|
||||
<Edit />
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -20,6 +25,35 @@ export default {
|
|||
Edit
|
||||
},
|
||||
|
||||
computed: {
|
||||
isSpellInSpellBook () {
|
||||
let isInSpellBook = false
|
||||
for (let s of this.$store.state.mySpells.spells) {
|
||||
if (s.key == this.$page.key) {
|
||||
isInSpellBook = true
|
||||
}
|
||||
}
|
||||
return isInSpellBook
|
||||
},
|
||||
|
||||
displayToggleSpellButton () {
|
||||
if (this.isSpellInSpellBook) {
|
||||
return 'Supprimer de mon grimoire'
|
||||
}
|
||||
return 'Ajouter à mon grimoire'
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleSpellInSpellBook () {
|
||||
if (this.isSpellInSpellBook) {
|
||||
this.$store.commit('mySpells/removeSpell', this.$page)
|
||||
} else {
|
||||
this.$store.commit('mySpells/addSpell', this.$page)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$store.commit('setHasRightDrawer', false)
|
||||
this.$store.commit('setRightDrawer', this.$vuetify.breakpoint.lgAndUp)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
<template>
|
||||
<div class="spells">
|
||||
|
||||
<Breadcrumb />
|
||||
<div class="d-flex align-center mb-4">
|
||||
<Breadcrumb class="mr-auto" />
|
||||
<v-btn color="primary" class="mr-4" depressed link to="/creation-de-sort/"><v-icon left>mdi-plus</v-icon> Créer un sort</v-btn>
|
||||
<v-btn color="primary" depressed link to="/mon-grimoire/">Mon grimoire</v-btn>
|
||||
</div>
|
||||
|
||||
<h1>Grimoire</h1>
|
||||
|
||||
|
||||
<v-data-table
|
||||
class="data-table"
|
||||
:headers="headers"
|
||||
|
|
@ -16,6 +21,10 @@
|
|||
:search="search"
|
||||
>
|
||||
|
||||
<template v-slot:item.isInSpellBook="{ item }">
|
||||
<v-simple-checkbox off-icon="mdi-bookmark-outline" on-icon="mdi-bookmark" @input="toggleSpellInSpellBook(item)" :value="isSpellInSpellBook(item)"></v-simple-checkbox>
|
||||
</template>
|
||||
|
||||
<template v-slot:item.title="{ item }">
|
||||
<router-link :to="{ path: item.path }" class="subtitle-2">{{ item.title }}</router-link>
|
||||
</template>
|
||||
|
|
@ -61,6 +70,7 @@ export default {
|
|||
sortBy: 'title',
|
||||
sortDesc: false,
|
||||
headers: [
|
||||
{ text: "", align: 'center', sortable: false, value: 'isInSpellBook' },
|
||||
{ text: "Nom", align: 'start', sortable: true, value: 'title' },
|
||||
{ text: "Niveau", align: 'center', sortable: true, value: 'frontmatter.level' },
|
||||
{ text: "École", align: 'start', sortable: false, value: 'frontmatter.school' },
|
||||
|
|
@ -172,6 +182,25 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
isSpellInSpellBook (spell) {
|
||||
let isInSpellBook = false
|
||||
for (let s of this.$store.state.mySpells.spells) {
|
||||
if (s.key == spell.key) {
|
||||
isInSpellBook = true
|
||||
}
|
||||
}
|
||||
return isInSpellBook
|
||||
},
|
||||
toggleSpellInSpellBook (spell) {
|
||||
if (this.isSpellInSpellBook(spell)) {
|
||||
this.$store.commit('mySpells/removeSpell', spell)
|
||||
} else {
|
||||
this.$store.commit('mySpells/addSpell', spell)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$store.commit('setDrawer', this.$vuetify.breakpoint.lgAndUp)
|
||||
this.$store.commit('setHasRightDrawer', true)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue