import { Entity , ObjectIdColumn , Column } from 'typeorm' ; import { get , compact , flatten , sortBy } from 'lodash' ; import { PlayerOwned } from './PlayerOwned' ; import { IAchievement , AchievementRewardType , PermanentUpgrade , PetAttribute } from '../../interfaces' ; import { Player } from './Player.entity' ; @ Entity ( ) export class Achievements extends PlayerOwned { @ ObjectIdColumn ( ) public _id : string ; @ Column ( ) private achievements : { [ key ] : IAchievement ; } ; @ Column ( ) private permanentGenders : { [ key ] : boolean ; } ; public get $achievementsData ( ) { return { achievements : this . achievements , permanentGenders : this . permanentGenders } ; } constructor ( ) { super ( ) ; if ( ! this . achievements ) this . achievements = { } ; if ( ! this . permanentGenders ) this . permanentGenders = { } ; } public init ( player ) { Object . keys ( this . achievements ) . forEach ( ach => { if ( isFinite ( this . achievements [ ach ] . tier ) && ! isNaN ( this . achievements [ ach ] . tier ) ) return ; delete this . achievements [ ach ] ; } ) ; player . $$game . achievementManager . checkAchievementsFor ( player ) ; } public hasBoughtGender ( gender ) { return this . permanentGenders [ gender ] ; } public buyGender ( gender ) { this . permanentGenders [ gender ] = true ; } public add ( ach ) { this . achievements [ ach . name ] = ach ; } public getAchievementAchieved ( achName ) { return get ( this . achievements , [ achName , 'achievedAt' ] , 0 ) ; } public getAchievementTier ( achName ) { return get ( this . achievements , [ achName , 'tier' ] , 0 ) ; } public resetAchievementsTo ( ach ) { this . achievements = { } ; ach . forEach ( achi => this . add ( achi ) ) ; } public totalAchievements ( ) { return Object . keys ( this . achievements ) . length ; } public totalAchievementTiers ( ) { return Object . values ( this . achievements ) . reduce ( ( prev , cur ) => prev + cur . tier , 0 ) ; } public getPermanentUpgrades ( ) { return Object . values ( this . achievements ) . reduce ( ( prev , ach ) => { const rewards = compact ( ach . rewards . filter ( reward => reward . type === AchievementRewardType . PermanentUpgrade ) ) ; rewards . forEach ( reward => { Object . keys ( reward . upgrades ) . forEach ( upgrade => { prev [ upgrade ] = prev [ upgrade ] || 0 ; prev [ upgrade ] += reward . upgrades [ upgrade ] ; } ) ; } ) ; return prev ; } , { } ) ; } public getTitles ( ) { return sortBy ( flatten ( Object . values ( this . achievements ) . map ( ach => { return compact ( ach . rewards . filter ( reward => reward . type === AchievementRewardType . Title ) . map ( reward => reward . title ) ) ; } ) ) ) ; } public getPersonalities ( ) { return sortBy ( flatten ( Object . values ( this . achievements ) . map ( ach => { return compact ( ach . rewards . filter ( reward => reward . type === AchievementRewardType . Personality ) . map ( reward => reward . personality ) ) ; } ) ) ) ; } public getPets ( ) { return sortBy ( flatten ( Object . values ( this . achievements ) . map ( ach => { return compact ( ach . rewards . filter ( reward => reward . type === AchievementRewardType . Pet ) . map ( reward => reward . pet ) ) ; } ) ) ) ; } public getGenders ( ) { const base = [ 'male' , 'female' , 'not a bear' , 'glowcloud' , 'astronomical entity' , 'soap' ] . concat ( Object . keys ( this . permanentGenders ) ) ; return base . concat ( flatten ( Object . values ( this . achievements ) . map ( ach => { return compact ( ach . rewards . filter ( reward => reward . type === AchievementRewardType . Gender ) . map ( reward => reward . gender ) ) ; } ) ) ) ; } public getPetAttributes ( ) { const base = [ PetAttribute . Cursed ] ; return base . concat ( flatten ( Object . values ( this . achievements ) . map ( ach => { return compact ( ach . rewards . filter ( reward => reward . type === AchievementRewardType . PetAttribute ) . map ( reward => reward . petattr ) ) ; } ) ) ) ; } }