import { Achievement } from './achievement' ; import { VisualAchievement } from './visual-achievement' ; export class VisualAchievementCategory { readonly id : string ; readonly name : string ; readonly icon : string ; readonly categories : readonly VisualAchievementCategory [ ] = [ ] ; readonly achievements : readonly VisualAchievement [ ] = [ ] ; public static create ( value ) { return Object . assign ( new VisualAchievementCategory ( ) , value ) ; } public findCategory ( categoryId ) { if ( ! categoryId ) { return null ; } if ( categoryId === this . id ) { return this ; } const matches = this . categories . map ( ( cat ) => cat . findCategory ( categoryId ) ) . filter ( ( cat ) => cat ) ; return matches . length > 0 ? matches [ 0 ] : null ; } public findCategoryHierarchy ( categoryId ) { if ( this . id === categoryId ) { return [ this ] ; } if ( this . categories . length === 0 ) { return [ ] ; } const subHierarchy = this . categories . map ( ( cat ) => cat . findCategoryHierarchy ( categoryId ) ) . filter ( ( cat ) => cat ) . find ( ( result ) => result . length > 0 && result [ result . length - 1 ] != null ) ; if ( ! subHierarchy ) { return [ ] ; } return [ this , ... subHierarchy ] . filter ( ( cat ) => cat ) ; } public findAchievementHierarchy ( achievementId ) { const achievement = this . achievements . find ( ( ach ) => ach . id === achievementId || ach . completionSteps . some ( ( step ) => step . id === achievementId ) ) ; if ( achievement ) { return [ [ this ] , achievement ] ; } const subHierarchy = this . categories . map ( ( cat ) => cat . findAchievementHierarchy ( achievementId ) ) . find ( ( result ) => result . length === 2 && result [ 1 ] ) ; if ( ! subHierarchy ) { return [ [ this ] , null ] ; } return [ [ this , ... subHierarchy [ 0 ] ] , subHierarchy [ 1 ] ] ; } public updateAchievement ( newAchievement ) { if ( this . achievements . find ( ( ach ) => ach . id === newAchievement . id || ach . completionSteps . some ( ( step ) => step . id === newAchievement . id ) ) ) { return Object . assign ( new VisualAchievementCategory ( ) , this , { achievements : this . achievements . map ( ( ach ) => ach . update ( newAchievement ) ) as readonly VisualAchievement [ ] , } as VisualAchievementCategory ) ; } return Object . assign ( new VisualAchievementCategory ( ) , this , { categories : this . categories . map ( ( cat ) => cat . updateAchievement ( newAchievement ) ) as readonly VisualAchievementCategory [ ] , } as VisualAchievementCategory ) ; } public retrieveAllAchievements ( ) { return [ ... this . achievements , ... this . categories . map ( ( cat ) => cat . retrieveAllAchievements ( ) ) . reduce ( ( a , b ) => a . concat ( b ) , [ ] ) , ] ; } }