isaacscript-common 2.3.2 → 3.0.0
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.lua +24 -0
- package/callbacks/customRevive.lua +2 -0
- package/callbacks/itemPickup.lua +2 -0
- package/callbacks/postBombInitLate.lua +2 -0
- package/callbacks/postBoneSwing.lua +2 -0
- package/callbacks/postCollectibleInitFirst.lua +2 -0
- package/callbacks/postCursedTeleport.lua +2 -0
- package/callbacks/postCustomDoorEnter.lua +44 -0
- package/callbacks/postDoorRender.lua +2 -0
- package/callbacks/postDoorUpdate.lua +2 -0
- package/callbacks/postEffectInitLate.lua +2 -0
- package/callbacks/postEffectStateChanged.lua +2 -0
- package/callbacks/postEsauJr.lua +2 -0
- package/callbacks/postFamiliarInitLate.lua +2 -0
- package/callbacks/postFamiliarStateChanged.lua +2 -0
- package/callbacks/postFlip.lua +2 -0
- package/callbacks/postGreedModeWave.lua +2 -0
- package/callbacks/postGridEntity.lua +2 -0
- package/callbacks/postGridEntityCollision.lua +2 -0
- package/callbacks/postGridEntityRender.lua +2 -0
- package/callbacks/postHolyMantleRemoved.lua +2 -0
- package/callbacks/postKnifeInitLate.lua +2 -0
- package/callbacks/postLaserInitLate.lua +2 -0
- package/callbacks/postNPCInitLate.lua +2 -0
- package/callbacks/postNPCStateChanged.lua +2 -0
- package/callbacks/postNewRoomEarly.lua +2 -0
- package/callbacks/postPickupCollect.lua +2 -0
- package/callbacks/postPickupInitLate.lua +2 -0
- package/callbacks/postPickupStateChanged.lua +2 -0
- package/callbacks/postPitRender.lua +2 -0
- package/callbacks/postPitUpdate.lua +2 -0
- package/callbacks/postPlayerChangeHealth.lua +2 -0
- package/callbacks/postPlayerChangeType.lua +2 -0
- package/callbacks/postPlayerFatalDamage.lua +2 -0
- package/callbacks/postPlayerInitLate.lua +2 -0
- package/callbacks/postPlayerReordered.lua +2 -0
- package/callbacks/postPoopRender.lua +2 -0
- package/callbacks/postPoopUpdate.lua +2 -0
- package/callbacks/postPressurePlateRender.lua +2 -0
- package/callbacks/postPressurePlateUpdate.lua +2 -0
- package/callbacks/postProjectileInitLate.lua +2 -0
- package/callbacks/postPurchase.lua +2 -0
- package/callbacks/postRockRender.lua +2 -0
- package/callbacks/postRockUpdate.lua +2 -0
- package/callbacks/postRoomClearChanged.lua +2 -0
- package/callbacks/postSacrifice.lua +2 -0
- package/callbacks/postSlotInitUpdate.lua +2 -0
- package/callbacks/postSlotRender.lua +2 -0
- package/callbacks/postSpikesRender.lua +2 -0
- package/callbacks/postSpikesUpdate.lua +2 -0
- package/callbacks/postTNTRender.lua +2 -0
- package/callbacks/postTNTUpdate.lua +2 -0
- package/callbacks/postTearInitLate.lua +2 -0
- package/callbacks/postTearInitVeryLate.lua +2 -0
- package/callbacks/postTransformation.lua +2 -0
- package/callbacks/postTrinketBreak.lua +2 -0
- package/callbacks/preBerserkDeath.lua +2 -0
- package/callbacks/preNewLevel.lua +2 -0
- package/callbacks/reorderedCallbacks.lua +16 -0
- package/callbacks/subscriptions/postBombInitLate.lua +6 -0
- package/callbacks/subscriptions/postBoneSwing.lua +6 -0
- package/callbacks/subscriptions/postCollectibleInitFirst.lua +6 -0
- package/callbacks/subscriptions/postCursedTeleport.lua +6 -0
- package/callbacks/subscriptions/postCustomDoorEnter.lua +6 -0
- package/callbacks/subscriptions/postCustomRevive.lua +6 -0
- package/callbacks/subscriptions/postDoorRender.lua +6 -0
- package/callbacks/subscriptions/postDoorUpdate.lua +6 -0
- package/callbacks/subscriptions/postEffectInitLate.lua +6 -0
- package/callbacks/subscriptions/postEffectStateChanged.lua +6 -0
- package/callbacks/subscriptions/postEsauJr.lua +6 -0
- package/callbacks/subscriptions/postFamiliarInitLate.lua +6 -0
- package/callbacks/subscriptions/postFamiliarStateChanged.lua +6 -0
- package/callbacks/subscriptions/postFirstEsauJr.lua +6 -0
- package/callbacks/subscriptions/postFirstFlip.lua +6 -0
- package/callbacks/subscriptions/postFlip.lua +6 -0
- package/callbacks/subscriptions/postGameStartedReordered.lua +6 -0
- package/callbacks/subscriptions/postGreedModeWave.lua +6 -0
- package/callbacks/subscriptions/postGridEntityBroken.lua +6 -0
- package/callbacks/subscriptions/postGridEntityCollision.lua +6 -0
- package/callbacks/subscriptions/postGridEntityInit.lua +6 -0
- package/callbacks/subscriptions/postGridEntityRemove.lua +6 -0
- package/callbacks/subscriptions/postGridEntityRender.lua +6 -0
- package/callbacks/subscriptions/postGridEntityStateChanged.lua +6 -0
- package/callbacks/subscriptions/postGridEntityUpdate.lua +6 -0
- package/callbacks/subscriptions/postHolyMantleRemoved.lua +6 -0
- package/callbacks/subscriptions/postItemDischarged.lua +6 -0
- package/callbacks/subscriptions/postItemPickup.lua +6 -0
- package/callbacks/subscriptions/postKnifeInitLate.lua +6 -0
- package/callbacks/subscriptions/postLaserInitLate.lua +6 -0
- package/callbacks/subscriptions/postNPCInitLate.lua +6 -0
- package/callbacks/subscriptions/postNPCStateChanged.lua +6 -0
- package/callbacks/subscriptions/postNewLevelReordered.lua +6 -0
- package/callbacks/subscriptions/postNewRoomEarly.lua +6 -0
- package/callbacks/subscriptions/postNewRoomReordered.lua +6 -0
- package/callbacks/subscriptions/postPEffectUpdateReordered.lua +6 -0
- package/callbacks/subscriptions/postPickupCollect.lua +6 -0
- package/callbacks/subscriptions/postPickupInitLate.lua +6 -0
- package/callbacks/subscriptions/postPickupStateChanged.lua +6 -0
- package/callbacks/subscriptions/postPitRender.lua +6 -0
- package/callbacks/subscriptions/postPitUpdate.lua +6 -0
- package/callbacks/subscriptions/postPlayerChangeHealth.lua +6 -0
- package/callbacks/subscriptions/postPlayerChangeType.lua +6 -0
- package/callbacks/subscriptions/postPlayerFatalDamage.lua +6 -0
- package/callbacks/subscriptions/postPlayerInitLate.lua +6 -0
- package/callbacks/subscriptions/postPlayerInitReordered.lua +6 -0
- package/callbacks/subscriptions/postPlayerRenderReordered.lua +6 -0
- package/callbacks/subscriptions/postPlayerUpdateReordered.lua +6 -0
- package/callbacks/subscriptions/postPoopRender.lua +6 -0
- package/callbacks/subscriptions/postPoopUpdate.lua +6 -0
- package/callbacks/subscriptions/postPressurePlateRender.lua +6 -0
- package/callbacks/subscriptions/postPressurePlateUpdate.lua +6 -0
- package/callbacks/subscriptions/postProjectileInitLate.lua +6 -0
- package/callbacks/subscriptions/postPurchase.lua +6 -0
- package/callbacks/subscriptions/postRockRender.lua +6 -0
- package/callbacks/subscriptions/postRockUpdate.lua +6 -0
- package/callbacks/subscriptions/postRoomClearChanged.lua +6 -0
- package/callbacks/subscriptions/postSacrifice.lua +6 -0
- package/callbacks/subscriptions/postSlotAnimationChanged.lua +6 -0
- package/callbacks/subscriptions/postSlotDestroyed.lua +6 -0
- package/callbacks/subscriptions/postSlotInit.lua +6 -0
- package/callbacks/subscriptions/postSlotRender.lua +6 -0
- package/callbacks/subscriptions/postSlotUpdate.lua +6 -0
- package/callbacks/subscriptions/postSpikesRender.lua +6 -0
- package/callbacks/subscriptions/postSpikesUpdate.lua +6 -0
- package/callbacks/subscriptions/postTNTRender.lua +6 -0
- package/callbacks/subscriptions/postTNTUpdate.lua +6 -0
- package/callbacks/subscriptions/postTearInitLate.lua +6 -0
- package/callbacks/subscriptions/postTearInitVeryLate.lua +6 -0
- package/callbacks/subscriptions/postTransformation.lua +6 -0
- package/callbacks/subscriptions/postTrinketBreak.lua +6 -0
- package/callbacks/subscriptions/preBerserkDeath.lua +6 -0
- package/callbacks/subscriptions/preCustomRevive.lua +6 -0
- package/callbacks/subscriptions/preItemPickup.lua +6 -0
- package/callbacks/subscriptions/preNewLevel.lua +6 -0
- package/classes/DefaultMap.d.ts +70 -39
- package/classes/DefaultMap.lua +94 -43
- package/classes/ModUpgraded.d.ts +3 -3
- package/classes/ModUpgraded.lua +5 -0
- package/constants.lua +41 -0
- package/constantsFirstLast.lua +63 -0
- package/enums/HealthType.lua +3 -0
- package/enums/ModCallbackCustom.d.ts +1 -1
- package/enums/ModCallbackCustom.lua +6 -0
- package/enums/private/CopyableIsaacAPIClassType.lua +1 -0
- package/enums/private/SerializationBrand.lua +5 -0
- package/features/characterHealthConversion.lua +6 -0
- package/features/characterStats.lua +17 -0
- package/features/debugDisplay/exports.lua +90 -0
- package/features/deployJSONRoom.lua +56 -0
- package/features/disableInputs.lua +45 -0
- package/features/disableSound.lua +14 -0
- package/features/extraConsoleCommands/commandsDisplay.lua +90 -0
- package/features/extraConsoleCommands/init.lua +16 -0
- package/features/extraConsoleCommands/listCommands.lua +172 -0
- package/features/fadeInRemover.lua +10 -0
- package/features/fastReset.lua +10 -0
- package/features/forgottenSwitch.lua +4 -0
- package/features/getCollectibleItemPoolType.lua +5 -0
- package/features/playerInventory.lua +18 -0
- package/features/ponyDetection.lua +4 -0
- package/features/preventCollectibleRotation.lua +9 -0
- package/features/runInNFrames.lua +50 -0
- package/features/saveDataManager/constants.lua +1 -0
- package/features/saveDataManager/exports.lua +115 -0
- package/features/saveDataManager/main.lua +6 -0
- package/features/saveDataManager/maps.lua +3 -0
- package/features/saveDataManager/merge.lua +20 -0
- package/features/sirenHelpers.lua +13 -0
- package/features/taintedLazarusPlayers.lua +11 -0
- package/featuresInitialized.lua +6 -0
- package/functions/array.lua +85 -0
- package/functions/benchmark.lua +6 -0
- package/functions/boss.lua +35 -0
- package/functions/cacheFlag.lua +4 -0
- package/functions/cards.lua +60 -0
- package/functions/challenges.lua +1 -0
- package/functions/character.lua +23 -0
- package/functions/charge.lua +39 -0
- package/functions/chargeBar.lua +4 -0
- package/functions/collectibleCacheFlag.lua +15 -0
- package/functions/collectibleSet.lua +3 -0
- package/functions/collectibleTag.lua +9 -0
- package/functions/collectibles.lua +131 -0
- package/functions/color.lua +18 -0
- package/functions/debug.lua +18 -0
- package/functions/deepCopy.lua +25 -0
- package/functions/doors.lua +53 -0
- package/functions/entity.lua +88 -0
- package/functions/entitySpecific.lua +182 -0
- package/functions/entityTypes.d.ts +1 -1
- package/functions/entityTypes.lua +1 -0
- package/functions/enums.lua +62 -0
- package/functions/familiars.lua +52 -0
- package/functions/flag.lua +77 -0
- package/functions/flying.lua +10 -0
- package/functions/globals.lua +6 -0
- package/functions/gridEntity.lua +105 -0
- package/functions/gridEntitySpecific.lua +8 -0
- package/functions/input.lua +11 -0
- package/functions/isaacAPIClass.lua +12 -0
- package/functions/jsonHelpers.lua +11 -0
- package/functions/jsonRoom.lua +5 -0
- package/functions/kColor.lua +9 -0
- package/functions/language.lua +5 -0
- package/functions/log.lua +28 -0
- package/functions/map.lua +18 -0
- package/functions/math.lua +26 -0
- package/functions/npc.lua +24 -0
- package/functions/pickupVariants.d.ts +11 -11
- package/functions/pickupVariants.lua +11 -0
- package/functions/pickups.lua +67 -0
- package/functions/pills.lua +45 -0
- package/functions/player.lua +166 -0
- package/functions/playerDataStructures.lua +65 -0
- package/functions/playerHealth.lua +10 -0
- package/functions/playerIndex.lua +47 -0
- package/functions/pocketItems.lua +18 -0
- package/functions/positionVelocity.lua +46 -0
- package/functions/random.lua +32 -0
- package/functions/revive.lua +15 -0
- package/functions/rng.lua +19 -0
- package/functions/roomData.lua +68 -0
- package/functions/roomGrid.lua +21 -0
- package/functions/roomShape.lua +22 -0
- package/functions/rooms.lua +100 -0
- package/functions/run.lua +5 -0
- package/functions/seeds.lua +4 -0
- package/functions/serialization.lua +4 -0
- package/functions/set.lua +22 -0
- package/functions/spawnCollectible.lua +24 -0
- package/functions/sprite.lua +25 -0
- package/functions/stage.lua +16 -0
- package/functions/string.lua +6 -0
- package/functions/table.lua +19 -0
- package/functions/tears.lua +12 -0
- package/functions/transformations.lua +18 -0
- package/functions/trinketCacheFlag.lua +3 -0
- package/functions/trinketGive.lua +24 -0
- package/functions/trinkets.lua +52 -0
- package/functions/tstlClass.lua +9 -0
- package/functions/ui.lua +16 -0
- package/functions/utils.d.ts +1 -0
- package/functions/utils.lua +88 -0
- package/functions/vector.lua +9 -0
- package/lualib_bundle.lua +21 -34
- package/maps/cardMap.lua +1 -0
- package/maps/characterMap.lua +1 -0
- package/maps/defaultPlayerStatMap.lua +1 -0
- package/maps/gridEntityXMLMap.lua +2 -0
- package/maps/pillEffectMap.lua +1 -0
- package/maps/roomShapeToTopLeftWallGridIndexMap.lua +2 -0
- package/maps/roomTypeMap.lua +1 -0
- package/objects/LRoomShapeToRectangles.lua +2 -0
- package/objects/colors.lua +4 -0
- package/objects/roomShapeBounds.lua +2 -0
- package/objects/roomShapeLayoutSizes.lua +4 -0
- package/objects/roomShapeToBottomRightPosition.lua +2 -0
- package/objects/roomShapeToDoorSlotsToGridIndexDelta.lua +2 -0
- package/objects/roomShapeToTopLeftPosition.lua +2 -0
- package/objects/roomShapeVolumes.lua +3 -0
- package/package.json +2 -2
- package/patchErrorFunctions.lua +8 -0
- package/sets/bossSets.lua +23 -0
- package/sets/charactersWithNoRedHeartsSet.lua +2 -0
- package/sets/charactersWithNoSoulHeartsSet.lua +2 -0
- package/sets/lostStyleCharactersSet.lua +2 -0
- package/types/PickingUpItem.lua +7 -0
- package/upgradeMod.d.ts +4 -4
- package/upgradeMod.lua +18 -0
|
@@ -26,10 +26,15 @@ function postPickupInitCollectible(self, pickup)
|
|
|
26
26
|
end
|
|
27
27
|
local FEATURE_NAME = "get collectible item pool type"
|
|
28
28
|
v = {run = {collectibleItemPoolTypeMap = __TS__New(Map)}}
|
|
29
|
+
---
|
|
30
|
+
-- @internal
|
|
29
31
|
function ____exports.getCollectibleItemPoolTypeInit(self, mod)
|
|
30
32
|
saveDataManager(nil, "getCollectibleItemPoolType", v)
|
|
31
33
|
mod:AddCallback(ModCallback.POST_PICKUP_INIT, postPickupInitCollectible, PickupVariant.COLLECTIBLE)
|
|
32
34
|
end
|
|
35
|
+
--- Helper function to get the item pool type that a given collectible came from. Since there is no
|
|
36
|
+
-- native method in the API to get this, we listen in the PreGetCollectible callback for item pool
|
|
37
|
+
-- types, and then assume that the next spawned collectible will match.
|
|
33
38
|
function ____exports.getCollectibleItemPoolType(self, collectible)
|
|
34
39
|
errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
|
|
35
40
|
if not isCollectible(nil, collectible) then
|
|
@@ -94,12 +94,24 @@ v = {run = {
|
|
|
94
94
|
function() return {} end
|
|
95
95
|
)
|
|
96
96
|
}}
|
|
97
|
+
---
|
|
98
|
+
-- @internal
|
|
97
99
|
function ____exports.playerInventoryInit(self, mod)
|
|
98
100
|
saveDataManager(nil, "playerInventory", v)
|
|
99
101
|
mod:AddCallback(ModCallback.POST_USE_ITEM, useItemD4, CollectibleType.D4)
|
|
100
102
|
mod:AddCallback(ModCallback.POST_GAME_STARTED, postGameStarted)
|
|
101
103
|
mod:AddCallbackCustom(ModCallbackCustom.POST_ITEM_PICKUP, postItemPickup)
|
|
102
104
|
end
|
|
105
|
+
--- Helper function to get all of the collectibles that the player has gotten so far on this run, in
|
|
106
|
+
-- order.
|
|
107
|
+
--
|
|
108
|
+
-- Note that this does not include active collectibles that have since been dropped for other
|
|
109
|
+
-- collectibles.
|
|
110
|
+
--
|
|
111
|
+
-- In the case of inventory initialization or the case where the player rerolls their build in the
|
|
112
|
+
-- middle of the run (e.g. with D4), the order of the inventory will not correspond to the order
|
|
113
|
+
-- that the items were actually given to the player. In this case, the inventory will be in the
|
|
114
|
+
-- order of the lowest `CollectibleType` to the highest.
|
|
103
115
|
function ____exports.getPlayerInventory(self, player, includeActiveCollectibles)
|
|
104
116
|
if includeActiveCollectibles == nil then
|
|
105
117
|
includeActiveCollectibles = true
|
|
@@ -116,6 +128,12 @@ function ____exports.getPlayerInventory(self, player, includeActiveCollectibles)
|
|
|
116
128
|
function(____, collectibleType) return not isActiveCollectible(nil, collectibleType) end
|
|
117
129
|
)
|
|
118
130
|
end
|
|
131
|
+
--- Helper function to add a collectible to a player. Use this instead of the
|
|
132
|
+
-- `EntityPlayer.AddCollectible` method if you want the collectible that is added to be
|
|
133
|
+
-- automatically tracked by the player inventory tracker feature.
|
|
134
|
+
--
|
|
135
|
+
-- You only need to use this function if you are using the inventory feature from the standard
|
|
136
|
+
-- library.
|
|
119
137
|
function ____exports.addCollectible(self, player, collectibleType, charge, firstTimePickingUp, activeSlot, varData)
|
|
120
138
|
player:AddCollectible(
|
|
121
139
|
collectibleType,
|
|
@@ -38,10 +38,14 @@ end
|
|
|
38
38
|
local FEATURE_NAME = "pony activation detector"
|
|
39
39
|
FLAGS_WHEN_PONY_IS_ACTIVE = {EntityFlag.NO_KNOCKBACK, EntityFlag.NO_PHYSICS_KNOCKBACK, EntityFlag.NO_DAMAGE_BLINK}
|
|
40
40
|
v = {run = {playersIsPonyActive = __TS__New(Set)}}
|
|
41
|
+
---
|
|
42
|
+
-- @internal
|
|
41
43
|
function ____exports.ponyDetectionInit(self, mod)
|
|
42
44
|
saveDataManager(nil, "ponyDetection", v)
|
|
43
45
|
mod:AddCallbackCustom(ModCallbackCustom.POST_PEFFECT_UPDATE_REORDERED, postPEffectUpdateReordered)
|
|
44
46
|
end
|
|
47
|
+
--- Helper function to see if the player is under the effects of A Pony or White Pony charge.
|
|
48
|
+
-- Detecting this is difficult, as the temporary effect will disappear upon entering a new room.
|
|
45
49
|
function ____exports.isPonyActive(self, player)
|
|
46
50
|
errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
|
|
47
51
|
return setHasPlayer(nil, v.run.playersIsPonyActive, player)
|
|
@@ -40,11 +40,20 @@ function getMapIndex(self, collectible)
|
|
|
40
40
|
end
|
|
41
41
|
local FEATURE_NAME = "prevent collectible rotation"
|
|
42
42
|
v = {room = {trackedCollectibles = __TS__New(Map)}}
|
|
43
|
+
---
|
|
44
|
+
-- @internal
|
|
43
45
|
function ____exports.preventCollectibleRotationInit(self, mod)
|
|
44
46
|
saveDataManager(nil, "preventCollectibleRotation", v)
|
|
45
47
|
mod:AddCallback(ModCallback.POST_USE_CARD, useCardSoulOfIsaac, Card.SOUL_ISAAC)
|
|
46
48
|
mod:AddCallback(ModCallback.POST_PICKUP_UPDATE, postPickupUpdateCollectible, PickupVariant.COLLECTIBLE)
|
|
47
49
|
end
|
|
50
|
+
--- Helper function to prevent a collectible from being affected by Tainted Isaac's rotation
|
|
51
|
+
-- mechanic. (This mechanic also happens from Glitched Crown and Binge Eater.) This is useful
|
|
52
|
+
-- because quest items that are manually spawned by mods will be automatically be affected by this
|
|
53
|
+
-- mechanic.
|
|
54
|
+
--
|
|
55
|
+
-- It is required to pass the intended collectible type to this function since it is possible for
|
|
56
|
+
-- collectibles to rotate on the first frame that they are spawned.
|
|
48
57
|
function ____exports.preventCollectibleRotation(self, collectible, collectibleType)
|
|
49
58
|
errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
|
|
50
59
|
if not isCollectible(nil, collectible) then
|
|
@@ -41,6 +41,8 @@ function checkExecuteQueuedFunctions(self, frameCount, functionTuples)
|
|
|
41
41
|
end
|
|
42
42
|
local FEATURE_NAME = "run in N frames"
|
|
43
43
|
v = {run = {queuedGameFunctionTuples = {}, queuedRenderFunctionTuples = {}}}
|
|
44
|
+
---
|
|
45
|
+
-- @internal
|
|
44
46
|
function ____exports.runInNFramesInit(self, mod)
|
|
45
47
|
saveDataManager(
|
|
46
48
|
nil,
|
|
@@ -51,6 +53,14 @@ function ____exports.runInNFramesInit(self, mod)
|
|
|
51
53
|
mod:AddCallback(ModCallback.POST_UPDATE, postUpdate)
|
|
52
54
|
mod:AddCallback(ModCallback.POST_RENDER, postRender)
|
|
53
55
|
end
|
|
56
|
+
--- Supply a function to run N game frames from now in the PostUpdate callback.
|
|
57
|
+
--
|
|
58
|
+
-- For a usage example, see the documentation for the `runNextGameFrame`, which is used in a similar
|
|
59
|
+
-- way.
|
|
60
|
+
--
|
|
61
|
+
-- Note that this function will not handle saving and quitting. If a player saving and quitting
|
|
62
|
+
-- before the deferred function fires would cause a bug in your mod, then you should handle deferred
|
|
63
|
+
-- functions manually using serializable data.
|
|
54
64
|
function ____exports.runInNGameFrames(self, func, gameFrames)
|
|
55
65
|
errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
|
|
56
66
|
local gameFrameCount = game:GetFrameCount()
|
|
@@ -59,6 +69,14 @@ function ____exports.runInNGameFrames(self, func, gameFrames)
|
|
|
59
69
|
local ____v_run_queuedGameFunctionTuples_0 = v.run.queuedGameFunctionTuples
|
|
60
70
|
____v_run_queuedGameFunctionTuples_0[#____v_run_queuedGameFunctionTuples_0 + 1] = tuple
|
|
61
71
|
end
|
|
72
|
+
--- Supply a function to run N render frames from now in the PostRender callback.
|
|
73
|
+
--
|
|
74
|
+
-- For a usage example, see the documentation for the `runNextGameFrame`, which is used in a similar
|
|
75
|
+
-- way.
|
|
76
|
+
--
|
|
77
|
+
-- Note that this function will not handle saving and quitting. If a player saving and quitting
|
|
78
|
+
-- before the deferred function fires would cause a bug in your mod, then you should handle deferred
|
|
79
|
+
-- functions manually using serializable data.
|
|
62
80
|
function ____exports.runInNRenderFrames(self, func, renderFrames)
|
|
63
81
|
errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
|
|
64
82
|
local renderFrameCount = Isaac.GetFrameCount()
|
|
@@ -67,10 +85,42 @@ function ____exports.runInNRenderFrames(self, func, renderFrames)
|
|
|
67
85
|
local ____v_run_queuedRenderFunctionTuples_1 = v.run.queuedRenderFunctionTuples
|
|
68
86
|
____v_run_queuedRenderFunctionTuples_1[#____v_run_queuedRenderFunctionTuples_1 + 1] = tuple
|
|
69
87
|
end
|
|
88
|
+
--- Supply a function to run on the next PostUpdate callback.
|
|
89
|
+
--
|
|
90
|
+
-- For example:
|
|
91
|
+
--
|
|
92
|
+
-- ```ts
|
|
93
|
+
-- const NUM_EXPLODER_EXPLOSIONS = 5;
|
|
94
|
+
--
|
|
95
|
+
-- function useItemExploder(player: EntityPlayer) {
|
|
96
|
+
-- playSound("exploderBegin");
|
|
97
|
+
-- explode(player, NUM_EXPLODER_EXPLOSIONS);
|
|
98
|
+
-- }
|
|
99
|
+
--
|
|
100
|
+
-- function explode(player: EntityPlayer, numFramesLeft: int) {
|
|
101
|
+
-- Isaac.Explode(player, undefined, 1);
|
|
102
|
+
-- numFramesLeft -= 1;
|
|
103
|
+
-- if (numFramesLeft === 0) {
|
|
104
|
+
-- runNextFrame(() => {
|
|
105
|
+
-- explode(player, numFramesLeft);
|
|
106
|
+
-- });
|
|
107
|
+
-- }
|
|
108
|
+
-- }
|
|
109
|
+
-- ```
|
|
110
|
+
--
|
|
111
|
+
-- Note that this function will not handle saving and quitting. If a player saving and quitting
|
|
112
|
+
-- before the deferred function fires would cause a bug in your mod, then you should handle deferred
|
|
113
|
+
-- functions manually using serializable data.
|
|
70
114
|
function ____exports.runNextGameFrame(self, func)
|
|
71
115
|
errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
|
|
72
116
|
____exports.runInNGameFrames(nil, func, 1)
|
|
73
117
|
end
|
|
118
|
+
--- Supply a function to run on the next PostRender callback.
|
|
119
|
+
--
|
|
120
|
+
-- For a usage example, see the documentation for the `runNextGameFrame`, which is used in a similar
|
|
121
|
+
-- way.
|
|
122
|
+
--
|
|
123
|
+
-- Note that this function will not handle saving and quitting.
|
|
74
124
|
function ____exports.runNextRenderFrame(self, func)
|
|
75
125
|
errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
|
|
76
126
|
____exports.runInNRenderFrames(nil, func, 1)
|
|
@@ -18,6 +18,89 @@ local ____maps = require("features.saveDataManager.maps")
|
|
|
18
18
|
local saveDataConditionalFuncMap = ____maps.saveDataConditionalFuncMap
|
|
19
19
|
local saveDataDefaultsMap = ____maps.saveDataDefaultsMap
|
|
20
20
|
local saveDataMap = ____maps.saveDataMap
|
|
21
|
+
--- This is the entry point to the save data manager, a system which provides two major features:
|
|
22
|
+
--
|
|
23
|
+
-- 1. automatic resetting of variables on a new run, on a new level, or on a new room (as desired)
|
|
24
|
+
-- 2. automatic saving and loading of all tracked data to the "save#.dat" file
|
|
25
|
+
--
|
|
26
|
+
-- You feed this function with an anonymous object containing your variables, and then it will
|
|
27
|
+
-- automatically manage them for you. (See below for an example.)
|
|
28
|
+
--
|
|
29
|
+
-- The save data manager is meant to be called once for each feature of your mod. In other words,
|
|
30
|
+
-- you should not put all of the data for your mod on the same object. Instead, scope your variables
|
|
31
|
+
-- locally to a single file that contains a mod feature, and then call this function to register
|
|
32
|
+
-- them. For example:
|
|
33
|
+
--
|
|
34
|
+
-- ```ts
|
|
35
|
+
-- // in file: feature1.ts
|
|
36
|
+
-- import { saveDataManager } from "isaacscript-common";
|
|
37
|
+
--
|
|
38
|
+
-- // Declare local variables for this file or feature.
|
|
39
|
+
-- const v = {
|
|
40
|
+
-- // These variables are never reset; manage them yourself at will.
|
|
41
|
+
-- persistent: {
|
|
42
|
+
-- foo1: 0,
|
|
43
|
+
-- },
|
|
44
|
+
--
|
|
45
|
+
-- // These variables are reset at the beginning of every run.
|
|
46
|
+
-- run: {
|
|
47
|
+
-- foo2: 0,
|
|
48
|
+
-- },
|
|
49
|
+
--
|
|
50
|
+
-- // These variables are reset at the beginning of every level.
|
|
51
|
+
-- level: {
|
|
52
|
+
-- foo3: 0,
|
|
53
|
+
-- },
|
|
54
|
+
--
|
|
55
|
+
-- // These variables are reset at the beginning of every room.
|
|
56
|
+
-- room: {
|
|
57
|
+
-- foo4: 0,
|
|
58
|
+
-- },
|
|
59
|
+
-- };
|
|
60
|
+
-- // Every child object is optional; only create the ones that you need.
|
|
61
|
+
--
|
|
62
|
+
-- // Register the variables with the save data manager. (We need to provide a string key that
|
|
63
|
+
-- // matches the name of this file.)
|
|
64
|
+
-- function feature1Init() {
|
|
65
|
+
-- saveDataManager("feature1", v);
|
|
66
|
+
-- }
|
|
67
|
+
--
|
|
68
|
+
-- // Elsewhere in the file, use your variables.
|
|
69
|
+
-- function feature1Function() {
|
|
70
|
+
-- if (v.run.foo1 > 0) {
|
|
71
|
+
-- // Insert code here.
|
|
72
|
+
-- }
|
|
73
|
+
-- }
|
|
74
|
+
-- ```
|
|
75
|
+
--
|
|
76
|
+
-- - Save data is loaded from disk in the `POST_PLAYER_INIT` callback (i.e. the first callback that
|
|
77
|
+
-- can possibly run).
|
|
78
|
+
-- - Save data is recorded to disk in the `PRE_GAME_EXIT` callback.
|
|
79
|
+
--
|
|
80
|
+
-- Note that before using the save data manager, you must call the `upgradeMod` function. (Upgrade
|
|
81
|
+
-- your mod before registering any of your own callbacks so that the save data manager will run
|
|
82
|
+
-- before any of your code does.)
|
|
83
|
+
--
|
|
84
|
+
-- If you want the save data manager to load data before the `POST_PLAYER_INIT` callback (i.e. in
|
|
85
|
+
-- the main menu), then you should explicitly call the `saveDataManagerLoad` function. (The save
|
|
86
|
+
-- data manager cannot do this on its own because it cannot know when your mod features are finished
|
|
87
|
+
-- initializing.)
|
|
88
|
+
--
|
|
89
|
+
-- Finally, some features may have variables that need to be automatically reset per run/level, but
|
|
90
|
+
-- not saved to disk on game exit. (For example, if they contain functions or other non-serializable
|
|
91
|
+
-- data.) For these cases, set the second argument to `() => false`.
|
|
92
|
+
--
|
|
93
|
+
-- @param key The name of the file or feature that is submitting data to be managed by the save data
|
|
94
|
+
-- manager. The save data manager will throw an error if the key is already registered.
|
|
95
|
+
-- @param v An object that corresponds to the `SaveData` interface. The object is conventionally
|
|
96
|
+
-- called "v" for brevity. ("v" is short for "local variables").
|
|
97
|
+
-- @param conditionalFunc An optional function to run upon saving this key to disk. For example,
|
|
98
|
+
-- this allows features to only save data to disk if the feature is enabled.
|
|
99
|
+
-- Specify a value of `() => false` to completely disable saving this feature
|
|
100
|
+
-- to disk. Disabling saving to disk is useful if you are using data that is
|
|
101
|
+
-- not serializable. Alternatively, it could be useful if you want to use the
|
|
102
|
+
-- save data manager to automatically reset variables on run/level/room, but
|
|
103
|
+
-- not clutter the the "save#.dat" file with unnecessary keys.
|
|
21
104
|
function ____exports.saveDataManager(self, key, v, conditionalFunc)
|
|
22
105
|
errorIfFeaturesNotInitialized(nil, SAVE_DATA_MANAGER_FEATURE_NAME)
|
|
23
106
|
local keyType = type(key)
|
|
@@ -39,18 +122,50 @@ function ____exports.saveDataManager(self, key, v, conditionalFunc)
|
|
|
39
122
|
saveDataConditionalFuncMap:set(key, conditionalFunc)
|
|
40
123
|
end
|
|
41
124
|
end
|
|
125
|
+
--- The save data manager will automatically load variables from disk at the appropriate times (i.e.
|
|
126
|
+
-- when a new run is started). Use this function to explicitly force the save data manager to load
|
|
127
|
+
-- all of its variables from disk immediately.
|
|
128
|
+
--
|
|
129
|
+
-- Obviously, doing this will overwrite the current data, so using this function can potentially
|
|
130
|
+
-- result in lost state.
|
|
42
131
|
function ____exports.saveDataManagerLoad(self)
|
|
43
132
|
errorIfFeaturesNotInitialized(nil, SAVE_DATA_MANAGER_FEATURE_NAME)
|
|
44
133
|
forceSaveDataManagerLoad(nil)
|
|
45
134
|
end
|
|
135
|
+
--- The save data manager will automatically save variables to disk at the appropriate times (i.e.
|
|
136
|
+
-- when the run is exited). Use this function to explicitly force the save data manager to write all
|
|
137
|
+
-- of its variables to disk immediately.
|
|
46
138
|
function ____exports.saveDataManagerSave(self)
|
|
47
139
|
errorIfFeaturesNotInitialized(nil, SAVE_DATA_MANAGER_FEATURE_NAME)
|
|
48
140
|
forceSaveDataManagerSave(nil)
|
|
49
141
|
end
|
|
142
|
+
--- - Sets the global variable of "g" equal to all of the save data variables for this mod.
|
|
143
|
+
-- - Sets the global variable of "gd" equal to all of the save data default variables for this mod.
|
|
144
|
+
--
|
|
145
|
+
-- This can make debugging easier, as you can access the variables from the game's debug console.
|
|
146
|
+
-- e.g. `l print(g.feature1.foo)`
|
|
50
147
|
function ____exports.saveDataManagerSetGlobal(self)
|
|
51
148
|
g = saveDataMap
|
|
52
149
|
gd = saveDataDefaultsMap
|
|
53
150
|
end
|
|
151
|
+
--- The save data manager will automatically reset variables at the appropriate times (i.e. when a
|
|
152
|
+
-- player enters a new room). Use this function to explicitly force the save data manager to reset a
|
|
153
|
+
-- specific variable group.
|
|
154
|
+
--
|
|
155
|
+
-- For example:
|
|
156
|
+
--
|
|
157
|
+
-- ```ts
|
|
158
|
+
-- const v = {
|
|
159
|
+
-- room: {
|
|
160
|
+
-- foo: 123,
|
|
161
|
+
-- },
|
|
162
|
+
-- };
|
|
163
|
+
--
|
|
164
|
+
-- saveDataManager("file1", v);
|
|
165
|
+
--
|
|
166
|
+
-- // Then, later on, to explicit reset all of the "room" variables:
|
|
167
|
+
-- saveDataManagerReset("file1", "room");
|
|
168
|
+
-- ```
|
|
54
169
|
function ____exports.saveDataManagerReset(self, key, childObjectKey)
|
|
55
170
|
errorIfFeaturesNotInitialized(nil, SAVE_DATA_MANAGER_FEATURE_NAME)
|
|
56
171
|
local keyType = type(key)
|
|
@@ -97,6 +97,8 @@ function clearAndCopyAllElements(self, oldTable, newTable)
|
|
|
97
97
|
end
|
|
98
98
|
mod = nil
|
|
99
99
|
loadedDataOnThisRun = false
|
|
100
|
+
---
|
|
101
|
+
-- @internal
|
|
100
102
|
function ____exports.saveDataManagerInit(self, incomingMod)
|
|
101
103
|
mod = incomingMod
|
|
102
104
|
mod:AddCallback(ModCallback.POST_PLAYER_INIT, postPlayerInit)
|
|
@@ -104,12 +106,16 @@ function ____exports.saveDataManagerInit(self, incomingMod)
|
|
|
104
106
|
mod:AddCallback(ModCallback.POST_NEW_LEVEL, postNewLevel)
|
|
105
107
|
mod:AddCallbackCustom(ModCallbackCustom.POST_NEW_ROOM_EARLY, postNewRoomEarly)
|
|
106
108
|
end
|
|
109
|
+
---
|
|
110
|
+
-- @internal
|
|
107
111
|
function ____exports.forceSaveDataManagerSave(self)
|
|
108
112
|
if mod == nil then
|
|
109
113
|
return
|
|
110
114
|
end
|
|
111
115
|
saveToDisk(nil, mod, saveDataMap, saveDataConditionalFuncMap)
|
|
112
116
|
end
|
|
117
|
+
---
|
|
118
|
+
-- @internal
|
|
113
119
|
function ____exports.forceSaveDataManagerLoad(self)
|
|
114
120
|
if mod == nil then
|
|
115
121
|
return
|
|
@@ -2,6 +2,9 @@ local ____lualib = require("lualib_bundle")
|
|
|
2
2
|
local Map = ____lualib.Map
|
|
3
3
|
local __TS__New = ____lualib.__TS__New
|
|
4
4
|
local ____exports = {}
|
|
5
|
+
--- The save data map is indexed by subscriber name. We use Lua tables instead of TypeScriptToLua
|
|
6
|
+
-- Maps for the master map so that we can access the variables via the in-game console when
|
|
7
|
+
-- debugging. (TSTL Maps don't expose the map keys as normal keys.)
|
|
5
8
|
____exports.saveDataMap = {}
|
|
6
9
|
____exports.saveDataDefaultsMap = {}
|
|
7
10
|
____exports.saveDataConditionalFuncMap = __TS__New(Map)
|
|
@@ -25,6 +25,26 @@ local ____constants = require("features.saveDataManager.constants")
|
|
|
25
25
|
local SAVE_DATA_MANAGER_DEBUG = ____constants.SAVE_DATA_MANAGER_DEBUG
|
|
26
26
|
local ____serializationBrand = require("features.saveDataManager.serializationBrand")
|
|
27
27
|
local isSerializationBrand = ____serializationBrand.isSerializationBrand
|
|
28
|
+
--- `merge` takes the values from a new table and recursively merges them into an old object (while
|
|
29
|
+
-- performing appropriate deserialization).
|
|
30
|
+
--
|
|
31
|
+
-- It supports the following object types:
|
|
32
|
+
--
|
|
33
|
+
-- - `LuaTable` / basic TSTL objects
|
|
34
|
+
-- - TSTL `Map`
|
|
35
|
+
-- - TSTL `Set`
|
|
36
|
+
-- - TSTL classes
|
|
37
|
+
-- - `DefaultMap`
|
|
38
|
+
-- - Isaac `Color` objects
|
|
39
|
+
-- - Isaac `KColor` objects
|
|
40
|
+
-- - Isaac `RNG` objects
|
|
41
|
+
-- - Isaac `Vector` objects
|
|
42
|
+
--
|
|
43
|
+
-- Since it is common for a variable to have a type of `something | null`, we must iterate over the
|
|
44
|
+
-- new object and copy over all of the values. (A value of null transpiles to nil, which means the
|
|
45
|
+
-- table key does not exist.) The consequence of this is that it can copy over old variables that
|
|
46
|
+
-- are no longer used in the code, or copy over old variables of a different type, which can cause
|
|
47
|
+
-- run-time errors. In such cases, users will have to manually delete their save data.
|
|
28
48
|
function ____exports.merge(self, oldObject, newTable, traversalDescription)
|
|
29
49
|
if SAVE_DATA_MANAGER_DEBUG then
|
|
30
50
|
log("merge is traversing: " .. traversalDescription)
|
|
@@ -50,10 +50,18 @@ function getSirenHelper(self, familiar)
|
|
|
50
50
|
end
|
|
51
51
|
local FEATURE_NAME = "siren helpers"
|
|
52
52
|
v = {run = {familiarBlacklist = {}}}
|
|
53
|
+
---
|
|
54
|
+
-- @internal
|
|
53
55
|
function ____exports.sirenHelpersInit(self, mod)
|
|
54
56
|
saveDataManager(nil, "sirenHelpers", v)
|
|
55
57
|
mod:AddCallback(ModCallback.POST_NPC_INIT, postNPCInitSirenHelper, EntityType.SIREN_HELPER)
|
|
56
58
|
end
|
|
59
|
+
--- Blacklists a familiar from being stolen by The Siren boss. This should be called once at the
|
|
60
|
+
-- beginning of every run.
|
|
61
|
+
--
|
|
62
|
+
-- @param familiarVariant The familiar variant to blacklist.
|
|
63
|
+
-- @param familiarSubType The sub-type to blacklist. Optional. The default is to blacklist all
|
|
64
|
+
-- sub-types of the given variant.
|
|
57
65
|
function ____exports.setFamiliarNoSirenSteal(self, familiarVariant, familiarSubType)
|
|
58
66
|
errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
|
|
59
67
|
if blacklistEntryExists(nil, familiarVariant, familiarSubType) then
|
|
@@ -62,6 +70,11 @@ function ____exports.setFamiliarNoSirenSteal(self, familiarVariant, familiarSubT
|
|
|
62
70
|
local ____v_run_familiarBlacklist_0 = v.run.familiarBlacklist
|
|
63
71
|
____v_run_familiarBlacklist_0[#____v_run_familiarBlacklist_0 + 1] = {familiarVariant, familiarSubType}
|
|
64
72
|
end
|
|
73
|
+
--- Helper function to check if the Siren boss has stolen a familiar. Some familiars may need to
|
|
74
|
+
-- behave differently when under The Siren's control (e.g. if they auto-target enemies).
|
|
75
|
+
--
|
|
76
|
+
-- @param familiar The familiar to be checked.
|
|
77
|
+
-- @returns Returns whether the familiar has been stolen by The Siren.
|
|
65
78
|
function ____exports.hasSirenStolenFamiliar(self, familiar)
|
|
66
79
|
errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
|
|
67
80
|
return getSirenHelper(nil, familiar) ~= nil
|
|
@@ -49,6 +49,8 @@ v = {run = {
|
|
|
49
49
|
queuedDeadTaintedLazarus = {},
|
|
50
50
|
subPlayerMap = __TS__New(Map)
|
|
51
51
|
}}
|
|
52
|
+
---
|
|
53
|
+
-- @internal
|
|
52
54
|
function ____exports.taintedLazarusPlayersInit(self, mod)
|
|
53
55
|
saveDataManager(
|
|
54
56
|
nil,
|
|
@@ -58,6 +60,15 @@ function ____exports.taintedLazarusPlayersInit(self, mod)
|
|
|
58
60
|
)
|
|
59
61
|
mod:AddCallback(ModCallback.POST_PLAYER_INIT, postPlayerInit)
|
|
60
62
|
end
|
|
63
|
+
--- Helper function to get the other version of Tainted Lazarus.
|
|
64
|
+
--
|
|
65
|
+
-- - On Tainted Lazarus, returns the player object for Dead Tainted Lazarus.
|
|
66
|
+
-- - On Dead Tainted Lazarus, returns the player object for Tainted Lazarus.
|
|
67
|
+
-- - Returns undefined if player object retrieval failed for any reason.
|
|
68
|
+
--
|
|
69
|
+
-- If you call the `EntityPlayer.Exists` method on the returned object, it will return false.
|
|
70
|
+
-- However, you can still call the other methods like you normally would (e.g.
|
|
71
|
+
-- `EntityPlayer.AddCollectible`).
|
|
61
72
|
function ____exports.getTaintedLazarusSubPlayer(self, player)
|
|
62
73
|
errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
|
|
63
74
|
local ptrHash = GetPtrHash(player)
|
package/featuresInitialized.lua
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
local ____exports = {}
|
|
2
2
|
local featuresInitialized = false
|
|
3
|
+
---
|
|
4
|
+
-- @internal
|
|
3
5
|
function ____exports.areFeaturesInitialized(self)
|
|
4
6
|
return featuresInitialized
|
|
5
7
|
end
|
|
8
|
+
---
|
|
9
|
+
-- @internal
|
|
6
10
|
function ____exports.errorIfFeaturesNotInitialized(self, featureName)
|
|
7
11
|
if not ____exports.areFeaturesInitialized(nil) then
|
|
8
12
|
error(("The " .. featureName) .. " is not initialized. You must first upgrade your mod object by calling the \"upgradeMod\" function.")
|
|
9
13
|
end
|
|
10
14
|
end
|
|
15
|
+
---
|
|
16
|
+
-- @internal
|
|
11
17
|
function ____exports.setFeaturesInitialized(self)
|
|
12
18
|
featuresInitialized = true
|
|
13
19
|
end
|
package/functions/array.lua
CHANGED
|
@@ -20,6 +20,11 @@ local newRNG = ____rng.newRNG
|
|
|
20
20
|
local ____utils = require("functions.utils")
|
|
21
21
|
local erange = ____utils.erange
|
|
22
22
|
local ____repeat = ____utils["repeat"]
|
|
23
|
+
--- Helper function to get a random index from the provided array.
|
|
24
|
+
--
|
|
25
|
+
-- @param array The array to get the index from.
|
|
26
|
+
-- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
|
|
27
|
+
-- `RNG.Next` method will be called. Default is `getRandomSeed()`.
|
|
23
28
|
function ____exports.getRandomArrayIndex(self, array, seedOrRNG)
|
|
24
29
|
if seedOrRNG == nil then
|
|
25
30
|
seedOrRNG = getRandomSeed(nil)
|
|
@@ -29,6 +34,13 @@ function ____exports.getRandomArrayIndex(self, array, seedOrRNG)
|
|
|
29
34
|
end
|
|
30
35
|
return getRandomInt(nil, 0, #array - 1, seedOrRNG)
|
|
31
36
|
end
|
|
37
|
+
--- Shuffles the provided array in-place using the Fisher-Yates algorithm.
|
|
38
|
+
--
|
|
39
|
+
-- From: https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
|
|
40
|
+
--
|
|
41
|
+
-- @param array The array to shuffle.
|
|
42
|
+
-- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
|
|
43
|
+
-- `RNG.Next` method will be called. Default is `getRandomSeed()`.
|
|
32
44
|
function ____exports.shuffleArrayInPlace(self, array, seedOrRNG)
|
|
33
45
|
if seedOrRNG == nil then
|
|
34
46
|
seedOrRNG = getRandomSeed(nil)
|
|
@@ -44,6 +56,8 @@ function ____exports.shuffleArrayInPlace(self, array, seedOrRNG)
|
|
|
44
56
|
array[randomIndex + 1] = ____temp_0[2]
|
|
45
57
|
end
|
|
46
58
|
end
|
|
59
|
+
--- Helper function for determining if two arrays contain the exact same elements. Note that this
|
|
60
|
+
-- only performs a shallow comparison.
|
|
47
61
|
function ____exports.arrayEquals(self, array1, array2)
|
|
48
62
|
if #array1 ~= #array2 then
|
|
49
63
|
return false
|
|
@@ -56,6 +70,11 @@ function ____exports.arrayEquals(self, array1, array2)
|
|
|
56
70
|
end
|
|
57
71
|
)
|
|
58
72
|
end
|
|
73
|
+
--- Shallow copies and removes the specified element(s) from the array. Returns the copied array. If
|
|
74
|
+
-- the specified element(s) are not found in the array, it will simply return a shallow copy of the
|
|
75
|
+
-- array.
|
|
76
|
+
--
|
|
77
|
+
-- This function is variadic, meaning that you can specify N arguments to remove N elements.
|
|
59
78
|
function ____exports.arrayRemove(self, originalArray, ...)
|
|
60
79
|
local elementsToRemove = {...}
|
|
61
80
|
local elementsToRemoveSet = __TS__New(Set, elementsToRemove)
|
|
@@ -67,6 +86,10 @@ function ____exports.arrayRemove(self, originalArray, ...)
|
|
|
67
86
|
end
|
|
68
87
|
return array
|
|
69
88
|
end
|
|
89
|
+
--- Removes the specified element(s) from the array. If the specified element(s) are not found in the
|
|
90
|
+
-- array, this function will do nothing. Returns whether or not one or more elements were removed.
|
|
91
|
+
--
|
|
92
|
+
-- This function is variadic, meaning that you can specify N arguments to remove N elements.
|
|
70
93
|
function ____exports.arrayRemoveInPlace(self, array, ...)
|
|
71
94
|
local elementsToRemove = {...}
|
|
72
95
|
local removedOneOrMoreElements = false
|
|
@@ -79,6 +102,11 @@ function ____exports.arrayRemoveInPlace(self, array, ...)
|
|
|
79
102
|
end
|
|
80
103
|
return removedOneOrMoreElements
|
|
81
104
|
end
|
|
105
|
+
--- Shallow copies and removes the elements at the specified indexes from the array. Returns the
|
|
106
|
+
-- copied array. If the specified indexes are not found in the array, it will simply return a
|
|
107
|
+
-- shallow copy of the array.
|
|
108
|
+
--
|
|
109
|
+
-- This function is variadic, meaning that you can specify N arguments to remove N elements.
|
|
82
110
|
function ____exports.arrayRemoveIndex(self, originalArray, ...)
|
|
83
111
|
local indexesToRemove = {...}
|
|
84
112
|
local indexesToRemoveSet = __TS__New(Set, indexesToRemove)
|
|
@@ -93,6 +121,11 @@ function ____exports.arrayRemoveIndex(self, originalArray, ...)
|
|
|
93
121
|
)
|
|
94
122
|
return array
|
|
95
123
|
end
|
|
124
|
+
--- Removes the elements at the specified indexes from the array. If the specified indexes are not
|
|
125
|
+
-- found in the array, this function will do nothing. Returns whether or not one or more elements
|
|
126
|
+
-- were removed.
|
|
127
|
+
--
|
|
128
|
+
-- This function is variadic, meaning that you can specify N arguments to remove N elements.
|
|
96
129
|
function ____exports.arrayRemoveIndexInPlace(self, array, ...)
|
|
97
130
|
local indexesToRemove = {...}
|
|
98
131
|
local legalIndexes = __TS__ArrayFilter(
|
|
@@ -123,6 +156,11 @@ function ____exports.arrayToString(self, array)
|
|
|
123
156
|
local commaSeparatedStrings = table.concat(strings, ", ")
|
|
124
157
|
return ("[" .. commaSeparatedStrings) .. "]"
|
|
125
158
|
end
|
|
159
|
+
--- Helper function to combine two or more arrays. Returns a new array that is the composition of all
|
|
160
|
+
-- of the specified arrays.
|
|
161
|
+
--
|
|
162
|
+
-- This function is variadic, meaning that you can specify N arguments to combine N arrays. Note
|
|
163
|
+
-- that this will only perform a shallow copy of the array elements.
|
|
126
164
|
function ____exports.combineArrays(self, ...)
|
|
127
165
|
local arrays = {...}
|
|
128
166
|
local elements = {}
|
|
@@ -133,6 +171,11 @@ function ____exports.combineArrays(self, ...)
|
|
|
133
171
|
end
|
|
134
172
|
return elements
|
|
135
173
|
end
|
|
174
|
+
--- Helper function to perform a shallow copy.
|
|
175
|
+
--
|
|
176
|
+
-- @param oldArray The array to copy.
|
|
177
|
+
-- @param numElements Optional. If specified, will only copy the first N elements. By default, the
|
|
178
|
+
-- entire array will be copied.
|
|
136
179
|
function ____exports.copyArray(self, oldArray, numElements)
|
|
137
180
|
if numElements == nil then
|
|
138
181
|
numElements = #oldArray
|
|
@@ -153,12 +196,24 @@ end
|
|
|
153
196
|
function ____exports.emptyArray(self, array)
|
|
154
197
|
__TS__ArraySplice(array, 0, #array)
|
|
155
198
|
end
|
|
199
|
+
--- Helper function to get an array containing the indexes of an array.
|
|
200
|
+
--
|
|
201
|
+
-- For example, an array of `["Apple", "Banana"]` would return an array of `[0, 1]`.
|
|
156
202
|
function ____exports.getArrayIndexes(self, array)
|
|
157
203
|
return erange(nil, #array)
|
|
158
204
|
end
|
|
205
|
+
--- Helper function to return the last element of an array.
|
|
206
|
+
--
|
|
207
|
+
-- If the array is empty, this will return undefined.
|
|
159
208
|
function ____exports.getLastElement(self, array)
|
|
160
209
|
return array[#array]
|
|
161
210
|
end
|
|
211
|
+
--- Helper function to get a random element from the provided array.
|
|
212
|
+
--
|
|
213
|
+
-- @param array The array to get an element from.
|
|
214
|
+
-- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
|
|
215
|
+
-- `RNG.Next` method will be called. Default is `getRandomSeed()`.
|
|
216
|
+
-- @param exceptions Optional. An array of elements to skip over if selected.
|
|
162
217
|
function ____exports.getRandomArrayElement(self, array, seedOrRNG, exceptions)
|
|
163
218
|
if seedOrRNG == nil then
|
|
164
219
|
seedOrRNG = getRandomSeed(nil)
|
|
@@ -181,6 +236,13 @@ function ____exports.getRandomArrayElement(self, array, seedOrRNG, exceptions)
|
|
|
181
236
|
end
|
|
182
237
|
return randomElement
|
|
183
238
|
end
|
|
239
|
+
--- Helper function to get a random element from the provided array. Once the random element is
|
|
240
|
+
-- decided, it is then removed from the array (in-place).
|
|
241
|
+
--
|
|
242
|
+
-- @param array The array to get an element from.
|
|
243
|
+
-- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
|
|
244
|
+
-- `RNG.Next` method will be called. Default is `getRandomSeed()`.
|
|
245
|
+
-- @param exceptions Optional. An array of elements to skip over if selected.
|
|
184
246
|
function ____exports.getRandomArrayElementAndRemove(self, array, seedOrRNG, exceptions)
|
|
185
247
|
if seedOrRNG == nil then
|
|
186
248
|
seedOrRNG = getRandomSeed(nil)
|
|
@@ -192,6 +254,13 @@ function ____exports.getRandomArrayElementAndRemove(self, array, seedOrRNG, exce
|
|
|
192
254
|
____exports.arrayRemoveInPlace(nil, array, randomArrayElement)
|
|
193
255
|
return randomArrayElement
|
|
194
256
|
end
|
|
257
|
+
--- Initializes an array with all elements containing the specified default value.
|
|
258
|
+
--
|
|
259
|
+
-- For example:
|
|
260
|
+
--
|
|
261
|
+
-- ```ts
|
|
262
|
+
-- const playerTransformations = initArray(false, PlayerForm.NUM_PLAYER_FORMS - 1);
|
|
263
|
+
-- ```
|
|
195
264
|
function ____exports.initArray(self, defaultValue, size)
|
|
196
265
|
local array = {}
|
|
197
266
|
____repeat(
|
|
@@ -203,6 +272,11 @@ function ____exports.initArray(self, defaultValue, size)
|
|
|
203
272
|
)
|
|
204
273
|
return array
|
|
205
274
|
end
|
|
275
|
+
--- Since Lua uses tables for every non-primitive data structure, it is non-trivial to determine if a
|
|
276
|
+
-- particular table is being used as an array. `isArray` returns true if:
|
|
277
|
+
--
|
|
278
|
+
-- - the table contains all numerical indexes that are contiguous, starting at 1
|
|
279
|
+
-- - the table has no keys (i.e. an "empty" table)
|
|
206
280
|
function ____exports.isArray(self, object)
|
|
207
281
|
if type(object) ~= "table" then
|
|
208
282
|
return false
|
|
@@ -234,6 +308,9 @@ function ____exports.isArray(self, object)
|
|
|
234
308
|
end
|
|
235
309
|
return true
|
|
236
310
|
end
|
|
311
|
+
--- Helper function to see if every element in the array is N + 1.
|
|
312
|
+
--
|
|
313
|
+
-- For example, `[2, 3, 4]` would return true, and `[2, 3, 5]` would return false.
|
|
237
314
|
function ____exports.isArrayContiguous(self, array)
|
|
238
315
|
local lastValue
|
|
239
316
|
for ____, element in ipairs(array) do
|
|
@@ -246,12 +323,20 @@ function ____exports.isArrayContiguous(self, array)
|
|
|
246
323
|
end
|
|
247
324
|
return true
|
|
248
325
|
end
|
|
326
|
+
--- Checks if an array is in the provided 2-dimensional array.
|
|
249
327
|
function ____exports.isArrayInArray(self, arrayToMatch, parentArray)
|
|
250
328
|
return __TS__ArraySome(
|
|
251
329
|
parentArray,
|
|
252
330
|
function(____, element) return ____exports.arrayEquals(nil, element, arrayToMatch) end
|
|
253
331
|
)
|
|
254
332
|
end
|
|
333
|
+
--- Shallow copies and shuffles the array using the Fisher-Yates algorithm. Returns the copied array.
|
|
334
|
+
--
|
|
335
|
+
-- From: https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
|
|
336
|
+
--
|
|
337
|
+
-- @param originalArray The array to shuffle.
|
|
338
|
+
-- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
|
|
339
|
+
-- `RNG.Next` method will be called. Default is `getRandomSeed()`.
|
|
255
340
|
function ____exports.shuffleArray(self, originalArray, seedOrRNG)
|
|
256
341
|
if seedOrRNG == nil then
|
|
257
342
|
seedOrRNG = getRandomSeed(nil)
|
package/functions/benchmark.lua
CHANGED
|
@@ -3,6 +3,12 @@ local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach
|
|
|
3
3
|
local ____exports = {}
|
|
4
4
|
local ____log = require("functions.log")
|
|
5
5
|
local log = ____log.log
|
|
6
|
+
--- Helper function to benchmark the performance of a function.
|
|
7
|
+
--
|
|
8
|
+
-- This function is variadic, which means that you can supply as many as you want to benchmark.
|
|
9
|
+
--
|
|
10
|
+
-- @returns An array containing the average time in milliseconds for each function. (This will also
|
|
11
|
+
-- be printed to the log.)
|
|
6
12
|
function ____exports.benchmark(self, numTrials, ...)
|
|
7
13
|
local functions = {...}
|
|
8
14
|
log(((("Benchmarking " .. tostring(#functions)) .. " function(s) with ") .. tostring(numTrials)) .. " trials.")
|