Merge branch 'develop' into firefox-extension-link
67
migrations/archive/2019/20190927_kickstarter.js
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20190927_kickstarter';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {};
|
||||
let push = {pinnedItems: {$each: []}};
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
set['achievements.ks2019'] = true;
|
||||
|
||||
// set['items.gear.owned.armor_special_ks2019'] = false;
|
||||
// push.pinnedItems.$each.push({type: 'marketGear', path: 'gear.flat.armor_special_ks2019', _id: uuid()});
|
||||
set['items.gear.owned.head_special_ks2019'] = false;
|
||||
push.pinnedItems.$each.push({type: 'marketGear', path: 'gear.flat.head_special_ks2019', _id: uuid()});
|
||||
// set['items.gear.owned.shield_special_ks2019'] = false;
|
||||
// push.pinnedItems.$each.push({type: 'marketGear', path: 'gear.flat.shield_special_ks2019', _id: uuid()});
|
||||
// set['items.gear.owned.weapon_special_ks2019'] = false;
|
||||
// push.pinnedItems.$each.push({type: 'marketGear', path: 'gear.flat.weapon_special_ks2019', _id: uuid()});
|
||||
set['items.gear.owned.eyewear_special_ks2019'] = false;
|
||||
push.pinnedItems.$each.push({type: 'marketGear', path: 'gear.flat.eyewear_special_ks2019', _id: uuid()});
|
||||
// set['items.pets.Gryphon-Gryphatrice'] = 5;
|
||||
// set['items.mounts.Gryphon-Gryphatrice'] = true;
|
||||
|
||||
return await User.update({_id: user._id}, {$set: set, $push: push}).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.local.lowerCaseUsername': {$in: []},
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = 'mystery_items_201908';
|
||||
const MYSTERY_ITEMS = ['armor_mystery_201908', 'headAccessory_mystery_201908'];
|
||||
const MIGRATION_NAME = 'mystery_items_201909';
|
||||
const MYSTERY_ITEMS = ['armor_mystery_201909', 'head_mystery_201909'];
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
import { model as UserNotification } from '../../website/server/models/userNotification';
|
||||
|
||||
|
|
|
|||
203
package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "habitica",
|
||||
"version": "4.112.1",
|
||||
"version": "4.116.3",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
@ -385,9 +385,9 @@
|
|||
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "12.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz",
|
||||
"integrity": "sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w=="
|
||||
"version": "12.7.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.8.tgz",
|
||||
"integrity": "sha512-FMdVn84tJJdV+xe+53sYiZS4R5yn1mAIxfj+DVoNiQjTYz1+OYmjwEZr1ev9nU0axXwda0QDbYl06QHanRVH3A=="
|
||||
},
|
||||
"@types/q": {
|
||||
"version": "1.5.2",
|
||||
|
|
@ -682,9 +682,9 @@
|
|||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.8.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.8.0.tgz",
|
||||
"integrity": "sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w=="
|
||||
"version": "6.9.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.0.tgz",
|
||||
"integrity": "sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA=="
|
||||
},
|
||||
"superagent": {
|
||||
"version": "3.8.3",
|
||||
|
|
@ -2022,9 +2022,9 @@
|
|||
}
|
||||
},
|
||||
"aws-sdk": {
|
||||
"version": "2.532.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.532.0.tgz",
|
||||
"integrity": "sha512-+auGlLHZlcAJaJFV6kcacLteggSdN1YsalyiXoGnLhHZTBH/s9YAwHTUftYI4ifyD3fPESr/rpdceWe1m0U2Mw==",
|
||||
"version": "2.536.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.536.0.tgz",
|
||||
"integrity": "sha512-d91ASAgDtjP5Al8nRtdOhnS6m7XczqdmVfkyFtd7GlWJ2jy2NxQ+PI4QVp7n/74BNRSSLoyxmCqz2Ulqu3TOsQ==",
|
||||
"requires": {
|
||||
"buffer": "4.9.1",
|
||||
"events": "1.1.1",
|
||||
|
|
@ -5273,9 +5273,9 @@
|
|||
}
|
||||
},
|
||||
"bowser": {
|
||||
"version": "2.5.4",
|
||||
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.5.4.tgz",
|
||||
"integrity": "sha512-74GGwfc2nzYD19JCiA0RwCxdq7IY5jHeEaSrrgm/5kusEuK+7UK0qDG3gyzN47c4ViNyO4osaKtZE+aSV6nlpQ=="
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.6.1.tgz",
|
||||
"integrity": "sha512-hySGUuLhi0KetfxPZpuJOsjM0kRvCiCgPBygBkzGzJNsq/nbJmaO8QJc6xlWfeFFnMvtd/LeKkhDJGVrmVobUA=="
|
||||
},
|
||||
"boxen": {
|
||||
"version": "1.3.0",
|
||||
|
|
@ -5571,9 +5571,9 @@
|
|||
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="
|
||||
},
|
||||
"normalize-url": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.4.0.tgz",
|
||||
"integrity": "sha512-R1TJlbt61ZWWfeTCjKjM67RyR5Ls8BABZPhNQ2sHCVEAUoC0B4CHakvBlx/y04x/U6oc336wyFSQwqnylcVnVw=="
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.4.1.tgz",
|
||||
"integrity": "sha512-rjH3yRt0Ssx19mUwS0hrDUOdG9VI+oRLpLHJ7tXRdjcuQ7v7wo6qPvOZppHRrqfslTKr0L2yBhjj4UXd7c3cQg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -5656,14 +5656,14 @@
|
|||
}
|
||||
},
|
||||
"caniuse-db": {
|
||||
"version": "1.0.30000996",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000996.tgz",
|
||||
"integrity": "sha512-WvzxMtKe5CCBUaTVBM/EjsoFXJf6f/2s17BlWeZMhc5DSP7d9QjAZe5vdZp3T3fjxtGkJbg5W24bnRAdz9LVIw=="
|
||||
"version": "1.0.30000997",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000997.tgz",
|
||||
"integrity": "sha512-rK1Jo9VT5F/cJ333iLURdNXecYvVn3erJheoPAETrccJVw4w/557HfkNPADB5agHKjGuhJETf1l6lssvgbqA0Q=="
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30000989",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz",
|
||||
"integrity": "sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw=="
|
||||
"version": "1.0.30000997",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000997.tgz",
|
||||
"integrity": "sha512-BQLFPIdj2ntgBNWp9Q64LGUIEmvhKkzzHhUHR3CD5A9Lb7ZKF20/+sgadhFap69lk5XmK1fTUleDclaRFvgVUA=="
|
||||
},
|
||||
"capture-stack-trace": {
|
||||
"version": "1.0.1",
|
||||
|
|
@ -6003,9 +6003,9 @@
|
|||
}
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz",
|
||||
"integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A=="
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz",
|
||||
"integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw=="
|
||||
},
|
||||
"chromedriver": {
|
||||
"version": "77.0.0",
|
||||
|
|
@ -7885,9 +7885,9 @@
|
|||
"integrity": "sha1-GK6XmmoMqZSwYlhTkW0mYruuCxo="
|
||||
},
|
||||
"date-fns": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.2.1.tgz",
|
||||
"integrity": "sha512-4V1i5CnTinjBvJpXTq7sDHD4NY6JPcl15112IeSNNLUWQOQ+kIuCvRGOFZMQZNvkadw8F9QTyZxz59rIRU6K+w=="
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.3.0.tgz",
|
||||
"integrity": "sha512-A8o+iXBVqQayl9Z39BHgb7m/zLOfhF7LK82t+n9Fq1adds1vaUn8ByVoADqWLe4OTc6BZYc/FdbdTwufNYqkJw=="
|
||||
},
|
||||
"date-format": {
|
||||
"version": "2.1.0",
|
||||
|
|
@ -8655,9 +8655,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.263",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.263.tgz",
|
||||
"integrity": "sha512-VfPi+sE/1nEKOV7DWDqWSUGP7ztJG5FeqHbMEj6dBb/arKnxpOCnRXOSC6HBV6qTfK5v8CX7xWCqzN36UqG1oA=="
|
||||
"version": "1.3.266",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.266.tgz",
|
||||
"integrity": "sha512-UTuTZ4v8T0gLPHI7U75PXLQePWI65MTS3mckRrnLCkNljHvsutbYs+hn2Ua/RFul3Jt/L3Ht2rLP+dU/AlBfrQ=="
|
||||
},
|
||||
"element-in-view": {
|
||||
"version": "0.1.0",
|
||||
|
|
@ -8775,9 +8775,9 @@
|
|||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||
"requires": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
|
|
@ -10436,9 +10436,9 @@
|
|||
}
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz",
|
||||
"integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==",
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
|
||||
"integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
|
||||
"requires": {
|
||||
"is-glob": "^4.0.1"
|
||||
}
|
||||
|
|
@ -10601,9 +10601,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"schema-utils": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.2.0.tgz",
|
||||
"integrity": "sha512-5EwsCNhfFTZvUreQhx/4vVQpJ/lnCAkgoIHLhSpp4ZirE+4hzFvdJi0FMub6hxbFVBJYSpeVVmon+2e7uEGRrA==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.3.0.tgz",
|
||||
"integrity": "sha512-0NWOS/em29583dLzou07qWp5xoKCnvm5NiDQ+IkI/Q8xP6rm1SMvQrmHseH0RSbBe4tM+LJ7IeZTqb/dF9dTRQ==",
|
||||
"requires": {
|
||||
"ajv": "^6.10.2",
|
||||
"ajv-keywords": "^3.4.1"
|
||||
|
|
@ -12293,9 +12293,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"gtoken": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-4.0.0.tgz",
|
||||
"integrity": "sha512-XaRCfHJxhj06LmnWNBzVTAr85NfAErq0W1oabkdqwbq3uL/QTB1kyvGog361Uu2FMG/8e3115sIy/97Rnd4GjQ==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-4.1.0.tgz",
|
||||
"integrity": "sha512-wqyn2gf5buzEZN4QNmmiiW2i2JkEdZnL7Z/9p44RtZqgt4077m4khRgAYNuu8cBwHWCc6MsP6eDUn/KkF6jFIw==",
|
||||
"requires": {
|
||||
"gaxios": "^2.0.0",
|
||||
"google-p12-pem": "^2.0.0",
|
||||
|
|
@ -12426,9 +12426,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"colors": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
|
||||
"integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg=="
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
|
||||
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -12800,9 +12800,9 @@
|
|||
"integrity": "sha512-T673GW3RSuM4xzYfJpp/wNPDbUG9FlNSNkQn0thII8DOpl3NphcmtmNrHrmv8hyk1fosJHkgzDfbcpJvmeq5Gw=="
|
||||
},
|
||||
"helmet": {
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.0.tgz",
|
||||
"integrity": "sha512-TS3GryQMPR7n/heNnGC0Cl3Ess30g8C6EtqZyylf+Y2/kF4lM8JinOR90rzIICsw4ymWTvji4OhDmqsqxkLrcg==",
|
||||
"version": "3.21.1",
|
||||
"resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.1.tgz",
|
||||
"integrity": "sha512-IC/54Lxvvad2YiUdgLmPlNFKLhNuG++waTF5KPYq/Feo3NNhqMFbcLAlbVkai+9q0+4uxjxGPJ9bNykG+3zZNg==",
|
||||
"requires": {
|
||||
"depd": "2.0.0",
|
||||
"dns-prefetch-control": "0.2.0",
|
||||
|
|
@ -12811,7 +12811,7 @@
|
|||
"feature-policy": "0.3.0",
|
||||
"frameguard": "3.1.0",
|
||||
"helmet-crossdomain": "0.4.0",
|
||||
"helmet-csp": "2.9.1",
|
||||
"helmet-csp": "2.9.2",
|
||||
"hide-powered-by": "1.1.0",
|
||||
"hpkp": "2.0.0",
|
||||
"hsts": "2.2.0",
|
||||
|
|
@ -12834,11 +12834,11 @@
|
|||
"integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA=="
|
||||
},
|
||||
"helmet-csp": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.1.tgz",
|
||||
"integrity": "sha512-HgdXSJ6AVyXiy5ohVGpK6L7DhjI9KVdKVB1xRoixxYKsFXFwoVqtLKgDnfe3u8FGGKf9Ml9k//C9rnncIIAmyA==",
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.2.tgz",
|
||||
"integrity": "sha512-Lt5WqNfbNjEJ6ysD4UNpVktSyjEKfU9LVJ1LaFmPfYseg/xPealPfgHhtqdAdjPDopp5zbg/VWCyp4cluMIckw==",
|
||||
"requires": {
|
||||
"bowser": "2.5.4",
|
||||
"bowser": "^2.6.1",
|
||||
"camelize": "1.0.0",
|
||||
"content-security-policy-builder": "2.1.0",
|
||||
"dasherize": "2.0.0"
|
||||
|
|
@ -13272,9 +13272,9 @@
|
|||
}
|
||||
},
|
||||
"image-size": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.8.1.tgz",
|
||||
"integrity": "sha512-X2HcWljsuWJPMTb1CGAN2+xuAAjQK5kdSzhqQXZlJBf0MpdXqfIeQCMJKYKS2OEVDwReS2zO5i7MlikWPBTotQ==",
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.8.2.tgz",
|
||||
"integrity": "sha512-0AO8bEDtAcC+dScZmCDUvmxIYWlJ+0DQOl1BkTQYrrM3/oQORS03P0gDT7ZoElRozHlfoUxT+L2ErLFmbT5tdA==",
|
||||
"requires": {
|
||||
"queue": "6.0.1"
|
||||
}
|
||||
|
|
@ -14876,9 +14876,9 @@
|
|||
}
|
||||
},
|
||||
"colors": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
|
||||
"integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==",
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
|
||||
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
|
||||
"dev": true
|
||||
},
|
||||
"core-js": {
|
||||
|
|
@ -14904,9 +14904,9 @@
|
|||
"optional": true
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz",
|
||||
"integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==",
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
|
||||
"integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-glob": "^4.0.1"
|
||||
|
|
@ -15244,9 +15244,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"colors": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
|
||||
"integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==",
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
|
||||
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
|
|
@ -16240,9 +16240,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"colors": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
|
||||
"integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg=="
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
|
||||
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -17026,20 +17026,31 @@
|
|||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.6.5.tgz",
|
||||
"integrity": "sha512-ewSKOPFH9blOLXx0YSE+mbrNMBFPS+11a2b03QZ+P4LVrUHW/GAlqeYC7DBknDyMWkHzrzTpDhUvy7MUxqyrPA==",
|
||||
"version": "2.8.6",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.8.6.tgz",
|
||||
"integrity": "sha512-lFG7d6g3+/UaFDCOtqPiKAC9zngWWsQZl1g5q6gaONqrjq61SX2xFqXMleQiFVyDpYwa018E9hmlAFY22PCb+A==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.2.tgz",
|
||||
"integrity": "sha512-hR3At21uSrsjjDTWrbu0IMLTpnkpv8IIMFDFaoz43Tmu4LkmAXfH44vNNzpTnf+OAQQCHrb91y/wc2J4x5XgSQ==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.1.tgz",
|
||||
"integrity": "sha512-8AgjrT7C8U/HQWM+02YJHLPh4BypAhc5pFddr0nCcowNy1Hj0hmKPMq9WkjBMn0rtUg3ia30MkCexdd1pTiTIA==",
|
||||
"requires": {
|
||||
"minipass": "^2.2.1"
|
||||
"minipass": "^2.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"minipass": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
|
||||
"integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mixin-deep": {
|
||||
|
|
@ -23624,9 +23635,9 @@
|
|||
}
|
||||
},
|
||||
"sinon": {
|
||||
"version": "7.4.2",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-7.4.2.tgz",
|
||||
"integrity": "sha512-pY5RY99DKelU3pjNxcWo6XqeB1S118GBcVIIdDi6V+h6hevn1izcg2xv1hTHW/sViRXU7sUOxt4wTUJ3gsW2CQ==",
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-7.5.0.tgz",
|
||||
"integrity": "sha512-AoD0oJWerp0/rY9czP/D6hDTTUYGpObhZjMpd7Cl/A6+j0xBE+ayL/ldfggkBXUs0IkvIiM1ljM8+WkOc5k78Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@sinonjs/commons": "^1.4.0",
|
||||
|
|
@ -23701,9 +23712,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"smartbanner.js": {
|
||||
"version": "1.14.3",
|
||||
"resolved": "https://registry.npmjs.org/smartbanner.js/-/smartbanner.js-1.14.3.tgz",
|
||||
"integrity": "sha512-sztCJyMU96IlMAYZyfb/5jsmXz7629QozKY0tJ9x39aqUbYHiWInNNm45iNwsqv9A8gASXo98LnLiay0646vWw=="
|
||||
"version": "1.14.5",
|
||||
"resolved": "https://registry.npmjs.org/smartbanner.js/-/smartbanner.js-1.14.5.tgz",
|
||||
"integrity": "sha512-Qw4dezZkPHbnVIOyG/BDTsm/ZDsnYZdSwPI9CL+PfRqqywh/Bk2XmWcAFLUzmDg5lGeAxhs7TrKO1+kQ4vWN9g=="
|
||||
},
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
|
|
@ -24633,9 +24644,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"qs": {
|
||||
"version": "6.8.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.8.0.tgz",
|
||||
"integrity": "sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w=="
|
||||
"version": "6.9.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.0.tgz",
|
||||
"integrity": "sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -24686,9 +24697,9 @@
|
|||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.8.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.8.0.tgz",
|
||||
"integrity": "sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w=="
|
||||
"version": "6.9.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.0.tgz",
|
||||
"integrity": "sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA=="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "3.4.0",
|
||||
|
|
@ -24959,13 +24970,13 @@
|
|||
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.11",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.11.tgz",
|
||||
"integrity": "sha512-iI4zh3ktLJKaDNZKZc+fUONiQrSn9HkCFzamtb7k8FFmVilHVob7QsLX/VySAW8lAviMzMbFw4QtFb4errwgYA==",
|
||||
"version": "4.4.13",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
|
||||
"integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
|
||||
"requires": {
|
||||
"chownr": "^1.1.1",
|
||||
"fs-minipass": "^1.2.5",
|
||||
"minipass": "^2.6.4",
|
||||
"minipass": "^2.8.6",
|
||||
"minizlib": "^1.2.1",
|
||||
"mkdirp": "^0.5.0",
|
||||
"safe-buffer": "^5.1.2",
|
||||
|
|
@ -27175,11 +27186,11 @@
|
|||
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw=="
|
||||
},
|
||||
"vuedraggable": {
|
||||
"version": "2.23.0",
|
||||
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.23.0.tgz",
|
||||
"integrity": "sha512-RgdH16k43WNoxyRcv/OarB/DZh9SY5TYthk9TS4YiHXpelD1DytEG0phLAXiXx5EhsmdH8ltSWxklGa4g1WTCw==",
|
||||
"version": "2.23.1",
|
||||
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.23.1.tgz",
|
||||
"integrity": "sha512-YgWnG7RC/V+nPksueT9cUGzvj7gBYqpEomazuAK5bBcImuPAeLsq0hwE5kSGItbHQpVnYdT/QX1kRR1XsjNeqw==",
|
||||
"requires": {
|
||||
"sortablejs": "^1.9.0"
|
||||
"sortablejs": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"vuejs-datepicker": {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "4.112.1",
|
||||
"version": "4.116.3",
|
||||
"main": "./website/server/index.js",
|
||||
"dependencies": {
|
||||
"@google-cloud/trace-agent": "^4.0.0",
|
||||
|
|
|
|||
|
|
@ -1,27 +1,11 @@
|
|||
import {
|
||||
translations,
|
||||
localePath,
|
||||
langCodes,
|
||||
approvedLanguages,
|
||||
} from '../../../../website/server/libs/i18n';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
describe('i18n', () => {
|
||||
let listOfLocales = [];
|
||||
|
||||
before((done) => {
|
||||
fs.readdir(localePath, (err, files) => {
|
||||
if (err) return done(err);
|
||||
|
||||
files.forEach((file) => {
|
||||
if (fs.statSync(path.join(localePath, file)).isDirectory() === false) return;
|
||||
listOfLocales.push(file);
|
||||
});
|
||||
|
||||
listOfLocales = listOfLocales.sort();
|
||||
done();
|
||||
});
|
||||
});
|
||||
let listOfLocales = approvedLanguages.sort();
|
||||
|
||||
describe('translations', () => {
|
||||
it('includes a translation object for each locale', () => {
|
||||
|
|
|
|||
|
|
@ -100,14 +100,23 @@ describe('Items Utils', () => {
|
|||
});
|
||||
|
||||
it('converts values for mounts paths to numbers', () => {
|
||||
expect(castItemVal('items.mounts.Cactus-Base', '5')).to.equal(5);
|
||||
expect(castItemVal('items.mounts.Aether-Invisible', '5')).to.equal(5);
|
||||
expect(castItemVal('items.mounts.Aether-Invalid', '5')).to.equal(5);
|
||||
expect(castItemVal('items.mounts.Cactus-Base', 'true')).to.equal(true);
|
||||
expect(castItemVal('items.mounts.Aether-Invisible', 'false')).to.equal(false);
|
||||
expect(castItemVal('items.mounts.Aether-Invalid', 'true')).to.equal(true);
|
||||
expect(castItemVal('items.mounts.Aether-Invalid', 'truish')).to.equal(true);
|
||||
expect(castItemVal('items.mounts.Aether-Invalid', 0)).to.equal(false);
|
||||
});
|
||||
|
||||
it('converts values for quests paths to numbers', () => {
|
||||
expect(castItemVal('items.quests.atom3', '5')).to.equal(5);
|
||||
expect(castItemVal('items.quests.invalid', '5')).to.equal(5);
|
||||
});
|
||||
|
||||
it('converts values for owned gear', () => {
|
||||
expect(castItemVal('items.gear.owned.shield_warrior_0', 'true')).to.equal(true);
|
||||
expect(castItemVal('items.gear.owned.invalid', 'false')).to.equal(false);
|
||||
expect(castItemVal('items.gear.owned.invalid', 'thruthy')).to.equal(true);
|
||||
expect(castItemVal('items.gear.owned.invalid', 0)).to.equal(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ describe('POST /group/:groupId/remove-manager', () => {
|
|||
type: groupType,
|
||||
privacy: 'public',
|
||||
},
|
||||
members: 1,
|
||||
members: 2,
|
||||
});
|
||||
|
||||
groupToUpdate = group;
|
||||
leader = groupLeader;
|
||||
nonLeader = members[0];
|
||||
nonManager = members[0];
|
||||
nonManager = members[1];
|
||||
});
|
||||
|
||||
it('returns an error when a non group leader tries to add member', async () => {
|
||||
|
|
@ -71,10 +71,10 @@ describe('POST /group/:groupId/remove-manager', () => {
|
|||
type: 'todo',
|
||||
requiresApproval: true,
|
||||
});
|
||||
await nonLeader.post(`/tasks/${task._id}/assign/${leader._id}`);
|
||||
let memberTasks = await leader.get('/tasks/user');
|
||||
await nonLeader.post(`/tasks/${task._id}/assign/${nonManager._id}`);
|
||||
let memberTasks = await nonManager.get('/tasks/user');
|
||||
let syncedTask = find(memberTasks, findAssignedTask);
|
||||
await expect(leader.post(`/tasks/${syncedTask._id}/score/up`))
|
||||
await expect(nonManager.post(`/tasks/${syncedTask._id}/score/up`))
|
||||
.to.eventually.be.rejected.and.to.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import {
|
||||
createAndPopulateGroup,
|
||||
translate as t,
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
import { find } from 'lodash';
|
||||
|
||||
describe('GET /approvals/group/:groupId', () => {
|
||||
let user, guild, member, task, syncedTask;
|
||||
let user, guild, member, addlMember, task, syncedTask, addlSyncedTask;
|
||||
|
||||
function findAssignedTask (memberTask) {
|
||||
return memberTask.group.id === guild._id;
|
||||
|
|
@ -17,12 +16,13 @@ describe('GET /approvals/group/:groupId', () => {
|
|||
name: 'Test Guild',
|
||||
type: 'guild',
|
||||
},
|
||||
members: 1,
|
||||
members: 2,
|
||||
});
|
||||
|
||||
guild = group;
|
||||
user = groupLeader;
|
||||
member = members[0];
|
||||
addlMember = members[1];
|
||||
|
||||
task = await user.post(`/tasks/group/${guild._id}`, {
|
||||
text: 'test todo',
|
||||
|
|
@ -31,37 +31,46 @@ describe('GET /approvals/group/:groupId', () => {
|
|||
});
|
||||
|
||||
await user.post(`/tasks/${task._id}/assign/${member._id}`);
|
||||
await user.post(`/tasks/${task._id}/assign/${addlMember._id}`);
|
||||
|
||||
let memberTasks = await member.get('/tasks/user');
|
||||
syncedTask = find(memberTasks, findAssignedTask);
|
||||
|
||||
let addlMemberTasks = await addlMember.get('/tasks/user');
|
||||
addlSyncedTask = find(addlMemberTasks, findAssignedTask);
|
||||
|
||||
try {
|
||||
await member.post(`/tasks/${syncedTask._id}/score/up`);
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-empty
|
||||
}
|
||||
|
||||
try {
|
||||
await addlMember.post(`/tasks/${addlSyncedTask._id}/score/up`);
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-empty
|
||||
}
|
||||
});
|
||||
|
||||
it('errors when user is not the group leader', async () => {
|
||||
await expect(member.get(`/approvals/group/${guild._id}`))
|
||||
.to.eventually.be.rejected.and.to.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('onlyGroupLeaderCanEditTasks'),
|
||||
});
|
||||
it('provides only user\'s own tasks when user is not the group leader', async () => {
|
||||
let approvals = await member.get(`/approvals/group/${guild._id}`);
|
||||
expect(approvals[0]._id).to.equal(syncedTask._id);
|
||||
expect(approvals[1]).to.not.exist;
|
||||
});
|
||||
|
||||
it('gets a list of task that need approval', async () => {
|
||||
it('allows group leaders to get a list of tasks that need approval', async () => {
|
||||
let approvals = await user.get(`/approvals/group/${guild._id}`);
|
||||
expect(approvals[0]._id).to.equal(syncedTask._id);
|
||||
expect(approvals[1]._id).to.equal(addlSyncedTask._id);
|
||||
});
|
||||
|
||||
it('allows managers to get a list of task that need approval', async () => {
|
||||
it('allows managers to get a list of tasks that need approval', async () => {
|
||||
await user.post(`/groups/${guild._id}/add-manager`, {
|
||||
managerId: member._id,
|
||||
});
|
||||
|
||||
let approvals = await member.get(`/approvals/group/${guild._id}`);
|
||||
expect(approvals[0]._id).to.equal(syncedTask._id);
|
||||
expect(approvals[1]._id).to.equal(addlSyncedTask._id);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -93,6 +93,25 @@ describe('POST /tasks/:taskId/assign/:memberId', () => {
|
|||
expect(syncedTask).to.exist;
|
||||
});
|
||||
|
||||
it('sends notifications to group leader and managers when a task is claimed', async () => {
|
||||
await user.post(`/groups/${guild._id}/add-manager`, {
|
||||
managerId: member2._id,
|
||||
});
|
||||
await member.post(`/tasks/${task._id}/assign/${member._id}`);
|
||||
await user.sync();
|
||||
await member2.sync();
|
||||
let groupTask = await user.get(`/tasks/group/${guild._id}`);
|
||||
|
||||
expect(user.notifications.length).to.equal(2); // includes Guild Joined achievement
|
||||
expect(user.notifications[1].type).to.equal('GROUP_TASK_CLAIMED');
|
||||
expect(user.notifications[1].data.taskId).to.equal(groupTask[0]._id);
|
||||
expect(user.notifications[1].data.groupId).to.equal(guild._id);
|
||||
expect(member2.notifications.length).to.equal(1);
|
||||
expect(member2.notifications[0].type).to.equal('GROUP_TASK_CLAIMED');
|
||||
expect(member2.notifications[0].data.taskId).to.equal(groupTask[0]._id);
|
||||
expect(member2.notifications[0].data.groupId).to.equal(guild._id);
|
||||
});
|
||||
|
||||
it('assigns a task to a user', async () => {
|
||||
await user.post(`/tasks/${task._id}/assign/${member._id}`);
|
||||
|
||||
|
|
|
|||
|
|
@ -56,11 +56,11 @@ describe('PUT /tasks/:id', () => {
|
|||
requiresApproval: true,
|
||||
});
|
||||
|
||||
let memberTasks = await member.get('/tasks/user');
|
||||
let memberTasks = await member2.get('/tasks/user');
|
||||
let syncedTask = find(memberTasks, (memberTask) => memberTask.group.taskId === task._id);
|
||||
|
||||
// score up to trigger approval
|
||||
await expect(member.post(`/tasks/${syncedTask._id}/score/up`))
|
||||
await expect(member2.post(`/tasks/${syncedTask._id}/score/up`))
|
||||
.to.eventually.be.rejected.and.to.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ describe('canDelete getter', () => {
|
|||
|
||||
|
||||
const task = {userId: 1, challenge: {id: 2}};
|
||||
expect(store.getters['tasks:canDelete'](task, 'challenge', true, null, null)).to.equal(false);
|
||||
expect(store.getters['tasks:canDelete'](task)).to.equal(false);
|
||||
});
|
||||
|
||||
it('can delete broken challenge task', () => {
|
||||
|
|
@ -14,6 +14,6 @@ describe('canDelete getter', () => {
|
|||
|
||||
|
||||
const task = {userId: 1, challenge: {id: 2, broken: true}};
|
||||
expect(store.getters['tasks:canDelete'](task, 'challenge', true, null, null)).to.equal(true);
|
||||
expect(store.getters['tasks:canDelete'](task)).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
import generateStore from 'client/store';
|
||||
|
||||
describe('canEdit getter', () => {
|
||||
it('cannot Edit active challenge task', () => {
|
||||
const store = generateStore();
|
||||
|
||||
|
||||
const task = {userId: 1, challenge: {id: 2}};
|
||||
expect(store.getters['tasks:canEdit'](task, 'challenge', true, null, null)).to.equal(false);
|
||||
});
|
||||
|
||||
it('can Edit broken challenge task', () => {
|
||||
const store = generateStore();
|
||||
|
||||
|
||||
const task = {userId: 1, challenge: {id: 2, broken: true}};
|
||||
expect(store.getters['tasks:canEdit'](task, 'challenge', true, null, null)).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
|
@ -109,12 +109,13 @@ describe('getTaskClasses getter', () => {
|
|||
});
|
||||
});
|
||||
|
||||
xit('returns good todo classes', () => {
|
||||
it('returns good todo classes', () => {
|
||||
const task = {type: 'todo', value: 2};
|
||||
expect(getTaskClasses(task, 'control')).to.deep.equal({
|
||||
bg: 'task-good-control-bg',
|
||||
checkbox: 'task-good-control-checkbox',
|
||||
inner: 'task-good-control-inner-daily-todo`',
|
||||
inner: 'task-good-control-inner-daily-todo',
|
||||
icon: 'task-good-control-icon',
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -140,4 +141,14 @@ describe('getTaskClasses getter', () => {
|
|||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('returns noninteractive classes and padlock icons for group board tasks', () => {
|
||||
const task = {type: 'todo', value: 2, group: {id: 'group-id'}};
|
||||
expect(getTaskClasses(task, 'control')).to.deep.equal({
|
||||
bg: 'task-good-control-bg-noninteractive',
|
||||
checkbox: 'task-good-control-checkbox',
|
||||
inner: 'task-good-control-inner-daily-todo',
|
||||
icon: 'task-good-control-icon',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -49,6 +49,15 @@ describe('shared.ops.buyQuestGems', () => {
|
|||
|
||||
buyQuest(user, {params: {key}});
|
||||
|
||||
expect(user.items.quests[key]).to.equal(1);
|
||||
expect(pinnedGearUtils.removeItemByPath.notCalled).to.equal(true);
|
||||
});
|
||||
it('if a user\'s count of a quest scroll is negative, it will be reset to 0 before incrementing when they buy a new one.', () => {
|
||||
let key = 'dustbunnies';
|
||||
user.items.quests[key] = -1;
|
||||
|
||||
buyQuest(user, {params: {key}});
|
||||
|
||||
expect(user.items.quests[key]).to.equal(1);
|
||||
expect(pinnedGearUtils.removeItemByPath.notCalled).to.equal(true);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import {
|
||||
generateUser,
|
||||
} from '../../../helpers/common.helper';
|
||||
import {BuyQuestWithGoldOperation} from '../../../../website/common/script/ops/buy/buyQuest';
|
||||
import {BuyQuestWithGoldOperation} from '../../../../website/common/script/ops/buy/buyQuestGold';
|
||||
import {
|
||||
BadRequest,
|
||||
NotAuthorized,
|
||||
|
|
@ -43,6 +43,18 @@ describe('shared.ops.buyQuest', () => {
|
|||
expect(analytics.track).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('if a user\'s count of a quest scroll is negative, it will be reset to 0 before incrementing when they buy a new one.', () => {
|
||||
user.stats.gp = 205;
|
||||
let key = 'dilatoryDistress1';
|
||||
user.items.quests[key] = -1;
|
||||
buyQuest(user, {
|
||||
params: {key},
|
||||
}, analytics);
|
||||
expect(user.items.quests[key]).to.equal(1);
|
||||
expect(user.stats.gp).to.equal(5);
|
||||
expect(analytics.track).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('buys a Quest scroll with the right quantity if a string is passed for quantity', () => {
|
||||
user.stats.gp = 1000;
|
||||
buyQuest(user, {
|
||||
|
|
@ -161,7 +161,7 @@ div
|
|||
overflow-y: scroll !important;
|
||||
}
|
||||
|
||||
.modal-backdrop.show {
|
||||
.modal-backdrop {
|
||||
opacity: .9 !important;
|
||||
background-color: $purple-100 !important;
|
||||
}
|
||||
|
|
@ -657,5 +657,6 @@ export default {
|
|||
<style src="assets/css/sprites/spritesmith-main-23.css"></style>
|
||||
<style src="assets/css/sprites/spritesmith-main-24.css"></style>
|
||||
<style src="assets/css/sprites/spritesmith-main-25.css"></style>
|
||||
<style src="assets/css/sprites/spritesmith-main-26.css"></style>
|
||||
<style src="assets/css/sprites.css"></style>
|
||||
<style src="smartbanner.js/dist/smartbanner.min.css"></style>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 194 B |
|
Before Width: | Height: | Size: 330 B |
|
Before Width: | Height: | Size: 582 B |
|
Before Width: | Height: | Size: 191 B |
|
Before Width: | Height: | Size: 334 B |
|
Before Width: | Height: | Size: 614 B |
|
|
@ -96,6 +96,52 @@
|
|||
background: url("~assets/images/BackerOnly-Pet-CerberusPup.gif") no-repeat;
|
||||
}
|
||||
|
||||
.broad_armor_special_ks2019, .slim_armor_special_ks2019, .eyewear_special_ks2019, .head_special_ks2019, .shield_special_ks2019 {
|
||||
width: 117px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.broad_armor_special_ks2019, .slim_armor_special_ks2019 {
|
||||
background: url("~assets/images/BackerOnly-Equip-MythicGryphonArmor.gif") no-repeat;
|
||||
}
|
||||
|
||||
.eyewear_special_ks2019 {
|
||||
background: url("~assets/images/BackerOnly-Equip-MythicGryphonVisor.gif") no-repeat;
|
||||
}
|
||||
|
||||
.head_special_ks2019 {
|
||||
background: url("~assets/images/BackerOnly-Equip-MythicGryphonHelm.gif") no-repeat;
|
||||
}
|
||||
|
||||
.shield_special_ks2019 {
|
||||
background: url("~assets/images/BackerOnly-Equip-MythicGryphonShield.gif") no-repeat;
|
||||
}
|
||||
|
||||
.weapon_special_ks2019 {
|
||||
background: url("~assets/images/BackerOnly-Equip-MythicGryphonGlaive.gif") no-repeat;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.Pet-Gryphon-Gryphatrice {
|
||||
background: url("~assets/images/BackerOnly-Pet-Gryphatrice.gif") no-repeat;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
|
||||
.Mount_Head_Gryphon-Gryphatrice, .Mount_Body_Gryphon-Gryphatrice {
|
||||
width: 135px;
|
||||
height: 135px;
|
||||
}
|
||||
|
||||
.Mount_Head_Gryphon-Gryphatrice {
|
||||
background: url("~assets/images/BackerOnly-Mount-Head-Gryphatrice.gif") no-repeat;
|
||||
}
|
||||
|
||||
.Mount_Body_Gryphon-Gryphatrice {
|
||||
background: url("~assets/images/BackerOnly-Mount-Body-Gryphatrice.gif") no-repeat;
|
||||
}
|
||||
|
||||
/* FIXME figure out how to handle customize menu!!
|
||||
.customize-menu .f_head_0 {
|
||||
width: 60px;
|
||||
|
|
|
|||
|
|
@ -1,42 +1,78 @@
|
|||
.promo_armoire_backgrounds_201909 {
|
||||
.promo_armoire_backgrounds_201910 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -343px;
|
||||
background-position: 0px -389px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_costume_achievement {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -698px -426px;
|
||||
width: 144px;
|
||||
height: 156px;
|
||||
}
|
||||
.promo_desert_pet_achievements {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -653px -211px;
|
||||
background-position: -891px -296px;
|
||||
width: 204px;
|
||||
height: 102px;
|
||||
}
|
||||
.promo_rocking_reptiles_bundle {
|
||||
.promo_fall_festival_2018 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -491px;
|
||||
width: 420px;
|
||||
background-position: 0px -208px;
|
||||
width: 372px;
|
||||
height: 180px;
|
||||
}
|
||||
.promo_fall_festival_2019 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -337px 0px;
|
||||
width: 360px;
|
||||
height: 189px;
|
||||
}
|
||||
.promo_fall_skins {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px 0px;
|
||||
width: 336px;
|
||||
height: 207px;
|
||||
}
|
||||
.customize-option.promo_fall_skins {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -25px -15px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.promo_mystery_201909 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -698px -148px;
|
||||
width: 282px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_seasonal_shop_fall {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -843px -426px;
|
||||
width: 162px;
|
||||
height: 138px;
|
||||
}
|
||||
.promo_shadow_spooky_potions {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -698px 0px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_spooky_sparkles {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -537px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_take_this {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -653px -314px;
|
||||
background-position: -981px -148px;
|
||||
width: 96px;
|
||||
height: 69px;
|
||||
}
|
||||
.scene_casting_spells {
|
||||
.scene_strength {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -340px 0px;
|
||||
width: 312px;
|
||||
height: 222px;
|
||||
}
|
||||
.scene_medal {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -653px 0px;
|
||||
width: 210px;
|
||||
height: 210px;
|
||||
}
|
||||
.scene_video_games {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px 0px;
|
||||
width: 339px;
|
||||
height: 342px;
|
||||
background-position: -698px -296px;
|
||||
width: 192px;
|
||||
height: 129px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,396 +1,402 @@
|
|||
.npc_matt {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -597px -1535px;
|
||||
width: 195px;
|
||||
height: 138px;
|
||||
}
|
||||
.background_dysheartener {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px 0px;
|
||||
width: 306px;
|
||||
height: 202px;
|
||||
}
|
||||
.banner_flair_dysheartener {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1963px -836px;
|
||||
width: 69px;
|
||||
height: 18px;
|
||||
}
|
||||
.phobia_dysheartener {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1187px -880px;
|
||||
width: 201px;
|
||||
height: 195px;
|
||||
}
|
||||
.quest_alligator {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -1079px;
|
||||
width: 201px;
|
||||
height: 213px;
|
||||
}
|
||||
.quest_armadillo {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -435px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_atom1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1105px -1315px;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_atom2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -389px -1535px;
|
||||
width: 207px;
|
||||
height: 138px;
|
||||
}
|
||||
.quest_atom3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -747px -440px;
|
||||
width: 216px;
|
||||
height: 180px;
|
||||
}
|
||||
.quest_axolotl {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -747px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_badger {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -747px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_basilist {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -392px;
|
||||
width: 189px;
|
||||
height: 141px;
|
||||
}
|
||||
.quest_beetle {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -1293px;
|
||||
width: 204px;
|
||||
height: 201px;
|
||||
}
|
||||
.quest_bronze {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -655px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_bunny {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -1543px;
|
||||
background-position: -967px -660px;
|
||||
width: 210px;
|
||||
height: 186px;
|
||||
}
|
||||
.quest_butterfly {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1320px -440px;
|
||||
background-position: -967px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_cheetah {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -892px;
|
||||
background-position: -967px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_cow {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1762px -175px;
|
||||
background-position: 0px -1535px;
|
||||
width: 174px;
|
||||
height: 213px;
|
||||
}
|
||||
.quest_dilatory {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -232px;
|
||||
background-position: -220px -875px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dilatoryDistress1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -1332px;
|
||||
background-position: -1627px -868px;
|
||||
width: 210px;
|
||||
height: 210px;
|
||||
}
|
||||
.quest_dilatoryDistress2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1762px -932px;
|
||||
background-position: -1844px -534px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_dilatoryDistress3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -660px -220px;
|
||||
background-position: -880px -875px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dilatory_derby {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -232px;
|
||||
background-position: 0px -875px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dolphin {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -452px;
|
||||
background-position: -1187px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dustbunnies {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -452px;
|
||||
background-position: -1187px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_egg {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1762px -573px;
|
||||
background-position: -1844px -184px;
|
||||
width: 165px;
|
||||
height: 207px;
|
||||
}
|
||||
.quest_evilsanta {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1762px -1385px;
|
||||
background-position: -1844px -836px;
|
||||
width: 118px;
|
||||
height: 131px;
|
||||
}
|
||||
.quest_evilsanta2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -880px 0px;
|
||||
background-position: 0px -1095px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_falcon {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -880px -220px;
|
||||
background-position: -220px -1095px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_ferret {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -880px -440px;
|
||||
background-position: -307px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_frog {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1540px 0px;
|
||||
background-position: -660px -1315px;
|
||||
width: 221px;
|
||||
height: 213px;
|
||||
}
|
||||
.quest_ghost_stag {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -672px;
|
||||
background-position: -880px -1095px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_goldenknight1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -672px;
|
||||
background-position: -1100px -1095px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_goldenknight2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1305px -1332px;
|
||||
background-position: -1356px -1315px;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_goldenknight3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px 0px;
|
||||
background-position: 0px -203px;
|
||||
width: 219px;
|
||||
height: 231px;
|
||||
}
|
||||
.quest_gryphon {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1088px -1332px;
|
||||
background-position: -527px -220px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_guineapig {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1100px -220px;
|
||||
background-position: -1407px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_harpy {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1100px -440px;
|
||||
background-position: -1407px -880px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_hedgehog {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -211px -1332px;
|
||||
background-position: -1407px -1100px;
|
||||
width: 219px;
|
||||
height: 186px;
|
||||
}
|
||||
.quest_hippo {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -892px;
|
||||
background-position: -220px -1315px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_horse {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px 0px;
|
||||
background-position: 0px -1315px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_kangaroo {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -892px;
|
||||
background-position: -1407px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_kraken {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -871px -1332px;
|
||||
background-position: -307px -220px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_lostMasterclasser1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -880px -892px;
|
||||
background-position: -660px -1095px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_lostMasterclasser2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1100px -892px;
|
||||
background-position: -440px -1095px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_lostMasterclasser3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1320px 0px;
|
||||
background-position: -1187px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_mayhemMistiflying1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1762px -1083px;
|
||||
background-position: -1844px -685px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_mayhemMistiflying2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -880px -672px;
|
||||
background-position: -660px -875px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_mayhemMistiflying3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1320px -660px;
|
||||
background-position: -440px -875px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_monkey {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1320px -880px;
|
||||
background-position: -660px -655px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moon1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1540px -431px;
|
||||
background-position: -1627px 0px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_moon2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -1112px;
|
||||
background-position: -220px -655px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moon3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -1112px;
|
||||
background-position: -440px -435px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -660px -1112px;
|
||||
background-position: -527px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -880px -1112px;
|
||||
background-position: -1407px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1100px -1112px;
|
||||
background-position: -440px -1315px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_nudibranch {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1540px -214px;
|
||||
background-position: -1627px -651px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_octopus {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -431px -1332px;
|
||||
background-position: -882px -1315px;
|
||||
width: 222px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_owl {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -1112px;
|
||||
background-position: -1187px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_peacock {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1540px -648px;
|
||||
background-position: -1627px -434px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_penguin {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1762px -389px;
|
||||
background-position: -1844px 0px;
|
||||
width: 190px;
|
||||
height: 183px;
|
||||
}
|
||||
.quest_pterodactyl {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -672px;
|
||||
background-position: -967px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_rat {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -660px -452px;
|
||||
background-position: 0px -655px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_robot {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -232px;
|
||||
background-position: -220px -435px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_rock {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1540px -865px;
|
||||
background-position: -1627px -217px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_rooster {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1762px 0px;
|
||||
background-position: -175px -1535px;
|
||||
width: 213px;
|
||||
height: 174px;
|
||||
}
|
||||
.quest_sabretooth {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1320px -1112px;
|
||||
background-position: -1407px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_seaserpent {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1100px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_sheep {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1320px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_silver {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -660px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_slime {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1100px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_sloth {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -660px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_snail {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1540px -1082px;
|
||||
width: 219px;
|
||||
height: 213px;
|
||||
}
|
||||
.quest_snake {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -654px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_spider {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -211px -1543px;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_squirrel {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_stoikalmCalamity1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1762px -781px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_stoikalmCalamity2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -660px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_stoikalmCalamity3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_taskwoodsTerror1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1762px -1234px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
|
|
|
|||
672
website/client/assets/css/sprites/spritesmith-main-26.css
Normal file
|
|
@ -0,0 +1,672 @@
|
|||
.Pet-Unicorn-CottonCandyBlue {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -82px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Unicorn-CottonCandyPink {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -164px -600px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Unicorn-Desert {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -164px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Unicorn-Golden {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: 0px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Unicorn-Red {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -82px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Unicorn-Shade {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -164px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Unicorn-Skeleton {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -246px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Unicorn-White {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -246px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Unicorn-Zombie {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: 0px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Velociraptor-Base {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -82px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Velociraptor-CottonCandyBlue {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -164px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Velociraptor-CottonCandyPink {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -246px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Velociraptor-Desert {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -328px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Velociraptor-Golden {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -328px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Velociraptor-Red {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -328px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Velociraptor-Shade {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: 0px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Velociraptor-Skeleton {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -82px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Velociraptor-White {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -164px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Velociraptor-Zombie {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -246px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Whale-Base {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -328px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Whale-CottonCandyBlue {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -410px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Whale-CottonCandyPink {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -410px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Whale-Desert {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -410px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Whale-Golden {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -410px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Whale-Red {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -492px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Whale-Shade {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -492px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Whale-Skeleton {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -492px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Whale-White {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -492px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Whale-Zombie {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: 0px -400px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Aquatic {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -82px -400px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Base {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -164px -400px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Bronze {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -246px -400px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Celestial {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -328px -400px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-CottonCandyBlue {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -410px -400px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-CottonCandyPink {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -492px -400px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Cupid {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -574px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Desert {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -574px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Ember {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -574px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Fairy {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -574px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Floral {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -574px -400px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Frost {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: 0px -500px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Ghost {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -82px -500px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Glass {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -164px -500px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Glow {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -246px -500px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Golden {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -328px -500px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Holly {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -410px -500px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-IcySnow {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -492px -500px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Peppermint {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -574px -500px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Rainbow {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -656px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Red {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -656px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-RoseQuartz {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -656px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-RoyalPurple {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -656px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Shade {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -656px -400px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Shadow {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -656px -500px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Shimmer {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: 0px -600px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Silver {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -82px -600px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Skeleton {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: 0px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Spooky {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -246px -600px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-StarryNight {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -328px -600px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Sunshine {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -410px -600px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Thunderstorm {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -492px -600px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Veggie {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -574px -600px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Veteran {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -656px -600px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Watery {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -738px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-White {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -738px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Zombie {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -738px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Base {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -738px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-CottonCandyBlue {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -738px -400px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-CottonCandyPink {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -738px -500px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Desert {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -738px -600px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Golden {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: 0px -700px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Red {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -82px -700px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Shade {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -164px -700px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Skeleton {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -246px -700px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-White {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -328px -700px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Zombie {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -410px -700px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet_HatchingPotion_Aquatic {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -561px -700px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Base {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -207px -800px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Bronze {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -630px -700px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Celestial {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -699px -700px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_CottonCandyBlue {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -820px 0px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_CottonCandyPink {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -820px -69px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Cupid {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -820px -138px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Desert {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -820px -207px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Ember {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -820px -276px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Fairy {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -820px -345px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Floral {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -820px -414px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Frost {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -820px -483px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Ghost {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -820px -552px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Glass {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -820px -621px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Glow {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -820px -690px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Golden {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: 0px -800px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Holly {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -69px -800px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_IcySnow {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -138px -800px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Peppermint {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -492px -700px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Purple {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -276px -800px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Rainbow {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -345px -800px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Red {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -414px -800px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_RoseQuartz {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -483px -800px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_RoyalPurple {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -552px -800px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Shade {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -621px -800px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Shadow {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -690px -800px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Shimmer {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -759px -800px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Silver {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -889px 0px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Skeleton {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -889px -69px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Spooky {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -889px -138px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_StarryNight {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -889px -207px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Sunshine {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -889px -276px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Thunderstorm {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -889px -345px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Watery {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -889px -414px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_White {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -889px -483px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Zombie {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-26.png');
|
||||
background-position: -889px -552px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
|
After Width: | Height: | Size: 9.6 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 992 B |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 29 KiB |
BIN
website/client/assets/images/BackerOnly-Pet-Gryphatrice.gif
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 486 KiB After Width: | Height: | Size: 482 KiB |
|
Before Width: | Height: | Size: 640 KiB After Width: | Height: | Size: 656 KiB |
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 430 KiB After Width: | Height: | Size: 388 KiB |
|
Before Width: | Height: | Size: 228 KiB After Width: | Height: | Size: 301 KiB |
|
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 151 KiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 182 KiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 163 KiB |
BIN
website/client/assets/images/sprites/spritesmith-main-26.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 120 KiB |
|
|
@ -74,10 +74,10 @@
|
|||
}
|
||||
|
||||
.btn-success {
|
||||
background: $green-10;
|
||||
background: $green-100;
|
||||
|
||||
&:disabled {
|
||||
background: $green-10;
|
||||
background: $green-100;
|
||||
}
|
||||
|
||||
&:hover:not(:disabled), &:active, &.active {
|
||||
|
|
|
|||
|
|
@ -78,3 +78,5 @@ $wizard-color: #2995CD;
|
|||
$gems-color: #24CC8F;
|
||||
$gold-color: #FFA624;
|
||||
$hourglass-color: #2995CD;
|
||||
|
||||
$purple-task: #925cf3;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@
|
|||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $maroon-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(26, 24, 29, 0.24) !important; }
|
||||
&-inner-daily-todo { background: $maroon-500 !important; }
|
||||
&-checkbox { color: $maroon-100 !important; }
|
||||
|
|
@ -38,6 +41,9 @@
|
|||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $red-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(26, 24, 29, 0.24) !important; }
|
||||
&-inner-daily-todo { background: $red-500 !important; }
|
||||
&-checkbox { color: $red-100 !important; }
|
||||
|
|
@ -69,6 +75,9 @@
|
|||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $orange-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(183, 90, 28, 0.4) !important; }
|
||||
&-inner-daily-todo { background: $orange-500 !important; }
|
||||
&-checkbox { color: $orange-100 !important; }
|
||||
|
|
@ -109,6 +118,9 @@
|
|||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $yellow-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(183, 90, 28, 0.32) !important; }
|
||||
&-inner-daily-todo { background: $yellow-500 !important; }
|
||||
&-checkbox { color: $yellow-100 !important; }
|
||||
|
|
@ -149,6 +161,9 @@
|
|||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $green-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(26, 24, 29, 0.24) !important; }
|
||||
&-inner-daily-todo { background: #77f4c7 !important; }
|
||||
&-checkbox { color: $green-10 !important; }
|
||||
|
|
@ -179,6 +194,9 @@
|
|||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $teal-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(26, 24, 29, 0.24) !important; }
|
||||
&-inner-daily-todo { background: #8dedf6 !important; }
|
||||
&-checkbox { color: $teal-100 !important; }
|
||||
|
|
@ -209,6 +227,9 @@
|
|||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $blue-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(26, 24, 29, 0.24) !important; }
|
||||
&-inner-daily-todo { background: $blue-500 !important; }
|
||||
&-checkbox { color: $blue-100 !important; }
|
||||
|
|
@ -231,6 +252,19 @@
|
|||
}
|
||||
|
||||
&-purple { // purple, only used in modals
|
||||
&-control {
|
||||
&-bg {
|
||||
background: $purple-task !important;
|
||||
&:hover {
|
||||
.habit-control { background: rgba(26, 24, 29, 0.48) !important; }
|
||||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
}
|
||||
&-inner-habit { background: rgba(26, 24, 29, 0.24) !important; }
|
||||
&-inner-daily-todo { background: #ffffff80 !important; }
|
||||
&-checkbox { color: $purple-task !important; }
|
||||
}
|
||||
|
||||
&-modal {
|
||||
&-bg { background: $purple-300 !important; }
|
||||
&-icon { color: $purple-300 !important; }
|
||||
|
|
@ -254,6 +288,10 @@
|
|||
|
||||
&:hover { background: rgba(255, 217, 160, 0.48) !important; }
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: rgba(255, 217, 160, 0.32) !important;
|
||||
.small-text { color: $orange-10 !important; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
// possible values are: normal, fall, habitoween, thanksgiving, winter, nye, birthday, valentines, spring, summer
|
||||
// more to be added on future seasons
|
||||
|
||||
$npc_market_flavor: 'normal';
|
||||
$npc_quests_flavor: 'normal';
|
||||
$npc_seasonal_flavor: 'normal';
|
||||
$npc_timetravelers_flavor: 'normal';
|
||||
$npc_tavern_flavor: 'normal';
|
||||
$npc_market_flavor: 'fall';
|
||||
$npc_quests_flavor: 'fall';
|
||||
$npc_seasonal_flavor: 'fall';
|
||||
$npc_timetravelers_flavor: 'fall';
|
||||
$npc_tavern_flavor: 'fall';
|
||||
|
|
|
|||
3
website/client/assets/svg/arrow_left.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<path fill="#A5A1AC" fill-rule="evenodd" d="M16 0h-4v32h4V0zm16 8H16v16h16V8zM12 4H8v24h4V4zM8 8H4v16h4V8zm-4 4H0v8h4v-8z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 220 B |
3
website/client/assets/svg/arrow_right.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<path fill="#A5A1AC" fill-rule="evenodd" d="M16 0h4v32h-4V0zM0 8h16v16H0V8zm20-4h4v24h-4V4zm4 4h4v16h-4V8zm4 4h4v8h-4v-8z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 220 B |
|
|
@ -164,30 +164,32 @@ export default {
|
|||
classGear (heroClass) {
|
||||
if (heroClass === 'rogue') {
|
||||
return {
|
||||
armor: 'armor_rogue_5',
|
||||
head: 'head_rogue_5',
|
||||
shield: 'shield_rogue_6',
|
||||
weapon: 'weapon_rogue_6',
|
||||
armor: 'armor_special_fall2019Rogue',
|
||||
eyewear: 'eyewear_special_fall2019Rogue',
|
||||
head: 'head_special_fall2019Rogue',
|
||||
shield: 'shield_special_fall2019Rogue',
|
||||
weapon: 'weapon_special_fall2019Rogue',
|
||||
};
|
||||
} else if (heroClass === 'wizard') {
|
||||
return {
|
||||
armor: 'armor_wizard_5',
|
||||
head: 'head_wizard_5',
|
||||
weapon: 'weapon_wizard_6',
|
||||
armor: 'armor_special_fall2019Mage',
|
||||
head: 'head_special_fall2019Mage',
|
||||
weapon: 'weapon_special_fall2019Mage',
|
||||
};
|
||||
} else if (heroClass === 'healer') {
|
||||
return {
|
||||
armor: 'armor_healer_5',
|
||||
head: 'head_healer_5',
|
||||
shield: 'shield_healer_5',
|
||||
weapon: 'weapon_healer_6',
|
||||
armor: 'armor_special_fall2019Healer',
|
||||
eyewear: 'eyewear_special_fall2019Healer',
|
||||
head: 'head_special_fall2019Healer',
|
||||
shield: 'shield_special_fall2019Healer',
|
||||
weapon: 'weapon_special_fall2019Healer',
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
armor: 'armor_warrior_5',
|
||||
head: 'head_warrior_5',
|
||||
shield: 'shield_warrior_5',
|
||||
weapon: 'weapon_warrior_6',
|
||||
armor: 'armor_special_fall2019Warrior',
|
||||
head: 'head_special_fall2019Warrior',
|
||||
shield: 'shield_special_fall2019Warrior',
|
||||
weapon: 'weapon_special_fall2019Warrior',
|
||||
};
|
||||
}
|
||||
},
|
||||
|
|
|
|||
92
website/client/components/avatarModal/body-settings.vue
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<template lang="pug">
|
||||
#body.section.customize-section
|
||||
sub-menu.text-center(:items="items", :activeSubPage="activeSubPage", @changeSubPage="changeSubPage($event)")
|
||||
div(v-if='activeSubPage === "size"')
|
||||
customize-options(
|
||||
:items="sizes",
|
||||
:currentValue="user.preferences.size"
|
||||
)
|
||||
div(v-if='activeSubPage === "shirt"')
|
||||
customize-options(
|
||||
:items="freeShirts",
|
||||
:currentValue="user.preferences.shirt"
|
||||
)
|
||||
customize-options(
|
||||
v-if='editing',
|
||||
:items='specialShirts',
|
||||
:currentValue="user.preferences.shirt",
|
||||
:fullSet='!userOwnsSet("shirt", specialShirtKeys)',
|
||||
@unlock='unlock(`shirt.${specialShirtKeys.join(",shirt.")}`)'
|
||||
)
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import appearance from 'common/script/content/appearance';
|
||||
import {subPageMixin} from '../../mixins/subPage';
|
||||
import {userStateMixin} from '../../mixins/userState';
|
||||
import {avatarEditorUtilies} from '../../mixins/avatarEditUtilities';
|
||||
import subMenu from './sub-menu';
|
||||
import customizeOptions from './customize-options';
|
||||
import gem from 'assets/svg/gem.svg';
|
||||
|
||||
const freeShirtKeys = Object.keys(appearance.shirt).filter(k => appearance.shirt[k].price === 0);
|
||||
const specialShirtKeys = Object.keys(appearance.shirt).filter(k => appearance.shirt[k].price !== 0);
|
||||
|
||||
|
||||
export default {
|
||||
props: [
|
||||
'editing',
|
||||
],
|
||||
components: {
|
||||
subMenu,
|
||||
customizeOptions,
|
||||
},
|
||||
mixins: [
|
||||
subPageMixin,
|
||||
userStateMixin,
|
||||
avatarEditorUtilies,
|
||||
],
|
||||
data () {
|
||||
return {
|
||||
specialShirtKeys,
|
||||
icons: Object.freeze({
|
||||
gem,
|
||||
}),
|
||||
items: [
|
||||
{
|
||||
id: 'size',
|
||||
label: this.$t('size'),
|
||||
},
|
||||
{
|
||||
id: 'shirt',
|
||||
label: this.$t('shirt'),
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sizes () {
|
||||
return ['slim', 'broad'].map(s => this.mapKeysToFreeOption(s, 'size'));
|
||||
},
|
||||
freeShirts () {
|
||||
return freeShirtKeys.map(s => this.mapKeysToFreeOption(s, 'shirt'));
|
||||
},
|
||||
specialShirts () {
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
let keys = this.specialShirtKeys;
|
||||
let options = keys.map(key => this.mapKeysToOption(key, 'shirt'));
|
||||
return options;
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.changeSubPage('size');
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
304
website/client/components/avatarModal/customize-options.vue
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
<template lang="pug">
|
||||
.customize-options(:class="{'background-set': fullSet}")
|
||||
.outer-option-background(
|
||||
v-for='option in items',
|
||||
:key='option.key',
|
||||
@click='option.click(option)',
|
||||
:class='{locked: option.gemLocked || option.goldLocked, premium: Boolean(option.gem), active: option.active || currentValue === option.key, none: option.none, hide: option.hide }'
|
||||
)
|
||||
.option
|
||||
.sprite.customize-option(:class='option.class')
|
||||
.redline-outer(v-if="option.none")
|
||||
.redline
|
||||
.gem-lock(v-if='option.gemLocked')
|
||||
.svg-icon.gem(v-html='icons.gem')
|
||||
span {{ option.gem }}
|
||||
.gold-lock(v-if='option.goldLocked')
|
||||
.svg-icon.gold(v-html='icons.gold')
|
||||
span {{ option.gold }}
|
||||
.purchase-set(v-if='fullSet', @click='unlock()')
|
||||
span.label {{ $t('purchaseAll') }}
|
||||
.svg-icon.gem(v-html='icons.gem')
|
||||
span.price 5
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import gem from 'assets/svg/gem.svg';
|
||||
import gold from 'assets/svg/gold.svg';
|
||||
import {avatarEditorUtilies} from '../../mixins/avatarEditUtilities';
|
||||
|
||||
export default {
|
||||
props: ['items', 'currentValue', 'fullSet'],
|
||||
mixins: [
|
||||
avatarEditorUtilies,
|
||||
],
|
||||
data () {
|
||||
return {
|
||||
icons: Object.freeze({
|
||||
gem,
|
||||
gold,
|
||||
}),
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
unlock () {
|
||||
this.$emit('unlock');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~client/assets/scss/colors.scss';
|
||||
|
||||
.customize-options {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.outer-option-background {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
pointer-events: visible;
|
||||
cursor: pointer;
|
||||
|
||||
&.premium {
|
||||
height: 112px;
|
||||
width: 96px;
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
.option {
|
||||
margin: 12px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.locked {
|
||||
border-radius: 2px;
|
||||
border: 1px solid transparent;
|
||||
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
||||
background-color: $white;
|
||||
|
||||
.option {
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
padding-left: 6px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 4px 0 rgba($black, 0.16), 0 1px 8px 0 rgba($black, 0.12);
|
||||
border: 1px solid $purple-500;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.locked):not(.active) {
|
||||
.option:hover {
|
||||
background-color: rgba(213, 200, 255, .32);
|
||||
}
|
||||
}
|
||||
|
||||
&.premium:not(.locked):not(.active) {
|
||||
border-radius: 2px;
|
||||
background-color: rgba(59, 202, 215, 0.1);
|
||||
}
|
||||
|
||||
&.none .option {
|
||||
.sprite {
|
||||
opacity: 0.24;
|
||||
}
|
||||
|
||||
.redline-outer {
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
margin: 0 auto 0 0;
|
||||
|
||||
.redline {
|
||||
width: 60px;
|
||||
height: 4px;
|
||||
display: block;
|
||||
background: red;
|
||||
transform: rotate(-45deg);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 20px;
|
||||
margin-left: -1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.active .option {
|
||||
background: white;
|
||||
border: solid 4px $purple-300;
|
||||
}
|
||||
|
||||
&.premium:not(.active) .option {
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
.option {
|
||||
vertical-align: bottom;
|
||||
height: 64px;
|
||||
width: 64px;
|
||||
|
||||
margin: 12px 8px;
|
||||
border: 4px solid transparent;
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.outer-option-background:not(.none) {
|
||||
|
||||
.sprite.customize-option {
|
||||
// margin: 0 auto;
|
||||
//margin-left: -3px;
|
||||
//margin-top: -7px;
|
||||
margin-top: 0;
|
||||
margin-left: 0;
|
||||
|
||||
&.size, &.shirt {
|
||||
margin-top: -8px;
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
&.color-bangs {
|
||||
margin-top: 3px;
|
||||
}
|
||||
&.skin {
|
||||
margin-top: -4px;
|
||||
margin-left: -4px;
|
||||
}
|
||||
&.chair {
|
||||
margin-left: -1px;
|
||||
margin-top: -1px;
|
||||
|
||||
&.button_chair_black {
|
||||
// different sprite margin?
|
||||
margin-top: -3px;
|
||||
}
|
||||
|
||||
&.handleless {
|
||||
margin-left: -5px;
|
||||
margin-top: -5px;
|
||||
}
|
||||
}
|
||||
&.color, &.bangs {
|
||||
margin-top: 4px;
|
||||
margin-left: -3px;
|
||||
}
|
||||
|
||||
&.hair.base {
|
||||
margin-top: 0px;
|
||||
margin-left: -5px;
|
||||
}
|
||||
|
||||
&.headAccessory {
|
||||
margin-top: 0;
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
&.headband {
|
||||
margin-top: -6px;
|
||||
margin-left: -27px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-center {
|
||||
.gem-lock, .gold-lock {
|
||||
display: inline-block;
|
||||
margin: 0 auto 8px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
|
||||
.gem-lock, .gold-lock {
|
||||
.svg-icon {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-weight: bold;
|
||||
margin-left: .5em;
|
||||
}
|
||||
|
||||
.svg-icon, span {
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
|
||||
.gem-lock span {
|
||||
color: $green-10
|
||||
}
|
||||
|
||||
.purchase-set {
|
||||
background: #fff;
|
||||
padding: 0.5em;
|
||||
border-radius: 0 0 2px 2px;
|
||||
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
||||
cursor: pointer;
|
||||
|
||||
span {
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
span.price {
|
||||
color: #24cc8f;
|
||||
}
|
||||
|
||||
.gem, .coin {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
&.single {
|
||||
width: 141px;
|
||||
}
|
||||
|
||||
width: 100%;
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.gem, .coin {
|
||||
width: 20px;
|
||||
margin: 0 .5em;
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
|
||||
.background-set {
|
||||
background-color: #edecee;
|
||||
border-radius: 2px;
|
||||
|
||||
padding-top: 12px;
|
||||
margin-left: 12px;
|
||||
margin-right: 12px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
|
||||
width: calc(100% - 24px);
|
||||
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
|
||||
max-width: unset; // disable col12 styling
|
||||
flex: unset;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
272
website/client/components/avatarModal/extra-settings.vue
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
<template lang="pug">
|
||||
#extra.section.container.customize-section
|
||||
sub-menu.text-center(:items="extraSubMenuItems", :activeSubPage="activeSubPage", @changeSubPage="changeSubPage($event)")
|
||||
|
||||
#hair-color(v-if='activeSubPage === "glasses"')
|
||||
customize-options(
|
||||
:items="eyewear"
|
||||
)
|
||||
|
||||
#animal-ears(v-if='activeSubPage === "ears"')
|
||||
customize-options(
|
||||
:items="animalItems('headAccessory')",
|
||||
:fullSet='!animalItemsOwned("headAccessory")',
|
||||
@unlock='unlock(animalItemsUnlockString("headAccessory"))'
|
||||
)
|
||||
|
||||
#animal-tails(v-if='activeSubPage === "tails"')
|
||||
customize-options(
|
||||
:items="animalItems('back')",
|
||||
:fullSet='!animalItemsOwned("back")',
|
||||
@unlock='unlock(animalItemsUnlockString("back"))'
|
||||
)
|
||||
#headband(v-if='activeSubPage === "headband"')
|
||||
customize-options(
|
||||
:items="headbands",
|
||||
)
|
||||
|
||||
#wheelchairs(v-if='activeSubPage === "wheelchair"')
|
||||
customize-options(
|
||||
:items="chairs",
|
||||
)
|
||||
#flowers(v-if='activeSubPage === "flower"')
|
||||
customize-options(
|
||||
:items="flowers",
|
||||
)
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import appearance from 'common/script/content/appearance';
|
||||
import {subPageMixin} from '../../mixins/subPage';
|
||||
import {userStateMixin} from '../../mixins/userState';
|
||||
import {avatarEditorUtilies} from '../../mixins/avatarEditUtilities';
|
||||
import subMenu from './sub-menu';
|
||||
import customizeOptions from './customize-options';
|
||||
import gem from 'assets/svg/gem.svg';
|
||||
|
||||
const freeShirtKeys = Object.keys(appearance.shirt).filter(k => appearance.shirt[k].price === 0);
|
||||
const specialShirtKeys = Object.keys(appearance.shirt).filter(k => appearance.shirt[k].price !== 0);
|
||||
|
||||
|
||||
export default {
|
||||
props: [
|
||||
'editing',
|
||||
],
|
||||
components: {
|
||||
subMenu,
|
||||
customizeOptions,
|
||||
},
|
||||
mixins: [
|
||||
subPageMixin,
|
||||
userStateMixin,
|
||||
avatarEditorUtilies,
|
||||
],
|
||||
data () {
|
||||
return {
|
||||
animalItemKeys: {
|
||||
back: ['bearTail', 'cactusTail', 'foxTail', 'lionTail', 'pandaTail', 'pigTail', 'tigerTail', 'wolfTail'],
|
||||
headAccessory: ['bearEars', 'cactusEars', 'foxEars', 'lionEars', 'pandaEars', 'pigEars', 'tigerEars', 'wolfEars'],
|
||||
},
|
||||
chairKeys: ['none', 'black', 'blue', 'green', 'pink', 'red', 'yellow', 'handleless_black', 'handleless_blue', 'handleless_green', 'handleless_pink', 'handleless_red', 'handleless_yellow'],
|
||||
specialShirtKeys,
|
||||
icons: Object.freeze({
|
||||
gem,
|
||||
}),
|
||||
items: [
|
||||
{
|
||||
id: 'size',
|
||||
label: this.$t('size'),
|
||||
},
|
||||
{
|
||||
id: 'shirt',
|
||||
label: this.$t('shirt'),
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
extraSubMenuItems () {
|
||||
const items = [];
|
||||
|
||||
if (this.editing) {
|
||||
items.push({
|
||||
id: 'glasses',
|
||||
label: this.$t('glasses'),
|
||||
});
|
||||
}
|
||||
|
||||
items.push(
|
||||
{
|
||||
id: 'wheelchair',
|
||||
label: this.$t('wheelchair'),
|
||||
},
|
||||
{
|
||||
id: 'flower',
|
||||
label: this.$t('accent'),
|
||||
},
|
||||
);
|
||||
|
||||
if (this.editing) {
|
||||
items.push({
|
||||
id: 'ears',
|
||||
label: this.$t('animalEars'),
|
||||
});
|
||||
|
||||
items.push({
|
||||
id: 'tails',
|
||||
label: this.$t('animalTails'),
|
||||
});
|
||||
|
||||
items.push({
|
||||
id: 'headband',
|
||||
label: this.$t('headband'),
|
||||
});
|
||||
}
|
||||
|
||||
return items;
|
||||
},
|
||||
eyewear () {
|
||||
let keys = [
|
||||
'blackTopFrame', 'blueTopFrame', 'greenTopFrame', 'pinkTopFrame', 'redTopFrame', 'whiteTopFrame', 'yellowTopFrame',
|
||||
'blackHalfMoon', 'blueHalfMoon', 'greenHalfMoon', 'pinkHalfMoon', 'redHalfMoon', 'whiteHalfMoon', 'yellowHalfMoon',
|
||||
];
|
||||
let options = keys.map(key => {
|
||||
let newKey = `eyewear_special_${key}`;
|
||||
let option = {};
|
||||
option.key = key;
|
||||
option.active = this.user.preferences.costume ? this.user.items.gear.costume.eyewear === newKey : this.user.items.gear.equipped.eyewear === newKey;
|
||||
option.class = `eyewear_special_${key}`;
|
||||
option.click = () => {
|
||||
let type = this.user.preferences.costume ? 'costume' : 'equipped';
|
||||
|
||||
return this.equip(newKey, type);
|
||||
};
|
||||
return option;
|
||||
});
|
||||
return options;
|
||||
},
|
||||
freeShirts () {
|
||||
return freeShirtKeys.map(s => this.mapKeysToFreeOption(s, 'shirt'));
|
||||
},
|
||||
specialShirts () {
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
let keys = this.specialShirtKeys;
|
||||
let options = keys.map(key => this.mapKeysToOption(key, 'shirt'));
|
||||
return options;
|
||||
},
|
||||
headbands () {
|
||||
let keys = ['blackHeadband', 'blueHeadband', 'greenHeadband', 'pinkHeadband', 'redHeadband', 'whiteHeadband', 'yellowHeadband'];
|
||||
let options = keys.map(key => {
|
||||
let newKey = `headAccessory_special_${key}`;
|
||||
let option = {};
|
||||
option.key = key;
|
||||
option.active = this.user.preferences.costume ? this.user.items.gear.costume.headAccessory === newKey : this.user.items.gear.equipped.headAccessory === newKey;
|
||||
option.class = `headAccessory_special_${option.key} headband`;
|
||||
option.click = () => {
|
||||
let type = this.user.preferences.costume ? 'costume' : 'equipped';
|
||||
return this.equip(newKey, type);
|
||||
};
|
||||
return option;
|
||||
});
|
||||
return options;
|
||||
},
|
||||
chairs () {
|
||||
let options = this.chairKeys.map(key => {
|
||||
let option = {};
|
||||
option.key = key;
|
||||
if (key === 'none') {
|
||||
option.none = true;
|
||||
}
|
||||
option.active = this.user.preferences.chair === key;
|
||||
option.class = `button_chair_${key} chair ${key.includes('handleless_') ? 'handleless' : ''}`;
|
||||
option.click = () => {
|
||||
return this.set({'preferences.chair': key});
|
||||
};
|
||||
return option;
|
||||
});
|
||||
return options;
|
||||
},
|
||||
flowers () {
|
||||
let keys = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
|
||||
let options = keys.map(key => {
|
||||
let option = {};
|
||||
option.key = key;
|
||||
if (key === 0) {
|
||||
option.none = true;
|
||||
}
|
||||
option.active = this.user.preferences.hair.flower === key;
|
||||
option.class = `hair_flower_${key} flower`;
|
||||
option.click = () => {
|
||||
return this.set({'preferences.hair.flower': key});
|
||||
};
|
||||
return option;
|
||||
});
|
||||
return options;
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.changeSubPage(this.extraSubMenuItems[0].id);
|
||||
},
|
||||
methods: {
|
||||
animalItems (category) {
|
||||
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
let keys = this.animalItemKeys[category];
|
||||
let options = keys.map(key => {
|
||||
let newKey = `${category}_special_${key}`;
|
||||
let userPurchased = this.user.items.gear.owned[newKey];
|
||||
|
||||
let option = {};
|
||||
option.key = key;
|
||||
option.active = this.user.preferences.costume ? this.user.items.gear.costume[category] === newKey : this.user.items.gear.equipped[category] === newKey;
|
||||
option.class = `headAccessory_special_${option.key} ${category}`;
|
||||
if (category === 'back') {
|
||||
option.class = `icon_back_special_${option.key} back`;
|
||||
}
|
||||
option.gemLocked = userPurchased === undefined;
|
||||
option.goldLocked = userPurchased === false;
|
||||
if (option.goldLocked) {
|
||||
option.gold = 20;
|
||||
}
|
||||
if (option.gemLocked) {
|
||||
option.gem = 2;
|
||||
}
|
||||
option.locked = option.gemLocked || option.goldLocked;
|
||||
option.click = () => {
|
||||
if (option.gemLocked) {
|
||||
return this.unlock(`items.gear.owned.${newKey}`);
|
||||
} else if (option.goldLocked) {
|
||||
return this.buy(newKey);
|
||||
} else {
|
||||
let type = this.user.preferences.costume ? 'costume' : 'equipped';
|
||||
return this.equip(newKey, type);
|
||||
}
|
||||
};
|
||||
return option;
|
||||
});
|
||||
return options;
|
||||
},
|
||||
animalItemsUnlockString (category) {
|
||||
const keys = this.animalItemKeys[category].map(key => {
|
||||
return `items.gear.owned.${category}_special_${key}`;
|
||||
});
|
||||
|
||||
return keys.join(',');
|
||||
},
|
||||
animalItemsOwned (category) {
|
||||
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
|
||||
let own = true;
|
||||
this.animalItemKeys[category].forEach(key => {
|
||||
if (this.user.items.gear.owned[`${category}_special_${key}`] === undefined) own = false;
|
||||
});
|
||||
return own;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
341
website/client/components/avatarModal/hair-settings.vue
Normal file
|
|
@ -0,0 +1,341 @@
|
|||
<template lang="pug">
|
||||
#hair.section.customize-section
|
||||
sub-menu.text-center(:items="hairSubMenuItems", :activeSubPage="activeSubPage", @changeSubPage="changeSubPage($event)")
|
||||
|
||||
#hair-color(v-if='activeSubPage === "color"')
|
||||
customize-options(
|
||||
:items="freeHairColors",
|
||||
:currentValue="user.preferences.hair.color"
|
||||
)
|
||||
|
||||
div(v-if='editing && set.key !== "undefined"', v-for='set in seasonalHairColors')
|
||||
customize-options(
|
||||
:items='set.options',
|
||||
:currentValue="user.preferences.skin",
|
||||
:fullSet='!hideSet(set) && !userOwnsSet("hair", set.keys, "color")',
|
||||
@unlock='unlock(`hair.color.${set.keys.join(",hair.color.")}`)'
|
||||
)
|
||||
|
||||
#style(v-if='activeSubPage === "style"')
|
||||
div(v-for='set in styleSets')
|
||||
customize-options(
|
||||
:items='set.options',
|
||||
:fullSet='set.fullSet',
|
||||
@unlock='set.unlock()'
|
||||
)
|
||||
#bangs(v-if='activeSubPage === "bangs"')
|
||||
customize-options(
|
||||
:items='hairBangs',
|
||||
:currentValue="user.preferences.hair.bangs"
|
||||
)
|
||||
#facialhair(v-if='activeSubPage === "facialhair"')
|
||||
customize-options(
|
||||
v-if='editing',
|
||||
:items='mustacheList'
|
||||
)
|
||||
customize-options(
|
||||
v-if='editing',
|
||||
:items='beardList',
|
||||
:fullSet='isPurchaseAllNeeded("hair", ["baseHair5", "baseHair6"], ["mustache", "beard"])',
|
||||
@unlock='unlock(`hair.mustache.${baseHair5Keys.join(",hair.mustache.")},hair.beard.${baseHair6Keys.join(",hair.beard.")}`)'
|
||||
)
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import appearance from 'common/script/content/appearance';
|
||||
import {subPageMixin} from '../../mixins/subPage';
|
||||
import {userStateMixin} from '../../mixins/userState';
|
||||
import {avatarEditorUtilies} from '../../mixins/avatarEditUtilities';
|
||||
import subMenu from './sub-menu';
|
||||
import customizeOptions from './customize-options';
|
||||
import gem from 'assets/svg/gem.svg';
|
||||
import appearanceSets from 'common/script/content/appearance/sets';
|
||||
import groupBy from 'lodash/groupBy';
|
||||
|
||||
const hairColorBySet = groupBy(appearance.hair.color, 'set.key');
|
||||
const freeHairColorKeys = hairColorBySet[undefined].map(s => s.key);
|
||||
|
||||
export default {
|
||||
props: [
|
||||
'editing',
|
||||
],
|
||||
components: {
|
||||
subMenu,
|
||||
customizeOptions,
|
||||
},
|
||||
mixins: [
|
||||
subPageMixin,
|
||||
userStateMixin,
|
||||
avatarEditorUtilies,
|
||||
],
|
||||
data () {
|
||||
return {
|
||||
freeHairColorKeys,
|
||||
icons: Object.freeze({
|
||||
gem,
|
||||
}),
|
||||
baseHair1: [1, 3],
|
||||
baseHair2Keys: [2, 4, 5, 6, 7, 8],
|
||||
baseHair3Keys: [9, 10, 11, 12, 13, 14],
|
||||
baseHair4Keys: [15, 16, 17, 18, 19, 20],
|
||||
baseHair5Keys: [1, 2],
|
||||
baseHair6Keys: [1, 2, 3],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
hairSubMenuItems () {
|
||||
const items = [
|
||||
{
|
||||
id: 'color',
|
||||
label: this.$t('color'),
|
||||
},
|
||||
{
|
||||
id: 'bangs',
|
||||
label: this.$t('bangs'),
|
||||
},
|
||||
{
|
||||
id: 'style',
|
||||
label: this.$t('style'),
|
||||
},
|
||||
];
|
||||
|
||||
if (this.editing) {
|
||||
items.push({
|
||||
id: 'facialhair',
|
||||
label: this.$t('facialhair'),
|
||||
});
|
||||
}
|
||||
|
||||
return items;
|
||||
},
|
||||
freeHairColors () {
|
||||
return freeHairColorKeys.map(s => this.mapKeysToFreeOption(s, 'hair', 'color'));
|
||||
},
|
||||
seasonalHairColors () {
|
||||
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
|
||||
let seasonalHairColors = [];
|
||||
for (let key in hairColorBySet) {
|
||||
let set = hairColorBySet[key];
|
||||
|
||||
let keys = set.map(item => {
|
||||
return item.key;
|
||||
});
|
||||
|
||||
let options = keys.map(optionKey => {
|
||||
const option = this.mapKeysToOption(optionKey, 'hair', 'color', key);
|
||||
return option;
|
||||
});
|
||||
|
||||
let text = this.$t(key);
|
||||
if (appearanceSets[key] && appearanceSets[key].text) {
|
||||
text = appearanceSets[key].text();
|
||||
}
|
||||
|
||||
let compiledSet = {
|
||||
key,
|
||||
options,
|
||||
keys,
|
||||
text,
|
||||
};
|
||||
seasonalHairColors.push(compiledSet);
|
||||
}
|
||||
|
||||
return seasonalHairColors;
|
||||
},
|
||||
premiumHairColors () {
|
||||
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
let keys = this.premiumHairColorKeys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'hair', 'color');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
baseHair2 () {
|
||||
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
let keys = this.baseHair2Keys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'hair', 'base');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
baseHair3 () {
|
||||
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
let keys = this.baseHair3Keys;
|
||||
let options = keys.map(key => {
|
||||
const option = this.mapKeysToOption(key, 'hair', 'base');
|
||||
return option;
|
||||
});
|
||||
return options;
|
||||
},
|
||||
baseHair4 () {
|
||||
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
let keys = this.baseHair4Keys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'hair', 'base');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
baseHair5 () {
|
||||
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
let keys = this.baseHair5Keys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'hair', 'mustache');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
baseHair6 () {
|
||||
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
let keys = this.baseHair6Keys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'hair', 'beard');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
hairBangs () {
|
||||
const none = this.mapKeysToFreeOption(0, 'hair', 'bangs');
|
||||
none.none = true;
|
||||
|
||||
const options = [1, 2, 3, 4].map(s => this.mapKeysToFreeOption(s, 'hair', 'bangs'));
|
||||
|
||||
return [none, ...options];
|
||||
},
|
||||
mustacheList () {
|
||||
const noneOption = this.mapKeysToFreeOption(0, 'hair', 'mustache');
|
||||
noneOption.none = true;
|
||||
|
||||
return [noneOption, ...this.baseHair5];
|
||||
},
|
||||
beardList () {
|
||||
const noneOption = this.mapKeysToFreeOption(0, 'hair', 'beard');
|
||||
noneOption.none = true;
|
||||
|
||||
return [noneOption, ...this.baseHair6];
|
||||
},
|
||||
styleSets () {
|
||||
const sets = [];
|
||||
|
||||
const emptyHairBase = {
|
||||
...this.mapKeysToFreeOption(0, 'hair', 'base'),
|
||||
none: true,
|
||||
};
|
||||
|
||||
if (this.editing) {
|
||||
sets.push({
|
||||
fullSet: !this.userOwnsSet('hair', this.baseHair3Keys, 'base'),
|
||||
unlock: () => this.unlock(`hair.base.${this.baseHair3Keys.join(',hair.base.')}`),
|
||||
options: [
|
||||
emptyHairBase,
|
||||
...this.baseHair3,
|
||||
],
|
||||
});
|
||||
|
||||
sets.push({
|
||||
fullSet: !this.userOwnsSet('hair', this.baseHair4Keys, 'base'),
|
||||
unlock: () => this.unlock(`hair.base.${this.baseHair4Keys.join(',hair.base.')}`),
|
||||
options: [
|
||||
...this.baseHair4,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
sets.push({
|
||||
options: [
|
||||
emptyHairBase,
|
||||
...this.baseHair1.map(key => this.mapKeysToFreeOption(key, 'hair', 'base')),
|
||||
],
|
||||
});
|
||||
|
||||
if (this.editing) {
|
||||
sets.push({
|
||||
fullSet: !this.userOwnsSet('hair', this.baseHair2Keys, 'base'),
|
||||
unlock: () => this.unlock(`hair.base.${this.baseHair2Keys.join(',hair.base.')}`),
|
||||
options: [
|
||||
...this.baseHair2,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return sets;
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.changeSubPage('color');
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Allows you to find out whether you need the "Purchase All" button or not. If there are more than 2 unpurchased items, returns true, otherwise returns false.
|
||||
* @param {string} category - The selected category.
|
||||
* @param {string[]} keySets - The items keySets.
|
||||
* @param {string[]} [types] - The items types (subcategories). Optional.
|
||||
* @returns {boolean} - Determines whether the "Purchase All" button is needed (true) or not (false).
|
||||
*/
|
||||
isPurchaseAllNeeded (category, keySets, types) {
|
||||
const purchasedItemsLengths = [];
|
||||
// If item types are specified, count them
|
||||
if (types && types.length > 0) {
|
||||
// Types can be undefined, so we must check them.
|
||||
types.forEach((type) => {
|
||||
if (this.user.purchased[category][type]) {
|
||||
purchasedItemsLengths
|
||||
.push(Object.keys(this.user.purchased[category][type]).length);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
let purchasedItemsCounter = 0;
|
||||
|
||||
// If types are not specified, recursively
|
||||
// search for purchased items in the category
|
||||
const findPurchasedItems = (item) => {
|
||||
if (typeof item === 'object') {
|
||||
Object.values(item)
|
||||
.forEach((innerItem) => {
|
||||
if (typeof innerItem === 'boolean' && innerItem === true) {
|
||||
purchasedItemsCounter += 1;
|
||||
}
|
||||
return findPurchasedItems(innerItem);
|
||||
});
|
||||
}
|
||||
return purchasedItemsCounter;
|
||||
};
|
||||
|
||||
findPurchasedItems(this.user.purchased[category]);
|
||||
if (purchasedItemsCounter > 0) {
|
||||
purchasedItemsLengths.push(purchasedItemsCounter);
|
||||
}
|
||||
}
|
||||
|
||||
// We don't need to count the key sets (below)
|
||||
// if there are no purchased items at all.
|
||||
if (purchasedItemsLengths.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const allItemsLengths = [];
|
||||
// Key sets must be specify correctly.
|
||||
keySets.forEach((keySet) => {
|
||||
allItemsLengths.push(Object.keys(this[keySet]).length);
|
||||
});
|
||||
|
||||
// Simply sum all the length values and
|
||||
// write them into variables for the convenience.
|
||||
const allItems = allItemsLengths.reduce((acc, val) => acc + val);
|
||||
const purchasedItems = purchasedItemsLengths.reduce((acc, val) => acc + val);
|
||||
|
||||
const unpurchasedItems = allItems - purchasedItems;
|
||||
return unpurchasedItems > 2;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
114
website/client/components/avatarModal/skin-settings.vue
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
<template lang="pug">
|
||||
#skin.section.customize-section
|
||||
sub-menu.text-center(:items="skinSubMenuItems", :activeSubPage="activeSubPage", @changeSubPage="changeSubPage($event)")
|
||||
customize-options(
|
||||
:items="freeSkins",
|
||||
:currentValue="user.preferences.skin"
|
||||
)
|
||||
|
||||
div(v-if='editing && set.key !== "undefined"', v-for='set in seasonalSkins')
|
||||
customize-options(
|
||||
:items='set.options',
|
||||
:currentValue="user.preferences.skin",
|
||||
:fullSet='!hideSet(set) && !userOwnsSet("skin", set.keys)',
|
||||
@unlock='unlock(`skin.${set.keys.join(",skin.")}`)'
|
||||
)
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import appearance from 'common/script/content/appearance';
|
||||
import {subPageMixin} from '../../mixins/subPage';
|
||||
import {userStateMixin} from '../../mixins/userState';
|
||||
import {avatarEditorUtilies} from '../../mixins/avatarEditUtilities';
|
||||
import appearanceSets from 'common/script/content/appearance/sets';
|
||||
import subMenu from './sub-menu';
|
||||
import customizeOptions from './customize-options';
|
||||
import gem from 'assets/svg/gem.svg';
|
||||
|
||||
import groupBy from 'lodash/groupBy';
|
||||
|
||||
const skinsBySet = groupBy(appearance.skin, 'set.key');
|
||||
|
||||
const freeSkinKeys = skinsBySet[undefined].map(s => s.key);
|
||||
|
||||
// const specialSkinKeys = Object.keys(appearance.shirt).filter(k => appearance.shirt[k].price !== 0);
|
||||
|
||||
|
||||
export default {
|
||||
props: [
|
||||
'editing',
|
||||
],
|
||||
components: {
|
||||
subMenu,
|
||||
customizeOptions,
|
||||
},
|
||||
mixins: [
|
||||
subPageMixin,
|
||||
userStateMixin,
|
||||
avatarEditorUtilies,
|
||||
],
|
||||
data () {
|
||||
return {
|
||||
freeSkinKeys,
|
||||
icons: Object.freeze({
|
||||
gem,
|
||||
}),
|
||||
skinSubMenuItems: [
|
||||
{
|
||||
id: 'color',
|
||||
label: this.$t('color'),
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
freeSkins () {
|
||||
return freeSkinKeys.map(s => this.mapKeysToFreeOption(s, 'skin'));
|
||||
},
|
||||
seasonalSkins () {
|
||||
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
|
||||
let seasonalSkins = [];
|
||||
for (let setKey in skinsBySet) {
|
||||
let set = skinsBySet[setKey];
|
||||
|
||||
let keys = set.map(item => {
|
||||
return item.key;
|
||||
});
|
||||
|
||||
let options = keys.map(optionKey => {
|
||||
const option = this.mapKeysToOption(optionKey, 'skin', '', setKey);
|
||||
|
||||
return option;
|
||||
});
|
||||
|
||||
let text = this.$t(setKey);
|
||||
if (appearanceSets[setKey] && appearanceSets[setKey].text) {
|
||||
text = appearanceSets[setKey].text();
|
||||
}
|
||||
|
||||
let compiledSet = {
|
||||
key: setKey,
|
||||
options,
|
||||
keys,
|
||||
text,
|
||||
};
|
||||
seasonalSkins.push(compiledSet);
|
||||
}
|
||||
|
||||
return seasonalSkins;
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.changeSubPage('color');
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
52
website/client/components/avatarModal/sub-menu.vue
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<template lang="pug">
|
||||
.sub-menu.text-center
|
||||
.sub-menu-item(
|
||||
v-for="item of items",
|
||||
:key="item.id",
|
||||
@click='$emit("changeSubPage", item.id)',
|
||||
:class='{active: activeSubPage === item.id}'
|
||||
)
|
||||
strong(v-once) {{ item.label }}
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['items', 'activeSubPage'],
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '~client/assets/scss/colors.scss';
|
||||
|
||||
.sub-menu {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 10px;
|
||||
padding-top: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.sub-menu:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sub-menu-item {
|
||||
padding: 6px 16px;
|
||||
text-align: center;
|
||||
border-bottom: 2px solid #f9f9f9;
|
||||
height: 32px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
font-stretch: normal;
|
||||
line-height: 1.67;
|
||||
letter-spacing: normal;
|
||||
text-align: center;
|
||||
color: $gray-100;
|
||||
}
|
||||
|
||||
.sub-menu .sub-menu-item:hover, .sub-menu .sub-menu-item.active {
|
||||
color: $purple-200;
|
||||
border-bottom: 2px solid $purple-200;
|
||||
}
|
||||
</style>
|
||||