1
mirror of https://github.com/thepeacockproject/Peacock synced 2025-03-21 00:04:22 +01:00

Fix ET challenges not ticked on the mission end page ()

* Fix et challenges not getting ticked

* refactor: remove redundant code and add a function

* fix elusive SA bugs
This commit is contained in:
moonysolari 2023-04-27 02:12:55 -04:00 committed by GitHub
parent d6a917ee50
commit 6f2c5ab3fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 53 deletions

@ -344,11 +344,12 @@ export abstract class ChallengeRegistry {
*/ */
protected static _parseContextListeners( protected static _parseContextListeners(
challenge: RegistryChallenge, challenge: RegistryChallenge,
Context?: Record<string, unknown>,
): ParsedContextListenerInfo { ): ParsedContextListenerInfo {
return parseContextListeners( return parseContextListeners(
challenge.Definition?.ContextListeners || {}, challenge.Definition?.ContextListeners || {},
{ {
...(challenge.Definition?.Context || {}), ...(Context || challenge.Definition?.Context || {}),
...(challenge.Definition?.Constants || {}), ...(challenge.Definition?.Constants || {}),
}, },
) )
@ -375,6 +376,19 @@ export class ChallengeService extends ChallengeRegistry {
} }
} }
/**
* Check if the challenge needs to be saved in the user's progression data
* i.e. challenges with scopes being "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 {
return (
challenge.Definition.Scope === "profile" ||
challenge.Definition.Scope === "hit"
)
}
/** /**
* Same concept as {@link getPersistentChallengeProgression}, * Same concept as {@link getPersistentChallengeProgression},
* but significantly faster. Why? Because it doesn't need to load the user's * but significantly faster. Why? Because it doesn't need to load the user's
@ -434,16 +448,12 @@ export class ChallengeService extends ChallengeRegistry {
} }
} }
// the default context, used if the user has no progression for this
// challenge
const initialContext =
(<ChallengeDefinitionLike>challenge?.Definition)?.Context || {}
// apply default context if no progression exists // apply default context if no progression exists
data[challengeId] ??= { data[challengeId] ??= {
Ticked: false, Ticked: false,
Completed: false, Completed: false,
State: initialContext, State:
(<ChallengeDefinitionLike>challenge?.Definition)?.Context || {},
} }
const dependencies = this.getDependenciesForChallenge( const dependencies = this.getDependenciesForChallenge(
@ -709,10 +719,7 @@ export class ChallengeService extends ChallengeRegistry {
for (const challenge of challengeGroups[group]) { for (const challenge of challengeGroups[group]) {
const isDone = this.fastGetIsCompleted(profile, challenge.Id) const isDone = this.fastGetIsCompleted(profile, challenge.Id)
if ( if (this.needSaveProgression(challenge)) {
challenge.Definition.Scope === "profile" ||
challenge.Definition.Scope === "hit"
) {
profile.Extensions.ChallengeProgression[challenge.Id] ??= { profile.Extensions.ChallengeProgression[challenge.Id] ??= {
Ticked: false, Ticked: false,
Completed: false, Completed: false,
@ -722,17 +729,13 @@ export class ChallengeService extends ChallengeRegistry {
} }
} }
// For challenges with scopes being "profile" or "hit", const ctx = this.needSaveProgression(challenge)
// update challenge progression with the user's progression data ? profile.Extensions.ChallengeProgression[challenge.Id]
const ctx = .State
challenge.Definition.Scope === "profile" || : fastClone(
challenge.Definition.Scope === "hit" (<ChallengeDefinitionLike>challenge.Definition)
? profile.Extensions.ChallengeProgression[challenge.Id] ?.Context || {},
.State ) || {}
: fastClone(
(<ChallengeDefinitionLike>challenge.Definition)
?.Context || {},
) || {}
challengeContexts[challenge.Id] = { challengeContexts[challenge.Id] = {
context: ctx, context: ctx,
@ -794,12 +797,7 @@ export class ChallengeService extends ChallengeRegistry {
options, options,
) )
// For challenges with scopes being "profile" or "hit", if (this.needSaveProgression(challenge)) {
// save challenge progression to the user's progression data
if (
challenge.Definition.Scope === "profile" ||
challenge.Definition.Scope === "hit"
) {
userData.Extensions.ChallengeProgression[challengeId].State = userData.Extensions.ChallengeProgression[challengeId].State =
result.context result.context
@ -916,18 +914,7 @@ export class ChallengeService extends ChallengeRegistry {
gameVersion: GameVersion, gameVersion: GameVersion,
compiler: Compiler, compiler: Compiler,
): CompiledChallengeTreeData[] { ): CompiledChallengeTreeData[] {
const progression = getUserData(userId, gameVersion).Extensions
.ChallengeProgression
return challenges.map((challengeData) => { return challenges.map((challengeData) => {
// Update challenge progression with the user's latest progression data
if (
!progression[challengeData.Id].Completed &&
(challengeData.Definition.Scope === "profile" ||
challengeData.Definition.Scope === "hit")
) {
challengeData.Definition.Context =
progression[challengeData.Id].State
}
const compiled = compiler( const compiled = compiler(
challengeData, challengeData,
this.getPersistentChallengeProgression( this.getPersistentChallengeProgression(
@ -939,12 +926,6 @@ export class ChallengeService extends ChallengeRegistry {
userId, userId,
) )
compiled.ChallengeProgress = this.getChallengeDependencyData(
challengeData,
userId,
gameVersion,
)
return compiled return compiled
}) })
} }
@ -978,8 +959,10 @@ export class ChallengeService extends ChallengeRegistry {
missing.push(dependency) missing.push(dependency)
} }
const { challengeCountData } = const { challengeCountData } = ChallengeService._parseContextListeners(
ChallengeService._parseContextListeners(challengeData) challengeData,
userData.Extensions.ChallengeProgression[challengeData.Id].State,
)
// If this challenge is counting something, AND it relies on other challenges (e.g. SA5, SA12, ...) // If this challenge is counting something, AND it relies on other challenges (e.g. SA5, SA12, ...)
// Then the "count & total" return format prevails. // Then the "count & total" return format prevails.
@ -1251,7 +1234,6 @@ export class ChallengeService extends ChallengeRegistry {
): CompiledChallengeTreeData { ): CompiledChallengeTreeData {
let contract: MissionManifest | null let contract: MissionManifest | null
// TODO: Properly get escalation groups for this
if (challenge.Type === "contract") { if (challenge.Type === "contract") {
contract = this.controller.resolveContract( contract = this.controller.resolveContract(
challenge.InclusionData?.ContractIds?.[0] || "", challenge.InclusionData?.ContractIds?.[0] || "",

@ -854,13 +854,13 @@ async function loadSession(
Ticked: false, Ticked: false,
} }
const scope = controller.challengeService.getChallengeById( const challenge = controller.challengeService.getChallengeById(
cid, cid,
sessionData.gameVersion, sessionData.gameVersion,
).Definition.Scope )
if ( if (
!userData.Extensions.ChallengeProgression[cid].Completed && !userData.Extensions.ChallengeProgression[cid].Completed &&
(scope === "hit" || scope === "profile") controller.challengeService.needSaveProgression(challenge)
) { ) {
sessionData.challengeContexts[cid].context = sessionData.challengeContexts[cid].context =
userData.Extensions.ChallengeProgression[cid].State userData.Extensions.ChallengeProgression[cid].State

@ -678,8 +678,13 @@ export async function missionEnd(
let justTickedChallenges = 0 let justTickedChallenges = 0
let totalXpGain = calculateXpResult.xp let totalXpGain = calculateXpResult.xp
// Calculate XP based on non-global challenges. // Calculate XP based on non-global challenges. Remember to add elusive challenges of the contract
Object.values(locationChallenges) Object.values({
...locationChallenges,
...(Object.keys(contractChallenges).includes("elusive") && {
elusive: contractChallenges.elusive,
}),
})
.flat() .flat()
.filter((challengeData) => { .filter((challengeData) => {
return ( return (