import { CardIds , GameTag } from '@firestone-hs/reference-data' ; import { DeckCard } from '../../../models/decktracker/deck-card' ; import { DeckState } from '../../../models/decktracker/deck-state' ; import { GameState } from '../../../models/decktracker/game-state' ; import { GameEvent } from '../../../models/game-event' ; import { CardsFacadeService } from '../../cards-facade.service' ; import { cardsRevealedWhenDrawn , forceHideInfoWhenDrawnInfluencers , publicCardCreators } from '../../hs-utils' ; import { LocalizationFacadeService } from '../../localization-facade.service' ; import { DeckManipulationHelper } from './deck-manipulation-helper' ; import { EventParser } from './event-parser' ; export class CardDrawParser implements EventParser { constructor ( private readonly helper , private readonly allCards , private readonly i18n ) { } applies ( gameEvent , state ) { return state && gameEvent . type === GameEvent . CARD_DRAW_FROM_DECK ; } async parse ( currentState , gameEvent ) { const [ cardId , controllerId , localPlayer , entityId ] = gameEvent . parse ( ) ; const isPlayer = controllerId === localPlayer . PlayerId ; const deck = isPlayer ? currentState . playerDeck : currentState . opponentDeck ; const card = this . helper . findCardInZone ( deck . deck , cardId , entityId , true ) ; const lastInfluencedByCardId = gameEvent . additionalData ?. lastInfluencedByCardId ?? card . lastAffectedByCardId ; const isCardDrawnBySecretPassage = forceHideInfoWhenDrawnInfluencers . includes ( gameEvent . additionalData ?. lastInfluencedByCardId ) ; const isTradable = ! ! this . allCards . getCard ( cardId ) . mechanics ?. includes ( GameTag [ GameTag . TRADEABLE ] ) ; const isCardInfoPublic = isPlayer || ( ! isCardDrawnBySecretPassage && ( cardsRevealedWhenDrawn . includes ( cardId as CardIds ) || ( ! isTradable && publicCardCreators . includes ( lastInfluencedByCardId ) ) ) ) ; const isCreatorPublic = isCardInfoPublic || ( ! isTradable && publicCardCreators . includes ( lastInfluencedByCardId ) ) ; const creatorCardId = gameEvent . additionalData ?. creatorCardId ; const cardWithCreator = card . update ( { creatorCardId : isCardInfoPublic ? creatorCardId : undefined , cardId : isCardInfoPublic ? card . cardId : undefined , cardName : isCardInfoPublic ? this . i18n . getCardName ( card ?. cardId ) : undefined , lastAffectedByCardId : isCreatorPublic ? lastInfluencedByCardId : undefined , } as DeckCard ) ; const previousDeck = deck . deck ; const newDeck = isCardInfoPublic ? this . helper . removeSingleCardFromZone ( previousDeck , cardId , entityId , deck . deckList . length === 0 , true ) [ 0 ] : this . helper . removeSingleCardFromZone ( previousDeck , null , - 1 , deck . deckList . length === 0 , true ) [ 0 ] ; const previousHand = deck . hand ; const newHand = this . helper . addSingleCardToZone ( previousHand , cardWithCreator ) ; const newPlayerDeck = Object . assign ( new DeckState ( ) , deck , { deck : newDeck , hand : newHand , } ) ; return Object . assign ( new GameState ( ) , currentState , { [ isPlayer ? 'playerDeck' : 'opponentDeck' ] : newPlayerDeck , } ) ; } event ( ) { return GameEvent . CARD_DRAW_FROM_DECK ; } }