From 5d6c5b45bb95d0ed9a2f2b081f7c81fa56b898b8 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 15 Oct 2017 14:08:43 -0700 Subject: [PATCH] Show the original ability/price for SplatNet gear Data is sourced from Inkipedia. --- package.json | 1 + src/css/main.scss | 80 +- src/js/components/AboutDialog.vue | 6 +- src/js/components/splatoon/MerchandiseBox.vue | 46 +- src/js/data/brands.json | 107 ++ src/js/data/inkipediaGear.json | 1366 +++++++++++++++++ src/js/data/skills.json | 132 ++ src/js/splatoon.js | 18 + src/updater/retrieveGearData.js | 49 + src/updater/splatnet.js | 7 + src/updater/updateGear.js | 95 ++ 11 files changed, 1884 insertions(+), 23 deletions(-) create mode 100644 src/js/data/brands.json create mode 100644 src/js/data/inkipediaGear.json create mode 100644 src/js/data/skills.json create mode 100644 src/js/splatoon.js create mode 100644 src/updater/retrieveGearData.js create mode 100644 src/updater/updateGear.js diff --git a/package.json b/package.json index 1b40289..fb313e2 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "html-loader": "^0.5.0", "html-webpack-plugin": "^2.30.1", "ical.js": "^1.2.2", + "json-stable-stringify": "^1.0.1", "make-runnable": "^1.3.6", "mkdirp": "^0.5.1", "moment-timezone": "^0.5.13", diff --git a/src/css/main.scss b/src/css/main.scss index 49022be..7b9454b 100644 --- a/src/css/main.scss +++ b/src/css/main.scss @@ -317,6 +317,15 @@ body.has-modal #main { border-radius: 15px; padding: 38px 10px 0 10px; + transition: transform 0.2s ease; + + &.tilt-left:hover { + transform: rotate(-1.4deg) scale(1.05); + } + &.tilt-right:hover { + transform: rotate(1.4deg) scale(1.05); + } + .brand { position: absolute; top: 6px; @@ -358,36 +367,75 @@ body.has-modal #main { .gear-image { margin: 0 20px; - transition: transform 0.2s ease; - } - - &:hover .gear-image { - transform: scale(1.1); } .gear-name { position: relative; } - .frequent-skill { + .info-overlay { position: absolute; bottom: 0; left: 0; right: 0; - background: rgba($white-ter, 0.9); - border-radius: 10px; - opacity: 0; - transition: opacity 0.2s ease; + transform: translate(0, 2px); + transition: all 0.2s ease; + + .info-overlay-container { + margin-top: 2px; + background: rgba($white-ter, 0.9); + border-radius: 10px; + } .skill-img-bg img { width: 26px; } + + .original-gear { + .skill-img-bg img { + width: 24px; + } + + .sub { + margin: 7px 0 0 2px; + img { + width: 15px; + } + } + + .cash { + width: 20px; + height: 20px; + } + + .strikethrough { + position: relative; + } + + .strikethrough:before { + position: absolute; + content: ""; + left: -5px; + top: 50%; + right: -5px; + border-top: 3px solid; + border-color: red; + opacity: 0.6; + + -webkit-transform:rotate(-20deg); + -moz-transform:rotate(-20deg); + -ms-transform:rotate(-20deg); + -o-transform:rotate(-20deg); + transform:rotate(-20deg); + } + } } - &:hover .frequent-skill { + &:hover .info-overlay { opacity: 1; + transform: none; } .bottom-bar { @@ -399,12 +447,12 @@ body.has-modal #main { color: $white-ter; @extend .text-shadow; + } - .cash { - width: 24px; - height: 24px; - vertical-align: text-bottom; - } + .cash { + width: 24px; + height: 24px; + vertical-align: text-bottom; } &.shoes .bottom-bar { diff --git a/src/js/components/AboutDialog.vue b/src/js/components/AboutDialog.vue index 74f5710..7ab46b8 100644 --- a/src/js/components/AboutDialog.vue +++ b/src/js/components/AboutDialog.vue @@ -18,7 +18,11 @@

This site was built with Vue.js and Bulma. - All data comes from the SplatNet 2 API. + Data comes from the SplatNet 2 API and other manually-maintained sources. +

+

+ Original SplatNet gear ability/price data comes from + Inkipedia.

Source code for this site is available on diff --git a/src/js/components/splatoon/MerchandiseBox.vue b/src/js/components/splatoon/MerchandiseBox.vue index d574771..bde5f73 100644 --- a/src/js/components/splatoon/MerchandiseBox.vue +++ b/src/js/components/splatoon/MerchandiseBox.vue @@ -28,13 +28,40 @@

{{ merchandise.gear.name }} -
-
{{ merchandise.gear.brand.name }}
-
-
- +
+
+
Original Gear
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+ + {{ originalGear.price }} +
+
+
+
+
+ +
+
{{ merchandise.gear.brand.name }}
+
+
+ +
+ Common Ability
- Common Ability
@@ -47,7 +74,14 @@ diff --git a/src/js/data/brands.json b/src/js/data/brands.json new file mode 100644 index 0000000..24b12ef --- /dev/null +++ b/src/js/data/brands.json @@ -0,0 +1,107 @@ +{ + "0": { + "frequent_skill": "11", + "id": "0", + "image": "/images/brand/5547e529d160b188d104e3b68ff4b7566eab9771.png", + "name": "SquidForce" + }, + "1": { + "frequent_skill": "9", + "id": "1", + "image": "/images/brand/3d4661b3f60f4b74e9bb6760ba7397ecd2502a20.png", + "name": "Zink" + }, + "10": { + "frequent_skill": "2", + "id": "10", + "image": "/images/brand/02286fe17bb6bc3f5f13c6b251ddc0a55c44c756.png", + "name": "Tentatek" + }, + "11": { + "frequent_skill": "5", + "id": "11", + "image": "/images/brand/eab05d2d502cf953b4ae034c87e52e8c999339d6.png", + "name": "Takoroka" + }, + "15": { + "frequent_skill": "13", + "id": "15", + "image": "/images/brand/0b09659e2770389dcb23d911359175e8686f85f5.png", + "name": "Annaki" + }, + "16": { + "frequent_skill": "10", + "id": "16", + "image": "/images/brand/de96243d58e41e928d30290162a6f496033da868.png", + "name": "Enperry" + }, + "17": { + "frequent_skill": "13", + "id": "17", + "image": "/images/brand/4b05e494bf9a547b4d625fd52dcdd930a6c4defc.png", + "name": "Toni Kensa" + }, + "2": { + "frequent_skill": "4", + "id": "2", + "image": "/images/brand/9ac5752790dd6dbdc7a427df95e1bfe89fe318e0.png", + "name": "Krak-On" + }, + "3": { + "frequent_skill": "3", + "id": "3", + "image": "/images/brand/451a2d0b5ceb7ea4ec4e47c3ff05eee362e9b722.png", + "name": "Rockenberg" + }, + "4": { + "frequent_skill": "6", + "id": "4", + "image": "/images/brand/f3d01187fd633e7d48d9e4e16ef31da73279293c.png", + "name": "Zekko" + }, + "5": { + "frequent_skill": "7", + "id": "5", + "image": "/images/brand/b38b99b3358f587efd1613b72a72c9ca9f81f406.png", + "name": "Forge" + }, + "6": { + "frequent_skill": "1", + "id": "6", + "image": "/images/brand/dee59c0797a6214114e527dfa51f0dd012085172.png", + "name": "Firefin" + }, + "7": { + "frequent_skill": "8", + "id": "7", + "image": "/images/brand/8175954b5a7e02b8097dbb484c808c8f39d31f41.png", + "name": "Skalop" + }, + "8": { + "frequent_skill": "0", + "id": "8", + "image": "/images/brand/36bc10db0aa2640c87ad712fc0281515beedcca1.png", + "name": "Splash Mob" + }, + "9": { + "frequent_skill": "12", + "id": "9", + "image": "/images/brand/80648c6e427eae4d32677797fa1be7c0e253fda5.png", + "name": "Inkline" + }, + "97": { + "id": "97", + "image": "/images/brand/ec85f17c315e0a1ea4dee55041fd30a88d6aba93.png", + "name": "Grizzco" + }, + "98": { + "id": "98", + "image": "/images/brand/047cbc2f0674eeb4796efb3b6ec1b710b22d07e7.png", + "name": "Cuttlegear" + }, + "99": { + "id": "99", + "image": "/images/brand/154440ecbfb65a22cdb224fac843b02cccbcad03.png", + "name": "amiibo" + } +} \ No newline at end of file diff --git a/src/js/data/inkipediaGear.json b/src/js/data/inkipediaGear.json new file mode 100644 index 0000000..8708397 --- /dev/null +++ b/src/js/data/inkipediaGear.json @@ -0,0 +1,1366 @@ +{ + "clothes": [ + { + "brand": "0", + "name": "Anchor Sweat", + "price": 2800, + "rarity": 1, + "skill": "13" + }, + { + "brand": "15", + "name": "Annaki Drive Tee", + "price": 5500, + "rarity": 1, + "skill": "106" + }, + { + "brand": "15", + "name": "Annaki Evolution Tee", + "price": 8800, + "rarity": 2, + "skill": "107" + }, + { + "brand": "1", + "name": "B-ball Jersey (Away)", + "price": 800, + "rarity": 0, + "skill": "1" + }, + { + "brand": "8", + "name": "Baby-Jelly Shirt", + "price": 1350, + "rarity": 0, + "skill": "12" + }, + { + "brand": "8", + "name": "Baby-Jelly Shirt & Tie", + "price": 3800, + "rarity": 1, + "skill": "13" + }, + { + "brand": "9", + "name": "Berry Ski Jacket", + "price": 3900, + "rarity": 1, + "skill": "7" + }, + { + "brand": "4", + "name": "Birded Corduroy Jacket", + "price": 10400, + "rarity": 2, + "skill": "3" + }, + { + "brand": "3", + "name": "Black Inky Rider", + "price": 12100, + "rarity": 2, + "skill": "10" + }, + { + "brand": "4", + "name": "Black LS", + "price": 3000, + "rarity": 1, + "skill": "9" + }, + { + "brand": "10", + "name": "Black Squideye", + "price": 500, + "rarity": 0, + "skill": "3" + }, + { + "brand": "0", + "name": "Black Tee", + "price": 400, + "rarity": 0, + "skill": "7" + }, + { + "brand": "3", + "name": "Black Urchin Rock Tee", + "price": 850, + "rarity": 0, + "skill": "2" + }, + { + "brand": "0", + "name": "Black V-Neck Tee", + "price": 3800, + "rarity": 1, + "skill": "106" + }, + { + "brand": "9", + "name": "Blue Peaks Tee", + "price": 400, + "rarity": 0, + "skill": "1" + }, + { + "brand": "5", + "name": "Blue Sailor Suit", + "price": 11000, + "rarity": 2, + "skill": "10" + }, + { + "brand": "10", + "name": "Blue Tentatek Tee", + "price": 3100, + "rarity": 1, + "skill": "8" + }, + { + "brand": "6", + "name": "Camo Zip Hoodie", + "price": 9000, + "rarity": 2, + "skill": "8" + }, + { + "brand": "9", + "name": "Chilly Mountain Coat", + "price": 7900, + "rarity": 2, + "skill": "4" + }, + { + "brand": "3", + "name": "Chirpy Chips Band Tee", + "price": 900, + "rarity": 0, + "skill": "13" + }, + { + "brand": "11", + "name": "Choco Layered LS", + "price": 1400, + "rarity": 0, + "skill": "1" + }, + { + "brand": "15", + "name": "Crimson Parashooter", + "price": 9200, + "rarity": 2, + "skill": "5" + }, + { + "brand": "10", + "name": "Cycle King Jersey", + "price": 8900, + "rarity": 2, + "skill": "12" + }, + { + "brand": "6", + "name": "Dark Urban Vest", + "price": 10000, + "rarity": 2, + "skill": "13" + }, + { + "brand": "9", + "name": "Eggplant Mountain Coat", + "price": 7600, + "rarity": 2, + "skill": "6" + }, + { + "brand": "5", + "name": "FA-01 Jacket", + "price": 10100, + "rarity": 2, + "skill": "2" + }, + { + "brand": "5", + "name": "FA-01 Reversed", + "price": 10100, + "rarity": 2, + "skill": "9" + }, + { + "brand": "11", + "name": "FC Albacore", + "price": 1200, + "rarity": 0, + "skill": "107" + }, + { + "brand": "6", + "name": "Fugu Tee", + "price": 750, + "rarity": 0, + "skill": "4" + }, + { + "brand": "16", + "name": "Grape Hoodie", + "price": 1100, + "rarity": 0, + "skill": "8" + }, + { + "brand": "6", + "name": "Gray 8-Bit FishFry", + "price": 800, + "rarity": 0, + "skill": "5" + }, + { + "brand": "7", + "name": "Gray Hoodie", + "price": 1900, + "rarity": 1, + "skill": "10" + }, + { + "brand": "5", + "name": "Green Tee", + "price": 1200, + "rarity": 0, + "skill": "6" + }, + { + "brand": "4", + "name": "Green-Check Shirt", + "price": 2000, + "rarity": 1, + "skill": "10" + }, + { + "brand": "17", + "name": "Half-Sleeve Sweater", + "price": 4100, + "rarity": 1, + "skill": "1" + }, + { + "brand": "3", + "name": "Hightide Era Band Tee", + "price": 900, + "rarity": 0, + "skill": "106" + }, + { + "brand": "15", + "name": "Hula Punk Shirt", + "price": 5000, + "rarity": 1, + "skill": "0" + }, + { + "brand": "17", + "name": "Inkfall Shirt", + "price": 4900, + "rarity": 1, + "skill": "5" + }, + { + "brand": "1", + "name": "Inkopolis Squaps Jersey", + "price": 1250, + "rarity": 0, + "skill": "13" + }, + { + "brand": "16", + "name": "King Jersey", + "price": 3100, + "rarity": 1, + "skill": "107" + }, + { + "brand": "0", + "name": "Layered Anchor LS", + "price": 4000, + "rarity": 1, + "skill": "3" + }, + { + "brand": "11", + "name": "Layered Vector LS", + "price": 1200, + "rarity": 0, + "skill": "6" + }, + { + "brand": "8", + "name": "Lime Easy-Stripe Shirt", + "price": 3800, + "rarity": 1, + "skill": "11" + }, + { + "brand": "4", + "name": "Logo Aloha Shirt", + "price": 2900, + "rarity": 1, + "skill": "2" + }, + { + "brand": "9", + "name": "Matcha Down Jacket", + "price": 9100, + "rarity": 2, + "skill": "104" + }, + { + "brand": "7", + "name": "Mint Tee", + "price": 400, + "rarity": 0, + "skill": "12" + }, + { + "brand": "2", + "name": "Mister Shrug Tee", + "price": 9200, + "rarity": 2, + "skill": "11" + }, + { + "brand": "1", + "name": "Navy Deca Logo Tee", + "price": 1200, + "rarity": 0, + "skill": "0" + }, + { + "brand": "16", + "name": "Navy King Tank", + "price": 600, + "rarity": 0, + "skill": "11" + }, + { + "brand": "8", + "name": "Navy Striped LS", + "price": 1050, + "rarity": 0, + "skill": "2" + }, + { + "brand": "17", + "name": "Negative Longcuff Sweater", + "price": 11800, + "rarity": 2, + "skill": "105" + }, + { + "brand": "2", + "name": "Octobowler Shirt", + "price": 2100, + "rarity": 1, + "skill": "0" + }, + { + "brand": "8", + "name": "Pink Easy-Stripe Shirt", + "price": 3800, + "rarity": 1, + "skill": "9" + }, + { + "brand": "17", + "name": "Positive Longcuff Sweater", + "price": 10800, + "rarity": 2, + "skill": "4" + }, + { + "brand": "15", + "name": "Prune Parashooter", + "price": 7800, + "rarity": 2, + "skill": "104" + }, + { + "brand": "17", + "name": "Pullover Coat", + "price": 13200, + "rarity": 2, + "skill": "106" + }, + { + "brand": "11", + "name": "Purple Camo LS", + "price": 600, + "rarity": 0, + "skill": "10" + }, + { + "brand": "10", + "name": "Red Tentatek Tee", + "price": 3100, + "rarity": 1, + "skill": "4" + }, + { + "brand": "11", + "name": "Red Vector Tee", + "price": 500, + "rarity": 0, + "skill": "0" + }, + { + "brand": "4", + "name": "Reel Sweat", + "price": 900, + "rarity": 0, + "skill": "7" + }, + { + "brand": "0", + "name": "Retro Sweat", + "price": 9000, + "rarity": 2, + "skill": "12" + }, + { + "brand": "8", + "name": "Sailor-Stripe Tee", + "price": 700, + "rarity": 0, + "skill": "3" + }, + { + "brand": "8", + "name": "Shirt & Tie", + "price": 8400, + "rarity": 2, + "skill": "6" + }, + { + "brand": "8", + "name": "Shirt with Blue Hoodie", + "price": 2900, + "rarity": 1, + "skill": "7" + }, + { + "brand": "17", + "name": "Short Knit Layers", + "price": 9850, + "rarity": 2, + "skill": "0" + }, + { + "brand": "8", + "name": "Shrimp-Pink Polo", + "price": 550, + "rarity": 0, + "skill": "104" + }, + { + "brand": "16", + "name": "Slash King Tank", + "price": 450, + "rarity": 0, + "skill": "106" + }, + { + "brand": "11", + "name": "Slipstream United", + "price": 1800, + "rarity": 1, + "skill": "12" + }, + { + "brand": "4", + "name": "Squid Satin Jacket", + "price": 9200, + "rarity": 2, + "skill": "8" + }, + { + "brand": "3", + "name": "Squid Squad Band Tee", + "price": 900, + "rarity": 0, + "skill": "11" + }, + { + "brand": "2", + "name": "Sunny-Day Tee", + "price": 300, + "rarity": 0, + "skill": "5" + }, + { + "brand": "11", + "name": "Takoroka Windcrusher", + "price": 8500, + "rarity": 2, + "skill": "13" + }, + { + "brand": "1", + "name": "Urchins Jersey", + "price": 700, + "rarity": 0, + "skill": "3" + }, + { + "brand": "4", + "name": "Varsity Jacket", + "price": 11500, + "rarity": 2, + "skill": "1" + }, + { + "brand": "3", + "name": "Vintage Check Shirt", + "price": 9000, + "rarity": 2, + "skill": "105" + }, + { + "brand": "3", + "name": "Wet Floor Band Tee", + "price": 900, + "rarity": 0, + "skill": "4" + }, + { + "brand": "6", + "name": "White 8-Bit FishFry", + "price": 800, + "rarity": 0, + "skill": "10" + }, + { + "brand": "0", + "name": "White Anchor Tee", + "price": 2800, + "rarity": 1, + "skill": "104" + }, + { + "brand": "3", + "name": "White Baseball LS", + "price": 800, + "rarity": 0, + "skill": "9" + }, + { + "brand": "1", + "name": "White Deca Logo Tee", + "price": 1200, + "rarity": 0, + "skill": "11" + }, + { + "brand": "3", + "name": "White Inky Rider", + "price": 12800, + "rarity": 2, + "skill": "7" + }, + { + "brand": "16", + "name": "White King Tank", + "price": 600, + "rarity": 0, + "skill": "105" + }, + { + "brand": "0", + "name": "White Tee", + "price": 400, + "rarity": 0, + "skill": "1" + }, + { + "brand": "3", + "name": "White Urchin Rock Tee", + "price": 850, + "rarity": 0, + "skill": "0" + }, + { + "brand": "0", + "name": "White V-Neck Tee", + "price": 3800, + "rarity": 1, + "skill": "6" + }, + { + "brand": "0", + "name": "Yellow Layered LS", + "price": 500, + "rarity": 0, + "skill": "9" + }, + { + "brand": "6", + "name": "Yellow Urban Vest", + "price": 4100, + "rarity": 1, + "skill": "105" + }, + { + "brand": "4", + "name": "Zekko Baseball LS", + "price": 800, + "rarity": 0, + "skill": "12" + }, + { + "brand": "4", + "name": "Zekko Hoodie", + "price": 2800, + "rarity": 1, + "skill": "104" + }, + { + "brand": "4", + "name": "Zekko Jade Coat", + "price": 3600, + "rarity": 1, + "skill": "107" + }, + { + "brand": "4", + "name": "Zekko Redleaf Coat", + "price": 2600, + "rarity": 1, + "skill": "105" + }, + { + "brand": "1", + "name": "Zink Layered LS", + "price": 600, + "rarity": 0, + "skill": "107" + } + ], + "head": [ + { + "brand": "3", + "name": "18K Aviators", + "price": 12000, + "rarity": 2, + "skill": "101" + }, + { + "brand": "15", + "name": "Annaki Beret", + "price": 11500, + "rarity": 2, + "skill": "11" + }, + { + "brand": "15", + "name": "Annaki Mask", + "price": 3600, + "rarity": 1, + "skill": "100" + }, + { + "brand": "4", + "name": "Backwards Cap", + "price": 700, + "rarity": 0, + "skill": "8" + }, + { + "brand": "9", + "name": "Bamboo Hat", + "price": 2200, + "rarity": 1, + "skill": "0" + }, + { + "brand": "7", + "name": "Bike Helmet", + "price": 4800, + "rarity": 1, + "skill": "2" + }, + { + "brand": "6", + "name": "Blowfish Bell Hat", + "price": 850, + "rarity": 0, + "skill": "2" + }, + { + "brand": "8", + "name": "Bobble Hat", + "price": 2000, + "rarity": 1, + "skill": "9" + }, + { + "brand": "0", + "name": "Bucket Hat", + "price": 400, + "rarity": 0, + "skill": "6" + }, + { + "brand": "6", + "name": "Camo Mesh", + "price": 1400, + "rarity": 0, + "skill": "4" + }, + { + "brand": "9", + "name": "Camping Hat", + "price": 800, + "rarity": 0, + "skill": "7" + }, + { + "brand": "10", + "name": "Cycle King Cap", + "price": 2400, + "rarity": 1, + "skill": "12" + }, + { + "brand": "10", + "name": "Fake Contacts", + "price": 2000, + "rarity": 1, + "skill": "5" + }, + { + "brand": "6", + "name": "Firefin Facemask", + "price": 650, + "rarity": 0, + "skill": "3" + }, + { + "brand": "6", + "name": "FishFry Visor", + "price": 500, + "rarity": 0, + "skill": "5" + }, + { + "brand": "4", + "name": "Five-Panel Cap", + "price": 1800, + "rarity": 1, + "skill": "103" + }, + { + "brand": "8", + "name": "Half-Rim Glasses", + "price": 4100, + "rarity": 1, + "skill": "7" + }, + { + "brand": "2", + "name": "Hickory Work Cap", + "price": 8700, + "rarity": 2, + "skill": "7" + }, + { + "brand": "5", + "name": "Hockey Helmet", + "price": 9900, + "rarity": 2, + "skill": "13" + }, + { + "brand": "7", + "name": "Jellyvader Cap", + "price": 10000, + "rarity": 2, + "skill": "1" + }, + { + "brand": "16", + "name": "King Facemask", + "price": 500, + "rarity": 0, + "skill": "1" + }, + { + "brand": "16", + "name": "King Flip Mesh", + "price": 3200, + "rarity": 1, + "skill": "3" + }, + { + "brand": "6", + "name": "Knitted Hat", + "price": 1400, + "rarity": 0, + "skill": "11" + }, + { + "brand": "9", + "name": "Lightweight Cap", + "price": 800, + "rarity": 0, + "skill": "4" + }, + { + "brand": "4", + "name": "MTB Helmet", + "price": 10500, + "rarity": 2, + "skill": "102" + }, + { + "brand": "5", + "name": "Noise Cancelers", + "price": 9200, + "rarity": 2, + "skill": "8" + }, + { + "brand": "5", + "name": "Paintball Mask", + "price": 10000, + "rarity": 2, + "skill": "103" + }, + { + "brand": "0", + "name": "Painter's Mask", + "price": 4500, + "rarity": 1, + "skill": "13" + }, + { + "brand": "7", + "name": "Patched Hat", + "price": 3600, + "rarity": 1, + "skill": "13" + }, + { + "brand": "5", + "name": "Pilot Goggles", + "price": 5500, + "rarity": 1, + "skill": "10" + }, + { + "brand": "8", + "name": "Retro Specs", + "price": 500, + "rarity": 0, + "skill": "8" + }, + { + "brand": "5", + "name": "Safari Hat", + "price": 2300, + "rarity": 1, + "skill": "101" + }, + { + "brand": "5", + "name": "Skull Bandana", + "price": 7800, + "rarity": 2, + "skill": "6" + }, + { + "brand": "5", + "name": "Snorkel Mask", + "price": 3000, + "rarity": 1, + "skill": "1" + }, + { + "brand": "10", + "name": "Soccer Headband", + "price": 3000, + "rarity": 1, + "skill": "102" + }, + { + "brand": "5", + "name": "Special Forces Beret", + "price": 9700, + "rarity": 2, + "skill": "100" + }, + { + "brand": "1", + "name": "Squash Headband", + "price": 400, + "rarity": 0, + "skill": "6" + }, + { + "brand": "0", + "name": "Squid Facemask", + "price": 300, + "rarity": 0, + "skill": "0" + }, + { + "brand": "5", + "name": "Squidfin Hook Cans", + "price": 3800, + "rarity": 1, + "skill": "11" + }, + { + "brand": "7", + "name": "Squidvader Cap", + "price": 1300, + "rarity": 0, + "skill": "5" + }, + { + "brand": "7", + "name": "Straw Boater", + "price": 550, + "rarity": 0, + "skill": "9" + }, + { + "brand": "8", + "name": "Striped Beanie", + "price": 900, + "rarity": 0, + "skill": "100" + }, + { + "brand": "5", + "name": "Studio Headphones", + "price": 2800, + "rarity": 1, + "skill": "0" + }, + { + "brand": "10", + "name": "Sun Visor", + "price": 2600, + "rarity": 1, + "skill": "10" + }, + { + "brand": "11", + "name": "Takoroka Mesh", + "price": 400, + "rarity": 0, + "skill": "12" + }, + { + "brand": "11", + "name": "Takoroka Visor", + "price": 7500, + "rarity": 2, + "skill": "9" + }, + { + "brand": "10", + "name": "Tennis Headband", + "price": 300, + "rarity": 0, + "skill": "103" + }, + { + "brand": "4", + "name": "Tinted Shades", + "price": 350, + "rarity": 0, + "skill": "101" + }, + { + "brand": "7", + "name": "Urchins Cap", + "price": 600, + "rarity": 0, + "skill": "10" + }, + { + "brand": "7", + "name": "Visor Skate Helmet", + "price": 8000, + "rarity": 2, + "skill": "101" + } + ], + "shoes": [ + { + "brand": "9", + "name": "Acerola Rain Boots", + "price": 600, + "rarity": 0, + "skill": "3" + }, + { + "brand": "17", + "name": "Arrow Pull-Ons", + "price": 10000, + "rarity": 2, + "skill": "111" + }, + { + "brand": "9", + "name": "Birch Climbing Shoes", + "price": 1200, + "rarity": 0, + "skill": "5" + }, + { + "brand": "1", + "name": "Black Dakroniks", + "price": 1500, + "rarity": 1, + "skill": "13" + }, + { + "brand": "4", + "name": "Black Flip-Flops", + "price": 300, + "rarity": 0, + "skill": "110" + }, + { + "brand": "10", + "name": "Black Norimaki 750s", + "price": 9800, + "rarity": 2, + "skill": "5" + }, + { + "brand": "10", + "name": "Black Trainers", + "price": 500, + "rarity": 0, + "skill": "8" + }, + { + "brand": "16", + "name": "Blue & Black Squidkid IV", + "price": 11000, + "rarity": 2, + "skill": "9" + }, + { + "brand": "3", + "name": "Blue Moto Boots", + "price": 10800, + "rarity": 2, + "skill": "11" + }, + { + "brand": "2", + "name": "Blue Slip-Ons", + "price": 400, + "rarity": 0, + "skill": "10" + }, + { + "brand": "2", + "name": "Blueberry Casuals", + "price": 700, + "rarity": 0, + "skill": "1" + }, + { + "brand": "10", + "name": "Canary Trainers", + "price": 900, + "rarity": 0, + "skill": "9" + }, + { + "brand": "3", + "name": "Cherry Kicks", + "price": 2400, + "rarity": 1, + "skill": "109" + }, + { + "brand": "2", + "name": "Choco Clogs", + "price": 1800, + "rarity": 1, + "skill": "8" + }, + { + "brand": "11", + "name": "Crazy Arrows", + "price": 4500, + "rarity": 1, + "skill": "109" + }, + { + "brand": "1", + "name": "Gold Hi-Horses", + "price": 7000, + "rarity": 2, + "skill": "3" + }, + { + "brand": "10", + "name": "Gray Sea-Slug Hi-Tops", + "price": 8500, + "rarity": 2, + "skill": "12" + }, + { + "brand": "2", + "name": "Hunter Hi-Tops", + "price": 500, + "rarity": 0, + "skill": "2" + }, + { + "brand": "8", + "name": "Hunting Boots", + "price": 11500, + "rarity": 2, + "skill": "12" + }, + { + "brand": "3", + "name": "Kid Clams", + "price": 9500, + "rarity": 2, + "skill": "7" + }, + { + "brand": "11", + "name": "LE Soccer Shoes", + "price": 7500, + "rarity": 2, + "skill": "11" + }, + { + "brand": "8", + "name": "Mawcasins", + "price": 2400, + "rarity": 1, + "skill": "2" + }, + { + "brand": "1", + "name": "Mint Dakroniks", + "price": 1200, + "rarity": 0, + "skill": "111" + }, + { + "brand": "3", + "name": "Moto Boots", + "price": 3800, + "rarity": 1, + "skill": "8" + }, + { + "brand": "9", + "name": "Neon Delta Straps", + "price": 4800, + "rarity": 1, + "skill": "10" + }, + { + "brand": "10", + "name": "Neon Sea Slugs", + "price": 700, + "rarity": 0, + "skill": "11" + }, + { + "brand": "11", + "name": "Orange Arrows", + "price": 1100, + "rarity": 0, + "skill": "0" + }, + { + "brand": "11", + "name": "Orca Hi-Tops", + "price": 2800, + "rarity": 1, + "skill": "6" + }, + { + "brand": "2", + "name": "Oyster Clogs", + "price": 600, + "rarity": 0, + "skill": "3" + }, + { + "brand": "10", + "name": "Pink Trainers", + "price": 500, + "rarity": 0, + "skill": "10" + }, + { + "brand": "8", + "name": "Piranha Moccasins", + "price": 9400, + "rarity": 2, + "skill": "109" + }, + { + "brand": "2", + "name": "Plum Casuals", + "price": 2000, + "rarity": 1, + "skill": "110" + }, + { + "brand": "9", + "name": "Pro Trail Boots", + "price": 9800, + "rarity": 2, + "skill": "11" + }, + { + "brand": "3", + "name": "Punk Blacks", + "price": 8800, + "rarity": 2, + "skill": "13" + }, + { + "brand": "3", + "name": "Punk Whites", + "price": 3800, + "rarity": 1, + "skill": "5" + }, + { + "brand": "1", + "name": "Purple Hi-Horses", + "price": 1000, + "rarity": 0, + "skill": "7" + }, + { + "brand": "10", + "name": "Purple Sea Slugs", + "price": 1800, + "rarity": 1, + "skill": "3" + }, + { + "brand": "16", + "name": "Red & Black Squidkid IV", + "price": 11000, + "rarity": 2, + "skill": "5" + }, + { + "brand": "1", + "name": "Red Hi-Horses", + "price": 800, + "rarity": 0, + "skill": "0" + }, + { + "brand": "10", + "name": "Red-Mesh Sneakers", + "price": 1700, + "rarity": 1, + "skill": "7" + }, + { + "brand": "3", + "name": "Roasted Brogues", + "price": 1200, + "rarity": 0, + "skill": "12" + }, + { + "brand": "3", + "name": "Smoky Wingtips", + "price": 8600, + "rarity": 2, + "skill": "110" + }, + { + "brand": "9", + "name": "Snow Delta Straps", + "price": 8800, + "rarity": 2, + "skill": "4" + }, + { + "brand": "8", + "name": "Strapping Reds", + "price": 1400, + "rarity": 0, + "skill": "11" + }, + { + "brand": "8", + "name": "Strapping Whites", + "price": 8700, + "rarity": 2, + "skill": "1" + }, + { + "brand": "9", + "name": "Sunny Climbing Shoes", + "price": 3200, + "rarity": 1, + "skill": "6" + }, + { + "brand": "11", + "name": "Sunset Orca Hi-Tops", + "price": 3800, + "rarity": 1, + "skill": "111" + }, + { + "brand": "9", + "name": "Trail Boots", + "price": 7500, + "rarity": 2, + "skill": "2" + }, + { + "brand": "3", + "name": "White Kicks", + "price": 1400, + "rarity": 0, + "skill": "4" + }, + { + "brand": "10", + "name": "White Norimaki 750s", + "price": 3800, + "rarity": 1, + "skill": "4" + }, + { + "brand": "1", + "name": "White Seahorses", + "price": 600, + "rarity": 0, + "skill": "2" + }, + { + "brand": "10", + "name": "Yellow-Mesh Sneakers", + "price": 1300, + "rarity": 0, + "skill": "13" + } + ] +} \ No newline at end of file diff --git a/src/js/data/skills.json b/src/js/data/skills.json new file mode 100644 index 0000000..4bbb073 --- /dev/null +++ b/src/js/data/skills.json @@ -0,0 +1,132 @@ +{ + "0": { + "id": "0", + "image": "/images/skill/04b1de71fba1f14197b9163503955c52fd74858b.png", + "name": "Ink Saver (Main)" + }, + "1": { + "id": "1", + "image": "/images/skill/da8ff08954fd5d890fc8bc4dd4cb761e2a33b703.png", + "name": "Ink Saver (Sub)" + }, + "10": { + "id": "10", + "image": "/images/skill/34e114a50a001778a574f7061039d43e632137b7.png", + "name": "Sub Power Up" + }, + "100": { + "id": "100", + "image": "/images/skill/492691ed2a7ce7ec694bf88d3ea1f692b7da1692.png", + "name": "Opening Gambit" + }, + "101": { + "id": "101", + "image": "/images/skill/03d1b1e0221fc82d0ab26cb8cd3f5f40107b6190.png", + "name": "Last-Ditch Effort" + }, + "102": { + "id": "102", + "image": "/images/skill/d59c8affb196bc3dcb6faea34899e782bce37656.png", + "name": "Tenacity" + }, + "103": { + "id": "103", + "image": "/images/skill/bdc5135874439cf3169d9a54b3f1fbdba3731b34.png", + "name": "Comeback" + }, + "104": { + "id": "104", + "image": "/images/skill/f0a99d1ab1a765b992b79610ebdc25b69d88fae9.png", + "name": "Ninja Squid" + }, + "105": { + "id": "105", + "image": "/images/skill/53c62995f9d2dc4a60f3850c5dbdd2323f1eef87.png", + "name": "Haunt" + }, + "106": { + "id": "106", + "image": "/images/skill/1d6ed2ef9cd1f71086368e9ec4b5704663ba3a0a.png", + "name": "Thermal Ink" + }, + "107": { + "id": "107", + "image": "/images/skill/344e4c16ad4ec9ab8f56711d8d79a1ffb9228a1a.png", + "name": "Respawn Punisher" + }, + "108": { + "id": "108", + "image": "/images/skill/67e4e8ec069dfaec1d732c7fe407a2c73e8e51b8.png", + "name": "Ability Doubler" + }, + "109": { + "id": "109", + "image": "/images/skill/8a3f06a972689b094f762626ff36b3db8ee545b5.png", + "name": "Stealth Jump" + }, + "11": { + "id": "11", + "image": "/images/skill/33087a476135074af856151a89a6fe4d1d3a996e.png", + "name": "Ink Resistance Up" + }, + "110": { + "id": "110", + "image": "/images/skill/47a74cd575b25a9de3e3592084ff3870db0cf4e0.png", + "name": "Object Shredder" + }, + "111": { + "id": "111", + "image": "/images/skill/d0de52e89947803e5b24165335855f39f9e8a6bd.png", + "name": "Drop Roller" + }, + "12": { + "id": "12", + "image": "/images/skill/35f4ec4284fc5a19da58ffb1a7988eb26eb8bd7f.png", + "name": "Bomb Defense Up" + }, + "13": { + "id": "13", + "image": "/images/skill/efa003501e1152ef7b617b9e01517c915e05b7ac.png", + "name": "Cold-Blooded" + }, + "2": { + "id": "2", + "image": "/images/skill/c14f4471b26e0f918c736b5c17e03212290f4541.png", + "name": "Ink Recovery Up" + }, + "3": { + "id": "3", + "image": "/images/skill/7de1bdfd875ef470b6066c17bed726b5b5113d48.png", + "name": "Run Speed Up" + }, + "4": { + "id": "4", + "image": "/images/skill/d138c293c8ddac42fadf0e6531100a88c79c81f6.png", + "name": "Swim Speed Up" + }, + "5": { + "id": "5", + "image": "/images/skill/1378f3963526d7216ec44da35b924b81a8ff6a37.png", + "name": "Special Charge Up" + }, + "6": { + "id": "6", + "image": "/images/skill/d83b962b84fcea9d02c591c296234f5de77f9682.png", + "name": "Special Saver" + }, + "7": { + "id": "7", + "image": "/images/skill/f20a3e85feeb6b4bb021d28059afd6265cee0b43.png", + "name": "Special Power Up" + }, + "8": { + "id": "8", + "image": "/images/skill/84ab4ba1188849dff63a4314955a53ab103b47df.png", + "name": "Quick Respawn" + }, + "9": { + "id": "9", + "image": "/images/skill/daf6883039afa62da91eb93eb2a40b673f10b715.png", + "name": "Quick Super Jump" + } +} \ No newline at end of file diff --git a/src/js/splatoon.js b/src/js/splatoon.js new file mode 100644 index 0000000..cb27423 --- /dev/null +++ b/src/js/splatoon.js @@ -0,0 +1,18 @@ +const skills = require('./data/skills'); +const inkipediaGear = require('./data/inkipediaGear'); + +function getOriginalGear(gear) { + if (!gear) + return; + + let originalGear = inkipediaGear[gear.kind].find(ig => ig.name == gear.name); + + if (!originalGear) + return; + + return Object.assign({}, originalGear, { skill: skills[originalGear.skill] }); +} + +module.exports = { + getOriginalGear, +} diff --git a/src/updater/retrieveGearData.js b/src/updater/retrieveGearData.js new file mode 100644 index 0000000..83836f9 --- /dev/null +++ b/src/updater/retrieveGearData.js @@ -0,0 +1,49 @@ +const delay = require('delay'); +const splatnet = require('./splatnet'); + +/** + * We can't retrieve gear/brand/skill data directly. + * This pulls data from the 50 most recent battles instead. + */ + +module.exports = async function retrieveGearData() { + let skills = {}; + let brands = {}; + let gear = { head: {}, clothes: {}, shoes: {} }; + + console.info('Getting battle data...'); + let battleResultsData = await splatnet.getResults(); + for (let battle of battleResultsData.results) { + await delay(250); + + console.info(`Getting data for battle #${battle.battle_number}...`); + let battleData = await splatnet.getResults(battle.battle_number); + + // Find all gear and skills + let players = [battleData.player_result].concat(battleData.my_team_members, battleData.other_team_members); + for (player of players) { + // Get the main and sub skills for each type of gear + let gearSkills = [ + player.player.head_skills.main, + player.player.clothes_skills.main, + player.player.shoes_skills.main, + ].concat(player.player.head_skills.subs, player.player.clothes_skills.subs, player.player.shoes_skills.subs); + + for (skill of gearSkills) { + if (skill) + skills[skill.id] = skill; + } + + // Get brands + for (brand of [player.player.head.brand, player.player.clothes.brand, player.player.shoes.brand]) + brands[brand.id] = brand; + + // Get gear + gear.head[player.player.head.id] = player.player.head; + gear.clothes[player.player.clothes.id] = player.player.clothes; + gear.shoes[player.player.shoes.id] = player.player.shoes; + } + } + + return { skills, brands, gear }; +} diff --git a/src/updater/splatnet.js b/src/updater/splatnet.js index 97f4deb..70d9982 100644 --- a/src/updater/splatnet.js +++ b/src/updater/splatnet.js @@ -72,6 +72,12 @@ async function getLeagueMatchRanking(year, month, day, hour, type = 'T', region return response.data; } +async function getResults(id = null) { + let url = (id) ? `results/${id}` : 'results'; + let response = await api.get(url); + return response.data; +} + async function getImage(imagePath) { let response = await axios.get(`${splatnetBaseUrl}${imagePath}`, { responseType: 'arraybuffer', headers: { 'User-Agent': userAgent } }); return response.data; @@ -85,5 +91,6 @@ module.exports = { getJPFestivals, getMerchandises, getLeagueMatchRanking, + getResults, getImage, } diff --git a/src/updater/updateGear.js b/src/updater/updateGear.js new file mode 100644 index 0000000..40f1413 --- /dev/null +++ b/src/updater/updateGear.js @@ -0,0 +1,95 @@ +// Note: this script is intended to be run during development (not in production). +// It updates the gear/brand/skill data located at /src/js/data/. + +require('./bootstrap'); +const path = require('path'); +const fs = require('fs'); +const mkdirp = require('mkdirp'); +const axios = require('axios'); +const retrieveGearData = require('./retrieveGearData'); +const stringify = require('json-stable-stringify'); + +const dataPath = path.resolve('src/js/data'); +const brandsFilename = `${dataPath}/brands.json`; +const skillsFilename = `${dataPath}/skills.json`; +const inkipediaGearFilename = `${dataPath}/inkipediaGear.json`; + +mkdirp(dataPath); + +function applyData(oldData, newData) { + if (!Array.isArray(newData)) + newData = Object.values(newData); + + for (let data of newData) { + if (data.id in oldData) + Object.assign(oldData[data.id], data); + else + oldData[data.id] = data; + } +} + +(async () => { + let brands = {}; + let skills = {}; + + // Retrieve existing gear/brand/skill data if it exists + if (fs.existsSync(brandsFilename)) + brands = JSON.parse(fs.readFileSync(brandsFilename)); + if (fs.existsSync(skillsFilename)) + skills = JSON.parse(fs.readFileSync(skillsFilename)); + + // Update gear/brand/skill data from SplatNet + // (This takes a while and doesn't need to be updated frequently, so just disabling this here for now) + if (false) { + let gearData = await retrieveGearData(); + + applyData(brands, gearData.brands); + applyData(skills, gearData.skills); + } + + // Process brands + for (let brand of Object.values(brands)) { + if (brand.frequent_skill && typeof brand.frequent_skill === 'object') + brand.frequent_skill = brand.frequent_skill.id; + } + + // Retrieve data from Inkipedia + let inkipediaGear = {}; + let inkipediaSources = { + head: 'https://splatoonwiki.org/w/index.php?title=Template:Gear/S2_Headgear&action=edit', + clothes: 'https://splatoonwiki.org/w/index.php?title=Template:Gear/S2_Clothing&action=edit', + shoes: 'https://splatoonwiki.org/w/index.php?title=Template:Gear/S2_Shoes&action=edit', + } + + for (let key in inkipediaSources) { + inkipediaGear[key] = []; + + let response = await axios.get(inkipediaSources[key]); + + let regex = /\{\{GearList\/Item.*?filter/g; + let row; + while (row = regex.exec(response.data)) { + let details = /name=(.*?)\|brand=(.*?)\|cost=(.*?)\|ability=(.*?)\|rarity=(.*?)\|/.exec(row[0]); + if (details) { + inkipediaGear[key].push({ + name: details[1], + brand: details[2], + price: parseInt(details[3].replace(',', '')), + skill: details[4], + rarity: parseInt(details[5]) - 1, + }); + } + } + } + + // Process Inkipedia gear + for (let item of [].concat(Object.values(inkipediaGear.head), Object.values(inkipediaGear.clothes), Object.values(inkipediaGear.shoes))) { + item.brand = Object.values(brands).find(b => b.name == item.brand).id; + item.skill = Object.values(skills).find(s => s.name == item.skill).id; + } + + // Write out the data + fs.writeFileSync(brandsFilename, stringify(brands, { space: 4 })); + fs.writeFileSync(skillsFilename, stringify(skills, { space: 4 })); + fs.writeFileSync(inkipediaGearFilename, stringify(inkipediaGear, { space: 4 })); +})();