import { CardIds , GameTag } from '@firestone-hs/reference-data' ; import { EntityGameState , GameEvent } from '../../../models/game-event' ; import { BattleMercenary , BattleSpeedModifier , MercenariesBattleState , MercenariesBattleTeam , } from '../../../models/mercenaries/mercenaries-battle-state' ; import { normalizeHeroCardId } from '../../battlegrounds/bgs-utils' ; import { CardsFacadeService } from '../../cards-facade.service' ; import { sumOnArray } from '../../utils' ; import { BUFF_SPEED_MODIFIER_ENCHANTMENTS , DEBUFF_SPEED_MODIFIER_ENCHANTMENTS , normalizeMercenariesCardId , } from '../mercenaries-utils' ; import { MercenariesParser } from './_mercenaries-parser' ; export class MercenariesBuffsParser implements MercenariesParser { constructor ( private readonly allCards ) { } public eventType = ( ) => GameEvent . TURN_START ; public applies = ( battleState ) => ! ! battleState ; public async parse ( battleState , event ) { const gameState = event . gameState ; if ( ! gameState ) { console . warn ( 'missing game state on turn start event' , event ) ; return battleState ; } const playerBoard = gameState . Player ?. Board ; const playerAbilities = gameState . Player ?. LettuceAbilities ; const opponentBoard = gameState . Opponent ?. Board ; const opponentAbilities = gameState . Opponent ?. LettuceAbilities ; const playerTeam = this . updateTeam ( battleState . playerTeam , playerBoard , playerAbilities ) ; const opponentTeam = this . updateTeam ( battleState . opponentTeam , opponentBoard , opponentAbilities ) ; return battleState . update ( { playerTeam : playerTeam , opponentTeam : opponentTeam , } ) ; } private updateTeam ( playerTeam , playerBoard , playerAbilities ) { if ( ! playerBoard || ! playerTeam || ! playerAbilities ) { return playerTeam ; } for ( const mercenary of playerTeam . mercenaries ?? [ ] ) { const playerEntity = playerBoard . find ( ( a ) => a . entityId === mercenary . entityId ) ?? playerBoard . find ( ( a ) => normalizeHeroCardId ( a . cardId ) === normalizeMercenariesCardId ( mercenary . cardId ) ) ; if ( ! playerEntity ) { if ( mercenary . inPlay ) { console . warn ( 'Merc in play, should have found something' , mercenary , playerBoard ) ; } playerTeam = playerTeam . updateMercenary ( mercenary . entityId , BattleMercenary . create ( { speedModifier : null } ) ) ; continue ; } const abilities = mercenary . abilities . map ( ( ability ) => { const playerAbility = playerAbilities . find ( ( a ) => a . entityId === ability . entityId ) ?? playerAbilities . find ( ( a ) => normalizeHeroCardId ( a . cardId ) === normalizeMercenariesCardId ( ability . cardId ) ) ; if ( ! playerAbility ) { console . debug ( 'could not find player ability' , ability , playerAbilities ) ; return ability ; } const speedModifier = this . buildSpeedModifier ( playerAbility ) ; return ability . update ( { speedModifier : speedModifier , } ) ; } ) ; playerTeam = playerTeam . updateMercenary ( mercenary . entityId , BattleMercenary . create ( { speedModifier : this . buildSpeedModifier ( playerEntity ) , abilities : abilities , } ) ) ; } return playerTeam ; } private buildSpeedModifier ( boardEntity ) { if ( ! boardEntity ) { return null ; } const debuffs = ( boardEntity . enchantments ?? [ ] ) . filter ( ( e ) => DEBUFF_SPEED_MODIFIER_ENCHANTMENTS . includes ( e . cardId as CardIds ) ) . filter ( ( e ) => ! ! e . tags . find ( ( tag ) => tag . Name === GameTag . TAG_SCRIPT_DATA_NUM_1 ) ?. Value ) ; const buffs = ( boardEntity . enchantments ?? [ ] ) . filter ( ( e ) => BUFF_SPEED_MODIFIER_ENCHANTMENTS . includes ( e . cardId as CardIds ) ) . filter ( ( e ) => ! ! e . tags . find ( ( tag ) => tag . Name === GameTag . TAG_SCRIPT_DATA_NUM_1 ) ?. Value ) ; const debuffValue = sumOnArray ( debuffs , ( buff ) => buff . tags . find ( ( tag ) => tag . Name === GameTag . TAG_SCRIPT_DATA_NUM_1 ) . Value ?? 0 ) ; const buffValue = sumOnArray ( buffs , ( buff ) => buff . tags . find ( ( tag ) => tag . Name === GameTag . TAG_SCRIPT_DATA_NUM_1 ) . Value ?? 0 ) ; return ! ! buffValue || ! ! debuffValue ? { value : debuffValue - buffValue , influences : [ ... debuffs , ... buffs ] . map ( ( buff ) => ( { cardId : buff . cardId , value : buff . tags . find ( ( tag ) => tag . Name === GameTag . TAG_SCRIPT_DATA_NUM_1 ) . Value , } ) ) , } : null ; } }