From 85bbd7abe5d8c17cc75e38298ee3b3d99fc76417 Mon Sep 17 00:00:00 2001 From: tritoch Date: Wed, 16 Mar 2016 16:21:22 -0500 Subject: [PATCH 1/9] ISD/DKA Rarity Corrected rarity for double faced cards in ISD and DKA --- src/make/cards.js | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/make/cards.js b/src/make/cards.js index 0a9d2ff..300b9cd 100644 --- a/src/make/cards.js +++ b/src/make/cards.js @@ -76,6 +76,60 @@ function before() { } function after() { + var {ISD} = Sets + ISD.special = { + mythic: [ + 'garruk relentless' + ], + rare: [ + 'bloodline keeper', + 'daybreak ranger', + 'instigator gang', + 'kruin outlaw', + 'ludevic\'s test subject', + 'mayor of avabruck' + ], + uncommon: [ + 'civilized scholar', + 'cloistered youth', + 'gatstaf shepherd', + 'hanweir watchkeep', + 'reckless waif', + 'screeching bat', + 'ulvenwald mystics' + ], + common: [ + 'delver of secrets', + 'grizzled outcasts', + 'thraben sentry', + 'tormented pariah', + 'village ironsmith', + 'villagers of estwald' + ] + } + var {DKA} = Sets + DKA.special = { + mythic: [ + 'elbrus, the binding blade', + 'huntmaster of the fells' + ], + rare: [ + 'mondronen shaman', + 'ravenous demon' + ], + uncommon: [ + 'afflicted deserter', + 'chalice of life', + 'lambholt elder', + 'soul seizer' + ], + common: [ + 'chosen of markov', + 'hinterland hermit', + 'loyal cathar', + 'scorned villager' + ] + } var {DGM} = Sets DGM.mythic.splice(DGM.mythic.indexOf("maze's end"), 1) DGM.special = { From 178284c5f7f942ee24754a49484c19f20dbc6be3 Mon Sep 17 00:00:00 2001 From: tritoch Date: Wed, 16 Mar 2016 16:22:48 -0500 Subject: [PATCH 2/9] ISD/DKA Rarity Corrected rarity for double-faced cards in ISD & DKA (and added DKA DFC) --- src/pool.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/pool.js b/src/pool.js index 991d2c8..23e878e 100644 --- a/src/pool.js +++ b/src/pool.js @@ -53,7 +53,33 @@ function toPack(code) { special = _.rand(20) ? special.common : special.fetch - break + break + case 'ISD': + //http://www.mtgsalvation.com/forums/magic-fundamentals/magic-general/327956-innistrad-block-transforming-card-pack-odds?comment=4 + //121 card sheet, 1 mythic, 12 rare (13), 42 uncommon (55), 66 common + var specialrnd = _.rand(121) + if (specialrnd == 1) + special = special.mythic + else if (specialrnd <= 13) + special = special.rare + else if (specialrnd <= 55) + special = special.uncommon + else + special = special.common + break + case 'DKA': + //http://www.mtgsalvation.com/forums/magic-fundamentals/magic-general/327956-innistrad-block-transforming-card-pack-odds?comment=4 + //80 card sheet, 2 mythic, 6 rare (8), 24 uncommon (32), 48 common + var specialrnd = _.rand(80) + if (specialrnd <= 2) + special = special.mythic + else if (specialrnd <= 8) + special = special.rare + else if (specialrnd <= 32) + special = special.uncommon + else + special = special.common + break } if (special) From a8ce8267f9708abb140f00d58a44b9c9fddaf7bf Mon Sep 17 00:00:00 2001 From: tritoch Date: Wed, 16 Mar 2016 20:55:36 -0500 Subject: [PATCH 3/9] ISD/DKA Math Fixes --- src/pool.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pool.js b/src/pool.js index 23e878e..4bbbf72 100644 --- a/src/pool.js +++ b/src/pool.js @@ -58,11 +58,11 @@ function toPack(code) { //http://www.mtgsalvation.com/forums/magic-fundamentals/magic-general/327956-innistrad-block-transforming-card-pack-odds?comment=4 //121 card sheet, 1 mythic, 12 rare (13), 42 uncommon (55), 66 common var specialrnd = _.rand(121) - if (specialrnd == 1) + if (specialrnd == 0) special = special.mythic - else if (specialrnd <= 13) + else if (specialrnd < 13) special = special.rare - else if (specialrnd <= 55) + else if (specialrnd < 55) special = special.uncommon else special = special.common @@ -71,11 +71,11 @@ function toPack(code) { //http://www.mtgsalvation.com/forums/magic-fundamentals/magic-general/327956-innistrad-block-transforming-card-pack-odds?comment=4 //80 card sheet, 2 mythic, 6 rare (8), 24 uncommon (32), 48 common var specialrnd = _.rand(80) - if (specialrnd <= 2) + if (specialrnd <= 1) special = special.mythic - else if (specialrnd <= 8) + else if (specialrnd < 8) special = special.rare - else if (specialrnd <= 32) + else if (specialrnd < 32) special = special.uncommon else special = special.common From 15857affbb22c118e1fe25741a7bb0b82aae9e24 Mon Sep 17 00:00:00 2001 From: tritoch Date: Wed, 16 Mar 2016 21:29:37 -0500 Subject: [PATCH 4/9] Declare implicitly --- src/pool.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pool.js b/src/pool.js index 4bbbf72..f5c1834 100644 --- a/src/pool.js +++ b/src/pool.js @@ -57,7 +57,7 @@ function toPack(code) { case 'ISD': //http://www.mtgsalvation.com/forums/magic-fundamentals/magic-general/327956-innistrad-block-transforming-card-pack-odds?comment=4 //121 card sheet, 1 mythic, 12 rare (13), 42 uncommon (55), 66 common - var specialrnd = _.rand(121) + specialrnd = _.rand(121) if (specialrnd == 0) special = special.mythic else if (specialrnd < 13) @@ -70,7 +70,7 @@ function toPack(code) { case 'DKA': //http://www.mtgsalvation.com/forums/magic-fundamentals/magic-general/327956-innistrad-block-transforming-card-pack-odds?comment=4 //80 card sheet, 2 mythic, 6 rare (8), 24 uncommon (32), 48 common - var specialrnd = _.rand(80) + specialrnd = _.rand(80) if (specialrnd <= 1) special = special.mythic else if (specialrnd < 8) From b73726ff6b8502864f9e86eef7f905dea1531fd9 Mon Sep 17 00:00:00 2001 From: tritoch Date: Tue, 29 Mar 2016 22:45:57 -0500 Subject: [PATCH 5/9] syntax update --- src/pool.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pool.js b/src/pool.js index f5c1834..569a41f 100644 --- a/src/pool.js +++ b/src/pool.js @@ -57,7 +57,7 @@ function toPack(code) { case 'ISD': //http://www.mtgsalvation.com/forums/magic-fundamentals/magic-general/327956-innistrad-block-transforming-card-pack-odds?comment=4 //121 card sheet, 1 mythic, 12 rare (13), 42 uncommon (55), 66 common - specialrnd = _.rand(121) + let specialrnd = _.rand(121) if (specialrnd == 0) special = special.mythic else if (specialrnd < 13) @@ -70,7 +70,7 @@ function toPack(code) { case 'DKA': //http://www.mtgsalvation.com/forums/magic-fundamentals/magic-general/327956-innistrad-block-transforming-card-pack-odds?comment=4 //80 card sheet, 2 mythic, 6 rare (8), 24 uncommon (32), 48 common - specialrnd = _.rand(80) + let specialrnd = _.rand(80) if (specialrnd <= 1) special = special.mythic else if (specialrnd < 8) From 5f9936a7449351ec7450824b9d36fa12f9f767dd Mon Sep 17 00:00:00 2001 From: tritoch Date: Tue, 29 Mar 2016 22:49:46 -0500 Subject: [PATCH 6/9] Change to MTGJSON format mtgjson no longer uses front side name first, now checking card number for 'b' --- src/make/cards.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/make/cards.js b/src/make/cards.js index 300b9cd..b7d9fd3 100644 --- a/src/make/cards.js +++ b/src/make/cards.js @@ -221,7 +221,7 @@ function doCard(rawCard, cards, code, set) { var {name} = rawCard if (['double-faced', 'flip'].indexOf(rawCard.layout) > -1 - && name !== rawCard.names[0]) + && rawCard.number.indexOf('b') > -1) return if (rawCard.layout === 'split') From 6afbf3e496f95eea31311bf32d4ed36ee6fc3a8b Mon Sep 17 00:00:00 2001 From: Waleed Khan Date: Mon, 9 May 2016 22:38:01 -0400 Subject: [PATCH 7/9] Syntax update update Previously, an attempt to run `node app.js` would fail with this mysterious and wholly unhelpful error: undefined:24786 throw errorReporter.errors; ^ :73:9: Duplicate declaration, specialrnd Evidently, a declaration is duplicated if it is made across case bodies. --- src/pool.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pool.js b/src/pool.js index 569a41f..34b8768 100644 --- a/src/pool.js +++ b/src/pool.js @@ -32,6 +32,8 @@ function toPack(code) { _.choose(1, rare) ) + let specialrnd + switch (code) { case 'DGM': special = _.rand(20) @@ -57,7 +59,7 @@ function toPack(code) { case 'ISD': //http://www.mtgsalvation.com/forums/magic-fundamentals/magic-general/327956-innistrad-block-transforming-card-pack-odds?comment=4 //121 card sheet, 1 mythic, 12 rare (13), 42 uncommon (55), 66 common - let specialrnd = _.rand(121) + specialrnd = _.rand(121) if (specialrnd == 0) special = special.mythic else if (specialrnd < 13) @@ -70,7 +72,7 @@ function toPack(code) { case 'DKA': //http://www.mtgsalvation.com/forums/magic-fundamentals/magic-general/327956-innistrad-block-transforming-card-pack-odds?comment=4 //80 card sheet, 2 mythic, 6 rare (8), 24 uncommon (32), 48 common - let specialrnd = _.rand(80) + specialrnd = _.rand(80) if (specialrnd <= 1) special = special.mythic else if (specialrnd < 8) From 0f4ca3d0f27e6ba28be9f030cc527ae06122fc2e Mon Sep 17 00:00:00 2001 From: Waleed Khan Date: Mon, 9 May 2016 23:25:19 -0400 Subject: [PATCH 8/9] Add highlight and autopick text to hovered and autopicked cards When hovered over, cards now turn slightly brighter. Additionally, the user can click a card to set it to be autopicked. The card then stays highlighted, and has the text 'autopick' on its bottom border. If the user picks another card, the old card is returned to normal and the new assumes autopick behavior. --- public/src/cards.js | 19 ++++++++++++--- public/src/components/grid.js | 15 ++++++++---- public/style.css | 45 +++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/public/src/cards.js b/public/src/cards.js index f92c01a..0f2aa13 100644 --- a/public/src/cards.js +++ b/public/src/cards.js @@ -218,10 +218,23 @@ function cube() { } function clickPack(cardName) { - if (clicked !== cardName) - return clicked = cardName - let index = rawPack.findIndex(x => x.name === cardName) + let card = rawPack[index] + + if (clicked !== cardName) { + clicked = cardName + // There may be duplicate cards in a pack, but only one copy of a card is + // shown in the pick view. We must be sure to mark them all since we don't + // know which one is being displayed. + rawPack.forEach(card => card.isSelected = card.name == cardName); + App.update() + return clicked + } else if (card.hasOwnProperty('isSelected')) { + // Don't leave the is-selected overlay when moving the card to a different + // zone. + delete card['isSelected'] + } + clicked = null Zones.pack = {} App.update() diff --git a/public/src/components/grid.js b/public/src/components/grid.js index 4a47ceb..1f553bc 100644 --- a/public/src/components/grid.js +++ b/public/src/components/grid.js @@ -16,11 +16,16 @@ function zone(zoneName) { let cards = _.flat(values) let items = cards.map(card => - d.img({ - onClick: App._emit('click', zoneName, card.name), - src: card.url, - alt: card.name - })) + d.span( + { + className: card.isSelected ? 'selected-card' : 'unselected-card', + title: card.isSelected ? 'This card will be automatically picked if your time expires.' : '', + onClick: App._emit('click', zoneName, card.name), + }, + d.img({ + src: card.url, + alt: card.name, + }))) return d.div({ className: 'zone' }, d.h1({}, `${zoneName} ${cards.length}`), diff --git a/public/style.css b/public/style.css index 2eb5c41..d3b9fc4 100644 --- a/public/style.css +++ b/public/style.css @@ -39,6 +39,51 @@ time { color: white; } +/* Tint the card blue when selected. */ +.selected-card, .unselected-card { + display: inline-block; + position: relative; + margin: 0; + cursor: pointer; +} + +.selected-card:before, .unselected-card:hover:before { + content: ''; + + display: block; + position: absolute; + + top: 0; + bottom: 0; + left: 0; + right: 0; + + margin-bottom: 5px; + border-radius: 12px; + + background: rgba(200, 200, 200, 0.25); +} + +.selected-card:after { + content: 'Autopick'; + + display: inline-block; + position: absolute; + + /* Center in the middle of the bottom border on the card. */ + line-height: 25px; + bottom: 5px; + left: 0; + right: 0; + + color: #fff; + font-family: Verdana, Arial, sans-serif; + font-size: 13px; + font-weight: 700; + text-align: center; + text-shadow: 0px 0px 2px #000; +} + .error { color: red; } From d17eebe8c8eb8fae16954d087fc7af561cc5e0be Mon Sep 17 00:00:00 2001 From: Waleed Khan Date: Wed, 11 May 2016 14:12:09 -0400 Subject: [PATCH 9/9] Implement autopicking When the user selects a card for autopicking, but then their time expires, the server automatically picks the autopick card on their behalf rather than picking a card at random. This is behavior similar to that of MTGO. If the user fails to select any card at all, the old behavior applies and one is selected at random. --- public/src/cards.js | 7 ++----- public/src/components/grid.js | 6 ++++-- public/style.css | 7 +++---- src/game.js | 2 +- src/human.js | 18 ++++++++++++++---- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/public/src/cards.js b/public/src/cards.js index 0f2aa13..300fe1a 100644 --- a/public/src/cards.js +++ b/public/src/cards.js @@ -226,13 +226,10 @@ function clickPack(cardName) { // There may be duplicate cards in a pack, but only one copy of a card is // shown in the pick view. We must be sure to mark them all since we don't // know which one is being displayed. - rawPack.forEach(card => card.isSelected = card.name == cardName); + rawPack.forEach(card => card.isAutopick = card.name === cardName) App.update() + App.send('autopick', index) return clicked - } else if (card.hasOwnProperty('isSelected')) { - // Don't leave the is-selected overlay when moving the card to a different - // zone. - delete card['isSelected'] } clicked = null diff --git a/public/src/components/grid.js b/public/src/components/grid.js index 1f553bc..c4e4d6d 100644 --- a/public/src/components/grid.js +++ b/public/src/components/grid.js @@ -15,11 +15,13 @@ function zone(zoneName) { let values = _.values(zone) let cards = _.flat(values) + let isAutopickable = card => zoneName === 'pack' && card.isAutopick + let items = cards.map(card => d.span( { - className: card.isSelected ? 'selected-card' : 'unselected-card', - title: card.isSelected ? 'This card will be automatically picked if your time expires.' : '', + className: `card ${isAutopickable(card) ? 'autopick-card' : ''}`, + title: isAutopickable(card) ? 'This card will be automatically picked if your time expires.' : '', onClick: App._emit('click', zoneName, card.name), }, d.img({ diff --git a/public/style.css b/public/style.css index d3b9fc4..baecae6 100644 --- a/public/style.css +++ b/public/style.css @@ -39,15 +39,14 @@ time { color: white; } -/* Tint the card blue when selected. */ -.selected-card, .unselected-card { +.card { display: inline-block; position: relative; margin: 0; cursor: pointer; } -.selected-card:before, .unselected-card:hover:before { +.card:hover:before, .autopick-card:before { content: ''; display: block; @@ -64,7 +63,7 @@ time { background: rgba(200, 200, 200, 0.25); } -.selected-card:after { +.autopick-card:after { content: 'Autopick'; display: inline-block; diff --git a/src/game.js b/src/game.js index ef002cb..f6ff306 100644 --- a/src/game.js +++ b/src/game.js @@ -17,7 +17,7 @@ var games = {} continue for (var p of game.players) if (p.time && !--p.time) - p.pickRand() + p.pickOnTimeout() } setTimeout(playerTimer, SECOND) })() diff --git a/src/human.js b/src/human.js index 510d1f6..24c85dd 100644 --- a/src/human.js +++ b/src/human.js @@ -10,6 +10,7 @@ module.exports = class extends EventEmitter { name: sock.name, time: 0, packs: [], + autopick_index: -1, pool: [] }) this.attach(sock) @@ -19,6 +20,7 @@ module.exports = class extends EventEmitter { this.sock.ws.close() sock.mixin(this) + sock.on('autopick', this._autopick.bind(this)) sock.on('pick', this._pick.bind(this)) sock.on('hash', this._hash.bind(this)) @@ -34,6 +36,11 @@ module.exports = class extends EventEmitter { this.hash = hash(deck) this.emit('meta') } + _autopick(index) { + var [pack] = this.packs + if (pack && index < pack.length) + this.autopick_index = index + } _pick(index) { var [pack] = this.packs if (pack && index < pack.length) @@ -65,17 +72,20 @@ module.exports = class extends EventEmitter { else this.sendPack(next) + this.autopick_index = -1 this.emit('pass', pack) } - pickRand() { - var index = _.rand(this.packs[0].length) + pickOnTimeout() { + let index = this.autopick_index + if (index === -1) + index = _.rand(this.packs[0].length) this.pick(index) } kick() { this.send = ()=>{} while(this.packs.length) - this.pickRand() - this.sendPack = this.pickRand + this.pickOnTimeout() + this.sendPack = this.pickOnTimeout this.isBot = true } }