import { CardIds } 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 { GameState } from '../../../models/decktracker/game-state' ; import { GameEvent } from '../../../models/game-event' ; import { cardsRevealedWhenDrawn , publicCardCreators } from '../../hs-utils' ; import { LocalizationFacadeService } from '../../localization-facade.service' ; import { DeckManipulationHelper } from './deck-manipulation-helper' ; import { EventParser } from './event-parser' ; export class ReceiveCardInHandParser implements EventParser { constructor ( private readonly helper , private readonly allCards , private readonly i18n ) { } applies ( gameEvent , state ) { return state && gameEvent . type === GameEvent . RECEIVE_CARD_IN_HAND ; } async parse ( currentState , gameEvent ) { const [ cardId , controllerId , localPlayer , entityId ] = gameEvent . parse ( ) ; const creatorCardId = gameEvent . additionalData . creatorCardId ; if ( ! localPlayer ) { console . warn ( '[ReceiveCardInHandParser] missing local player from event' , gameEvent ) ; return currentState ; } const isPlayer = controllerId === localPlayer . PlayerId ; const deck = isPlayer ? currentState . playerDeck : currentState . opponentDeck ; const lastInfluencedByCardId = gameEvent . additionalData ?. lastInfluencedByCardId ?? gameEvent . additionalData ?. creatorCardId ; const buffingEntityCardId = gameEvent . additionalData . buffingEntityCardId ; const buffCardId = gameEvent . additionalData . buffCardId ; const isCardInfoPublic = isPlayer || cardsRevealedWhenDrawn . includes ( cardId as CardIds ) || publicCardCreators . indexOf ( lastInfluencedByCardId ) !== - 1 ; const boardCard = this . helper . findCardInZone ( deck . board , null , entityId ) ; const otherCard = this . helper . findCardInZone ( deck . otherZone , null , entityId ) ; const otherCardWithObfuscation = isCardInfoPublic || ! otherCard ? otherCard : otherCard . update ( { creatorCardId : undefined , cardId : undefined , cardName : undefined , lastAffectedByCardId : undefined , } as DeckCard ) ; const newBoard = boardCard ? this . helper . removeSingleCardFromZone ( deck . board , null , entityId , deck . deckList . length === 0 ) [ 0 ] : deck . board ; const newOther = otherCardWithObfuscation ? this . helper . removeSingleCardFromZone ( deck . otherZone , null , entityId ) [ 0 ] : deck . otherZone ; const cardData = cardId ? this . allCards . getCard ( cardId ) : null ; const cardWithDefault = boardCard || otherCardWithObfuscation || DeckCard . create ( { cardId : cardId , entityId : entityId , cardName : cardData && this . i18n . getCardName ( cardId , cardData . name ) , manaCost : cardData && cardData . cost , rarity : cardData && cardData . rarity ? cardData . rarity . toLowerCase ( ) : null , creatorCardId : creatorCardId , } as DeckCard ) ; const otherCardWithBuffs = buffingEntityCardId != null || buffCardId != null ? cardWithDefault . update ( { buffingEntityCardIds : [ ... ( cardWithDefault . buffingEntityCardIds || [ ] ) , buffingEntityCardId , ] as readonly string [ ] , buffCardIds : [ ... ( cardWithDefault . buffCardIds || [ ] ) , buffCardId ] as readonly string [ ] , } as DeckCard ) : cardWithDefault ; const previousHand = deck . hand ; const newHand = this . helper . addSingleCardToZone ( previousHand , otherCardWithBuffs , true ) ; const newPlayerDeck = Object . assign ( new DeckState ( ) , deck , { hand : newHand , board : newBoard , otherZone : newOther , } as DeckState ) ; return Object . assign ( new GameState ( ) , currentState , { [ isPlayer ? 'playerDeck' : 'opponentDeck' ] : newPlayerDeck , } ) ; } event ( ) { return GameEvent . RECEIVE_CARD_IN_HAND ; } }