add support for UC zone restrictions

This commit is contained in:
Emi Matchu 2020-08-31 19:23:56 -07:00
parent f6b9f7f440
commit d91cd80603
5 changed files with 428 additions and 145 deletions

View file

@ -119,13 +119,21 @@ export function getVisibleLayers(petAppearance, itemAppearances) {
.map((l) => ({ ...l, source: "item" })); .map((l) => ({ ...l, source: "item" }));
let allLayers = [...petLayers, ...itemLayers]; let allLayers = [...petLayers, ...itemLayers];
const allRestrictedZoneIds = validItemAppearances const itemRestrictedZoneIds = validItemAppearances
.map((a) => a.restrictedZones)
.flat()
.map((z) => z.id);
const petRestrictedZoneIds = petLayers
.map((l) => l.restrictedZones) .map((l) => l.restrictedZones)
.flat() .flat()
.map((z) => z.id); .map((z) => z.id);
const allRestrictedZoneIds = new Set([
...itemRestrictedZoneIds,
...petRestrictedZoneIds,
]);
const visibleLayers = allLayers.filter( const visibleLayers = allLayers.filter(
(l) => !allRestrictedZoneIds.includes(l.zone.id) (l) => !allRestrictedZoneIds.has(l.zone.id)
); );
visibleLayers.sort((a, b) => a.zone.depth - b.zone.depth); visibleLayers.sort((a, b) => a.zone.depth - b.zone.depth);
@ -166,6 +174,9 @@ export const petAppearanceFragment = gql`
id id
depth @client depth @client
} }
restrictedZones {
id
}
} }
} }
`; `;

View file

@ -12,6 +12,7 @@ const {
getEmotion, getEmotion,
getGenderPresentation, getGenderPresentation,
getPoseName, getPoseName,
getRestrictedZoneIds,
loadBodyName, loadBodyName,
logToDiscord, logToDiscord,
normalizeRow, normalizeRow,
@ -102,6 +103,7 @@ const typeDefs = gql`
bodyId: ID! bodyId: ID!
layers: [AppearanceLayer!]! layers: [AppearanceLayer!]!
petStateId: ID! # Deprecated, an alias for id petStateId: ID! # Deprecated, an alias for id
# Whether this PetAppearance is known to look incorrect. This is a manual # Whether this PetAppearance is known to look incorrect. This is a manual
# flag that we set, in the case where this glitchy PetAppearance really did # flag that we set, in the case where this glitchy PetAppearance really did
@ -157,6 +159,14 @@ const typeDefs = gql`
The item this layer is for, if any. (For pet layers, this is null.) The item this layer is for, if any. (For pet layers, this is null.)
""" """
item: Item item: Item
"""
The zones that this layer restricts, if any. Note that, for item layers,
this is generally empty and the restriction is on the ItemAppearance, not
the individual layers. For pet layers, this is generally used for
Unconverted pets.
"""
restrictedZones: [Zone!]!
} }
# Cache for 1 week (unlikely to change) # Cache for 1 week (unlikely to change)
@ -347,14 +357,7 @@ const resolvers = {
}, },
restrictedZones: async ({ item: { id: itemId } }, _, { itemLoader }) => { restrictedZones: async ({ item: { id: itemId } }, _, { itemLoader }) => {
const item = await itemLoader.load(itemId); const item = await itemLoader.load(itemId);
const restrictedZones = []; return getRestrictedZoneIds(item.zonesRestrict).map((id) => ({ id }));
for (const [i, bit] of Array.from(item.zonesRestrict).entries()) {
if (bit === "1") {
const zone = { id: i + 1 };
restrictedZones.push(zone);
}
}
return restrictedZones;
}, },
}, },
PetAppearance: { PetAppearance: {
@ -400,6 +403,10 @@ const resolvers = {
const layer = await swfAssetLoader.load(id); const layer = await swfAssetLoader.load(id);
return { id: layer.zoneId }; return { id: layer.zoneId };
}, },
restrictedZones: async ({ id }, _, { swfAssetLoader }) => {
const layer = await swfAssetLoader.load(id);
return getRestrictedZoneIds(layer.zonesRestrict).map((id) => ({ id }));
},
swfUrl: async ({ id }, _, { swfAssetLoader }) => { swfUrl: async ({ id }, _, { swfAssetLoader }) => {
const layer = await swfAssetLoader.load(id); const layer = await swfAssetLoader.load(id);
return layer.url; return layer.url;

View file

@ -27,6 +27,9 @@ describe("PetAppearance", () => {
zone { zone {
depth depth
} }
restrictedZones {
id
}
} }
} }
} }
@ -47,7 +50,8 @@ describe("PetAppearance", () => {
Array [ Array [
"SELECT * FROM pet_states "SELECT * FROM pet_states
WHERE pet_type_id IN (?) WHERE pet_type_id IN (?)
ORDER BY mood_id ASC, female DESC, id DESC", ORDER BY (mood_id IS NULL) ASC, mood_id ASC, female DESC,
unconverted DESC, glitched ASC, id DESC",
Array [ Array [
"2", "2",
], ],
@ -143,7 +147,8 @@ describe("PetAppearance", () => {
Array [ Array [
"SELECT * FROM pet_states "SELECT * FROM pet_states
WHERE pet_type_id IN (?) WHERE pet_type_id IN (?)
ORDER BY mood_id ASC, female DESC, id DESC", ORDER BY (mood_id IS NULL) ASC, mood_id ASC, female DESC,
unconverted DESC, glitched ASC, id DESC",
Array [ Array [
"2", "2",
], ],
@ -155,14 +160,14 @@ describe("PetAppearance", () => {
rel.swf_asset_id = sa.id rel.swf_asset_id = sa.id
WHERE rel.parent_id IN (?,?,?,?,?,?,?,?)", WHERE rel.parent_id IN (?,?,?,?,?,?,?,?)",
Array [ Array [
"4751",
"2",
"17723", "17723",
"17742", "17742",
"5991", "5991",
"436", "436",
"10014", "10014",
"11089", "11089",
"4751",
"2",
], ],
], ],
Array [ Array [
@ -186,8 +191,102 @@ describe("PetAppearance", () => {
"5", "5",
"37", "37",
"30", "30",
"34",
"33", "33",
"34",
],
],
]
`);
});
it("loads unconverted appearance", async () => {
const res = await query({
query: gql`
query {
petAppearance(speciesId: "1", colorId: "63", pose: UNCONVERTED) {
id
species {
id
name
}
color {
id
name
isStandard
}
layers {
id
imageUrl(size: SIZE_600)
svgUrl
zone {
depth
}
restrictedZones {
id
}
}
}
}
`,
});
expect(res).toHaveNoErrors();
expect(res.data).toMatchSnapshot();
expect(getDbCalls()).toMatchInlineSnapshot(`
Array [
Array [
"SELECT * FROM pet_types WHERE (species_id = ? AND color_id = ?)",
Array [
"1",
"63",
],
],
Array [
"SELECT * FROM pet_states
WHERE pet_type_id IN (?)
ORDER BY (mood_id IS NULL) ASC, mood_id ASC, female DESC,
unconverted DESC, glitched ASC, id DESC",
Array [
"2274",
],
],
Array [
"SELECT sa.*, rel.parent_id FROM swf_assets sa
INNER JOIN parents_swf_assets rel ON
rel.parent_type = \\"PetState\\" AND
rel.swf_asset_id = sa.id
WHERE rel.parent_id IN (?)",
Array [
"2571",
],
],
Array [
"SELECT * FROM species_translations
WHERE species_id IN (?) AND locale = \\"en\\"",
Array [
"1",
],
],
Array [
"SELECT * FROM color_translations
WHERE color_id IN (?) AND locale = \\"en\\"",
Array [
"63",
],
],
Array [
"SELECT * FROM colors WHERE id IN (?) AND prank = 0",
Array [
"63",
],
],
Array [
"SELECT * FROM zones WHERE id IN (?)",
Array [
"46",
], ],
], ],
] ]

View file

@ -13,6 +13,7 @@ Object {
Object { Object {
"id": "5995", "id": "5995",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7941/600x600.png?v2-0", "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7941/600x600.png?v2-0",
"restrictedZones": Array [],
"svgUrl": "http://images.neopets.com/cp/bio/data/000/000/007/7941_2c4cc4b846/7941.svg", "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/007/7941_2c4cc4b846/7941.svg",
"zone": Object { "zone": Object {
"depth": 18, "depth": 18,
@ -21,6 +22,7 @@ Object {
Object { Object {
"id": "5996", "id": "5996",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7942/600x600.png?v2-0", "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7942/600x600.png?v2-0",
"restrictedZones": Array [],
"svgUrl": "http://images.neopets.com/cp/bio/data/000/000/007/7942_2eab06fd7b/7942.svg", "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/007/7942_2eab06fd7b/7942.svg",
"zone": Object { "zone": Object {
"depth": 7, "depth": 7,
@ -29,6 +31,7 @@ Object {
Object { Object {
"id": "6000", "id": "6000",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7946/600x600.png?v2-0", "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7946/600x600.png?v2-0",
"restrictedZones": Array [],
"svgUrl": "http://images.neopets.com/cp/bio/data/000/000/007/7946_0348dad587/7946.svg", "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/007/7946_0348dad587/7946.svg",
"zone": Object { "zone": Object {
"depth": 40, "depth": 40,
@ -37,6 +40,7 @@ Object {
Object { Object {
"id": "16467", "id": "16467",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/024/24008/600x600.png?v2-0", "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/024/24008/600x600.png?v2-0",
"restrictedZones": Array [],
"svgUrl": "http://images.neopets.com/cp/bio/data/000/000/024/24008_a05fe9876a/24008.svg", "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/024/24008_a05fe9876a/24008.svg",
"zone": Object { "zone": Object {
"depth": 34, "depth": 34,
@ -45,6 +49,7 @@ Object {
Object { Object {
"id": "19784", "id": "19784",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28892/600x600.png?v2-1313418652000", "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28892/600x600.png?v2-1313418652000",
"restrictedZones": Array [],
"svgUrl": "http://images.neopets.com/cp/bio/data/000/000/028/28892_a8e3a8b430/28892.svg", "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/028/28892_a8e3a8b430/28892.svg",
"zone": Object { "zone": Object {
"depth": 37, "depth": 37,
@ -53,6 +58,7 @@ Object {
Object { Object {
"id": "178150", "id": "178150",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/036/36887/600x600.png?v2-1354240708000", "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/036/36887/600x600.png?v2-1354240708000",
"restrictedZones": Array [],
"svgUrl": "http://images.neopets.com/cp/bio/data/000/000/036/36887_a335fbba09/36887.svg", "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/036/36887_a335fbba09/36887.svg",
"zone": Object { "zone": Object {
"depth": 38, "depth": 38,
@ -70,136 +76,6 @@ Object {
exports[`PetAppearance loads multiple for species and color 1`] = ` exports[`PetAppearance loads multiple for species and color 1`] = `
Object { Object {
"petAppearances": Array [ "petAppearances": Array [
Object {
"bodyId": "180",
"color": Object {
"id": "75",
"name": "Starry",
},
"id": "4751",
"layers": Array [
Object {
"id": "5995",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7941/600x600.png?v2-0",
"zone": Object {
"depth": 18,
},
},
Object {
"id": "5996",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7942/600x600.png?v2-0",
"zone": Object {
"depth": 7,
},
},
Object {
"id": "6000",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7946/600x600.png?v2-0",
"zone": Object {
"depth": 40,
},
},
Object {
"id": "16467",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/024/24008/600x600.png?v2-0",
"zone": Object {
"depth": 34,
},
},
Object {
"id": "19550",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-0",
"zone": Object {
"depth": 38,
},
},
Object {
"id": "19784",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28892/600x600.png?v2-1313418652000",
"zone": Object {
"depth": 37,
},
},
Object {
"id": "163528",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-1326455337000",
"zone": Object {
"depth": 38,
},
},
],
"petStateId": "4751",
"pose": "UNKNOWN",
"species": Object {
"id": "54",
"name": "Zafara",
},
},
Object {
"bodyId": "180",
"color": Object {
"id": "75",
"name": "Starry",
},
"id": "2",
"layers": Array [
Object {
"id": "5995",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7941/600x600.png?v2-0",
"zone": Object {
"depth": 18,
},
},
Object {
"id": "5996",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7942/600x600.png?v2-0",
"zone": Object {
"depth": 7,
},
},
Object {
"id": "6000",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7946/600x600.png?v2-0",
"zone": Object {
"depth": 40,
},
},
Object {
"id": "16467",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/024/24008/600x600.png?v2-0",
"zone": Object {
"depth": 34,
},
},
Object {
"id": "19549",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28548/600x600.png?v2-1345719457000",
"zone": Object {
"depth": 37,
},
},
Object {
"id": "19550",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-0",
"zone": Object {
"depth": 38,
},
},
Object {
"id": "163528",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-1326455337000",
"zone": Object {
"depth": 38,
},
},
],
"petStateId": "2",
"pose": "UNKNOWN",
"species": Object {
"id": "54",
"name": "Zafara",
},
},
Object { Object {
"bodyId": "180", "bodyId": "180",
"color": Object { "color": Object {
@ -548,6 +424,285 @@ Object {
"name": "Zafara", "name": "Zafara",
}, },
}, },
Object {
"bodyId": "180",
"color": Object {
"id": "75",
"name": "Starry",
},
"id": "4751",
"layers": Array [
Object {
"id": "5995",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7941/600x600.png?v2-0",
"zone": Object {
"depth": 18,
},
},
Object {
"id": "5996",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7942/600x600.png?v2-0",
"zone": Object {
"depth": 7,
},
},
Object {
"id": "6000",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7946/600x600.png?v2-0",
"zone": Object {
"depth": 40,
},
},
Object {
"id": "16467",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/024/24008/600x600.png?v2-0",
"zone": Object {
"depth": 34,
},
},
Object {
"id": "19550",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-0",
"zone": Object {
"depth": 38,
},
},
Object {
"id": "19784",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28892/600x600.png?v2-1313418652000",
"zone": Object {
"depth": 37,
},
},
Object {
"id": "163528",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-1326455337000",
"zone": Object {
"depth": 38,
},
},
],
"petStateId": "4751",
"pose": "UNKNOWN",
"species": Object {
"id": "54",
"name": "Zafara",
},
},
Object {
"bodyId": "180",
"color": Object {
"id": "75",
"name": "Starry",
},
"id": "2",
"layers": Array [
Object {
"id": "5995",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7941/600x600.png?v2-0",
"zone": Object {
"depth": 18,
},
},
Object {
"id": "5996",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7942/600x600.png?v2-0",
"zone": Object {
"depth": 7,
},
},
Object {
"id": "6000",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7946/600x600.png?v2-0",
"zone": Object {
"depth": 40,
},
},
Object {
"id": "16467",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/024/24008/600x600.png?v2-0",
"zone": Object {
"depth": 34,
},
},
Object {
"id": "19549",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28548/600x600.png?v2-1345719457000",
"zone": Object {
"depth": 37,
},
},
Object {
"id": "19550",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-0",
"zone": Object {
"depth": 38,
},
},
Object {
"id": "163528",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-1326455337000",
"zone": Object {
"depth": 38,
},
},
],
"petStateId": "2",
"pose": "UNKNOWN",
"species": Object {
"id": "54",
"name": "Zafara",
},
},
], ],
} }
`; `;
exports[`PetAppearance loads unconverted appearance 1`] = `
Object {
"petAppearance": Object {
"color": Object {
"id": "63",
"isStandard": true,
"name": "Royalboy",
},
"id": "2571",
"layers": Array [
Object {
"id": "9941",
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/013/13024/600x600.png?v2-0",
"restrictedZones": Array [
Object {
"id": "4",
},
Object {
"id": "5",
},
Object {
"id": "6",
},
Object {
"id": "7",
},
Object {
"id": "8",
},
Object {
"id": "9",
},
Object {
"id": "10",
},
Object {
"id": "11",
},
Object {
"id": "12",
},
Object {
"id": "13",
},
Object {
"id": "14",
},
Object {
"id": "15",
},
Object {
"id": "16",
},
Object {
"id": "17",
},
Object {
"id": "18",
},
Object {
"id": "19",
},
Object {
"id": "20",
},
Object {
"id": "21",
},
Object {
"id": "22",
},
Object {
"id": "23",
},
Object {
"id": "24",
},
Object {
"id": "25",
},
Object {
"id": "26",
},
Object {
"id": "27",
},
Object {
"id": "28",
},
Object {
"id": "29",
},
Object {
"id": "30",
},
Object {
"id": "31",
},
Object {
"id": "32",
},
Object {
"id": "33",
},
Object {
"id": "34",
},
Object {
"id": "35",
},
Object {
"id": "36",
},
Object {
"id": "37",
},
Object {
"id": "38",
},
Object {
"id": "39",
},
Object {
"id": "40",
},
Object {
"id": "41",
},
Object {
"id": "42",
},
Object {
"id": "43",
},
],
"svgUrl": "http://images.neopets.com/cp/bio/data/000/000/013/13024_18911a85d1/13024.svg",
"zone": Object {
"depth": 48,
},
},
],
"species": Object {
"id": "1",
"name": "Acara",
},
},
}
`;

View file

@ -122,6 +122,16 @@ function getPoseName(pose) {
return POSE_NAMES[pose]; return POSE_NAMES[pose];
} }
function getRestrictedZoneIds(zonesRestrict) {
const restrictedZoneIds = [];
for (const [i, bit] of Array.from(zonesRestrict).entries()) {
if (bit === "1") {
restrictedZoneIds.push(i + 1);
}
}
return restrictedZoneIds;
}
async function loadBodyName(bodyId, db) { async function loadBodyName(bodyId, db) {
if (String(bodyId) === "0") { if (String(bodyId) === "0") {
return "All bodies"; return "All bodies";
@ -188,6 +198,7 @@ module.exports = {
getPetStateFieldsFromPose, getPetStateFieldsFromPose,
getPoseFromPetData, getPoseFromPetData,
getPoseName, getPoseName,
getRestrictedZoneIds,
loadBodyName, loadBodyName,
logToDiscord, logToDiscord,
normalizeRow, normalizeRow,