isaacscript-common 6.6.1-dev.1 → 6.6.1-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cachedClasses.d.ts +1 -0
- package/cachedClasses.js +59 -0
- package/callbacks/customRevive.js +153 -0
- package/callbacks/itemPickup.js +64 -0
- package/callbacks/postAmbush.js +54 -0
- package/callbacks/postBombExploded.js +20 -0
- package/callbacks/postBombInitLate.js +28 -0
- package/callbacks/postBoneSwing.js +49 -0
- package/callbacks/postCollectibleEmpty.js +32 -0
- package/callbacks/postCollectibleInitFirst.js +27 -0
- package/callbacks/postCursedTeleport.js +120 -0
- package/callbacks/postCustomDoorEnter.js +205 -0
- package/callbacks/postDiceRoomActivated.js +39 -0
- package/callbacks/postDoorRender.js +20 -0
- package/callbacks/postDoorUpdate.js +20 -0
- package/callbacks/postEffectInitLate.js +28 -0
- package/callbacks/postEffectStateChanged.js +31 -0
- package/callbacks/postEsauJr.js +70 -0
- package/callbacks/postFamiliarInitLate.js +28 -0
- package/callbacks/postFamiliarStateChanged.js +31 -0
- package/callbacks/postFlip.js +59 -0
- package/callbacks/postGreedModeWave.js +31 -0
- package/callbacks/postGridEntity.js +107 -0
- package/callbacks/postGridEntityCollision.js +49 -0
- package/callbacks/postGridEntityRender.js +20 -0
- package/callbacks/postHolyMantleRemoved.js +33 -0
- package/callbacks/postItemDischarged.js +94 -0
- package/callbacks/postKnifeInitLate.js +28 -0
- package/callbacks/postLaserInitLate.js +28 -0
- package/callbacks/postNPCInitLate.js +28 -0
- package/callbacks/postNPCStateChanged.js +31 -0
- package/callbacks/postNewRoomEarly.js +69 -0
- package/callbacks/postPickupCollect.js +37 -0
- package/callbacks/postPickupInitFirst.js +52 -0
- package/callbacks/postPickupInitLate.js +28 -0
- package/callbacks/postPickupStateChanged.js +31 -0
- package/callbacks/postPitRender.js +20 -0
- package/callbacks/postPitUpdate.js +20 -0
- package/callbacks/postPlayerChangeHealth.js +43 -0
- package/callbacks/postPlayerChangeType.js +31 -0
- package/callbacks/postPlayerCollectible.js +74 -0
- package/callbacks/postPlayerFatalDamage.js +74 -0
- package/callbacks/postPlayerInitLate.js +28 -0
- package/callbacks/postPlayerReordered.js +109 -0
- package/callbacks/postPoopRender.js +20 -0
- package/callbacks/postPoopUpdate.js +20 -0
- package/callbacks/postPressurePlateRender.js +20 -0
- package/callbacks/postPressurePlateUpdate.js +20 -0
- package/callbacks/postProjectileInitLate.js +28 -0
- package/callbacks/postPurchase.js +39 -0
- package/callbacks/postRockRender.js +20 -0
- package/callbacks/postRockUpdate.js +20 -0
- package/callbacks/postRoomClearChanged.js +41 -0
- package/callbacks/postSacrifice.js +38 -0
- package/callbacks/postSlotDestroyed.js +64 -0
- package/callbacks/postSlotInitUpdate.js +49 -0
- package/callbacks/postSlotRender.js +48 -0
- package/callbacks/postSpikesRender.js +20 -0
- package/callbacks/postSpikesUpdate.js +20 -0
- package/callbacks/postTNTRender.js +20 -0
- package/callbacks/postTNTUpdate.js +20 -0
- package/callbacks/postTearInitLate.js +28 -0
- package/callbacks/postTearInitVeryLate.js +32 -0
- package/callbacks/postTransformation.js +37 -0
- package/callbacks/postTrinketBreak.js +64 -0
- package/callbacks/preBerserkDeath.js +35 -0
- package/callbacks/preNewLevel.js +45 -0
- package/callbacks/reorderedCallbacks.js +136 -0
- package/callbacks/subscriptions/postAmbushFinished.js +20 -0
- package/callbacks/subscriptions/postAmbushStarted.js +20 -0
- package/callbacks/subscriptions/postBombInitLate.js +20 -0
- package/callbacks/subscriptions/postBoneExploded.js +20 -0
- package/callbacks/subscriptions/postBoneSwing.js +16 -0
- package/callbacks/subscriptions/postCollectibleEmpty.js +21 -0
- package/callbacks/subscriptions/postCollectibleInitFirst.js +21 -0
- package/callbacks/subscriptions/postCursedTeleport.js +16 -0
- package/callbacks/subscriptions/postCustomDoorEnter.js +21 -0
- package/callbacks/subscriptions/postCustomRevive.js +21 -0
- package/callbacks/subscriptions/postDiceRoomActivated.js +21 -0
- package/callbacks/subscriptions/postDoorRender.js +22 -0
- package/callbacks/subscriptions/postDoorUpdate.js +22 -0
- package/callbacks/subscriptions/postEffectInitLate.js +20 -0
- package/callbacks/subscriptions/postEffectStateChanged.js +20 -0
- package/callbacks/subscriptions/postEsauJr.js +16 -0
- package/callbacks/subscriptions/postFamiliarInitLate.js +20 -0
- package/callbacks/subscriptions/postFamiliarStateChanged.js +20 -0
- package/callbacks/subscriptions/postFirstEsauJr.js +16 -0
- package/callbacks/subscriptions/postFirstFlip.js +16 -0
- package/callbacks/subscriptions/postFlip.js +16 -0
- package/callbacks/subscriptions/postGameStartedReordered.js +16 -0
- package/callbacks/subscriptions/postGreedModeWave.js +16 -0
- package/callbacks/subscriptions/postGridEntityBroken.js +28 -0
- package/callbacks/subscriptions/postGridEntityCollision.js +28 -0
- package/callbacks/subscriptions/postGridEntityInit.js +28 -0
- package/callbacks/subscriptions/postGridEntityRemove.js +26 -0
- package/callbacks/subscriptions/postGridEntityRender.js +28 -0
- package/callbacks/subscriptions/postGridEntityStateChanged.js +28 -0
- package/callbacks/subscriptions/postGridEntityUpdate.js +28 -0
- package/callbacks/subscriptions/postHolyMantleRemoved.js +25 -0
- package/callbacks/subscriptions/postItemDischarged.js +21 -0
- package/callbacks/subscriptions/postItemPickup.js +25 -0
- package/callbacks/subscriptions/postKnifeInitLate.js +20 -0
- package/callbacks/subscriptions/postLaserInitLate.js +20 -0
- package/callbacks/subscriptions/postNPCInitLate.js +20 -0
- package/callbacks/subscriptions/postNPCStateChanged.js +24 -0
- package/callbacks/subscriptions/postNewLevelReordered.js +16 -0
- package/callbacks/subscriptions/postNewRoomEarly.js +16 -0
- package/callbacks/subscriptions/postNewRoomReordered.js +16 -0
- package/callbacks/subscriptions/postPEffectUpdateReordered.js +25 -0
- package/callbacks/subscriptions/postPickupCollect.js +20 -0
- package/callbacks/subscriptions/postPickupInitFirst.js +20 -0
- package/callbacks/subscriptions/postPickupInitLate.js +20 -0
- package/callbacks/subscriptions/postPickupStateChanged.js +20 -0
- package/callbacks/subscriptions/postPitRender.js +22 -0
- package/callbacks/subscriptions/postPitUpdate.js +22 -0
- package/callbacks/subscriptions/postPlayerChangeHealth.js +25 -0
- package/callbacks/subscriptions/postPlayerChangeType.js +20 -0
- package/callbacks/subscriptions/postPlayerCollectibleAdded.js +21 -0
- package/callbacks/subscriptions/postPlayerCollectibleRemoved.js +21 -0
- package/callbacks/subscriptions/postPlayerFatalDamage.js +29 -0
- package/callbacks/subscriptions/postPlayerInitLate.js +25 -0
- package/callbacks/subscriptions/postPlayerInitReordered.js +25 -0
- package/callbacks/subscriptions/postPlayerRenderReordered.js +25 -0
- package/callbacks/subscriptions/postPlayerUpdateReordered.js +25 -0
- package/callbacks/subscriptions/postPoopRender.js +22 -0
- package/callbacks/subscriptions/postPoopUpdate.js +22 -0
- package/callbacks/subscriptions/postPressurePlateRender.js +22 -0
- package/callbacks/subscriptions/postPressurePlateUpdate.js +22 -0
- package/callbacks/subscriptions/postProjectileInitLate.js +21 -0
- package/callbacks/subscriptions/postPurchase.js +16 -0
- package/callbacks/subscriptions/postRockRender.js +22 -0
- package/callbacks/subscriptions/postRockUpdate.js +22 -0
- package/callbacks/subscriptions/postRoomClearChanged.js +20 -0
- package/callbacks/subscriptions/postSacrifice.js +25 -0
- package/callbacks/subscriptions/postSlotAnimationChanged.js +20 -0
- package/callbacks/subscriptions/postSlotDestroyed.js +26 -0
- package/callbacks/subscriptions/postSlotInit.js +20 -0
- package/callbacks/subscriptions/postSlotRender.js +20 -0
- package/callbacks/subscriptions/postSlotUpdate.js +20 -0
- package/callbacks/subscriptions/postSpikesRender.js +22 -0
- package/callbacks/subscriptions/postSpikesUpdate.js +22 -0
- package/callbacks/subscriptions/postTNTRender.js +22 -0
- package/callbacks/subscriptions/postTNTUpdate.js +22 -0
- package/callbacks/subscriptions/postTearInitLate.js +20 -0
- package/callbacks/subscriptions/postTearInitVeryLate.js +20 -0
- package/callbacks/subscriptions/postTransformation.js +20 -0
- package/callbacks/subscriptions/postTrinketBreak.js +21 -0
- package/callbacks/subscriptions/preBerserkDeath.js +26 -0
- package/callbacks/subscriptions/preCustomRevive.js +29 -0
- package/callbacks/subscriptions/preItemPickup.js +25 -0
- package/callbacks/subscriptions/preNewLevel.js +16 -0
- package/classes/DefaultMap.js +145 -0
- package/classes/ModUpgraded.js +57 -0
- package/constants.js +143 -0
- package/constantsFirstLast.js +156 -0
- package/enums/AmbushType.js +6 -0
- package/enums/CornerType.js +8 -0
- package/enums/DecorationVariant.js +11 -0
- package/enums/HealthType.js +18 -0
- package/enums/ModCallbackCustom.js +1213 -0
- package/enums/PocketItemType.js +10 -0
- package/enums/RockAltType.js +9 -0
- package/enums/SerializationType.js +7 -0
- package/enums/SlotDestructionType.js +6 -0
- package/enums/private/CopyableIsaacAPIClassType.js +9 -0
- package/enums/private/SaveDataKey.js +8 -0
- package/enums/private/SerializationBrand.js +41 -0
- package/features/characterHealthConversion.js +86 -0
- package/features/characterStats.js +52 -0
- package/features/collectibleItemPoolType.js +45 -0
- package/features/customGridEntity.js +148 -0
- package/features/customStage/backdrop.js +191 -0
- package/features/customStage/customStageConstants.js +2 -0
- package/features/customStage/exports.js +147 -0
- package/features/customStage/gridEntities.js +138 -0
- package/features/customStage/init.js +104 -0
- package/features/customStage/metadata.json +1 -0
- package/features/customStage/shadows.js +63 -0
- package/features/customStage/streakText.js +35 -0
- package/features/customStage/util.js +36 -0
- package/features/customStage/v.js +18 -0
- package/features/customStage/versusScreen.js +184 -0
- package/features/debugDisplay/debugDisplay.js +183 -0
- package/features/debugDisplay/exports.js +441 -0
- package/features/debugDisplay/v.d.ts +18 -0
- package/features/debugDisplay/v.js +61 -0
- package/features/deployJSONRoom.js +532 -0
- package/features/disableAllSound.js +63 -0
- package/features/disableInputs.js +130 -0
- package/features/extraConsoleCommands/commandsDisplay.js +236 -0
- package/features/extraConsoleCommands/commandsSubroutines.js +109 -0
- package/features/extraConsoleCommands/exports.js +53 -0
- package/features/extraConsoleCommands/init.js +239 -0
- package/features/extraConsoleCommands/listCommands.js +1081 -0
- package/features/extraConsoleCommands/v.js +25 -0
- package/features/fadeInRemover.js +51 -0
- package/features/fastReset.js +61 -0
- package/features/forgottenSwitch.js +33 -0
- package/features/pause.js +68 -0
- package/features/persistentEntities.js +120 -0
- package/features/playerInventory.js +89 -0
- package/features/ponyDetection.js +63 -0
- package/features/preventCollectibleRotation.js +81 -0
- package/features/registerHotkey.js +91 -0
- package/features/roomClearFrame.js +42 -0
- package/features/runInNFrames.js +189 -0
- package/features/runNextRoom.js +34 -0
- package/features/saveDataManager/exports.js +183 -0
- package/features/saveDataManager/load.js +69 -0
- package/features/saveDataManager/main.js +131 -0
- package/features/saveDataManager/maps.js +9 -0
- package/features/saveDataManager/merge.js +139 -0
- package/features/saveDataManager/save.js +43 -0
- package/features/saveDataManager/saveDataManagerConstants.js +4 -0
- package/features/saveDataManager/serializationBrand.js +12 -0
- package/features/sirenHelpers.js +90 -0
- package/features/stageHistory.js +43 -0
- package/features/taintedLazarusPlayers.js +92 -0
- package/featuresInitialized.js +16 -0
- package/functions/ambush.js +35 -0
- package/functions/array.js +423 -0
- package/functions/benchmark.js +28 -0
- package/functions/bitwise.js +74 -0
- package/functions/bombs.js +11 -0
- package/functions/boss.js +137 -0
- package/functions/cacheFlag.js +11 -0
- package/functions/cards.js +217 -0
- package/functions/challenges.js +9 -0
- package/functions/character.js +102 -0
- package/functions/charge.js +202 -0
- package/functions/chargeBar.js +44 -0
- package/functions/collectibleCacheFlag.js +68 -0
- package/functions/collectibleSet.js +108 -0
- package/functions/collectibleTag.js +65 -0
- package/functions/collectibles.js +469 -0
- package/functions/color.d.ts +1 -1
- package/functions/color.js +60 -0
- package/functions/debug.js +60 -0
- package/functions/deepCopy.js +361 -0
- package/functions/deepCopyTests.js +308 -0
- package/functions/direction.js +41 -0
- package/functions/doors.js +326 -0
- package/functions/easing.js +142 -0
- package/functions/eden.js +32 -0
- package/functions/effects.js +11 -0
- package/functions/entity.js +324 -0
- package/functions/entitySpecific.js +481 -0
- package/functions/entityTypes.js +6 -0
- package/functions/enums.js +151 -0
- package/functions/familiars.js +85 -0
- package/functions/flag.js +137 -0
- package/functions/flying.js +88 -0
- package/functions/globals.js +230 -0
- package/functions/gridEntity.js +488 -0
- package/functions/gridEntitySpecific.js +109 -0
- package/functions/input.js +95 -0
- package/functions/isaacAPIClass.js +48 -0
- package/functions/jsonHelpers.js +40 -0
- package/functions/jsonRoom.js +132 -0
- package/functions/kColor.d.ts +1 -1
- package/functions/kColor.js +63 -0
- package/functions/language.js +13 -0
- package/functions/level.js +20 -0
- package/functions/log.js +567 -0
- package/functions/map.js +45 -0
- package/functions/math.js +103 -0
- package/functions/mergeTests.js +213 -0
- package/functions/minimap.js +80 -0
- package/functions/nextStage.js +290 -0
- package/functions/npc.js +101 -0
- package/functions/pickupVariants.js +47 -0
- package/functions/pickups.js +219 -0
- package/functions/pills.js +160 -0
- package/functions/player.js +808 -0
- package/functions/playerCenter.js +50 -0
- package/functions/playerDataStructures.js +114 -0
- package/functions/playerHealth.js +321 -0
- package/functions/playerIndex.js +160 -0
- package/functions/pocketItems.js +124 -0
- package/functions/positionVelocity.js +136 -0
- package/functions/random.js +73 -0
- package/functions/revive.js +140 -0
- package/functions/rng.d.ts +1 -1
- package/functions/rng.js +117 -0
- package/functions/roomData.js +174 -0
- package/functions/roomGrid.js +81 -0
- package/functions/roomShape.js +99 -0
- package/functions/rooms.js +487 -0
- package/functions/run.js +53 -0
- package/functions/saveFile.js +104 -0
- package/functions/seeds.js +18 -0
- package/functions/serialization.js +52 -0
- package/functions/set.js +99 -0
- package/functions/sound.js +9 -0
- package/functions/spawnCollectible.js +66 -0
- package/functions/sprite.js +80 -0
- package/functions/stage.js +172 -0
- package/functions/string.js +37 -0
- package/functions/table.js +143 -0
- package/functions/tears.js +31 -0
- package/functions/transformations.js +101 -0
- package/functions/trinketCacheFlag.js +46 -0
- package/functions/trinketGive.js +121 -0
- package/functions/trinkets.js +169 -0
- package/functions/tstlClass.js +125 -0
- package/functions/types.js +27 -0
- package/functions/ui.js +124 -0
- package/functions/utils.js +172 -0
- package/functions/vector.js +68 -0
- package/index.js +140 -0
- package/initCustomCallbacks.js +133 -0
- package/initFeatures.js +51 -0
- package/interfaces/AddCallbackParameterCustom.js +2 -0
- package/interfaces/ChargeBarSprites.js +2 -0
- package/interfaces/Corner.js +2 -0
- package/interfaces/CustomGridEntityData.js +2 -0
- package/interfaces/CustomStage.js +2 -0
- package/interfaces/CustomStageLua.js +13 -0
- package/interfaces/JSONRoomsFile.js +2 -0
- package/interfaces/PlayerHealth.js +2 -0
- package/interfaces/PocketItemDescription.js +2 -0
- package/interfaces/SaveData.js +2 -0
- package/interfaces/TrinketSituation.js +2 -0
- package/interfaces/private/TSTLClassMetatable.js +2 -0
- package/maps/PHDPillConversions.js +20 -0
- package/maps/cardMap.js +208 -0
- package/maps/characterMap.js +86 -0
- package/maps/collectibleDescriptionMap.js +728 -0
- package/maps/collectibleNameMap.js +727 -0
- package/maps/defaultPlayerStatMap.js +14 -0
- package/maps/falsePHDPillConversions.js +34 -0
- package/maps/gridEntityTypeToBrokenStateMap.js +29 -0
- package/maps/gridEntityXMLMap.js +128 -0
- package/maps/pillEffectMap.js +88 -0
- package/maps/roomShapeToTopLeftWallGridIndexMap.js +14 -0
- package/maps/roomTypeMap.js +39 -0
- package/maps/trinketDescriptionMap.js +196 -0
- package/maps/trinketNameMap.js +195 -0
- package/objects/LRoomShapeToRectangles.js +33 -0
- package/objects/backdropTypeToRockAltType.js +66 -0
- package/objects/bossNamePNGFileNames.js +112 -0
- package/objects/bossPortraitPNGFileNames.js +115 -0
- package/objects/callbackRegisterFunctions.js +170 -0
- package/objects/cardDescriptions.js +104 -0
- package/objects/cardNames.js +104 -0
- package/objects/cardTypes.js +103 -0
- package/objects/challengeNames.js +51 -0
- package/objects/characterNames.js +46 -0
- package/objects/coinSubTypeToValue.js +13 -0
- package/objects/colors.d.ts +1 -0
- package/objects/colors.js +24 -0
- package/objects/directionNames.js +9 -0
- package/objects/directionToDegrees.js +9 -0
- package/objects/directionToVector.js +10 -0
- package/objects/doorSlotFlagToDoorSlot.js +13 -0
- package/objects/doorSlotToDirection.js +13 -0
- package/objects/doorSlotToDoorSlotFlag.js +13 -0
- package/objects/isaacAPIClassTypeToBrand.js +9 -0
- package/objects/isaacAPIClassTypeToCopyFunction.js +12 -0
- package/objects/languageNames.js +11 -0
- package/objects/oppositeDoorSlots.js +13 -0
- package/objects/pillEffectClasses.js +56 -0
- package/objects/pillEffectNames.js +55 -0
- package/objects/pillEffectTypes.js +55 -0
- package/objects/playerNamePNGFileNames.js +55 -0
- package/objects/playerPortraitPNGFileNames.js +52 -0
- package/objects/roomShapeBounds.js +46 -0
- package/objects/roomShapeCorners.js +268 -0
- package/objects/roomShapeLayoutSizes.js +39 -0
- package/objects/roomShapeToBottomRightPosition.js +22 -0
- package/objects/roomShapeToDoorSlotCoordinates.js +109 -0
- package/objects/roomShapeToDoorSlots.js +69 -0
- package/objects/roomShapeToDoorSlotsToGridIndexDelta.js +113 -0
- package/objects/roomShapeToGridWidth.js +18 -0
- package/objects/roomShapeToTopLeftPosition.js +23 -0
- package/objects/roomShapeVolumes.js +30 -0
- package/objects/roomTypeGotoPrefixes.js +33 -0
- package/objects/roomTypeNames.js +34 -0
- package/objects/serializedIsaacAPIClassTypeToIdentityFunction.js +12 -0
- package/objects/stageTypeSuffixes.js +10 -0
- package/objects/stageTypeToLetter.js +12 -0
- package/objects/transformationNames.js +18 -0
- package/objects/versusScreenBackgroundColors.js +36 -0
- package/objects/versusScreenDirtSpotColors.js +36 -0
- package/package.json +1 -1
- package/patchErrorFunctions.js +67 -0
- package/sets/LRoomShapesSet.js +8 -0
- package/sets/bossSets.js +374 -0
- package/sets/charactersThatStartWithAnActiveItemSet.js +15 -0
- package/sets/charactersWithBlackHeartFromEternalHeartSet.js +6 -0
- package/sets/charactersWithFreeDevilDealsSet.js +3 -0
- package/sets/charactersWithNoRedHeartsSet.js +16 -0
- package/sets/charactersWithNoSoulHeartsSet.js +13 -0
- package/sets/chestPickupVariantsSet.js +16 -0
- package/sets/consoleCommandsSet.js +61 -0
- package/sets/familiarsThatShootPlayerTearsSet.js +12 -0
- package/sets/lostStyleCharactersSet.js +13 -0
- package/sets/mineShaftRoomSubTypesSet.js +9 -0
- package/sets/narrowRoomShapesSet.js +8 -0
- package/sets/redHeartSubTypesSet.js +7 -0
- package/sets/sinEntityTypesSet.js +11 -0
- package/sets/singleUseActiveCollectibleTypesSet.js +12 -0
- package/sets/storyBossesSet.js +17 -0
- package/shaderCrashFix.js +17 -0
- package/types/AnyEntity.js +2 -0
- package/types/CollectibleIndex.js +2 -0
- package/types/PickingUpItem.js +38 -0
- package/types/PlayerIndex.js +2 -0
- package/types/private/IsaacAPIClass.js +2 -0
- package/types/private/SerializedIsaacAPIClass.js +2 -0
- package/types/private/TSTLClass.js +2 -0
- package/upgradeMod.js +47 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import { DefaultMap } from "../classes/DefaultMap";
|
|
2
|
+
import { CopyableIsaacAPIClassType } from "../enums/private/CopyableIsaacAPIClassType";
|
|
3
|
+
import { SerializationBrand } from "../enums/private/SerializationBrand";
|
|
4
|
+
import { SerializationType } from "../enums/SerializationType";
|
|
5
|
+
import { SAVE_DATA_MANAGER_DEBUG } from "../features/saveDataManager/saveDataManagerConstants";
|
|
6
|
+
import { isSerializationBrand } from "../features/saveDataManager/serializationBrand";
|
|
7
|
+
import { isArray } from "./array";
|
|
8
|
+
import { getEnumValues } from "./enums";
|
|
9
|
+
import { getIsaacAPIClassName } from "./isaacAPIClass";
|
|
10
|
+
import { log, logTable } from "./log";
|
|
11
|
+
import { copyIsaacAPIClass, deserializeIsaacAPIClass, isSerializedIsaacAPIClass, } from "./serialization";
|
|
12
|
+
import { getTSTLClassName, isDefaultMap, isTSTLMap, isTSTLSet, isUserDefinedTSTLClass, newTSTLClass, } from "./tstlClass";
|
|
13
|
+
import { isNumber, isPrimitive } from "./types";
|
|
14
|
+
import { getTraversalDescription, twoDimensionalSort } from "./utils";
|
|
15
|
+
const COPYABLE_ISAAC_API_CLASS_TYPES_SET = new Set(getEnumValues(CopyableIsaacAPIClassType));
|
|
16
|
+
/**
|
|
17
|
+
* `deepCopy` is a semi-generic deep cloner. It will recursively copy all of the values so that none
|
|
18
|
+
* of the nested references remain.
|
|
19
|
+
*
|
|
20
|
+
* It supports the following object types:
|
|
21
|
+
*
|
|
22
|
+
* - Primitives (i.e. strings, numbers, and booleans)
|
|
23
|
+
* - `LuaTable` / basic TSTL objects
|
|
24
|
+
* - TSTL `Map`
|
|
25
|
+
* - TSTL `Set`
|
|
26
|
+
* - TSTL classes
|
|
27
|
+
* - `DefaultMap`
|
|
28
|
+
* - Isaac `Color` objects
|
|
29
|
+
* - Isaac `KColor` objects
|
|
30
|
+
* - Isaac `RNG` objects
|
|
31
|
+
* - Isaac `Vector` objects
|
|
32
|
+
*
|
|
33
|
+
* It does not support:
|
|
34
|
+
* - objects with values of `null` (since that transpiles to `nil`)
|
|
35
|
+
* - other Isaac API objects such as `EntityPtr` (that have a type of "userdata")
|
|
36
|
+
*
|
|
37
|
+
* @param value The primitive or object to copy.
|
|
38
|
+
* @param serializationType Has 3 possible values. Can leave objects as-is, or can serialize objects
|
|
39
|
+
* to Lua tables, or can deserialize Lua tables to objects. Default is
|
|
40
|
+
* `SerializationType.NONE`.
|
|
41
|
+
* @param traversalDescription Used to track the current key that we are operating on.
|
|
42
|
+
*/
|
|
43
|
+
export function deepCopy(value, serializationType = SerializationType.NONE, traversalDescription = "") {
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
45
|
+
if (SAVE_DATA_MANAGER_DEBUG) {
|
|
46
|
+
let logString = `deepCopy is operating on: ${traversalDescription}`;
|
|
47
|
+
if (serializationType === SerializationType.SERIALIZE) {
|
|
48
|
+
logString += " (serializing)";
|
|
49
|
+
}
|
|
50
|
+
else if (serializationType === SerializationType.DESERIALIZE) {
|
|
51
|
+
logString += " (deserializing)";
|
|
52
|
+
}
|
|
53
|
+
logString += `: ${value}`;
|
|
54
|
+
log(logString);
|
|
55
|
+
}
|
|
56
|
+
const valueType = type(value);
|
|
57
|
+
switch (valueType) {
|
|
58
|
+
// First, handling the trivial case of primitives.
|
|
59
|
+
case "nil":
|
|
60
|
+
case "boolean":
|
|
61
|
+
case "number":
|
|
62
|
+
case "string": {
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
// Second, handle values that cannot be serialized.
|
|
66
|
+
case "function":
|
|
67
|
+
case "thread": {
|
|
68
|
+
if (serializationType === SerializationType.SERIALIZE) {
|
|
69
|
+
error(`The deep copy function does not support serialization of "${traversalDescription}", since it is type: ${valueType}`);
|
|
70
|
+
}
|
|
71
|
+
// We cannot copy this, so simply return the reference.
|
|
72
|
+
return value;
|
|
73
|
+
}
|
|
74
|
+
case "table": {
|
|
75
|
+
const luaTable = value;
|
|
76
|
+
return deepCopyTable(luaTable, serializationType, traversalDescription);
|
|
77
|
+
}
|
|
78
|
+
case "userdata": {
|
|
79
|
+
return deepCopyUserdata(value, serializationType, traversalDescription);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function deepCopyTable(luaTable, serializationType, traversalDescription) {
|
|
84
|
+
// First, handle the cases of TSTL classes or serialized TSTL classes.
|
|
85
|
+
if (isDefaultMap(luaTable) || luaTable.has(SerializationBrand.DEFAULT_MAP)) {
|
|
86
|
+
return deepCopyDefaultMap(luaTable, serializationType, traversalDescription);
|
|
87
|
+
}
|
|
88
|
+
if (isTSTLMap(luaTable) || luaTable.has(SerializationBrand.MAP)) {
|
|
89
|
+
return deepCopyMap(luaTable, serializationType, traversalDescription);
|
|
90
|
+
}
|
|
91
|
+
if (isTSTLSet(luaTable) || luaTable.has(SerializationBrand.SET)) {
|
|
92
|
+
return deepCopySet(luaTable, serializationType, traversalDescription);
|
|
93
|
+
}
|
|
94
|
+
const className = getTSTLClassName(luaTable);
|
|
95
|
+
if (className === "WeakMap") {
|
|
96
|
+
error(`The deep copy function does not support copying the "WeakMap" class for: ${traversalDescription}`);
|
|
97
|
+
}
|
|
98
|
+
if (className === "WeakSet") {
|
|
99
|
+
error(`The deep copy function does not support copying the "WeakSet" class for: ${traversalDescription}`);
|
|
100
|
+
}
|
|
101
|
+
if (isUserDefinedTSTLClass(luaTable)) {
|
|
102
|
+
return deepCopyTSTLClass(luaTable, serializationType, traversalDescription);
|
|
103
|
+
}
|
|
104
|
+
// This is not a TSTL Map/Set/class. If it has a metatable, abort.
|
|
105
|
+
checkMetatable(luaTable, traversalDescription);
|
|
106
|
+
// Handle the special case of serialized Isaac API classes.
|
|
107
|
+
if (isSerializedIsaacAPIClass(luaTable) &&
|
|
108
|
+
serializationType === SerializationType.DESERIALIZE) {
|
|
109
|
+
return deserializeIsaacAPIClass(luaTable);
|
|
110
|
+
}
|
|
111
|
+
// Handle the special case of an array.
|
|
112
|
+
if (isArray(luaTable)) {
|
|
113
|
+
return deepCopyArray(luaTable, serializationType, traversalDescription);
|
|
114
|
+
}
|
|
115
|
+
// Base case: copy a normal Lua table
|
|
116
|
+
return deepCopyNormalLuaTable(luaTable, serializationType, traversalDescription);
|
|
117
|
+
}
|
|
118
|
+
function deepCopyDefaultMap(defaultMap, serializationType, traversalDescription) {
|
|
119
|
+
// First, handle the special case of serializing a DefaultMap instantiated with a factory
|
|
120
|
+
// function. If this is the case, then we cannot serialize it, so we serialize it as a normal
|
|
121
|
+
// `Map` instead. We do not throw a runtime error because the merge function does not need to
|
|
122
|
+
// instantiate the DefaultMap class in most circumstances.
|
|
123
|
+
const constructorArg = isDefaultMap(defaultMap)
|
|
124
|
+
? defaultMap.getConstructorArg()
|
|
125
|
+
: undefined;
|
|
126
|
+
if (serializationType === SerializationType.SERIALIZE &&
|
|
127
|
+
!isPrimitive(constructorArg)) {
|
|
128
|
+
return deepCopyMap(defaultMap, serializationType, traversalDescription);
|
|
129
|
+
}
|
|
130
|
+
const newDefaultMap = getNewDefaultMap(defaultMap, serializationType, traversalDescription, constructorArg);
|
|
131
|
+
const { entries, convertedNumberKeysToStrings } = getCopiedEntries(defaultMap, serializationType, traversalDescription);
|
|
132
|
+
if (convertedNumberKeysToStrings) {
|
|
133
|
+
// Differentiating between the two types looks superfluous but is necessary for TSTL to produce
|
|
134
|
+
// the proper set method call.
|
|
135
|
+
if (isDefaultMap(newDefaultMap)) {
|
|
136
|
+
newDefaultMap.set(SerializationBrand.OBJECT_WITH_NUMBER_KEYS, "");
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
newDefaultMap.set(SerializationBrand.OBJECT_WITH_NUMBER_KEYS, "");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
for (const [key, value] of entries) {
|
|
143
|
+
// Differentiating between the two types looks superfluous but is necessary for TSTL to produce
|
|
144
|
+
// the proper set method call.
|
|
145
|
+
if (isDefaultMap(newDefaultMap)) {
|
|
146
|
+
newDefaultMap.set(key, value);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
newDefaultMap.set(key, value);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return newDefaultMap;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* The new default map with either be a TSTL `DefaultMap` class or a Lua table, depending on whether
|
|
156
|
+
* we are serializing or not.
|
|
157
|
+
*/
|
|
158
|
+
function getNewDefaultMap(defaultMap, serializationType, traversalDescription, constructorArg) {
|
|
159
|
+
switch (serializationType) {
|
|
160
|
+
case SerializationType.NONE: {
|
|
161
|
+
// eslint-disable-next-line isaacscript/no-invalid-default-map
|
|
162
|
+
return new DefaultMap(constructorArg);
|
|
163
|
+
}
|
|
164
|
+
case SerializationType.SERIALIZE: {
|
|
165
|
+
// Since we are serializing, the new object will be a Lua table. (At this point, we already
|
|
166
|
+
// handled the special case of a DefaultMap instantiated with a factory function.)
|
|
167
|
+
const newDefaultMap = new LuaTable();
|
|
168
|
+
newDefaultMap.set(SerializationBrand.DEFAULT_MAP, "");
|
|
169
|
+
newDefaultMap.set(SerializationBrand.DEFAULT_MAP_VALUE, constructorArg);
|
|
170
|
+
return newDefaultMap;
|
|
171
|
+
}
|
|
172
|
+
case SerializationType.DESERIALIZE: {
|
|
173
|
+
if (isDefaultMap(defaultMap)) {
|
|
174
|
+
error(`The deep copy function failed to deserialize a default map of "${traversalDescription}", since it was not a Lua table.`);
|
|
175
|
+
}
|
|
176
|
+
const defaultMapValue = defaultMap.get(SerializationBrand.DEFAULT_MAP_VALUE);
|
|
177
|
+
if (defaultMapValue === undefined) {
|
|
178
|
+
error(`The deep copy function failed to deserialize a default map of "${traversalDescription}", since there was no serialization brand of: ${SerializationBrand.DEFAULT_MAP_VALUE}`);
|
|
179
|
+
}
|
|
180
|
+
// eslint-disable-next-line isaacscript/no-invalid-default-map
|
|
181
|
+
return new DefaultMap(defaultMapValue);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function deepCopyMap(map, serializationType, traversalDescription) {
|
|
186
|
+
let newMap;
|
|
187
|
+
if (serializationType === SerializationType.SERIALIZE) {
|
|
188
|
+
// Since we are serializing, the new object will be a Lua table.
|
|
189
|
+
newMap = new LuaTable();
|
|
190
|
+
newMap.set(SerializationBrand.MAP, "");
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
newMap = new Map();
|
|
194
|
+
}
|
|
195
|
+
const { entries, convertedNumberKeysToStrings } = getCopiedEntries(map, serializationType, traversalDescription);
|
|
196
|
+
if (convertedNumberKeysToStrings) {
|
|
197
|
+
// Differentiating between the two types looks superfluous but is necessary for TSTL to produce
|
|
198
|
+
// the proper set method call.
|
|
199
|
+
if (isTSTLMap(newMap)) {
|
|
200
|
+
newMap.set(SerializationBrand.OBJECT_WITH_NUMBER_KEYS, "");
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
newMap.set(SerializationBrand.OBJECT_WITH_NUMBER_KEYS, "");
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
for (const [key, value] of entries) {
|
|
207
|
+
// Differentiating between the two types looks superfluous but is necessary for TSTL to produce
|
|
208
|
+
// the proper set method call.
|
|
209
|
+
if (isTSTLMap(newMap)) {
|
|
210
|
+
newMap.set(key, value);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
newMap.set(key, value);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return newMap;
|
|
217
|
+
}
|
|
218
|
+
function deepCopySet(set, serializationType, traversalDescription) {
|
|
219
|
+
let newSet;
|
|
220
|
+
if (serializationType === SerializationType.SERIALIZE) {
|
|
221
|
+
// For serialization purposes, we represent a `Set` as a table with keys that match the
|
|
222
|
+
// keys/values in the Set and values of an empty string.
|
|
223
|
+
newSet = new LuaTable();
|
|
224
|
+
newSet.set(SerializationBrand.SET, "");
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
newSet = new Set();
|
|
228
|
+
}
|
|
229
|
+
const { entries, convertedNumberKeysToStrings } = getCopiedEntries(set, serializationType, traversalDescription);
|
|
230
|
+
if (convertedNumberKeysToStrings) {
|
|
231
|
+
// Differentiating between the two types looks superfluous but is necessary for TSTL to produce
|
|
232
|
+
// the proper set method call.
|
|
233
|
+
if (isTSTLSet(newSet)) {
|
|
234
|
+
// We should never be serializing an object of type Set.
|
|
235
|
+
error("The deep copy function cannot convert number keys to strings for a Set.");
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
newSet.set(SerializationBrand.OBJECT_WITH_NUMBER_KEYS, "");
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
for (const [key] of entries) {
|
|
242
|
+
// Differentiating between the two types looks superfluous but is necessary for TSTL to produce
|
|
243
|
+
// the proper set method call.
|
|
244
|
+
if (isTSTLSet(newSet)) {
|
|
245
|
+
newSet.add(key);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
newSet.set(key, "");
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return newSet;
|
|
252
|
+
}
|
|
253
|
+
function deepCopyTSTLClass(tstlClass, serializationType, traversalDescription) {
|
|
254
|
+
let newClass;
|
|
255
|
+
if (serializationType === SerializationType.SERIALIZE) {
|
|
256
|
+
// Since we are serializing, the new object will be a Lua table.
|
|
257
|
+
newClass = new LuaTable();
|
|
258
|
+
// (We do not brand it with the class type because we will not have the associated class
|
|
259
|
+
// constructor during deserialization, so knowing what type of class it is is pointless.)
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
newClass = newTSTLClass(tstlClass);
|
|
263
|
+
}
|
|
264
|
+
const { entries, convertedNumberKeysToStrings } = getCopiedEntries(tstlClass, serializationType, traversalDescription);
|
|
265
|
+
if (convertedNumberKeysToStrings) {
|
|
266
|
+
newClass.set(SerializationBrand.OBJECT_WITH_NUMBER_KEYS, "");
|
|
267
|
+
}
|
|
268
|
+
for (const [key, value] of entries) {
|
|
269
|
+
newClass.set(key, value);
|
|
270
|
+
}
|
|
271
|
+
return newClass;
|
|
272
|
+
}
|
|
273
|
+
function deepCopyArray(array, serializationType, traversalDescription) {
|
|
274
|
+
const newArray = [];
|
|
275
|
+
for (const value of array) {
|
|
276
|
+
const newValue = deepCopy(value, serializationType, traversalDescription);
|
|
277
|
+
newArray.push(newValue);
|
|
278
|
+
}
|
|
279
|
+
return newArray;
|
|
280
|
+
}
|
|
281
|
+
function deepCopyNormalLuaTable(luaTable, serializationType, traversalDescription) {
|
|
282
|
+
const newTable = new LuaTable();
|
|
283
|
+
const { entries, convertedNumberKeysToStrings } = getCopiedEntries(luaTable, serializationType, traversalDescription);
|
|
284
|
+
if (convertedNumberKeysToStrings) {
|
|
285
|
+
newTable.set(SerializationBrand.OBJECT_WITH_NUMBER_KEYS, "");
|
|
286
|
+
}
|
|
287
|
+
for (const [key, value] of entries) {
|
|
288
|
+
newTable.set(key, value);
|
|
289
|
+
}
|
|
290
|
+
return newTable;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Recursively clones the object's entries, automatically converting number keys to strings, if
|
|
294
|
+
* necessary.
|
|
295
|
+
*/
|
|
296
|
+
function getCopiedEntries(object, serializationType, traversalDescription) {
|
|
297
|
+
// First, shallow copy the entries. We cannot use "pairs" to iterate over a Map or Set. We cannot
|
|
298
|
+
// use "[...pairs(object)]", as it results in a run-time error.
|
|
299
|
+
const entries = [];
|
|
300
|
+
if (isTSTLMap(object) || isTSTLSet(object) || isDefaultMap(object)) {
|
|
301
|
+
for (const [key, value] of object.entries()) {
|
|
302
|
+
entries.push([key, value]);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
for (const [key, value] of pairs(object)) {
|
|
307
|
+
entries.push([key, value]);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
311
|
+
if (SAVE_DATA_MANAGER_DEBUG) {
|
|
312
|
+
logTable(entries);
|
|
313
|
+
entries.sort(twoDimensionalSort);
|
|
314
|
+
}
|
|
315
|
+
const hasNumberKeys = entries.some(([key]) => isNumber(key));
|
|
316
|
+
const convertNumberKeysToStrings = serializationType === SerializationType.SERIALIZE && hasNumberKeys;
|
|
317
|
+
// Second, deep copy the entries.
|
|
318
|
+
const copiedEntries = [];
|
|
319
|
+
for (const [key, value] of entries) {
|
|
320
|
+
// When deserializing, we do not need to copy the serialization brands that are used to denote
|
|
321
|
+
// the object type.
|
|
322
|
+
if (isSerializationBrand(key)) {
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
traversalDescription = getTraversalDescription(key, traversalDescription);
|
|
326
|
+
const newValue = deepCopy(value, serializationType, traversalDescription);
|
|
327
|
+
const keyToUse = convertNumberKeysToStrings ? tostring(key) : key;
|
|
328
|
+
copiedEntries.push([keyToUse, newValue]);
|
|
329
|
+
}
|
|
330
|
+
return {
|
|
331
|
+
entries: copiedEntries,
|
|
332
|
+
convertedNumberKeysToStrings: convertNumberKeysToStrings,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Lua tables can have metatables, which make writing a generic deep cloner impossible. The deep
|
|
337
|
+
* copy function will refuse to copy a table type that has a metatable, outside of specifically
|
|
338
|
+
* supported TSTL objects.
|
|
339
|
+
*/
|
|
340
|
+
function checkMetatable(luaTable, traversalDescription) {
|
|
341
|
+
const metatable = getmetatable(luaTable);
|
|
342
|
+
if (metatable === undefined) {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
const tableDescription = traversalDescription === ""
|
|
346
|
+
? "the table to copy"
|
|
347
|
+
: `"${traversalDescription}"`;
|
|
348
|
+
error(`The deepCopy function detected that ${tableDescription} has a metatable. Copying tables with metatables is not supported, unless they are explicitly handled by the save data manager. (e.g. TypeScriptToLua Maps, TypeScriptToLua Sets, etc.)`);
|
|
349
|
+
}
|
|
350
|
+
/** Isaac API classes are of type "userdata". End-user code cannot create userdata. */
|
|
351
|
+
function deepCopyUserdata(value, serializationType, traversalDescription) {
|
|
352
|
+
const classType = getIsaacAPIClassName(value);
|
|
353
|
+
if (classType === undefined) {
|
|
354
|
+
error(`The deep copy function was not able to derive the Isaac API class type for: ${traversalDescription}`);
|
|
355
|
+
}
|
|
356
|
+
if (!COPYABLE_ISAAC_API_CLASS_TYPES_SET.has(classType)) {
|
|
357
|
+
error(`The deep copy function does not support copying "${traversalDescription}", since it is an Isaac API class of type: ${classType}`);
|
|
358
|
+
}
|
|
359
|
+
return copyIsaacAPIClass(value, serializationType);
|
|
360
|
+
}
|
|
361
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVlcENvcHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9pc2FhY3NjcmlwdC1jb21tb24vc3JjL2Z1bmN0aW9ucy9kZWVwQ29weS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDbkQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDdkYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDekUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDL0QsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sc0RBQXNELENBQUM7QUFDL0YsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0RBQWdELENBQUM7QUFFdEYsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNsQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBQ3RDLE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsd0JBQXdCLEVBQ3hCLHlCQUF5QixHQUMxQixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsWUFBWSxFQUNaLFNBQVMsRUFDVCxTQUFTLEVBQ1Qsc0JBQXNCLEVBQ3RCLFlBQVksR0FDYixNQUFNLGFBQWEsQ0FBQztBQUNyQixPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNoRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFdEUsTUFBTSxrQ0FBa0MsR0FBRyxJQUFJ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
|