import { CardIds , Race , ReferenceCard } from '@firestone-hs/reference-data' ; import { CardsFacadeService } from '@services/cards-facade.service' ; import { DeckCard } from '../../../models/decktracker/deck-card' ; import { DeckState } from '../../../models/decktracker/deck-state' ; import { LocalizationFacadeService } from '../../localization-facade.service' ; export const modifyDeckForSpecialCards = ( cardId , deckState , allCards , i18n ) : DeckState => { switch ( cardId ) { case CardIds . CelestialAlignment : return handleCelestialAlignment ( deckState , allCards , i18n ) ; case CardIds . Embiggen : return handleEmbiggen ( deckState , allCards , i18n ) ; case CardIds . DeckOfLunacy : return handleDeckOfLunacy ( deckState , allCards , i18n ) ; case CardIds . IncantersFlow : return handleIncantersFlow ( deckState , allCards , i18n ) ; case CardIds . LunasPocketGalaxy : return handleLunasPocketGalaxy ( deckState , allCards , i18n ) ; case CardIds . PrinceLiam : return handlePrinceLiam ( deckState , allCards , i18n ) ; case CardIds . AldorAttendant : case CardIds . LordaeronAttendantToken : return handleLibram ( deckState , allCards , i18n , 1 ) ; case CardIds . AldorTruthseeker : case CardIds . RadiantLightspawn : return handleLibram ( deckState , allCards , i18n , 2 ) ; case CardIds . DeckOfChaos : return handleDeckOfChaos ( deckState , allCards , i18n ) ; case CardIds . ExploreUngoro : return handleExploreUngoro ( deckState , allCards , i18n ) ; case CardIds . FrizzKindleroost : return handleFrizzKindleroost ( deckState , allCards , i18n ) ; case CardIds . HemetJungleHunter : return handleHemet ( deckState , allCards , i18n ) ; case CardIds . LadyPrestor1 : return handleLadyPrestor ( deckState , allCards , i18n ) ; case CardIds . OoopsAllSpellsTavernBrawl : return handleOoopsAllSpells ( deckState , allCards , i18n ) ; case CardIds . ScepterOfSummoning : return handleScepterOfSummoning ( deckState , allCards , i18n ) ; case CardIds . SkulkingGeist : return handleSkulkingGeist ( deckState , allCards , i18n ) ; case CardIds . VanndarStormpike : return handleVanndarStormpike ( deckState , allCards , i18n ) ; case CardIds . WyrmrestPurifier : return handleWyrmrestPurifier ( deckState , allCards , i18n ) ; default : return deckState ; } } ; const handleCelestialAlignment = ( deckState , allCards , i18n ) : DeckState => { const withDeck = updateCostInDeck ( ( card , refCard ) => true , ( card ) => 1 , deckState , allCards , i18n ) ; return updateCostInHand ( ( card , refCard ) => true , ( card ) => 1 , withDeck , allCards , i18n ) ; } ; const handleEmbiggen = ( deckState , allCards , i18n ) : DeckState => { return updateCostInDeck ( ( card , refCard ) => refCard ?. type === 'Minion' || card ?. cardType === 'Minion' , ( card ) => Math . min ( 10 , card . getEffectiveManaCost ( ) + 1 ) , deckState , allCards , i18n ) ; } ; const handleLibram = ( deckState , allCards , i18n , costReduction ) : DeckState => { return updateCostInDeck ( ( card , refCard ) => refCard ?. name ?. includes ( 'Libram of' ) , ( card ) => Math . max ( 0 , card . getEffectiveManaCost ( ) - costReduction ) , deckState , allCards , i18n ) ; } ; const handleIncantersFlow = ( deckState , allCards , i18n ) : DeckState => { return updateCostInDeck ( ( card , refCard ) => refCard ?. type === 'Spell' || card ?. cardType === 'Spell' , ( card ) => Math . max ( 0 , card . getEffectiveManaCost ( ) - 1 ) , deckState , allCards , i18n ) ; } ; const handleVanndarStormpike = ( deckState , allCards , i18n ) : DeckState => { return updateCostInDeck ( ( card , refCard ) => refCard ?. type === 'Minion' || card ?. cardType === 'Minion' , ( card ) => Math . max ( 0 , card . getEffectiveManaCost ( ) - 3 ) , deckState , allCards , i18n ) ; } ; const handleFrizzKindleroost = ( deckState , allCards , i18n ) : DeckState => { return updateCostInDeck ( ( card , refCard ) => refCard ?. race === Race . DRAGON . toString ( ) , ( card ) => Math . max ( 0 , card . getEffectiveManaCost ( ) - 2 ) , deckState , allCards , i18n ) ; } ; const handleLunasPocketGalaxy = ( deckState , allCards , i18n ) : DeckState => { return updateCostInDeck ( ( card , refCard ) => refCard ?. type === 'Minion' || card ?. cardType === 'Minion' , ( card ) => 1 , deckState , allCards , i18n ) ; } ; const handleScepterOfSummoning = ( deckState , allCards , i18n ) : DeckState => { return updateCostInDeck ( ( card , refCard ) => ( refCard ?. type === 'Minion' || card ?. cardType === 'Minion' ) && card ?. actualManaCost >= 5 , ( card ) => 5 , deckState , allCards , i18n ) ; } ; const handleWyrmrestPurifier = ( deckState , allCards , i18n ) : DeckState => { return updateCardInDeck ( ( card , refCard ) => refCard ?. playerClass === 'Neutral' , ( card ) => card . update ( { cardId : undefined , cardName : i18n . getUnknownCardName ( deckState . hero ?. playerClass ) , creatorCardId : CardIds . WyrmrestPurifier , rarity : undefined , cardType : undefined , manaCost : undefined , actualManaCost : undefined , cardMatchCondition : ( other ) => other . cost === card . getEffectiveManaCost ( ) + 3 , } as DeckCard ) , deckState , allCards , i18n ) ; } ; const handleExploreUngoro = ( deckState , allCards , i18n ) : DeckState => { const refCard = allCards . getCard ( CardIds . ExploreUngoro_ChooseYourPathToken ) ; return updateCardInDeck ( ( card , refCard ) => ! ! refCard , ( card ) => card . update ( { cardId : refCard . id , cardName : i18n . getCardName ( refCard . id , refCard . name ) , creatorCardId : CardIds . ExploreUngoro , manaCost : refCard . cost , rarity : refCard . rarity , cardType : refCard . type , } as DeckCard ) , deckState , allCards , i18n ) ; } ; const handleDeckOfLunacy = ( deckState , allCards , i18n ) : DeckState => { return updateCardInDeck ( ( card , refCard ) => refCard ?. type === 'Spell' || card ?. cardType === 'Spell' , ( card ) => card . update ( { cardId : undefined , cardName : i18n . getUnknownManaSpellName ( Math . min ( 10 , card . getEffectiveManaCost ( ) + 3 ) ) , creatorCardId : CardIds . DeckOfLunacy , actualManaCost : Math . min ( 10 , card . getEffectiveManaCost ( ) + 3 ) - 3 , rarity : 'unknown' , cardType : 'Spell' , cardMatchCondition : ( other ) => other . cost === card . getEffectiveManaCost ( ) + 3 , } as DeckCard ) , deckState , allCards , i18n ) ; } ; const handleLadyPrestor = ( deckState , allCards , i18n ) : DeckState => { return updateCardInDeck ( ( card , refCard ) => refCard ?. type === 'Minion' , ( card ) => card . update ( { cardId : undefined , cardName : i18n . getUnknownRaceName ( 'dragon' ) , creatorCardId : CardIds . LadyPrestor1 , actualManaCost : card . getEffectiveManaCost ( ) , rarity : 'unknown' , cardType : 'Minion' , cardMatchCondition : ( other ) => other . cost === card . getEffectiveManaCost ( ) , } as DeckCard ) , deckState , allCards , i18n ) ; } ; const handleHemet = ( deckState , allCards , i18n ) : DeckState => { return updateCardInDeck ( ( card , refCard ) => refCard ?. cost <= 3 , ( card ) => null , deckState , allCards , i18n ) ; } ; const handleOoopsAllSpells = ( deckState , allCards , i18n ) : DeckState => { const stateWithoutSpells = updateCardInDeck ( ( card , refCard ) => refCard ?. type === 'Minion' , ( card ) => null , deckState , allCards , i18n ) ; return updateCostInDeck ( ( card , refCard ) => refCard ?. type === 'Spell' || card ?. cardType === 'Spell' , ( card ) => Math . max ( 0 , card . getEffectiveManaCost ( ) - 1 ) , stateWithoutSpells , allCards , i18n ) ; } ; const handleSkulkingGeist = ( deckState , allCards , i18n ) : DeckState => { return updateCardInDeckAndHand ( ( card , refCard ) => refCard ?. cost == 1 , ( card ) => null , deckState , allCards , i18n ) ; } ; const handleDeckOfChaos = ( deckState , allCards , i18n ) : DeckState => { return updateCardInDeck ( ( card , refCard ) => refCard ?. type === 'Minion' || card ?. cardType === 'Minion' , ( card , refCard ) => card . update ( { actualManaCost : refCard ?. attack , } as DeckCard ) , deckState , allCards , i18n ) ; } ; const handlePrinceLiam = ( deckState , allCards , i18n ) : DeckState => { return updateCardInDeck ( ( card , refCard ) => card ?. getEffectiveManaCost ( ) === 1 , ( card ) => card . update ( { cardId : undefined , cardName : i18n . getUnknownRaceName ( 'Legendary Minion' ) , creatorCardId : CardIds . PrinceLiam , rarity : 'legendary' , cardType : 'Minion' , manaCost : undefined , actualManaCost : undefined , cardMatchCondition : ( drawnCard ) => drawnCard . rarity ?. toLowerCase ( ) === 'legendary' , } as DeckCard ) , deckState , allCards , i18n ) ; } ; const updateCostInDeck = ( cardSelector , costUpdator , deckState , allCards , i18n ) : DeckState => { const currentDeck = deckState . deck ; const newDeck = currentDeck . map ( ( card ) => { const refCard = card . cardId ? allCards . getCard ( card . cardId ) : null ; if ( ! cardSelector ( card , refCard ) ) { return card ; } return card . update ( { actualManaCost : costUpdator ( card ) , } as DeckCard ) ; } ) ; return deckState . update ( { deck : newDeck , } as DeckState ) ; } ; const updateCostInHand = ( cardSelector , costUpdator , deckState , allCards , i18n ) : DeckState => { const currentHand = deckState . hand ; const newHand = currentHand . map ( ( card ) => { const refCard = card . cardId ? allCards . getCard ( card . cardId ) : null ; if ( ! cardSelector ( card , refCard ) ) { return card ; } return card . update ( { actualManaCost : costUpdator ( card ) , } as DeckCard ) ; } ) ; return deckState . update ( { hand : newHand , } as DeckState ) ; } ; const updateCardInDeck = ( cardSelector , cardUpdater , deckState , allCards , i18n ) : DeckState => { const currentDeck = deckState . deck ; const newDeck = currentDeck . map ( ( card ) => { const refCard = card . cardId ? allCards . getCard ( card . cardId ) : null ; if ( ! cardSelector ( card , refCard ) ) { return card ; } return cardUpdater ( card , refCard ) ; } ) . filter ( ( card ) => card ) ; return deckState . update ( { deck : newDeck , } as DeckState ) ; } ; const updateCardInDeckAndHand = ( cardSelector , cardUpdater , deckState , allCards , i18n ) : DeckState => { const newDeck = deckState . deck . map ( ( card ) => { const refCard = card . cardId ? allCards . getCard ( card . cardId ) : null ; if ( ! cardSelector ( card , refCard ) ) { return card ; } return cardUpdater ( card , refCard ) ; } ) . filter ( ( card ) => card ) ; const newHand = deckState . hand . map ( ( card ) => { const refCard = card . cardId ? allCards . getCard ( card . cardId ) : null ; if ( ! cardSelector ( card , refCard ) ) { return card ; } return cardUpdater ( card , refCard ) ; } ) . filter ( ( card ) => card ) ; return deckState . update ( { deck : newDeck , hand : newHand , } as DeckState ) ; } ;