/* * The Peacock Project - a HITMAN server replacement. * Copyright (C) 2021-2022 The Peacock Project Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ import { ChallengeProgressionData, CompiledChallengeRewardData, CompiledChallengeRuntimeData, RegistryChallenge, } from "../types/types" import assert from "assert" export function compileScoringChallenge( challenge: RegistryChallenge, ): CompiledChallengeRewardData { return { ChallengeId: challenge.Id, ChallengeName: challenge.Name, ChallengeDescription: challenge.Description, ChallengeImageUrl: challenge.ImageName, XPGain: challenge.Rewards?.MasteryXP || 0, } } export function compileRuntimeChallenge( challenge: RegistryChallenge, progression: ChallengeProgressionData, ): CompiledChallengeRuntimeData { return { // GetActiveChallengesAndProgression Challenge: { Id: challenge.Id, GroupId: challenge.inGroup, Name: challenge.Name, Type: challenge.RuntimeType || "contract", Description: challenge.Description, ImageName: challenge.ImageName, InclusionData: challenge.InclusionData || undefined, Definition: challenge.Definition, Tags: challenge.Tags, Drops: challenge.Drops, LastModified: "2021-01-06T23:00:32.0117635", // this is a lie 👍 PlayableSince: null, PlayableUntil: null, Xp: challenge.Rewards.MasteryXP || 0, XpModifier: challenge.XpModifier || {}, }, Progression: progression, } } export enum ChallengeFilterType { None = "None", Contract = "Contract", ParentLocation = "ParentLocation", } export type ChallengeFilterOptions = | { type: ChallengeFilterType.None } | { type: ChallengeFilterType.Contract contractId: string locationId: string locationParentId: string } | { type: ChallengeFilterType.ParentLocation locationParentId: string } export function filterChallenge( options: ChallengeFilterOptions, challenge: RegistryChallenge, ): boolean { switch (options.type) { case ChallengeFilterType.None: return true case ChallengeFilterType.Contract: { assert.ok(options.contractId) assert.ok(options.locationId) assert.ok(options.locationParentId) if (!challenge) { return false } // is this for the current contract? const isForContract = ( challenge.InclusionData?.ContractIds || [] ).includes(options.contractId) // is this a location-wide challenge? const isForLocation = challenge.Type === "location" // is this for the current location? const isCurrentLocation = // is this challenge for the current parent location? challenge.ParentLocationId === options.locationParentId && // and, is this challenge's location the current sub-location // or the parent location? (yup, that can happen) (challenge.LocationId === options.locationId || challenge.LocationId === options.locationParentId) return isForContract || (isForLocation && isCurrentLocation) } case ChallengeFilterType.ParentLocation: assert.ok(options.locationParentId) return ( (challenge?.ParentLocationId || "") === options.locationParentId ) } }