mlpcardgame/src/components/DeckBuilder/DeckList.vue

230 lines
4.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<section class="decklist">
<section class="card-section" v-for="section in sections" :key="section">
<header>
<h1>{{ section }}</h1>
</header>
<article
class="ccgcard"
@click="() => _drop(card)"
v-for="(card, i) in getCards(section, true)"
:key="i"
>
<img :src="imageURL(card.data.ID)" class="cardbg" />
<div class="amt">{{ card.howmany }}</div>
<div class="fullname">
<div class="name">{{ card.data.Name }}</div>
<div class="subname">
{{ card.data.Subname ? card.data.Subname : "" }}
</div>
</div>
</article>
</section>
</section>
</template>
<style lang="scss" scoped>
@import "@/assets/scss/_variables.scss";
.decklist {
display: flex;
flex-direction: column;
}
.card-section {
header {
h1 {
padding: 5px 10px;
font-family: $fantasy;
font-size: 10pt;
}
}
}
.ccgcard {
display: flex;
align-content: space-between;
align-items: center;
border: 1px solid $grey;
border-radius: 10px;
padding: 5px 3px;
margin: 2px 0;
cursor: pointer;
position: relative;
overflow: hidden;
div {
z-index: 2;
}
}
.cardbg {
position: absolute;
margin-top: 30%;
right: -20px;
left: -20px;
max-width: none;
width: 120%;
filter: brightness(20%);
z-index: 1;
}
.fullname {
display: flex;
flex-direction: column;
}
.amt {
margin: 0 6pt 0 10pt;
font-weight: bold;
font-size: 13pt;
&:after {
content: " ×";
font-weight: 300;
}
}
.name {
font-family: $fantasy;
font-size: 10.5pt;
line-height: 1rem;
}
.subname {
color: $grey-light;
font-size: 10pt;
line-height: 1rem;
}
</style>
<script lang="ts">
import { Component, Vue, Prop } from "vue-property-decorator";
import {
cardFullName,
CardSlot,
Card,
cardImageURL,
multiElemStr,
typeNames
} from "@/mlpccg";
function sortCards(a: CardSlot, b: CardSlot): number {
// Sort by element
// (Cards are guaranteed to be the same type)
switch (a.data.Type) {
case "Friend":
{
// Sort by requirement
if (a.data.Requirement && b.data.Requirement) {
const reqA = multiElemStr(Object.keys(a.data.Requirement));
const reqB = multiElemStr(Object.keys(b.data.Requirement));
if (reqA > reqB) {
return 1;
}
if (reqB > reqA) {
return -1;
}
}
// Sort by cost
if (a.data.Cost && b.data.Cost) {
if (a.data.Cost > b.data.Cost) {
return 1;
}
if (a.data.Cost < b.data.Cost) {
return -1;
}
}
// Sort by element
const elemA = multiElemStr(a.data.Element);
const elemB = multiElemStr(b.data.Element);
if (elemA > elemB) {
return 1;
}
if (elemB > elemA) {
return -1;
}
}
break;
case "Problem":
if (a.data.ProblemRequirement && b.data.ProblemRequirement) {
const preqA = multiElemStr(Object.keys(a.data.ProblemRequirement));
const preqB = multiElemStr(Object.keys(b.data.ProblemRequirement));
if (preqA > preqB) {
return 1;
}
if (preqB > preqA) {
return -1;
}
}
break;
case "Event":
case "Resource":
if (a.data.Requirement && b.data.Requirement) {
const reqA = multiElemStr(Object.keys(a.data.Requirement));
const reqB = multiElemStr(Object.keys(b.data.Requirement));
if (reqA > reqB) {
return 1;
}
if (reqB > reqA) {
return -1;
}
}
break;
}
// Sort by power
if (a.data.Power && b.data.Power) {
if (a.data.Power > b.data.Power) {
return 1;
}
if (a.data.Power < b.data.Power) {
return -1;
}
}
// If all else fail, sort by name
const nameA = cardFullName(a.data);
const nameB = cardFullName(b.data);
if (nameA > nameB) {
return 1;
}
if (nameA < nameB) {
return -1;
}
return 0;
}
@Component({
components: {}
})
export default class DeckList extends Vue {
@Prop()
public cards!: CardSlot[];
private fullName(card: Card): string {
return cardFullName(card);
}
private _drop(slot: CardSlot) {
this.$emit("removed", slot);
}
private imageURL(id: string) {
return cardImageURL(id);
}
private getCards(section: string, sort: boolean): CardSlot[] {
let cards = this.cards.filter(c => c.data.Type == section);
if (!sort) {
return cards;
}
return cards.sort(sortCards);
}
private get sections(): string[] {
return typeNames.filter(s => this.getCards(s, false).length > 0);
}
}
</script>