"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isDead = exports.copyEntity = exports.getTeamInitialStates = exports.getTeammateInitialState = exports.getPlayerState = exports.isBoardEntity = exports.isGolden = exports.isPilotedWhirlOTron = exports.isFish = exports.stringifySimpleCard = exports.stringifySimple = exports.normalizeCardIdForSkin = exports.addImpliedMechanics = exports.getRaceEnum = exports.isCorrectTribe = exports.getEffectiveTribesForEntity = exports.alreadyHasVolumizerBuff = exports.isVolumizer = exports.hasCorrectTribe = exports.hasEntityMechanic = exports.hasMechanic = exports.getMinionsOfDifferentTypes = exports.grantStatsToMinionsOfEachType = exports.addStatsToAliveBoard = exports.addStatsToBoard = exports.getRandomMinionWithHighestHealth = exports.getRandomRevivableMinion = exports.getRandomAliveMinion = exports.grantRandomStats = exports.grantRandomHealth = exports.grantRandomAttack = exports.buildRandomUndeadCreation = exports.buildSingleBoardEntity = void 0;
const reference_data_1 = require("@firestone-hs/reference-data");
const card_interface_1 = require("./cards/card.interface");
const _card_mappings_1 = require("./cards/impl/_card-mappings");
const utils_1 = require("./services/utils");
const stats_1 = require("./simulation/stats");
const CLEAVE_IDS = [
    "BG_LOOT_078",
    "TB_BaconUps_151",
    "BG_GVG_113",
    "TB_BaconUps_153",
    "BG26_817",
    "BG26_817_G",
    "BG31_HERO_811t10",
    "BG31_HERO_811t10_G",
    "BG34_Treasure_994",
    "BG34_Treasure_994_G",
];
const ATTACK_IMMEDIATELY_IDS = [
    "BGS_061t",
    "TB_BaconUps_141t",
    "BG22_HERO_305t",
    "BRM_004t",
    "BG34_630t",
    "BG34_630_Gt",
];
const CANT_ATTACK_IDS = [];
const buildSingleBoardEntity = (cardId, controllerHero, friendlyBoard, allCards, friendly, entityId = 1, spawnReborn = false, cardsData, sharedState, entityToSpawn, originalEntity = null, options = null) => {
    var _a, _b, _c, _d, _e;
    const trueRefCard = allCards.getCard(cardId);
    const card = (_a = options === null || options === void 0 ? void 0 : options.referenceCardToUse) !== null && _a !== void 0 ? _a : trueRefCard;
    const attackImmediately = ATTACK_IMMEDIATELY_IDS.indexOf(cardId) !== -1;
    const newEntity = !!entityToSpawn
        ? {
            ...entityToSpawn,
            entityId: sharedState.currentEntityId++,
            definitelyDead: false,
            avengeCurrent: entityToSpawn.avengeDefault,
            damageMultiplier: 1,
            frenzyChargesLeft: 1,
            friendly: friendly,
            hasAttacked: 0,
        }
        : (0, exports.addImpliedMechanics)({
            entityId: entityId,
            attack: card.attack,
            hasAttacked: 0,
            cardId: cardId,
            divineShield: (0, exports.hasMechanic)(card, reference_data_1.GameTag.DIVINE_SHIELD),
            health: card.health,
            maxHealth: card.health || trueRefCard.health,
            maxAttack: card.attack || trueRefCard.attack,
            taunt: (0, exports.hasMechanic)(card, reference_data_1.GameTag.TAUNT),
            reborn: (0, exports.hasMechanic)(card, reference_data_1.GameTag.REBORN),
            poisonous: (0, exports.hasMechanic)(card, reference_data_1.GameTag.POISONOUS),
            venomous: (0, exports.hasMechanic)(card, reference_data_1.GameTag.VENOMOUS),
            stealth: (0, exports.hasMechanic)(card, reference_data_1.GameTag.STEALTH),
            windfury: (0, exports.hasMechanic)(card, reference_data_1.GameTag.WINDFURY),
            enchantments: [],
            pendingAttackBuffs: [],
            friendly: friendly,
            attackImmediately: attackImmediately,
            avengeCurrent: cardsData.avengeValue(cardId),
            avengeDefault: cardsData.avengeValue(cardId),
            scriptDataNum1: (_b = originalEntity === null || originalEntity === void 0 ? void 0 : originalEntity.scriptDataNum1) !== null && _b !== void 0 ? _b : 0,
            scriptDataNum2: (_c = originalEntity === null || originalEntity === void 0 ? void 0 : originalEntity.scriptDataNum2) !== null && _c !== void 0 ? _c : 0,
        }, cardsData);
    if (spawnReborn && !entityToSpawn) {
        if (cardId === "BG25_HERO_100pt") {
            const stitchedCardId = !!((_d = originalEntity.additionalCards) === null || _d === void 0 ? void 0 : _d.length) ? originalEntity.additionalCards[0] : null;
            if (stitchedCardId) {
                const stitchedCard = allCards.getCard(stitchedCardId);
                newEntity.attack = newEntity.attack + stitchedCard.attack;
                newEntity.maxHealth = newEntity.maxHealth + stitchedCard.health;
                newEntity.taunt = newEntity.taunt || (0, exports.hasMechanic)(stitchedCard, reference_data_1.GameTag.TAUNT);
                newEntity.divineShield = newEntity.divineShield || (0, exports.hasMechanic)(stitchedCard, reference_data_1.GameTag.DIVINE_SHIELD);
                newEntity.hadDivineShield = newEntity.hadDivineShield || newEntity.divineShield;
                newEntity.poisonous = newEntity.poisonous || (0, exports.hasMechanic)(stitchedCard, reference_data_1.GameTag.POISONOUS);
                newEntity.venomous = newEntity.venomous || (0, exports.hasMechanic)(stitchedCard, reference_data_1.GameTag.VENOMOUS);
                newEntity.windfury = newEntity.windfury || (0, exports.hasMechanic)(stitchedCard, reference_data_1.GameTag.WINDFURY);
                newEntity.avengeCurrent = newEntity.avengeCurrent || cardsData.avengeValue(stitchedCardId);
                newEntity.avengeDefault = newEntity.avengeDefault || cardsData.avengeValue(stitchedCardId);
            }
        }
        else if (cardId === "BG29_100_G" &&
            !!((_e = originalEntity.additionalCards) === null || _e === void 0 ? void 0 : _e.filter((c) => !!c).length)) {
            for (const moduleCardId of originalEntity.additionalCards) {
                const moduleCard = allCards.getCard(moduleCardId);
                newEntity.taunt = newEntity.taunt || (0, exports.hasMechanic)(moduleCard, reference_data_1.GameTag.TAUNT);
                newEntity.divineShield = newEntity.divineShield || (0, exports.hasMechanic)(moduleCard, reference_data_1.GameTag.DIVINE_SHIELD);
                newEntity.hadDivineShield = newEntity.hadDivineShield || newEntity.divineShield;
                newEntity.poisonous = newEntity.poisonous || (0, exports.hasMechanic)(moduleCard, reference_data_1.GameTag.POISONOUS);
                newEntity.venomous = newEntity.venomous || (0, exports.hasMechanic)(moduleCard, reference_data_1.GameTag.VENOMOUS);
                newEntity.windfury = newEntity.windfury || (0, exports.hasMechanic)(moduleCard, reference_data_1.GameTag.WINDFURY);
                newEntity.stealth = newEntity.stealth || (0, exports.hasMechanic)(moduleCard, reference_data_1.GameTag.STEALTH);
            }
        }
        newEntity.health = 1;
        newEntity.reborn = false;
        newEntity.scriptDataNum1 = getScriptDataNum1(cardId, originalEntity);
    }
    newEntity.hadDivineShield = newEntity.divineShield || newEntity.hadDivineShield;
    return newEntity;
};
exports.buildSingleBoardEntity = buildSingleBoardEntity;
const getScriptDataNum1 = (cardId, originalEntity) => {
    switch (cardId) {
        case "BG26_804":
            return 8;
        case "BG26_804_G":
            return 16;
        default:
            return 0;
    }
};
const buildRandomUndeadCreation = (controllerHero, friendlyBoard, allCards, friendly, cardsData, sharedState) => {
    const baseCard = (0, utils_1.pickRandom)(cardsData.putricidePool1);
    const newEntity = (0, exports.buildSingleBoardEntity)(baseCard, controllerHero, friendlyBoard, allCards, friendly, sharedState.currentEntityId++, false, cardsData, sharedState, null);
    const stitchedCardId = baseCard === "BG25_009"
        ? (0, utils_1.pickRandom)(cardsData.putridicePool2ForEternalSummoner)
        : (0, utils_1.pickRandom)(cardsData.putricidePool2);
    const stitchedCard = allCards.getCard(stitchedCardId);
    newEntity.attack += stitchedCard.attack;
    newEntity.health += stitchedCard.health;
    newEntity.taunt = newEntity.taunt || (0, exports.hasMechanic)(stitchedCard, reference_data_1.GameTag.TAUNT);
    newEntity.divineShield = newEntity.divineShield || (0, exports.hasMechanic)(stitchedCard, reference_data_1.GameTag.DIVINE_SHIELD);
    newEntity.poisonous = newEntity.poisonous || (0, exports.hasMechanic)(stitchedCard, reference_data_1.GameTag.POISONOUS);
    newEntity.venomous = newEntity.venomous || (0, exports.hasMechanic)(stitchedCard, reference_data_1.GameTag.VENOMOUS);
    newEntity.windfury = newEntity.windfury || (0, exports.hasMechanic)(stitchedCard, reference_data_1.GameTag.WINDFURY);
    newEntity.reborn = newEntity.reborn || (0, exports.hasMechanic)(stitchedCard, reference_data_1.GameTag.REBORN);
    newEntity.avengeCurrent = newEntity.avengeCurrent || cardsData.avengeValue(stitchedCardId);
    newEntity.avengeDefault = newEntity.avengeDefault || cardsData.avengeValue(stitchedCardId);
    return newEntity;
};
exports.buildRandomUndeadCreation = buildRandomUndeadCreation;
const grantRandomAttack = (source, board, hero, additionalAttack, gameState, excludeSource = false) => {
    const candidateBoard = board
        .filter((e) => !excludeSource || e.entityId !== source.entityId)
        .filter((e) => e.health > 0 && !e.definitelyDead);
    if (candidateBoard.length > 0) {
        const target = candidateBoard[Math.floor(Math.random() * candidateBoard.length)];
        (0, stats_1.modifyStats)(target, source, additionalAttack, 0, candidateBoard, hero, gameState);
    }
};
exports.grantRandomAttack = grantRandomAttack;
const grantRandomHealth = (source, board, hero, health, gameState, excludeSource = false) => {
    const candidateBoard = board
        .filter((e) => !excludeSource || e.entityId !== source.entityId)
        .filter((e) => e.health > 0 && !e.definitelyDead);
    if (candidateBoard.length > 0) {
        const target = (0, utils_1.pickRandom)(candidateBoard);
        (0, stats_1.modifyStats)(target, source, 0, health, board, hero, gameState);
    }
};
exports.grantRandomHealth = grantRandomHealth;
const grantRandomStats = (source, board, hero, attack, health, race, excludeSource, gameState) => {
    if (board.length > 0) {
        const target = (0, exports.getRandomAliveMinion)(board.filter((e) => !!e.cardId).filter((e) => (excludeSource ? e.entityId !== source.entityId : true)), hero, race, gameState);
        if (target) {
            (0, stats_1.modifyStats)(target, source, attack, health, board, hero, gameState);
            return target;
        }
    }
    return null;
};
exports.grantRandomStats = grantRandomStats;
const getRandomAliveMinion = (board, hero, race, gameState) => {
    const validTribes = board
        .filter((e) => !race || (0, exports.hasCorrectTribe)(e, hero, race, gameState.anomalies, gameState.allCards))
        .filter((e) => (e === null || e === void 0 ? void 0 : e.health) > 0 && !e.definitelyDead);
    if (!validTribes.length) {
        return null;
    }
    const randomIndex = Math.floor(Math.random() * validTribes.length);
    return validTribes[randomIndex];
};
exports.getRandomAliveMinion = getRandomAliveMinion;
const getRandomRevivableMinion = (board, hero, race, gameState) => {
    const validTribes = board
        .filter((e) => !race || (0, exports.hasCorrectTribe)(e, hero, race, gameState.anomalies, gameState.allCards))
        .filter((e) => !e.definitelyDead);
    if (!validTribes.length) {
        return null;
    }
    const randomIndex = Math.floor(Math.random() * validTribes.length);
    return validTribes[randomIndex];
};
exports.getRandomRevivableMinion = getRandomRevivableMinion;
const getRandomMinionWithHighestHealth = (board) => {
    if (!board.length) {
        return null;
    }
    const highestHealth = Math.max(...board.map((e) => e.health));
    const validMinions = board.filter((e) => e.health === highestHealth);
    return validMinions[Math.floor(Math.random() * validMinions.length)];
};
exports.getRandomMinionWithHighestHealth = getRandomMinionWithHighestHealth;
const addStatsToBoard = (sourceEntity, board, hero, attack, health, gameState, tribe, countsAsStatsGain = true) => {
    for (const entity of board) {
        if (!tribe || (0, exports.hasCorrectTribe)(entity, hero, reference_data_1.Race[tribe], gameState.anomalies, gameState.allCards)) {
            if (countsAsStatsGain) {
                (0, stats_1.modifyStats)(entity, sourceEntity, attack, health, board, hero, gameState);
            }
            else {
                entity.attack += attack;
                entity.health += health;
            }
        }
    }
};
exports.addStatsToBoard = addStatsToBoard;
const addStatsToAliveBoard = (sourceEntity, board, hero, attack, health, gameState, tribe) => {
    for (const entity of board.filter((e) => e.health > 0 && !e.definitelyDead)) {
        if (!tribe || (0, exports.hasCorrectTribe)(entity, hero, reference_data_1.Race[tribe], gameState.anomalies, gameState.allCards)) {
            (0, stats_1.modifyStats)(entity, sourceEntity, attack, health, board, hero, gameState);
        }
    }
};
exports.addStatsToAliveBoard = addStatsToAliveBoard;
const grantStatsToMinionsOfEachType = (source, board, hero, attack, health, gameState, numberOfDifferentTypes = 99, canRevive = true) => {
    const minionsToBuff = (0, exports.getMinionsOfDifferentTypes)(board, hero, gameState, canRevive, numberOfDifferentTypes);
    for (const entity of minionsToBuff) {
        (0, stats_1.modifyStats)(entity, source, attack, health, board, hero, gameState);
    }
};
exports.grantStatsToMinionsOfEachType = grantStatsToMinionsOfEachType;
const getMinionsOfDifferentTypes = (board, hero, gameState, canRevive = true, numberOfDifferentTypes = 99) => {
    const result = [];
    if (board.length > 0) {
        let boardCopy = board.filter((e) => { var _a; return !((_a = (0, exports.getEffectiveTribesForEntity)(e, hero, gameState.anomalies, gameState.allCards)) === null || _a === void 0 ? void 0 : _a.includes(reference_data_1.Race.ALL)); });
        const allRaces = (0, utils_1.shuffleArray)(reference_data_1.ALL_BG_RACES);
        let typesBuffed = 0;
        const racesProcessed = [];
        for (let i = 1; i <= 2; i++) {
            for (const tribe of allRaces) {
                const minionsWithRaces = boardCopy
                    .filter((e) => (0, exports.getEffectiveTribesForEntity)(e, hero, gameState.anomalies, gameState.allCards).length === i)
                    .filter((e) => (0, exports.hasCorrectTribe)(e, hero, tribe, gameState.anomalies, gameState.allCards))
                    .filter((e) => (0, exports.getEffectiveTribesForEntity)(e, hero, gameState.anomalies, gameState.allCards).some((r) => !racesProcessed.includes(r)));
                if (typesBuffed >= numberOfDifferentTypes) {
                    return result;
                }
                const validMinion = canRevive
                    ? (0, exports.getRandomRevivableMinion)(minionsWithRaces, hero, tribe, gameState)
                    : (0, exports.getRandomAliveMinion)(minionsWithRaces, hero, tribe, gameState);
                if (validMinion) {
                    result.push(validMinion);
                    boardCopy = boardCopy.filter((e) => e !== validMinion);
                    typesBuffed++;
                    racesProcessed.push(tribe);
                }
            }
        }
        result.push(...board.filter((e) => {
            const effectiveTribes = (0, exports.getEffectiveTribesForEntity)(e, hero, gameState.anomalies, gameState.allCards);
            return effectiveTribes === null || effectiveTribes === void 0 ? void 0 : effectiveTribes.includes(reference_data_1.Race.ALL);
        }));
    }
    return result;
};
exports.getMinionsOfDifferentTypes = getMinionsOfDifferentTypes;
const hasMechanic = (card, mechanic) => {
    var _a;
    return (_a = card.mechanics) === null || _a === void 0 ? void 0 : _a.includes(reference_data_1.GameTag[mechanic]);
};
exports.hasMechanic = hasMechanic;
const hasEntityMechanic = (entity, mechanic, allCards) => {
    var _a, _b;
    const card = allCards.getCard(entity.cardId);
    if ((_a = card.mechanics) === null || _a === void 0 ? void 0 : _a.includes(reference_data_1.GameTag[mechanic])) {
        return true;
    }
    if (card.entityDbfIf) {
        return (0, exports.hasMechanic)(allCards.getCard(card.entityDbfIf), mechanic);
    }
    for (const enchant of (_b = entity.enchantments) !== null && _b !== void 0 ? _b : []) {
        if ((0, exports.hasEntityMechanic)(enchant, mechanic, allCards)) {
            return true;
        }
    }
    return false;
};
exports.hasEntityMechanic = hasEntityMechanic;
const hasCorrectTribe = (entity, playerEntity, targetTribe, anomalies, allCards) => {
    if (entity == null) {
        return false;
    }
    const effectiveTribesForEntity = (0, exports.getEffectiveTribesForEntity)(entity, playerEntity, anomalies, allCards);
    return (effectiveTribesForEntity.length > 0 &&
        (effectiveTribesForEntity.includes(targetTribe) || effectiveTribesForEntity.includes(reference_data_1.Race.ALL)));
};
exports.hasCorrectTribe = hasCorrectTribe;
const isVolumizer = (cardId, playerEntity, anomalies, allCards) => {
    var _a;
    if (cardId == null) {
        return false;
    }
    const refCard = allCards.getCard(cardId);
    return (_a = refCard.mechanics) === null || _a === void 0 ? void 0 : _a.includes('BACON_VOLUMIZER');
};
exports.isVolumizer = isVolumizer;
const alreadyHasVolumizerBuff = (entity, playerEntity, gameState) => {
    var _a;
    return (_a = entity.enchantments) === null || _a === void 0 ? void 0 : _a.some((e) => { var _a; return (_a = e.cardId) === null || _a === void 0 ? void 0 : _a.includes('BG34_170'); });
};
exports.alreadyHasVolumizerBuff = alreadyHasVolumizerBuff;
const getEffectiveTribesForEntity = (entity, playerEntity, anomalies, allCards) => {
    var _a, _b, _c, _d;
    const cardId = (_a = entity === null || entity === void 0 ? void 0 : entity.originalCardId) !== null && _a !== void 0 ? _a : entity === null || entity === void 0 ? void 0 : entity.cardId;
    if (!cardId) {
        return [];
    }
    const refCard = allCards.getCard(cardId);
    const nativeTribes = (_c = (_b = refCard.races) === null || _b === void 0 ? void 0 : _b.map((r) => reference_data_1.Race[r])) !== null && _c !== void 0 ? _c : [];
    if (!nativeTribes.length && (anomalies === null || anomalies === void 0 ? void 0 : anomalies.includes("BG31_Anomaly_112"))) {
        return [reference_data_1.Race.ALL];
    }
    if (((_d = refCard.mechanics) === null || _d === void 0 ? void 0 : _d.includes(reference_data_1.GameTag[reference_data_1.GameTag.BACON_BUDDY])) &&
        (anomalies === null || anomalies === void 0 ? void 0 : anomalies.includes("BG33_Anomaly_005"))) {
        return [reference_data_1.Race.ALL];
    }
    return [...nativeTribes, ...getSpecialTribesForEntity(entity, playerEntity, allCards)];
};
exports.getEffectiveTribesForEntity = getEffectiveTribesForEntity;
const getSpecialTribesForEntity = (entity, playerEntity, allCards) => {
    switch (entity.cardId) {
        case "BG21_013":
        case "BG21_013_G":
            return playerEntity.trinkets.some((t) => t.cardId === "BG30_MagicItem_825")
                ? [reference_data_1.Race.DRAGON]
                : [];
        case "BGS_009":
        case "TB_BaconUps_082":
            return playerEntity.trinkets.some((t) => t.cardId === "BG30_MagicItem_971")
                ? [reference_data_1.Race.ALL]
                : [];
        case "BG_LOE_077":
        case "TB_BaconUps_045":
            return playerEntity.trinkets.some((t) => t.cardId === "BG30_MagicItem_418")
                ? [reference_data_1.Race.DRAGON, reference_data_1.Race.MURLOC]
                : [];
        case "BG26_ICC_901":
        case "BG26_ICC_901_G":
            return playerEntity.trinkets.some((t) => t.cardId === "BG32_MagicItem_179")
                ? [reference_data_1.Race.MECH, reference_data_1.Race.ELEMENTAL]
                : [];
    }
    return [];
};
const isCorrectTribe = (cardRaces, targetTribe) => {
    if (!(cardRaces === null || cardRaces === void 0 ? void 0 : cardRaces.length)) {
        return false;
    }
    return cardRaces
        .map((cardRace) => (0, exports.getRaceEnum)(cardRace))
        .some((raceEnum) => raceEnum === reference_data_1.Race.ALL || raceEnum === targetTribe);
};
exports.isCorrectTribe = isCorrectTribe;
const getRaceEnum = (race) => {
    return reference_data_1.Race[race];
};
exports.getRaceEnum = getRaceEnum;
const addImpliedMechanics = (entity, cardsData) => {
    const cleave = CLEAVE_IDS.indexOf(entity.cardId) !== -1;
    const cantAttack = CANT_ATTACK_IDS.indexOf(entity.cardId) !== -1;
    entity.cleave = cleave;
    entity.cantAttack = cantAttack;
    entity.divineShield = entity.divineShield || entity.hadDivineShield;
    entity.immuneWhenAttackCharges = [
        "BG24_004",
        "BG24_004_G",
        "BG31_HERO_811t8",
        "BG31_HERO_811t8_G",
        "BG34_Treasure_990",
        "BG34_Treasure_990_G",
    ].includes(entity.cardId)
        ? 99999
        : null;
    entity.frenzyChargesLeft =
        entity.cardId === "BG20_204_G"
            ? 2
            : entity.cardId === "BG20_204"
                ? 1
                : 0;
    const defaultChargesImpl = _card_mappings_1.cardMappings[entity.cardId];
    if ((0, card_interface_1.hasDefaultCharges)(defaultChargesImpl)) {
        entity.abiityChargesLeft = defaultChargesImpl.defaultCharges(entity);
    }
    else {
        entity.abiityChargesLeft = [].includes(entity.cardId)
            ? 3
            : [
                "BG27_507_G",
                "TB_BaconShop_HERO_08_Buddy_G",
                "BG28_404_G",
                "BG29_844",
                "BG29_844_G",
                "BG30_111_G",
            ].includes(entity.cardId)
                ? 2
                : 1;
    }
    return setImplicitDataForEntity(entity, cardsData);
};
exports.addImpliedMechanics = addImpliedMechanics;
const setImplicitDataForEntity = (entity, cardsData) => {
    var _a, _b;
    entity.cardId = (0, exports.normalizeCardIdForSkin)(entity.cardId);
    entity.maxHealth = Math.max(0, entity.health, (_a = entity.maxHealth) !== null && _a !== void 0 ? _a : 0);
    entity.maxAttack = Math.max(0, entity.attack, (_b = entity.maxAttack) !== null && _b !== void 0 ? _b : 0);
    const avengeValue = cardsData.avengeValue(entity.cardId);
    if (avengeValue > 0) {
        entity.avengeCurrent = avengeValue;
        entity.avengeDefault = avengeValue;
    }
    return entity;
};
const normalizeCardIdForSkin = (cardId) => {
    if (!(cardId === null || cardId === void 0 ? void 0 : cardId.length)) {
        return cardId;
    }
    const skinMatch = cardId.match(/(.*)_SKIN_.*/);
    if (skinMatch) {
        return skinMatch[1];
    }
    return cardId;
};
exports.normalizeCardIdForSkin = normalizeCardIdForSkin;
const stringifySimple = (board, allCards = null) => {
    return '[' + board.map((entity) => (0, exports.stringifySimpleCard)(entity, allCards)).join(', ') + ']';
};
exports.stringifySimple = stringifySimple;
const stringifySimpleCard = (entity, allCards = null) => {
    var _a, _b;
    return entity
        ? `${(_b = (_a = allCards === null || allCards === void 0 ? void 0 : allCards.getCard(entity.cardId)) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : entity.cardId}/entityId=${entity.entityId}/atk=${entity.attack}/hp=${entity.health}/ench=${entity.enchantments.map((e) => e.cardId).join(',')}`
        : null;
};
exports.stringifySimpleCard = stringifySimpleCard;
const isFish = (entity) => {
    var _a, _b, _c;
    return (((_a = entity.cardId) === null || _a === void 0 ? void 0 : _a.startsWith("TB_BaconShop_HP_105t")) ||
        ((_b = entity.cardId) === null || _b === void 0 ? void 0 : _b.startsWith("TB_BaconUps_307")) ||
        ((_c = entity.additionalCards) === null || _c === void 0 ? void 0 : _c.includes("BG_RLK_538")));
};
exports.isFish = isFish;
const isPilotedWhirlOTron = (entity) => {
    var _a;
    return (_a = entity.cardId) === null || _a === void 0 ? void 0 : _a.startsWith("BG21_HERO_030_Buddy");
};
exports.isPilotedWhirlOTron = isPilotedWhirlOTron;
const isGolden = (cardId, allCards) => {
    return allCards.getCard(cardId).premium;
};
exports.isGolden = isGolden;
const isBoardEntity = (entity) => {
    return entity != null && 'maxHealth' in entity;
};
exports.isBoardEntity = isBoardEntity;
const getPlayerState = (gameState, hero) => {
    var _a, _b;
    return gameState.player.player === hero
        ? gameState.player
        : ((_a = gameState.player.teammate) === null || _a === void 0 ? void 0 : _a.player) === hero
            ? gameState.player.teammate
            : gameState.opponent.player === hero
                ? gameState.opponent
                : ((_b = gameState.opponent.teammate) === null || _b === void 0 ? void 0 : _b.player) === hero
                    ? gameState.opponent.teammate
                    : null;
};
exports.getPlayerState = getPlayerState;
const getTeammateInitialState = (gameState, hero) => {
    var _a, _b, _c, _d, _e, _f;
    return ((_a = gameState.playerInitial.player) === null || _a === void 0 ? void 0 : _a.entityId) === (hero === null || hero === void 0 ? void 0 : hero.entityId)
        ? gameState.playerInitial.teammate
        : ((_c = (_b = gameState.playerInitial.teammate) === null || _b === void 0 ? void 0 : _b.player) === null || _c === void 0 ? void 0 : _c.entityId) === (hero === null || hero === void 0 ? void 0 : hero.entityId)
            ? gameState.playerInitial
            : ((_d = gameState.opponentInitial.player) === null || _d === void 0 ? void 0 : _d.entityId) === (hero === null || hero === void 0 ? void 0 : hero.entityId)
                ? gameState.opponentInitial.teammate
                : ((_f = (_e = gameState.opponentInitial.teammate) === null || _e === void 0 ? void 0 : _e.player) === null || _f === void 0 ? void 0 : _f.entityId) === (hero === null || hero === void 0 ? void 0 : hero.entityId)
                    ? gameState.opponentInitial
                    : null;
};
exports.getTeammateInitialState = getTeammateInitialState;
const getTeamInitialStates = (gameState, hero) => {
    var _a;
    return ((_a = gameState.playerInitial.player) === null || _a === void 0 ? void 0 : _a.friendly) === (hero === null || hero === void 0 ? void 0 : hero.friendly)
        ? [gameState.playerInitial, gameState.playerInitial.teammate].filter((p) => p)
        : [gameState.opponentInitial, gameState.opponentInitial.teammate].filter((p) => p);
};
exports.getTeamInitialStates = getTeamInitialStates;
const copyEntity = (entity) => {
    var _a, _b;
    const copy = {
        ...entity,
        enchantments: entity.enchantments.map((ench) => ({ ...ench })),
        pendingAttackBuffs: [],
        rememberedDeathrattles: ((_a = entity.rememberedDeathrattles) !== null && _a !== void 0 ? _a : []).map((r) => ({ ...r })),
        additionalCards: (_b = entity.additionalCards) === null || _b === void 0 ? void 0 : _b.map((c) => c),
        tags: entity.tags ? { ...entity.tags } : null,
        lastAffectedByEntity: null,
    };
    return copy;
};
exports.copyEntity = copyEntity;
const isDead = (entity) => {
    return entity.health <= 0 || entity.definitelyDead;
};
exports.isDead = isDead;
//# sourceMappingURL=utils.js.map