Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ET challenges not ticked on the mission end page #254

Merged
merged 5 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 30 additions & 48 deletions components/candle/challengeService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,11 +344,12 @@ export abstract class ChallengeRegistry {
*/
protected static _parseContextListeners(
challenge: RegistryChallenge,
Context?: Record<string, unknown>,
): ParsedContextListenerInfo {
return parseContextListeners(
challenge.Definition?.ContextListeners || {},
{
...(challenge.Definition?.Context || {}),
...(Context || challenge.Definition?.Context || {}),
...(challenge.Definition?.Constants || {}),
},
)
Expand All @@ -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},
* but significantly faster. Why? Because it doesn't need to load the user's
Expand Down Expand Up @@ -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
data[challengeId] ??= {
Ticked: false,
Completed: false,
State: initialContext,
State:
(<ChallengeDefinitionLike>challenge?.Definition)?.Context || {},
}

const dependencies = this.getDependenciesForChallenge(
Expand Down Expand Up @@ -709,10 +719,7 @@ export class ChallengeService extends ChallengeRegistry {
for (const challenge of challengeGroups[group]) {
const isDone = this.fastGetIsCompleted(profile, challenge.Id)

if (
challenge.Definition.Scope === "profile" ||
challenge.Definition.Scope === "hit"
) {
if (this.needSaveProgression(challenge)) {
profile.Extensions.ChallengeProgression[challenge.Id] ??= {
Ticked: false,
Completed: false,
Expand All @@ -722,17 +729,13 @@ export class ChallengeService extends ChallengeRegistry {
}
}

// For challenges with scopes being "profile" or "hit",
// update challenge progression with the user's progression data
const ctx =
challenge.Definition.Scope === "profile" ||
challenge.Definition.Scope === "hit"
? profile.Extensions.ChallengeProgression[challenge.Id]
.State
: fastClone(
(<ChallengeDefinitionLike>challenge.Definition)
?.Context || {},
) || {}
const ctx = this.needSaveProgression(challenge)
? profile.Extensions.ChallengeProgression[challenge.Id]
.State
: fastClone(
(<ChallengeDefinitionLike>challenge.Definition)
?.Context || {},
) || {}

challengeContexts[challenge.Id] = {
context: ctx,
Expand Down Expand Up @@ -794,12 +797,7 @@ export class ChallengeService extends ChallengeRegistry {
options,
)

// For challenges with scopes being "profile" or "hit",
// save challenge progression to the user's progression data
if (
challenge.Definition.Scope === "profile" ||
challenge.Definition.Scope === "hit"
) {
if (this.needSaveProgression(challenge)) {
userData.Extensions.ChallengeProgression[challengeId].State =
result.context

Expand Down Expand Up @@ -916,18 +914,7 @@ export class ChallengeService extends ChallengeRegistry {
gameVersion: GameVersion,
compiler: Compiler,
): CompiledChallengeTreeData[] {
const progression = getUserData(userId, gameVersion).Extensions
.ChallengeProgression
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(
challengeData,
this.getPersistentChallengeProgression(
Expand All @@ -939,12 +926,6 @@ export class ChallengeService extends ChallengeRegistry {
userId,
)

compiled.ChallengeProgress = this.getChallengeDependencyData(
challengeData,
userId,
gameVersion,
)

return compiled
})
}
Expand Down Expand Up @@ -978,8 +959,10 @@ export class ChallengeService extends ChallengeRegistry {
missing.push(dependency)
}

const { challengeCountData } =
ChallengeService._parseContextListeners(challengeData)
const { challengeCountData } = ChallengeService._parseContextListeners(
challengeData,
userData.Extensions.ChallengeProgression[challengeData.Id].State,
)

// If this challenge is counting something, AND it relies on other challenges (e.g. SA5, SA12, ...)
// Then the "count & total" return format prevails.
Expand Down Expand Up @@ -1251,7 +1234,6 @@ export class ChallengeService extends ChallengeRegistry {
): CompiledChallengeTreeData {
let contract: MissionManifest | null

// TODO: Properly get escalation groups for this
if (challenge.Type === "contract") {
contract = this.controller.resolveContract(
challenge.InclusionData?.ContractIds?.[0] || "",
Expand Down
6 changes: 3 additions & 3 deletions components/profileHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -854,13 +854,13 @@ async function loadSession(
Ticked: false,
}

const scope = controller.challengeService.getChallengeById(
const challenge = controller.challengeService.getChallengeById(
cid,
sessionData.gameVersion,
).Definition.Scope
)
if (
!userData.Extensions.ChallengeProgression[cid].Completed &&
(scope === "hit" || scope === "profile")
controller.challengeService.needSaveProgression(challenge)
) {
sessionData.challengeContexts[cid].context =
userData.Extensions.ChallengeProgression[cid].State
Expand Down
9 changes: 7 additions & 2 deletions components/scoreHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -678,8 +678,13 @@ export async function missionEnd(
let justTickedChallenges = 0
let totalXpGain = calculateXpResult.xp

// Calculate XP based on non-global challenges.
Object.values(locationChallenges)
// Calculate XP based on non-global challenges. Remember to add elusive challenges of the contract
Object.values({
...locationChallenges,
...(Object.keys(contractChallenges).includes("elusive") && {
elusive: contractChallenges.elusive,
}),
})
.flat()
.filter((challengeData) => {
return (
Expand Down