Skip to content

Commit

Permalink
refactor: rewrite to script setup
Browse files Browse the repository at this point in the history
  • Loading branch information
rudnovd committed Apr 1, 2024
1 parent c7f17b4 commit a5e9525
Show file tree
Hide file tree
Showing 26 changed files with 975 additions and 1,386 deletions.
62 changes: 25 additions & 37 deletions src/components/CalculatorTabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class="tab"
:class="{ active: index === activeIndex }"
:title="calculatorTitle(calculator.attacker, calculator.defender)"
@click="$emit('selectTab', index)"
@click="emit('selectTab', index)"
>
<span class="tab-title">
{{ calculatorTitle(calculator.attacker, calculator.defender) }}
Expand All @@ -16,7 +16,7 @@
<button
class="tab-close-button"
:class="{ disabled: calculators.length < 2 }"
@click="$emit('deleteTab', index)"
@click="emit('deleteTab', index)"
/>
</li>
</ul>
Expand All @@ -25,48 +25,36 @@
class="tab-add-button"
:class="{ disabled: calculators.length >= 7 }"
title="Add new Calculator tab"
@click="$emit('addTab')"
@click="emit('addTab')"
/>
</section>
</template>

<script lang="ts">
import type { PropType } from 'vue'
import { defineComponent } from 'vue'
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router'
export default defineComponent({
name: 'CalculatorTabs',
props: {
calculators: {
type: Array as PropType<Array<{ attacker: string | null; defender: string | null }>>,
required: true,
},
activeIndex: {
type: Number,
required: true,
},
},
emits: ['addTab', 'selectTab', 'deleteTab'],
setup() {
const { t } = useI18n()
const route = useRoute()
const calculatorTitle = (attacker: string | null, defender: string | null) => {
if (attacker && defender) return `${attacker} — ${defender}`
else if (attacker) return attacker
else if (defender) return defender
else if (route.path === '/damage') return t('pages.damageCalculator')
else if (route.path === '/magic') return t('pages.magicCalculator')
else return t('pages.damageCalculator')
}
return {
calculatorTitle,
}
},
})
defineProps<{
calculators: Array<{ attacker: string | null; defender: string | null }>
activeIndex: number
}>()
const emit = defineEmits<{
addTab: []
selectTab: [index: number]
deleteTab: [index: number]
}>()
const { t } = useI18n()
const route = useRoute()
const calculatorTitle = (attacker: string | null, defender: string | null) => {
if (attacker && defender) return `${attacker} — ${defender}`
else if (attacker) return attacker
else if (defender) return defender
else if (route.path === '/damage') return t('pages.damageCalculator')
else if (route.path === '/magic') return t('pages.magicCalculator')
else return t('pages.damageCalculator')
}
</script>

<style lang="scss" scoped>
Expand Down
171 changes: 68 additions & 103 deletions src/components/DamageCalculator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
</section>
</template>

<script lang="ts">
<script setup lang="ts">
import PickCreatureButton from '@/components/PickCreatureButton.vue'
import SelectHero from '@/components/SelectHero.vue'
import SelectTerrain from '@/components/SelectTerrain.vue'
Expand All @@ -143,117 +143,82 @@ import { HeroInstance } from '@/models/Hero'
import type { Spell } from '@/models/Spell'
import type { Terrain } from '@/models/Terrain'
import { useStore } from '@/store'
import { computed, defineAsyncComponent, defineComponent, reactive, type PropType } from 'vue'
import { computed, defineAsyncComponent, reactive } from 'vue'
import { useI18n } from 'vue-i18n'
export default defineComponent({
name: 'DamageCalculator',
components: {
PickCreatureButton,
SelectHero,
SelectTerrain,
ObjectPortrait: defineAsyncComponent(() => import('@/components/ObjectPortrait.vue')),
BaseInputNumber: defineAsyncComponent(() => import('@/components/base/BaseInputNumber.vue')),
InputHeroStat: defineAsyncComponent(() => import('@/components/damageCalculator/InputHeroStat.vue')),
SelectSkillButtons: defineAsyncComponent(() => import('@/components/damageCalculator/SelectSkillButtons.vue')),
BaseCheckbox: defineAsyncComponent(() => import('@/components/base/BaseCheckbox.vue')),
},
props: {
battleValue: {
type: Object as PropType<Battle>,
required: true,
},
},
setup(props) {
const { t } = useI18n()
const store = useStore()
const battle = reactive(props.battleValue)
const heroes = computed(() => store.heroes)
const terrains = computed(() => store.terrains)
const levels = computed(() => store.levels)
const skills = computed(() => {
const damageCalculatorSkillsIds = [
SecondarySkills.Offense,
SecondarySkills.AirMagic,
SecondarySkills.Armorer,
SecondarySkills.FireMagic,
SecondarySkills.Archery,
SecondarySkills.EarthMagic,
SecondarySkills.Artillery,
SecondarySkills.WaterMagic,
]
const damageCalculatorSkills = ['air', 'archery', 'armorer', 'artillery', 'earth', 'fire', 'offense', 'water']
const skills = {}
store.skills
.filter((skill) => damageCalculatorSkillsIds.includes(skill.id))
.forEach((skill, index) => (skills[damageCalculatorSkills[index]] = skill.name))
return skills
})
const effects = computed(() => [
store.attackPositiveEffects,
store.defensePositiveEffects,
store.attackNegativeEffects,
])
// Return string of total damage or total kills
const getTotalResultString = (min: number, max: number, average: number) => {
if (min !== max) return `${min} — ${max} (~ ${average})`
else if (min === max) return min
else return 0
}
const ObjectPortrait = defineAsyncComponent(() => import('@/components/ObjectPortrait.vue'))
const BaseInputNumber = defineAsyncComponent(() => import('@/components/base/BaseInputNumber.vue'))
const InputHeroStat = defineAsyncComponent(() => import('@/components/damageCalculator/InputHeroStat.vue'))
const SelectSkillButtons = defineAsyncComponent(() => import('@/components/damageCalculator/SelectSkillButtons.vue'))
const BaseCheckbox = defineAsyncComponent(() => import('@/components/base/BaseCheckbox.vue'))
const props = defineProps<{
battleValue: Battle
}>()
const { t } = useI18n()
const store = useStore()
const battle = reactive(props.battleValue)
const heroes = computed(() => store.heroes)
const terrains = computed(() => store.terrains)
const levels = computed(() => store.levels)
const skills = computed(() => {
const damageCalculatorSkillsIds = [
SecondarySkills.Offense,
SecondarySkills.AirMagic,
SecondarySkills.Armorer,
SecondarySkills.FireMagic,
SecondarySkills.Archery,
SecondarySkills.EarthMagic,
SecondarySkills.Artillery,
SecondarySkills.WaterMagic,
]
const damageCalculatorSkills = ['air', 'archery', 'armorer', 'artillery', 'earth', 'fire', 'offense', 'water']
const skills = {}
store.skills
.filter((skill) => damageCalculatorSkillsIds.includes(skill.id))
.forEach((skill, index) => (skills[damageCalculatorSkills[index]] = skill.name))
return skills
})
const effects = computed(() => [store.attackPositiveEffects, store.defensePositiveEffects, store.attackNegativeEffects])
const onSelectCreature = (side: DamageCalculatorBattleSide, creature: Creature) => {
const creatureInstance = new CreatureInstance(creature)
if (side.activeCreature) creatureInstance.count = side.activeCreature.count
side.activeCreature = creatureInstance
side.creatures[0] = creatureInstance
}
// Return string of total damage or total kills
const getTotalResultString = (min: number, max: number, average: number) => {
if (min !== max) return `${min} — ${max} (~ ${average})`
else if (min === max) return min
else return 0
}
const onSelectHero = (side: DamageCalculatorBattleSide, hero: Hero) => {
side.hero = new HeroInstance(hero)
}
const onSelectCreature = (side: DamageCalculatorBattleSide, creature: Creature) => {
const creatureInstance = new CreatureInstance(creature)
if (side.activeCreature) creatureInstance.count = side.activeCreature.count
side.activeCreature = creatureInstance
side.creatures[0] = creatureInstance
}
const onSelectCreatureEffect = (side: DamageCalculatorBattleSide, spell: Spell, effectEnabled: boolean) => {
if (!side.activeCreature) return
const onSelectHero = (side: DamageCalculatorBattleSide, hero: Hero) => {
side.hero = new HeroInstance(hero)
}
if (!effectEnabled) {
side.activeCreature.effects.push(spell)
} else {
side.activeCreature.effects = side.activeCreature.effects.filter(
(creatureEffect) => creatureEffect.id !== spell.id,
)
}
}
const onSelectCreatureEffect = (side: DamageCalculatorBattleSide, spell: Spell, effectEnabled: boolean) => {
if (!side.activeCreature) return
const isEffectEnabled = (side: DamageCalculatorBattleSide, spell: Spell) => {
return side.activeCreature?.effects.findIndex((creatureEffect) => creatureEffect.id === spell.id) !== -1
}
if (!effectEnabled) {
side.activeCreature.effects.push(spell)
} else {
side.activeCreature.effects = side.activeCreature.effects.filter((creatureEffect) => creatureEffect.id !== spell.id)
}
}
const onSelectTerrain = (terrain: Terrain | null) => {
battle.attacker.terrain = terrain
battle.defender.terrain = terrain
}
const isEffectEnabled = (side: DamageCalculatorBattleSide, spell: Spell) => {
return side.activeCreature?.effects.findIndex((creatureEffect) => creatureEffect.id === spell.id) !== -1
}
return {
t,
battle,
heroes,
terrains,
levels,
skills,
effects,
getTotalResultString,
onSelectCreature,
onSelectHero,
onSelectCreatureEffect,
isEffectEnabled,
onSelectTerrain,
}
},
})
const onSelectTerrain = (terrain: Terrain | null) => {
battle.attacker.terrain = terrain
battle.defender.terrain = terrain
}
</script>

<style lang="scss" scoped>
Expand Down
Loading

0 comments on commit a5e9525

Please sign in to comment.