@peacockproject/core
Version:
Type definitions for Peacock's core.
292 lines (291 loc) • 15.4 kB
TypeScript
import type { ChallengeCompletion, ChallengeProgressionData, ClientToServerEvent, CompiledChallengeTreeCategory, CompiledChallengeTreeData, ContractSession, GameVersion, RegistryChallenge, Unlockable, UserProfile } from "../types/types";
import { Controller } from "../controller";
import { ParsedContextListenerInfo } from "../statemachines/contextListeners";
import { ChallengeContext, SavedChallengeGroup } from "../types/challenges";
import { ChallengeFilterOptions } from "./challengeHelpers";
import { SyncHook } from "../hooksImpl";
type GroupIndexedChallengeLists = {
[groupId: string]: RegistryChallenge[];
};
export type ChallengePack = {
Name: string;
Description: string;
GameVersions: GameVersion[];
Image: string;
Icon: string;
};
export type GlobalChallengeGroup = {
/**
* ID of a challenge group that will have location and global challenges merged.
*
* Not necessarily should match the group it's being merged with,
* but it's highly advised to match them.
*/
groupId: string;
/**
* The global challenge group location ID from where the global challenges are merged.
*/
location: string;
/**
* Which game versions are supported by this global challenge group.
*/
gameVersions: GameVersion[];
/**
* If set, this global challenge group will be visible in all locations,
* regardless if this group has challenges in that location or not.
*
* This option is useful when challenge group has to be active for all locations,
* but doesn't have any location-specific challenges.
* However, it's advised to create location-specific challenges instead,
* as this option will apply the challenge group to all locations and missions,
* including Freelancer and Sniper modes.
*
* This can be alleviated by providing valid InclusionData filter to challenges,
* in order to exclude them from locations you do not wish them to be in.
*/
allLocations?: boolean;
};
/**
* A base class providing challenge registration support.
*/
export declare abstract class ChallengeRegistry {
protected readonly controller: Controller;
/**
* @Key1 Game version.
* @Key2 The challenge Id.
* @value A `RegistryChallenge` object.
*/
protected challenges: Record<GameVersion, Map<string, RegistryChallenge>>;
/**
* @Key1 Game version.
* @Key2 The parent location Id.
* @Key3 The group's categoryId.
* @Value A `SavedChallengeGroup` object.
*/
protected groups: Record<GameVersion, Map<string, Map<string, SavedChallengeGroup>>>;
/**
* @Key1 Game version.
* @Key2 The parent location Id.
* @Key3 The group Id.
* @Value A `Set` of challenge Ids.
*/
protected groupContents: Record<GameVersion, Map<string, Map<string, Set<string>>>>;
/**
* @Key1 Game version.
* @Key2 The challenge Id.
* @Value An `array` of challenge Ids that Key2 depends on.
*/
protected readonly _dependencyTree: Record<GameVersion, Map<string, readonly string[]>>;
protected constructor(controller: Controller);
challengePacks: Map<string, ChallengePack>;
/**
* The list of user-made challenge groups that span multiple locations
* and should merge their global type challenges merged with location challenges.
*
* @see GlobalChallengeGroup fields for more information.
*/
globalMergeGroups: Map<string, GlobalChallengeGroup>;
registerChallenge(challenge: RegistryChallenge, groupId: string, location: string, gameVersion: GameVersion): void;
registerChallengeList(challenges: RegistryChallenge[], groupId: string, location: string, gameVersion: GameVersion): void;
registerGroup(group: SavedChallengeGroup, location: string, gameVersion: GameVersion): void;
/**
* Check if `groupId` is already registered for given `location` and `gameVersion`.
*
* @param groupId The group ID to check
* @param location The location group belongs to
* @param gameVersion The game version group works in
*/
hasGroup(groupId: string, location: string, gameVersion: GameVersion): boolean;
getChallengeById(challengeId: string, gameVersion: GameVersion): RegistryChallenge | undefined;
getChallengeIds(gameVersion: GameVersion): string[];
removeChallenge(challengeId: string, gameVersion: GameVersion): boolean;
/**
* This method retrieves all the unlockables associated with the challenges for a given game version.
* It iterates over all the challenges for the specified game version and for each challenge, it checks if there are any unlockables (Drops).
* If there are unlockables, it adds them to the accumulator object with the dropId as the key and the challenge Id as the value.
*
* @param gameVersion The version of the game for which to retrieve the unlockables.
* @returns An object where each key is an unlockable's id (dropId) and the corresponding value is the id of the challenge that unlocks it.
*/
getChallengesUnlockables(gameVersion: GameVersion): Record<string, string>;
/**
* Gets a challenge group by its parent location and group ID.
* @param groupId The group ID of the challenge group.
* @param location The parent location for this challenge group.
* @param gameVersion The current game version.
* @returns A `SavedChallengeGroup` if such a group exists, or `undefined` if not.
*/
getGroupByIdLoc(groupId: string, location: string, gameVersion: GameVersion): SavedChallengeGroup | undefined;
getChallengesForGroup(groupId: string, gameVersion: GameVersion): GroupIndexedChallengeLists;
getGroupContentByIdLoc(groupId: string, location: string, gameVersion: GameVersion): Set<string> | undefined;
getDependenciesForChallenge(challengeId: string, gameVersion: GameVersion): readonly string[];
/**
* This method checks the heuristics of a challenge.
* It parses the context listeners of the challenge and if the challenge has any dependencies (other challenges that need to be completed before this one), it adds them to the dependency tree.
*
* @param challenge The challenge to check.
* @param gameVersion The game version this challenge belongs to.
*/
protected checkHeuristics(challenge: RegistryChallenge, gameVersion: GameVersion): void;
/**
* Parse a challenge's context listeners into the format used internally.
*
* @param challenge The challenge.
* @param Context The current context of the challenge.
* @returns The context listener details.
*/
protected static _parseContextListeners(challenge: RegistryChallenge, Context?: Record<string, unknown>): ParsedContextListenerInfo;
}
export declare class ChallengeService extends ChallengeRegistry {
hooks: {
/**
* A hook that is called when a challenge is completed.
*
* Params:
* - userId: The user's ID.
* - challenge: The challenge.
* - gameVersion: The game version.
*/
onChallengeCompleted: SyncHook<[
userId: string,
challenge: RegistryChallenge,
gameVersion: GameVersion
]>;
};
constructor(controller: Controller);
/**
* Check if the challenge needs to be saved in the user's progression data.
* Challenges with scopes "profile" or "hit".
*
* @param challenge The challenge.
* @returns Whether the challenge needs to be saved in the user's progression data.
*/
needSaveProgression(challenge: RegistryChallenge): boolean;
/**
* Same concept as {@link getPersistentChallengeProgression},
* but significantly faster. Why? Because it doesn't need to load the user's
* data, check dependencies, etc. It's just a yes or no.
*
* @param userData The user's data object. Will not be modified.
* @param challengeId The ID of the challenge.
* @returns Whether the challenge is completed.
* @see getPersistentChallengeProgression
*/
fastGetIsCompleted(userData: Readonly<UserProfile>, challengeId: string): boolean;
/**
* Same concept as {@link fastGetIsCompleted},
* but for if a challenge is unticked.
*
* @param userData The user's data object. Will not be modified.
* @param challengeId The ID of the challenge.
* @returns Whether the challenge is completed and unticked.
* @see fastGetIsCompleted
*/
fastGetIsUnticked(userData: Readonly<UserProfile>, challengeId: string): boolean;
/**
* Get the persistent challenge progression data for a challenge.
* WARNING: slow! Use sparingly.
* @param userId The user's ID.
* @param challengeId The challenge ID.
* @param gameVersion The game version.
* @returns The challenge progression data.
*/
getPersistentChallengeProgression(userId: string, challengeId: string, gameVersion: GameVersion): ChallengeProgressionData;
/**
* This is a helper function for {@link getGroupedChallengeLists}. It is not expected to be used elsewhere.
*
* Filter all challenges in a parent location using a given filter, sort them into groups,
* and write them into the `challenges` array provided.
*
* @param filter The filter to use.
* @param location The parent location whose challenges to get.
* @param challenges The array to write results to.
* @param gameVersion The game's version.
*/
getGroupedChallengesByLoc(filter: ChallengeFilterOptions, location: string, challenges: [string, RegistryChallenge[]][], gameVersion: GameVersion): void;
/**
* Filter all challenges (except global) within Peacock and return them as a `CompiledChallengeTreeCategory[]`.
*
* @param filter The filter to use.
* @param userId The user's id.
* @param gameVersion The active game version.
* @returns A CompiledChallengeTreeCategory[] returning
*/
getFilteredChallengeTree(filter: ChallengeFilterOptions, userId: string, gameVersion: GameVersion): CompiledChallengeTreeCategory[];
/**
* Filter all challenges in a parent location using a given filter, sort them into groups,
* and return them as a `GroupIndexedChallengeLists`.
*
* @param filter The filter to use.
* @param location The parent location whose challenges to get.
* @param gameVersion The active game version.
* @returns A GroupIndexedChallengeLists containing the resulting challenge groups.
*/
getGroupedChallengeLists(filter: ChallengeFilterOptions, location: string, gameVersion: GameVersion): GroupIndexedChallengeLists;
getChallengesForContract(contractId: string, gameVersion: GameVersion, userId: string, difficulty?: number): GroupIndexedChallengeLists;
getChallengesForLocation(child: string, gameVersion: GameVersion): GroupIndexedChallengeLists;
startContract(session: ContractSession): void;
/**
* Updates the challenge context for a given challenge on an event.
* @param event The event to handle.
* @param session The session to handle the event for.
* @param challengeId The challenge to handle the event for.
* @param userData The user data to update.
* @param data The context of the challenge.
*/
challengeOnEvent(event: ClientToServerEvent, session: ContractSession, challengeId: string, userData: UserProfile, data: ChallengeContext): void;
/**
* Upon an event, updates the context for all challenges in a contract session. Challenges not in the session are ignored.
* @param event The event to handle.
* @param session The session.
*/
onContractEvent(event: ClientToServerEvent, session: ContractSession): void;
/**
* Get the challenge tree for a contract.
*
* @param contractId The ID of the contract.
* @param gameVersion The game version requesting the challenges.
* @param userId The user requesting the challenges' ID.
* @param difficulty The upper bound on the difficulty of the challenges to return, defaulted to 4 (return challenges of all difficulties).
* @returns The challenge tree.
*/
getChallengeTreeForContract(contractId: string, gameVersion: GameVersion, userId: string, difficulty?: 4): CompiledChallengeTreeCategory[];
private mapSwitchChallenges;
private getChallengeDependencyData;
getChallengeDataForDestination(locationParentId: string, gameVersion: GameVersion, userId: string, isPro1: boolean): CompiledChallengeTreeCategory[];
getChallengeDataForCategory(categoryId: string | null, location: Unlockable | undefined, gameVersion: GameVersion, userId: string): CompiledChallengeTreeCategory[];
/**
* Re-batch a `GroupIndexedChallengeLists` object into a `CompiledChallengeTreeCategory` array.
* @param challengeLists The challenge lists to use.
* @param userId The id of the user.
* @param gameVersion The current game version.
* @param isDestination Will also get escalation challenges if set to true.
* @param location A location as an `Unlockable`. If challengeLists contains all challenges of a challenge pack, this parameter should be "undefined". Otherwise, it might be a parent location or a sublocation, depending on `isDestination`.
* @returns An array of `CompiledChallengeTreeCategory` objects.
*/
private reBatchIntoSwitchedData;
compileRegistryChallengeTreeData(challenge: RegistryChallenge, progression: ChallengeProgressionData, gameVersion: GameVersion, userId: string, isDestination?: boolean): CompiledChallengeTreeData;
compileRegistryDestinationChallengeData(challenge: RegistryChallenge, progression: ChallengeProgressionData, gameVersion: GameVersion, userId: string): CompiledChallengeTreeData;
/**
* Counts the number of challenges and completed challenges in a GroupIndexedChallengeLists object.
* CAUTION: THIS IS SLOW. Use sparingly.
*
* @param challengeLists A GroupIndexedChallengeLists object, holding some challenges to be counted
* @param userId The userId of the user to acquire completion information
* @param gameVersion The version of the game
* @param multiplier What to multiply the final completion percentage by
* @returns An object with two properties: ChallengesCount and CompletedChallengesCount.
*/
countTotalNCompletedChallenges(challengeLists: GroupIndexedChallengeLists, userId: string, gameVersion: GameVersion, multiplier?: number): ChallengeCompletion;
/**
* Checks if the conditions to complete a challenge are met. If so, calls `onChallengeCompleted` for it.
* @param session The contract session where the challenge was completed.
* @param challengeId The id of the challenge.
* @param userData The profile of the user.
* @param parentId A parent challenge of this challenge, the completion of which might cause this challenge to complete. Pass `undefined` if such a parent is unknown or doesn't exist.
* @param gameVersion The game version.
*/
tryToCompleteChallenge(session: ContractSession, challengeId: string, userData: UserProfile, parentId: string, gameVersion: GameVersion): void;
private onChallengeCompleted;
}
export {};