diff options
| -rw-r--r-- | src/card_db.js | 19 | ||||
| -rw-r--r-- | src/components/card_thumb.svelte | 77 | ||||
| -rw-r--r-- | src/components/main_panel.svelte | 25 | ||||
| -rw-r--r-- | src/components/right_panel.svelte | 6 | ||||
| -rw-r--r-- | src/deck.js | 43 | ||||
| -rw-r--r-- | src/ocg_banlist.json | 195 |
6 files changed, 338 insertions, 27 deletions
diff --git a/src/card_db.js b/src/card_db.js index b9b991f..5660ff3 100644 --- a/src/card_db.js +++ b/src/card_db.js @@ -1,5 +1,23 @@ +import ocgBanList from "./ocg_banlist.json"; + let cardDb = {}; let altId = {}; +let banList = { + none: { + ban: [], + limit: [], + semiLimit: [], + }, + ocg: ocgBanList, +}; + +function cardLimit(id, env) { + let lst = banList[env]; + if (lst.ban.includes(id)) return 0; + if (lst.limit.includes(id)) return 1; + if (lst.semiLimit.includes(id)) return 2; + return 3; +} function setCardDb(d) { cardDb = d; @@ -22,4 +40,5 @@ export { setCardDb, getAltId, setAltId, + cardLimit, }; diff --git a/src/components/card_thumb.svelte b/src/components/card_thumb.svelte index 8e701ea..e68a37e 100644 --- a/src/components/card_thumb.svelte +++ b/src/components/card_thumb.svelte @@ -1,9 +1,8 @@ <script lang="js"> - import { setLeftPanelCard } from '../left_panel'; import { cardImageUrl } from '../utils'; - let {id, area, idx} = $props(); + let {id, area, idx, limitNum} = $props(); function onhover() { setLeftPanelCard(id); @@ -12,22 +11,74 @@ function onDragStart(e) { e.dataTransfer.setData('text', JSON.stringify({id, area, idx})) } - </script> {#if id} - <img - style="margin:2px;" - draggable="true" - onmouseover={onhover} - onfocus={onhover} - ondragstart={onDragStart} - height="100%" - src={cardImageUrl(id)} - alt="yugioh card {id}" - /> + <img + style="margin:2px;" + draggable="true" + onmouseover={onhover} + onfocus={onhover} + ondragstart={onDragStart} + height="100%" + src={cardImageUrl(id)} + alt="yugioh card {id}" + /> + {#if limitNum === 1 || limitNum == 2} + <div class="overlay">{limitNum}</div> + {:else if limitNum === 0} + <div class="ban-overlay"></div> + {/if} {/if} <style> + .overlay { + position: absolute; + top: 0; + left: 0; + border: 3px solid red; + border-radius: 50%; + background-color: black; + width: 20px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; + font-weight: bold; + color: yellow; + font-size: 15px; + font-family: Arial, sans-serif; + box-sizing: border-box; + pointer-events: none; + } + + .ban-overlay { + position: absolute; + top: 0; + left: 0; + border: 3px solid red; + border-radius: 50%; + background-color: black; + width: 20px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; + font-weight: bold; + color: yellow; + font-size: 15px; + font-family: Arial, sans-serif; + box-sizing: border-box; + pointer-events: none; + } + .ban-overlay::after { + content: ''; + width: 15px; + height: 3px; + background-color: red; + transform: rotate(45deg); + position: absolute; + pointer-events: none; + } </style> diff --git a/src/components/main_panel.svelte b/src/components/main_panel.svelte index 2db7a34..1c55d49 100644 --- a/src/components/main_panel.svelte +++ b/src/components/main_panel.svelte @@ -1,6 +1,7 @@ <script lang="js"> import CardThumb from './card_thumb.svelte'; - import { deck, setDeck, deckOps } from '../deck'; + import { deck, setDeck, deckOps, format, setFormat } from '../deck'; + import { cardLimit } from '../card_db'; import { parseYdk, genYdk, @@ -74,6 +75,8 @@ } + + </script> <input bind:this={fileInput} style="display:none;" onchange={loadDeck} type="file" class="file-input" accept=".ydk" /> @@ -84,6 +87,11 @@ <button class="btn" onclick={saveDeck}>保存</button> <button class="btn" onclick={copyDeck}>复制到剪贴板</button> <button class="btn" onclick={shareDeck}>分享</button> + <select bind:value={$format} class="select-format" id="format" onchange={()=>setFormat($format)}> + <option value="none">无禁限</option> + <option value="ocg">OCG</option> + </select> + </div> <div class="deck-section"> <div class="deck-group"> @@ -91,7 +99,7 @@ <div role="region" ondragover={(e)=>e.preventDefault()} ondrop={(e)=>onDrop("main", e, -1)} class="card-grid main-deck"> {#each $deck.main as card, i} <div class="card-grid-thumb" role="region" ondragover={(e)=>e.preventDefault()} ondrop={(e)=>onDrop("main", e, i)}> - <CardThumb id={card} idx={i} area="main" /> + <CardThumb id={card} idx={i} area="main" limitNum={cardLimit(card, $format)} /> </div> {/each} </div> @@ -101,7 +109,7 @@ <div role="region" ondragover={(e)=>e.preventDefault()} ondrop={(e)=>onDrop("extra", e, -1)} class="card-grid extra-deck"> {#each $deck.extra as card, i} <div class="card-grid-thumb" role="region" ondragover={(e)=>e.preventDefault()} ondrop={(e)=>onDrop("extra", e, i)}> - <CardThumb id={card} idx={i} area="extra" /> + <CardThumb id={card} idx={i} area="extra" limitNum={cardLimit(card, $format)} /> </div> {/each} </div> @@ -111,7 +119,7 @@ <div role="region" ondragover={(e)=>e.preventDefault()} ondrop={(e)=>onDrop("side", e, -1)} class="card-grid side-deck"> {#each $deck.side as card, i} <div class="card-grid-thumb" role="region" ondragover={(e)=>e.preventDefault()} ondrop={(e)=>onDrop("side", e, i)}> - <CardThumb id={card} idx={i} area="side" /> + <CardThumb id={card} idx={i} area="side" limitNum={cardLimit(card, $format)} /> </div> {/each} </div> @@ -142,6 +150,14 @@ cursor: pointer; } + +.select-format { + padding: 8px 8px; + margin-right: 10px; + cursor: pointer; + font-size: 1.1em; +} + .deck-group { margin-bottom: 30px; } @@ -163,6 +179,7 @@ } .card-grid-thumb { + position: relative; aspect-ratio: 1/1.4; border-radius: 5px; } diff --git a/src/components/right_panel.svelte b/src/components/right_panel.svelte index 816687e..9863d97 100644 --- a/src/components/right_panel.svelte +++ b/src/components/right_panel.svelte @@ -1,7 +1,8 @@ <script lang="js"> import CardThumb from './card_thumb.svelte'; import { changeInput, showingCards, onPrevPage, onNextPage } from '../search' - import { deckOps } from '../deck'; + import { deckOps, format } from '../deck'; + import { cardLimit } from '../card_db'; function onChange(event) { changeInput(event.target.value); @@ -24,7 +25,7 @@ {#each $showingCards as card} <div class="card-item"> <div class="card-thumbnail"> - <CardThumb id={card.id} idx={-1} area="search" /> + <CardThumb id={card.id} idx={-1} area="search" limitNum={cardLimit(card.id, $format)} /> </div> <span>{card.name}</span> </div> @@ -87,6 +88,7 @@ } .card-thumbnail { + position: relative; width: 50px; height: 70px; background-color: #eee; diff --git a/src/deck.js b/src/deck.js index 285320b..7812128 100644 --- a/src/deck.js +++ b/src/deck.js @@ -1,11 +1,15 @@ import { writable } from "svelte/store"; import { parseYdke } from './utils'; -import { getCardDb, getAltId } from './card_db'; +import { getCardDb, getAltId, cardLimit } from './card_db'; let deck = writable({main: [], extra: [], side: []}); let deckState = {main: [], extra: [], side: []}; -function sanitizeDeck(deck) { +let defaultFormat = 'none'; +let format = writable(defaultFormat); +let formatState = defaultFormat; + +function sanitizeDeck(cardCnt, deck) { let cardDb = getCardDb(); let altId = getAltId(); let ret = []; @@ -13,17 +17,26 @@ function sanitizeDeck(deck) { if (altId[id] !== undefined) { id = altId[id]; } - if (cardDb[id] !== undefined) { - ret.push(id); + if (cardDb[id] === undefined) { + continue; + } + if (!cardCnt.has(id)) { + cardCnt.set(id, 0); } + if (cardCnt.get(id) >= cardLimit(id, formatState)) { + continue; + } + ret.push(id); + cardCnt.set(id, cardCnt.get(id) + 1); } return ret; } function setDeck(d) { - d.main = sanitizeDeck(d.main); - d.side = sanitizeDeck(d.side); - d.extra = sanitizeDeck(d.extra); + let cardCnt = new Map(); + d.main = sanitizeDeck(cardCnt, d.main); + d.side = sanitizeDeck(cardCnt, d.side); + d.extra = sanitizeDeck(cardCnt, d.extra); deckState = d; deck.set(d); localStorage.setItem('cachedDeck', JSON.stringify(d)); @@ -82,7 +95,6 @@ let deckOps = { }, "add2main": (id, targetIdx) => { let cardDb = getCardDb(); - console.log(targetIdx); if (cardDb[id].isExtra) return; let d = deckState; if (canAdd(d, id)) { @@ -117,6 +129,10 @@ function initDeck() { return; } } + let cachedFormat = localStorage.getItem('format'); + if (cachedFormat !== null) { + setFormat(cachedFormat); + } let cachedDeck = localStorage.getItem('cachedDeck'); if (cachedDeck !== null) { cachedDeck = JSON.parse(cachedDeck); @@ -125,8 +141,19 @@ function initDeck() { } } +function setFormat(newFormat) { + if (newFormat === 'none' || newFormat === 'ocg') { + localStorage.setItem('format', newFormat); + formatState = newFormat; + format.set(newFormat); + setDeck(deckState); + } +} + export { deck, + format, + setFormat, setDeck, deckOps, initDeck, diff --git a/src/ocg_banlist.json b/src/ocg_banlist.json new file mode 100644 index 0000000..2763143 --- /dev/null +++ b/src/ocg_banlist.json @@ -0,0 +1,195 @@ +{ + "ban": [ + "95727991", + "69015963", + "11384280", + "79571449", + "55144522", + "80604091", + "85602018", + "17375316", + "44763025", + "42829885", + "42703248", + "74191942", + "61740673", + "70828912", + "57953380", + "60682203", + "91869203", + "78706415", + "63789924", + "93016201", + "28566710", + "41482598", + "64697231", + "79875176", + "46411259", + "35059553", + "34206604", + "34906152", + "69243953", + "44910027", + "23557835", + "3280747", + "27174286", + "32723153", + "31423101", + "15341821", + "17178486", + "73356503", + "75732622", + "14702066", + "20663556", + "96782886", + "63101919", + "23558733", + "93369354", + "57421866", + "8903700", + "88071625", + "5851097", + "16923472", + "34086406", + "54719828", + "51858306", + "21044178", + "54447022", + "17412721", + "63504681", + "77679716", + "34945480", + "58820923", + "52653092", + "62242678", + "27552504", + "9929398", + "90809975", + "85115440", + "88581108", + "50588353", + "3679218", + "39064822", + "22593417", + "86148577", + "59537380", + "76375976", + "83152482", + "70369116", + "85243784", + "3040496", + "2563463", + "92731385", + "27381364", + "25926710", + "62320425", + "32909498" + ], + "limit": [ + "8124921", + "44519536", + "70903634", + "7902349", + "33396948", + "18144506", + "72892473", + "83764718", + "19613556", + "34124316", + "81439173", + "32807846", + "73628505", + "90846359", + "82732705", + "23701465", + "75500286", + "1845204", + "1475311", + "23516703", + "17266660", + "53334471", + "2295440", + "27970830", + "6602300", + "93600443", + "90953320", + "33782437", + "75433814", + "20292186", + "90361010", + "7394770", + "38814750", + "74586817", + "94689206", + "78872731", + "48905153", + "76794549", + "73468603", + "21076084", + "24207889", + "24094258", + "23002292", + "52340444", + "65681983", + "37818794", + "84211599", + "44362883", + "92107604", + "76145933", + "13533678", + "74078255", + "572850", + "37961969", + "73956664", + "36521307", + "15443125", + "77103950", + "63542003", + "99937011", + "33854624", + "6637331", + "32731036", + "68304193", + "72656408", + "4928565", + "71832012", + "21347668", + "61292243", + "85106525", + "72270339", + "9674034", + "29301450", + "90241276", + "91810826", + "30336082", + "80453041", + "60764609", + "98567237", + "34022970" + ], + "semiLimit": [ + "33508719", + "45986603", + "48130397", + "67723438", + "23434538", + "81275020", + "17330916", + "35261759", + "46060017", + "35726888", + "11110587", + "12289247", + "21377582", + "24224830", + "49238328", + "52947044", + "91800273", + "65734501", + "92714517", + "2526224", + "93729896", + "7477101" + ] +} + |
