UNPKG

isaacscript-common

Version:

Helper functions and features for IsaacScript mods.

135 lines (134 loc) 7.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAliveNPCs = getAliveNPCs; exports.isAliveExceptionNPC = isAliveExceptionNPC; exports.isDaddyLongLegsChildStompEntity = isDaddyLongLegsChildStompEntity; exports.isDyingDump = isDyingDump; exports.isDyingEggyWithNoSpidersLeft = isDyingEggyWithNoSpidersLeft; exports.isRaglingDeathPatch = isRaglingDeathPatch; const isaac_typescript_definitions_1 = require("isaac-typescript-definitions"); const constants_1 = require("../core/constants"); const ReadonlySet_1 = require("../types/ReadonlySet"); const entitiesSpecific_1 = require("./entitiesSpecific"); /** * Used to filter out certain NPCs when determining of an NPC is "alive" and/or should keep the * doors open. */ const NON_ALIVE_NPCS_TYPE_VARIANT = new ReadonlySet_1.ReadonlySet([ `${isaac_typescript_definitions_1.EntityType.VIS}.${isaac_typescript_definitions_1.VisVariant.CHUBBER_PROJECTILE}`, // 39.22 `${isaac_typescript_definitions_1.EntityType.DEATH}.${isaac_typescript_definitions_1.DeathVariant.DEATH_SCYTHE}`, // 66.10 `${isaac_typescript_definitions_1.EntityType.PEEP}.${isaac_typescript_definitions_1.PeepVariant.PEEP_EYE}`, // 68.10 `${isaac_typescript_definitions_1.EntityType.PEEP}.${isaac_typescript_definitions_1.PeepVariant.BLOAT_EYE}`, // 68.11 `${isaac_typescript_definitions_1.EntityType.BEGOTTEN}.${isaac_typescript_definitions_1.BegottenVariant.BEGOTTEN_CHAIN}`, // 251.10 `${isaac_typescript_definitions_1.EntityType.MAMA_GURDY}.${isaac_typescript_definitions_1.MamaGurdyVariant.LEFT_HAND}`, // 266.1 `${isaac_typescript_definitions_1.EntityType.MAMA_GURDY}.${isaac_typescript_definitions_1.MamaGurdyVariant.RIGHT_HAND}`, // 266.2 `${isaac_typescript_definitions_1.EntityType.BIG_HORN}.${isaac_typescript_definitions_1.BigHornVariant.SMALL_HOLE}`, // 411.1 `${isaac_typescript_definitions_1.EntityType.BIG_HORN}.${isaac_typescript_definitions_1.BigHornVariant.BIG_HOLE}`, // 411.2 `${isaac_typescript_definitions_1.EntityType.DARK_ESAU}.${isaac_typescript_definitions_1.DarkEsauVariant.DARK_ESAU}`, // 866.0 `${isaac_typescript_definitions_1.EntityType.DARK_ESAU}.${isaac_typescript_definitions_1.DarkEsauVariant.PIT}`, // 866.1 ]); /** * Used to filter out certain NPCs when determining of an NPC is "alive" and/or should keep the * doors open. */ const NON_ALIVE_NPCS_TYPE_VARIANT_SUB_TYPE = new ReadonlySet_1.ReadonlySet([ `${isaac_typescript_definitions_1.EntityType.CHARGER}.${isaac_typescript_definitions_1.ChargerVariant.CHARGER}.${isaac_typescript_definitions_1.ChargerSubType.MY_SHADOW}`, // 23.0.1 `${isaac_typescript_definitions_1.EntityType.MOTHER}.${isaac_typescript_definitions_1.MotherVariant.MOTHER_1}.${isaac_typescript_definitions_1.MotherSubType.PHASE_2}`, // 912 ]); /** * Helper function to get all of the non-dead NPCs in the room. * * This function will not include NPCs on an internal blacklist, such as Death's scythes or Big Horn * holes. * * @param entityType Optional. If specified, will only get the NPCs that match the type. Default is * -1, which matches every type. * @param variant Optional. If specified, will only get the NPCs that match the variant. Default is * -1, which matches every variant. * @param subType Optional. If specified, will only get the NPCs that match the sub-type. Default is * -1, which matches every sub-type. * @param ignoreFriendly Optional. Default is false. */ function getAliveNPCs(entityType = -1, variant = -1, subType = -1, ignoreFriendly = false) { const npcs = (0, entitiesSpecific_1.getNPCs)(entityType, variant, subType, ignoreFriendly); return npcs.filter((npc) => !npc.IsDead() && !isAliveExceptionNPC(npc)); } /** * Checks for specific NPCs that have "CanShutDoors" set to true naturally by the game, but should * not actually keep the doors closed (like Death's scythes). */ function isAliveExceptionNPC(npc) { const entityTypeVariant = `${npc.Type}.${npc.Variant}`; if (NON_ALIVE_NPCS_TYPE_VARIANT.has(entityTypeVariant)) { return true; } const entityTypeVariantSubType = `${npc.Type}.${npc.Variant}.${npc.SubType}`; if (NON_ALIVE_NPCS_TYPE_VARIANT_SUB_TYPE.has(entityTypeVariantSubType)) { return true; } // EntityType.HOPPER (29) // HopperVariant.EGGY (2) if (isDyingEggyWithNoSpidersLeft(npc)) { return true; } // EntityType.DADDY_LONG_LEGS (101) if (isDaddyLongLegsChildStompEntity(npc)) { return true; } // EntityType.RAGLING (256) if (isRaglingDeathPatch(npc)) { return true; } // EntityType.DUMP (876) if (isDyingDump(npc)) { return true; } return false; } /** * Helper function to distinguish between a normal Daddy Long Legs / Triachnid and the child entity * that is spawned when the boss does the multi-stomp attack. * * When this attack occurs, four extra copies of Daddy Long Legs will be spawned with the same * entity type, variant, and sub-type. The `Entity.Parent` field will be undefined in this case, so * the way to tell them apart is to check for a non-undefined `Entity.SpawnerEntity` field. */ function isDaddyLongLegsChildStompEntity(npc) { return (npc.Type === isaac_typescript_definitions_1.EntityType.DADDY_LONG_LEGS && npc.SpawnerEntity !== undefined); } /** * Helper function to detect the custom death state of a Dump. When Dumps die, they go to * `NPCState.SPECIAL`, spit out their head, and then slowly fade away while shooting a burst of * tears. */ function isDyingDump(npc) { return (npc.Type === isaac_typescript_definitions_1.EntityType.DUMP // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison && npc.Variant === isaac_typescript_definitions_1.DumpVariant.DUMP && npc.State === isaac_typescript_definitions_1.NPCState.SPECIAL); } /** * Helper function to detect the custom death state of an Eggy. Eggies are never actually marked * dead by the game. Instead, when Eggies take fatal damage, they go into NPCState.STATE_SUICIDE and * spawn 14 Swarm Spiders while their StateFrame ticks upwards. */ function isDyingEggyWithNoSpidersLeft(npc) { return (npc.Type === isaac_typescript_definitions_1.EntityType.HOPPER // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison && npc.Variant === isaac_typescript_definitions_1.HopperVariant.EGGY && npc.State === isaac_typescript_definitions_1.NPCState.SUICIDE && npc.StateFrame >= constants_1.EGGY_STATE_FRAME_OF_FINAL_SPIDER); } /** * Helper function to detect the custom death state of a Rag Man Ragling. When Rag Man Raglings die, * they turn into a patch on the ground and can be revived by Rag Man at a later time. This causes * them to show up as an "alive" enemy, so they should usually be filtered out of lists of alive * enemies. */ function isRaglingDeathPatch(npc) { return (npc.Type === isaac_typescript_definitions_1.EntityType.RAGLING // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison && npc.Variant === isaac_typescript_definitions_1.RaglingVariant.RAG_MANS_RAGLING // They go to `STATE_SPECIAL` when they are patches on the ground. && npc.State === isaac_typescript_definitions_1.NPCState.SPECIAL); }