diff --git a/package.json b/package.json index 70c4542..3b45895 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "babel-plugin-styled-components": "^1.10.7", "clean-webpack-plugin": "^0.1.19", "clipboard-polyfill": "^2.8.6", - "deckstrings": "^2.2.1", + "deckstrings": "^3.1.1", "file-loader": "^2.0.0", "hearthstonejson-client": "^1.4.0", "html-webpack-include-sibling-chunks-plugin": "0.1.0", diff --git a/src/globals.d.ts b/src/globals.d.ts index 8cab7c7..da02a23 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -14,8 +14,3 @@ declare module "*.otf" { } declare const APPLICATION_VERSION: string; - -declare module "deckstrings" { - export function decode(deckString: string): object; - export function encode(deck: object): string; -} diff --git a/src/twitch-hdt.d.ts b/src/twitch-hdt.d.ts index 625b964..af2b4b1 100644 --- a/src/twitch-hdt.d.ts +++ b/src/twitch-hdt.d.ts @@ -140,10 +140,43 @@ export interface BoardStateHand { size: number; } -export type BoardStateDeckCard = [number, number, number]; +export type BoardStateDeckCard = [ + /** + * dbf id + */ + number, + /** + * current count + */ + number, + /** + * initial count + */ + number, +]; + +export type SideboardDeckCard = [ + /** + * owner dbf id + */ + number, + /** + * dbf id + */ + number, + /** + * current count + */ + number, + /** + * initial count + */ + number, +]; export interface BoardStateDeck { - cards?: BoardStateDeckCard[]; // [dbfId, current, initial] + cards?: BoardStateDeckCard[]; + sideboard?: SideboardDeckCard[]; name?: string; hero?: number; format?: FormatType; @@ -157,6 +190,7 @@ export const enum FormatType { FT_WILD = 1, FT_STANDARD = 2, FT_CLASSIC = 3, + FT_TWIST = 4, } export const enum BnetGameType { diff --git a/src/utils/hearthstone.ts b/src/utils/hearthstone.ts index ef70c06..3ed9c39 100644 --- a/src/utils/hearthstone.ts +++ b/src/utils/hearthstone.ts @@ -1,8 +1,13 @@ -import { encode } from "deckstrings"; -import { BoardStateDeckCard, FormatType } from "../twitch-hdt"; +import { DeckDefinition, encode } from "deckstrings"; +import { + BoardStateDeckCard, + FormatType, + SideboardDeckCard, +} from "../twitch-hdt"; export const getDeckToCopy = ( cardList: BoardStateDeckCard[], + sideboard: SideboardDeckCard[], format: FormatType, heroes: number[], name?: string, @@ -11,10 +16,9 @@ export const getDeckToCopy = ( return null; } - const initialCards: [number, number][] = cardList + const initialCards: DeckDefinition["cards"] = cardList .filter((card: BoardStateDeckCard) => { - const [dbfId, current, initial] = card; - return !!initial; + return !!card[2]; }) .map<[number, number]>((card: BoardStateDeckCard) => { const [dbfId, current, initial] = card; @@ -34,15 +38,40 @@ export const getDeckToCopy = ( }, [], ); - const deckDescription = { + + const sideboardCards: DeckDefinition["sideboardCards"] = sideboard + .filter((card: SideboardDeckCard) => { + return !!card[3]; + }) + .map<[number, number, number]>((card: SideboardDeckCard) => { + const [owner, dbfId, current, initial] = card; + return [dbfId, initial, owner]; + }) + .reduce<[number, number, number][]>( + (result: [number, number, number][], card: [number, number, number]) => { + result = result.slice(0); + for (let i = 0; i < result.length; i++) { + if (result[i][0] === card[0] && result[i][2] === card[2]) { + result[i][1] += card[1]; + return result; + } + } + // new card, append + return result.concat([card]); + }, + [], + ); + + const deckDefinition: DeckDefinition = { cards: initialCards, + sideboardCards, format, heroes, }; let deckstring = null; try { - deckstring = encode(deckDescription); + deckstring = encode(deckDefinition); } catch (e) { console.error(e); return null; @@ -54,13 +83,20 @@ export const getDeckToCopy = ( const isStandard = format === FormatType.FT_STANDARD; const isClassic = format === FormatType.FT_CLASSIC; + const isTwist = format === FormatType.FT_TWIST; return [ ...(name ? [`### ${name}`] : []), ...(format ? [ `# Format: ${ - isStandard ? "Standard" : isClassic ? "Classic" : "Wild" + isStandard + ? "Standard" + : isTwist + ? "Twist" + : isClassic + ? "Classic" + : "Wild" }`, ] : []), diff --git a/src/viewer/CopyDeckButton.tsx b/src/viewer/CopyDeckButton.tsx index 86b830d..ff1e691 100644 --- a/src/viewer/CopyDeckButton.tsx +++ b/src/viewer/CopyDeckButton.tsx @@ -92,11 +92,11 @@ const CopyDeckButton: React.FC = ({ if (!deck) { return null; } - const { name, cards, format, hero } = deck; + const { name, cards, sideboard, format, hero } = deck; if (!format || !cards || !hero) { return null; } - return getDeckToCopy(cards, format, [hero], name); + return getDeckToCopy(cards, sideboard || [], format, [hero], name); }, [deck]); const copy = useCallback(async () => { diff --git a/yarn.lock b/yarn.lock index baea64c..7b263b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2513,10 +2513,10 @@ decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= -deckstrings@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/deckstrings/-/deckstrings-2.2.1.tgz#691fb8d8e19e77219cfd71ce56e38e1cd54d97a9" - integrity sha512-dwbSCKhmoPjT54Bs99PJB5Ur2F3vSwYKhkbiKXI2KoOmsc5orYSRfGAK10Qd9WAeUeFdPQ4PoUBrvtMuT7dveQ== +deckstrings@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/deckstrings/-/deckstrings-3.1.1.tgz#7cc60d97c9ddbd4bb22f3f1b608589cba119724b" + integrity sha512-FYrls5s83vE+y/fPVU5DjXUPh0aM77+fh52Rz/LWxZvS/fskWJ2z2JeyBTTV2y+CSq95MM/JexZeGCDYELtu6g== decode-uri-component@^0.2.0: version "0.2.0"