isaacscript-common 4.0.0 → 4.0.1-dev.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.ts +39 -0
- package/callbacks/customRevive.lua +2 -1
- package/callbacks/customRevive.ts +215 -0
- package/callbacks/itemPickup.ts +101 -0
- package/callbacks/postAmbush.ts +73 -0
- package/callbacks/postBombExploded.ts +26 -0
- package/callbacks/postBombInitLate.ts +36 -0
- package/callbacks/postBoneSwing.ts +64 -0
- package/callbacks/postCollectibleInitFirst.ts +40 -0
- package/callbacks/postCursedTeleport.ts +183 -0
- package/callbacks/postCustomDoorEnter.lua +0 -7
- package/callbacks/postCustomDoorEnter.ts +292 -0
- package/callbacks/postDiceRoomActivated.ts +60 -0
- package/callbacks/postDoorRender.ts +26 -0
- package/callbacks/postDoorUpdate.ts +26 -0
- package/callbacks/postEffectInitLate.ts +36 -0
- package/callbacks/postEffectStateChanged.ts +43 -0
- package/callbacks/postEsauJr.ts +107 -0
- package/callbacks/postFamiliarInitLate.ts +36 -0
- package/callbacks/postFamiliarStateChanged.ts +43 -0
- package/callbacks/postFlip.ts +88 -0
- package/callbacks/postGreedModeWave.ts +41 -0
- package/callbacks/postGridEntity.ts +164 -0
- package/callbacks/postGridEntityCollision.ts +69 -0
- package/callbacks/postGridEntityRender.ts +26 -0
- package/callbacks/postHolyMantleRemoved.ts +55 -0
- package/callbacks/postItemDischarged.ts +149 -0
- package/callbacks/postKnifeInitLate.ts +36 -0
- package/callbacks/postLaserInitLate.ts +36 -0
- package/callbacks/postNPCInitLate.ts +36 -0
- package/callbacks/postNPCStateChanged.ts +42 -0
- package/callbacks/postNewRoomEarly.ts +90 -0
- package/callbacks/postPickupCollect.ts +48 -0
- package/callbacks/postPickupInitFirst.ts +70 -0
- package/callbacks/postPickupInitLate.ts +36 -0
- package/callbacks/postPickupStateChanged.ts +43 -0
- package/callbacks/postPitRender.ts +26 -0
- package/callbacks/postPitUpdate.ts +26 -0
- package/callbacks/postPlayerChangeHealth.ts +62 -0
- package/callbacks/postPlayerChangeType.ts +56 -0
- package/callbacks/postPlayerCollectible.ts +113 -0
- package/callbacks/postPlayerFatalDamage.ts +141 -0
- package/callbacks/postPlayerInitLate.ts +37 -0
- package/callbacks/postPlayerReordered.ts +142 -0
- package/callbacks/postPoopRender.ts +26 -0
- package/callbacks/postPoopUpdate.ts +26 -0
- package/callbacks/postPressurePlateRender.ts +26 -0
- package/callbacks/postPressurePlateUpdate.ts +26 -0
- package/callbacks/postProjectileInitLate.ts +36 -0
- package/callbacks/postPurchase.ts +64 -0
- package/callbacks/postRockRender.ts +26 -0
- package/callbacks/postRockUpdate.ts +26 -0
- package/callbacks/postRoomClearChanged.ts +57 -0
- package/callbacks/postSacrifice.ts +62 -0
- package/callbacks/postSlotDestroyed.ts +92 -0
- package/callbacks/postSlotInitUpdate.ts +68 -0
- package/callbacks/postSlotRender.ts +69 -0
- package/callbacks/postSpikesRender.ts +26 -0
- package/callbacks/postSpikesUpdate.ts +26 -0
- package/callbacks/postTNTRender.ts +26 -0
- package/callbacks/postTNTUpdate.ts +26 -0
- package/callbacks/postTearInitLate.ts +36 -0
- package/callbacks/postTearInitVeryLate.ts +41 -0
- package/callbacks/postTransformation.ts +59 -0
- package/callbacks/postTrinketBreak.ts +110 -0
- package/callbacks/preBerserkDeath.ts +49 -0
- package/callbacks/preNewLevel.ts +55 -0
- package/callbacks/reorderedCallbacks.ts +166 -0
- package/callbacks/subscriptions/postAmbushFinished.ts +32 -0
- package/callbacks/subscriptions/postAmbushStarted.ts +32 -0
- package/callbacks/subscriptions/postBombInitLate.ts +32 -0
- package/callbacks/subscriptions/postBoneExploded.ts +32 -0
- package/callbacks/subscriptions/postBoneSwing.ts +24 -0
- package/callbacks/subscriptions/postCollectibleInitFirst.ts +37 -0
- package/callbacks/subscriptions/postCursedTeleport.ts +24 -0
- package/callbacks/subscriptions/postCustomDoorEnter.ts +45 -0
- package/callbacks/subscriptions/postCustomRevive.ts +36 -0
- package/callbacks/subscriptions/postDiceRoomActivated.ts +38 -0
- package/callbacks/subscriptions/postDoorRender.ts +35 -0
- package/callbacks/subscriptions/postDoorUpdate.ts +35 -0
- package/callbacks/subscriptions/postEffectInitLate.ts +32 -0
- package/callbacks/subscriptions/postEffectStateChanged.ts +40 -0
- package/callbacks/subscriptions/postEsauJr.ts +24 -0
- package/callbacks/subscriptions/postFamiliarInitLate.ts +32 -0
- package/callbacks/subscriptions/postFamiliarStateChanged.ts +40 -0
- package/callbacks/subscriptions/postFirstEsauJr.ts +24 -0
- package/callbacks/subscriptions/postFirstFlip.ts +24 -0
- package/callbacks/subscriptions/postFlip.ts +22 -0
- package/callbacks/subscriptions/postGameStartedReordered.ts +24 -0
- package/callbacks/subscriptions/postGreedModeWave.ts +24 -0
- package/callbacks/subscriptions/postGridEntityBroken.ts +51 -0
- package/callbacks/subscriptions/postGridEntityCollision.ts +54 -0
- package/callbacks/subscriptions/postGridEntityInit.ts +51 -0
- package/callbacks/subscriptions/postGridEntityRemove.ts +52 -0
- package/callbacks/subscriptions/postGridEntityRender.ts +51 -0
- package/callbacks/subscriptions/postGridEntityStateChanged.ts +55 -0
- package/callbacks/subscriptions/postGridEntityUpdate.ts +51 -0
- package/callbacks/subscriptions/postHolyMantleRemoved.ts +48 -0
- package/callbacks/subscriptions/postItemDischarged.ts +43 -0
- package/callbacks/subscriptions/postItemPickup.ts +64 -0
- package/callbacks/subscriptions/postKnifeInitLate.ts +32 -0
- package/callbacks/subscriptions/postLaserInitLate.ts +32 -0
- package/callbacks/subscriptions/postNPCInitLate.ts +32 -0
- package/callbacks/subscriptions/postNPCStateChanged.ts +42 -0
- package/callbacks/subscriptions/postNewLevelReordered.ts +22 -0
- package/callbacks/subscriptions/postNewRoomEarly.ts +22 -0
- package/callbacks/subscriptions/postNewRoomReordered.ts +22 -0
- package/callbacks/subscriptions/postPEffectUpdateReordered.ts +40 -0
- package/callbacks/subscriptions/postPickupCollect.ts +35 -0
- package/callbacks/subscriptions/postPickupInitFirst.ts +32 -0
- package/callbacks/subscriptions/postPickupInitLate.ts +32 -0
- package/callbacks/subscriptions/postPickupStateChanged.ts +40 -0
- package/callbacks/subscriptions/postPitRender.ts +35 -0
- package/callbacks/subscriptions/postPitUpdate.ts +35 -0
- package/callbacks/subscriptions/postPlayerChangeHealth.ts +49 -0
- package/callbacks/subscriptions/postPlayerChangeType.ts +40 -0
- package/callbacks/subscriptions/postPlayerCollectibleAdded.ts +38 -0
- package/callbacks/subscriptions/postPlayerCollectibleRemoved.ts +38 -0
- package/callbacks/subscriptions/postPlayerFatalDamage.d.ts +1 -1
- package/callbacks/subscriptions/postPlayerFatalDamage.ts +68 -0
- package/callbacks/subscriptions/postPlayerInitLate.ts +40 -0
- package/callbacks/subscriptions/postPlayerInitReordered.ts +40 -0
- package/callbacks/subscriptions/postPlayerRenderReordered.ts +40 -0
- package/callbacks/subscriptions/postPlayerUpdateReordered.ts +40 -0
- package/callbacks/subscriptions/postPoopRender.ts +35 -0
- package/callbacks/subscriptions/postPoopUpdate.ts +35 -0
- package/callbacks/subscriptions/postPressurePlateRender.ts +37 -0
- package/callbacks/subscriptions/postPressurePlateUpdate.ts +37 -0
- package/callbacks/subscriptions/postProjectileInitLate.ts +35 -0
- package/callbacks/subscriptions/postPurchase.ts +31 -0
- package/callbacks/subscriptions/postRockRender.ts +35 -0
- package/callbacks/subscriptions/postRockUpdate.ts +35 -0
- package/callbacks/subscriptions/postRoomClearChanged.ts +30 -0
- package/callbacks/subscriptions/postSacrifice.ts +43 -0
- package/callbacks/subscriptions/postSlotAnimationChanged.ts +40 -0
- package/callbacks/subscriptions/postSlotDestroyed.ts +55 -0
- package/callbacks/subscriptions/postSlotInit.ts +32 -0
- package/callbacks/subscriptions/postSlotRender.ts +32 -0
- package/callbacks/subscriptions/postSlotUpdate.ts +32 -0
- package/callbacks/subscriptions/postSpikesRender.ts +35 -0
- package/callbacks/subscriptions/postSpikesUpdate.ts +35 -0
- package/callbacks/subscriptions/postTNTRender.ts +35 -0
- package/callbacks/subscriptions/postTNTUpdate.ts +35 -0
- package/callbacks/subscriptions/postTearInitLate.ts +32 -0
- package/callbacks/subscriptions/postTearInitVeryLate.ts +32 -0
- package/callbacks/subscriptions/postTransformation.ts +40 -0
- package/callbacks/subscriptions/postTrinketBreak.ts +38 -0
- package/callbacks/subscriptions/preBerserkDeath.ts +42 -0
- package/callbacks/subscriptions/preCustomRevive.d.ts +1 -1
- package/callbacks/subscriptions/preCustomRevive.ts +46 -0
- package/callbacks/subscriptions/preItemPickup.ts +64 -0
- package/callbacks/subscriptions/preNewLevel.ts +24 -0
- package/classes/DefaultMap.ts +174 -0
- package/classes/ModUpgraded.ts +77 -0
- package/constants.ts +162 -0
- package/constantsFirstLast.ts +217 -0
- package/enums/AmbushType.ts +4 -0
- package/enums/HealthType.ts +16 -0
- package/enums/ModCallbackCustom.d.ts +2 -2
- package/enums/ModCallbackCustom.ts +1278 -0
- package/enums/PocketItemType.ts +8 -0
- package/enums/SerializationType.ts +5 -0
- package/enums/SlotDestructionType.ts +4 -0
- package/enums/private/CopyableIsaacAPIClassType.ts +7 -0
- package/enums/private/SaveDataKey.ts +14 -0
- package/enums/private/SerializationBrand.ts +42 -0
- package/features/characterHealthConversion.lua +2 -9
- package/features/characterHealthConversion.ts +111 -0
- package/features/characterStats.ts +61 -0
- package/features/debugDisplay/debugDisplay.ts +221 -0
- package/features/debugDisplay/exports.ts +368 -0
- package/features/debugDisplay/v.ts +65 -0
- package/features/deployJSONRoom.ts +743 -0
- package/features/disableInputs.ts +193 -0
- package/features/disableSound.ts +77 -0
- package/features/extraConsoleCommands/commandsDisplay.ts +290 -0
- package/features/extraConsoleCommands/commandsSubroutines.ts +139 -0
- package/features/extraConsoleCommands/init.ts +334 -0
- package/features/extraConsoleCommands/listCommands.ts +1299 -0
- package/features/extraConsoleCommands/v.ts +14 -0
- package/features/fadeInRemover.ts +60 -0
- package/features/fastReset.ts +75 -0
- package/features/forgottenSwitch.ts +50 -0
- package/features/getCollectibleItemPoolType.ts +66 -0
- package/features/persistentEntities.ts +183 -0
- package/features/playerInventory.ts +133 -0
- package/features/ponyDetection.ts +74 -0
- package/features/preventCollectibleRotation.ts +115 -0
- package/features/runInNFrames.ts +148 -0
- package/features/saveDataManager/constants.ts +4 -0
- package/features/saveDataManager/exports.ts +229 -0
- package/features/saveDataManager/load.ts +99 -0
- package/features/saveDataManager/main.ts +195 -0
- package/features/saveDataManager/maps.ts +13 -0
- package/features/saveDataManager/merge.ts +194 -0
- package/features/saveDataManager/save.ts +74 -0
- package/features/saveDataManager/serializationBrand.ts +16 -0
- package/features/sirenHelpers.ts +129 -0
- package/features/taintedLazarusPlayers.ts +113 -0
- package/featuresInitialized.ts +20 -0
- package/functions/ambush.ts +47 -0
- package/functions/array.ts +410 -0
- package/functions/benchmark.ts +36 -0
- package/functions/bitwise.ts +24 -0
- package/functions/bombs.ts +12 -0
- package/functions/boss.ts +227 -0
- package/functions/cacheFlag.ts +12 -0
- package/functions/cards.ts +271 -0
- package/functions/challenges.ts +13 -0
- package/functions/character.ts +126 -0
- package/functions/charge.ts +237 -0
- package/functions/chargeBar.ts +67 -0
- package/functions/collectibleCacheFlag.ts +90 -0
- package/functions/collectibleSet.ts +56 -0
- package/functions/collectibleTag.ts +89 -0
- package/functions/collectibles.ts +659 -0
- package/functions/color.lua +0 -7
- package/functions/color.ts +128 -0
- package/functions/debug.ts +68 -0
- package/functions/deepCopy.lua +46 -51
- package/functions/deepCopy.ts +535 -0
- package/functions/deepCopyTests.ts +386 -0
- package/functions/direction.ts +49 -0
- package/functions/doors.ts +347 -0
- package/functions/easing.ts +182 -0
- package/functions/eden.ts +47 -0
- package/functions/effects.ts +20 -0
- package/functions/entity.ts +439 -0
- package/functions/entitySpecific.ts +889 -0
- package/functions/entityTypes.ts +6 -0
- package/functions/enums.ts +146 -0
- package/functions/familiars.ts +106 -0
- package/functions/flag.ts +165 -0
- package/functions/flying.ts +117 -0
- package/functions/globals.ts +242 -0
- package/functions/gridEntity.ts +511 -0
- package/functions/gridEntitySpecific.ts +112 -0
- package/functions/input.ts +139 -0
- package/functions/isaacAPIClass.ts +67 -0
- package/functions/jsonHelpers.ts +45 -0
- package/functions/jsonRoom.ts +100 -0
- package/functions/kColor.lua +0 -7
- package/functions/kColor.ts +129 -0
- package/functions/language.ts +13 -0
- package/functions/level.ts +31 -0
- package/functions/log.ts +720 -0
- package/functions/map.ts +56 -0
- package/functions/math.ts +149 -0
- package/functions/mergeTests.ts +288 -0
- package/functions/npc.ts +148 -0
- package/functions/pickupVariants.ts +60 -0
- package/functions/pickups.ts +499 -0
- package/functions/pills.ts +205 -0
- package/functions/player.lua +0 -6
- package/functions/player.ts +1060 -0
- package/functions/playerDataStructures.ts +150 -0
- package/functions/playerHealth.lua +28 -39
- package/functions/playerHealth.ts +382 -0
- package/functions/playerIndex.ts +195 -0
- package/functions/pocketItems.ts +149 -0
- package/functions/positionVelocity.ts +188 -0
- package/functions/random.ts +77 -0
- package/functions/revive.ts +201 -0
- package/functions/rng.lua +0 -7
- package/functions/rng.ts +172 -0
- package/functions/roomData.ts +199 -0
- package/functions/roomGrid.ts +109 -0
- package/functions/roomShape.ts +80 -0
- package/functions/rooms.ts +648 -0
- package/functions/run.ts +36 -0
- package/functions/saveFile.ts +128 -0
- package/functions/seeds.ts +19 -0
- package/functions/serialization.ts +91 -0
- package/functions/set.ts +95 -0
- package/functions/sound.ts +9 -0
- package/functions/spawnCollectible.ts +104 -0
- package/functions/sprite.ts +107 -0
- package/functions/stage.ts +125 -0
- package/functions/string.ts +47 -0
- package/functions/table.ts +189 -0
- package/functions/tears.ts +32 -0
- package/functions/transformations.ts +131 -0
- package/functions/trinketCacheFlag.ts +60 -0
- package/functions/trinketGive.ts +157 -0
- package/functions/trinkets.ts +215 -0
- package/functions/tstlClass.ts +157 -0
- package/functions/types.ts +36 -0
- package/functions/ui.ts +138 -0
- package/functions/utils.d.ts +0 -37
- package/functions/utils.lua +0 -35
- package/functions/utils.ts +189 -0
- package/functions/vector.lua +0 -7
- package/functions/vector.ts +126 -0
- package/index.ts +172 -0
- package/initCustomCallbacks.ts +132 -0
- package/initFeatures.ts +39 -0
- package/interfaces/AddCallbackParameterCustom.ts +188 -0
- package/interfaces/ChargeBarSprites.ts +12 -0
- package/interfaces/JSONDoor.d.ts +3 -3
- package/interfaces/JSONDoor.ts +13 -0
- package/interfaces/JSONEntity.d.ts +4 -4
- package/interfaces/JSONEntity.ts +16 -0
- package/interfaces/JSONRoom.d.ts +8 -8
- package/interfaces/JSONRoom.ts +36 -0
- package/interfaces/JSONRooms.ts +12 -0
- package/interfaces/JSONSpawn.d.ts +2 -2
- package/interfaces/JSONSpawn.ts +14 -0
- package/interfaces/PlayerHealth.ts +16 -0
- package/interfaces/PocketItemDescription.ts +9 -0
- package/interfaces/SaveData.ts +29 -0
- package/interfaces/TrinketSituation.ts +9 -0
- package/interfaces/private/TSTLClassMetatable.ts +8 -0
- package/maps/PHDPillConversions.ts +21 -0
- package/maps/cardMap.ts +209 -0
- package/maps/characterMap.ts +87 -0
- package/maps/collectibleDescriptionMap.ts +732 -0
- package/maps/collectibleNameMap.ts +731 -0
- package/maps/defaultPlayerStatMap.ts +17 -0
- package/maps/falsePHDPillConversions.ts +35 -0
- package/maps/gridEntityTypeToBrokenStateMap.ts +50 -0
- package/maps/gridEntityXMLMap.ts +176 -0
- package/maps/pillEffectMap.ts +88 -0
- package/maps/roomShapeToTopLeftWallGridIndexMap.ts +18 -0
- package/maps/roomTypeMap.ts +40 -0
- package/maps/trinketDescriptionMap.ts +200 -0
- package/maps/trinketNameMap.ts +198 -0
- package/objects/LRoomShapeToRectangles.ts +44 -0
- package/objects/callbackRegisterFunctions.ts +187 -0
- package/objects/cardDescriptions.ts +105 -0
- package/objects/cardNames.ts +105 -0
- package/objects/cardTypes.ts +104 -0
- package/objects/challengeNames.ts +52 -0
- package/objects/characterNames.ts +48 -0
- package/objects/coinSubTypeToValue.ts +14 -0
- package/objects/colors.ts +16 -0
- package/objects/directionNames.ts +11 -0
- package/objects/directionToDegrees.ts +11 -0
- package/objects/directionToVector.ts +12 -0
- package/objects/doorSlotFlagToDoorSlot.ts +16 -0
- package/objects/doorSlotToDirection.ts +14 -0
- package/objects/isaacAPIClassTypeToBrand.ts +11 -0
- package/objects/isaacAPIClassTypeToCopyFunction.ts +18 -0
- package/objects/languageNames.ts +13 -0
- package/objects/oppositeDoorSlots.ts +15 -0
- package/objects/pillEffectClasses.ts +63 -0
- package/objects/pillEffectNames.ts +57 -0
- package/objects/pillEffectTypes.ts +62 -0
- package/objects/roomShapeBounds.ts +71 -0
- package/objects/roomShapeLayoutSizes.ts +45 -0
- package/objects/roomShapeToBottomRightPosition.ts +25 -0
- package/objects/roomShapeToDoorSlots.ts +83 -0
- package/objects/roomShapeToDoorSlotsToGridIndexDelta.ts +127 -0
- package/objects/roomShapeToGridWidth.ts +21 -0
- package/objects/roomShapeToTopLeftPosition.ts +26 -0
- package/objects/roomShapeVolumes.ts +38 -0
- package/objects/roomTypeNames.ts +36 -0
- package/objects/serializedIsaacAPIClassTypeToIdentityFunction.ts +14 -0
- package/objects/stageTypeToLetter.ts +15 -0
- package/objects/transformationNames.d.ts +0 -1
- package/objects/transformationNames.lua +0 -1
- package/objects/transformationNames.ts +18 -0
- package/package.json +1 -1
- package/patchErrorFunctions.ts +92 -0
- package/sets/LRoomShapesSet.ts +8 -0
- package/sets/bossSets.ts +470 -0
- package/sets/charactersThatStartWithAnActiveItemSet.ts +16 -0
- package/sets/charactersWithBlackHeartFromEternalHeartSet.ts +7 -0
- package/sets/charactersWithFreeDevilDealsSet.ts +4 -0
- package/sets/charactersWithNoRedHeartsSet.ts +17 -0
- package/sets/charactersWithNoSoulHeartsSet.ts +14 -0
- package/sets/chestPickupVariantsSet.ts +16 -0
- package/sets/familiarsThatShootPlayerTearsSet.ts +13 -0
- package/sets/lostStyleCharactersSet.ts +13 -0
- package/sets/mineShaftRoomSubTypesSet.ts +10 -0
- package/sets/redHeartSubTypesSet.ts +7 -0
- package/sets/sinEntityTypesSet.ts +11 -0
- package/sets/singleUseActiveCollectibleTypesSet.ts +13 -0
- package/sets/storyBossesSet.ts +17 -0
- package/types/AnyEntity.ts +12 -0
- package/types/AwaitingTextInput.d.ts +2 -0
- package/types/CollectibleIndex.ts +16 -0
- package/types/PickingUpItem.ts +89 -0
- package/types/PlayerIndex.ts +13 -0
- package/types/private/IsaacAPIClass.ts +3 -0
- package/types/private/SerializedIsaacAPIClass.ts +3 -0
- package/types/private/TSTLClass.ts +3 -0
- package/upgradeMod.ts +55 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { DefaultMap } from "../classes/DefaultMap";
|
|
2
|
+
import { PlayerIndex } from "../types/PlayerIndex";
|
|
3
|
+
import { getPlayerIndex } from "./playerIndex";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Helper function to make using default maps with an index of `PlayerIndex` easier. Use this
|
|
7
|
+
* instead of the `DefaultMap.getAndSetDefault` method if you have a default map of this type.
|
|
8
|
+
*
|
|
9
|
+
* For example:
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* const v = {
|
|
13
|
+
* run: {
|
|
14
|
+
* playersSpeedBoost: new DefaultMap<PlayerIndex, int>(0),
|
|
15
|
+
* },
|
|
16
|
+
* };
|
|
17
|
+
*
|
|
18
|
+
* function evaluateCacheSpeed(player: EntityPlayer) {
|
|
19
|
+
* player.MoveSpeed = defaultMapGetPlayer(v.run.playersSpeedBoost, player);
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function defaultMapGetPlayer<V, A extends unknown[]>(
|
|
24
|
+
map: DefaultMap<PlayerIndex, V, A>,
|
|
25
|
+
player: EntityPlayer,
|
|
26
|
+
...extraArgs: A
|
|
27
|
+
): V {
|
|
28
|
+
const playerIndex = getPlayerIndex(player);
|
|
29
|
+
return map.getAndSetDefault(playerIndex, ...extraArgs);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Helper function to make using maps with an index of `PlayerIndex` easier. Use this instead of the
|
|
34
|
+
* `Map.set` method if you have a map of this type.
|
|
35
|
+
*
|
|
36
|
+
* Since `Map` and `DefaultMap` set values in the same way, this function is simply an alias for the
|
|
37
|
+
* `mapSetPlayer` helper function.
|
|
38
|
+
*/
|
|
39
|
+
export function defaultMapSetPlayer<V>(
|
|
40
|
+
map: Map<PlayerIndex, V>,
|
|
41
|
+
player: EntityPlayer,
|
|
42
|
+
value: V,
|
|
43
|
+
): void {
|
|
44
|
+
mapSetPlayer(map, player, value);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Helper function to make using maps with an index of `PlayerIndex` easier. Use this instead of the
|
|
49
|
+
* `Map.get` method if you have a map of this type.
|
|
50
|
+
*
|
|
51
|
+
* For example:
|
|
52
|
+
*
|
|
53
|
+
* ```ts
|
|
54
|
+
* const v = {
|
|
55
|
+
* run: {
|
|
56
|
+
* playersSpeedBoost: new Map<PlayerIndex, int>(),
|
|
57
|
+
* },
|
|
58
|
+
* };
|
|
59
|
+
*
|
|
60
|
+
* function incrementSpeedBoost(player: EntityPlayer) {
|
|
61
|
+
* const oldSpeedBoost = mapGetPlayer(v.run.playersSpeedBoost, player);
|
|
62
|
+
* const newSpeedBoost = oldSpeedBoost + 0.1;
|
|
63
|
+
* mapSetPlayer(v.run.playersSpeedBoost, player);
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export function mapGetPlayer<V>(
|
|
68
|
+
map: Map<PlayerIndex, V>,
|
|
69
|
+
player: EntityPlayer,
|
|
70
|
+
): V | undefined {
|
|
71
|
+
const playerIndex = getPlayerIndex(player);
|
|
72
|
+
return map.get(playerIndex);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Helper function to make using maps with an index of `PlayerIndex` easier. Use this instead of the
|
|
77
|
+
* `Map.has` method if you have a map of this type.
|
|
78
|
+
*/
|
|
79
|
+
export function mapHasPlayer<V>(
|
|
80
|
+
map: Map<PlayerIndex, V>,
|
|
81
|
+
player: EntityPlayer,
|
|
82
|
+
): boolean {
|
|
83
|
+
const playerIndex = getPlayerIndex(player);
|
|
84
|
+
return map.has(playerIndex);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Helper function to make using maps with an index of `PlayerIndex` easier. Use this instead of the
|
|
89
|
+
* `Map.set` method if you have a map of this type.
|
|
90
|
+
*
|
|
91
|
+
* For example:
|
|
92
|
+
*
|
|
93
|
+
* ```ts
|
|
94
|
+
* const v = {
|
|
95
|
+
* run: {
|
|
96
|
+
* playersSpeedBoost: new Map<PlayerIndex, int>(),
|
|
97
|
+
* },
|
|
98
|
+
* };
|
|
99
|
+
*
|
|
100
|
+
* function incrementSpeedBoost(player: EntityPlayer) {
|
|
101
|
+
* const oldSpeedBoost = mapGetPlayer(v.run.playersSpeedBoost, player);
|
|
102
|
+
* const newSpeedBoost = oldSpeedBoost + 0.1;
|
|
103
|
+
* mapSetPlayer(v.run.playersSpeedBoost, player);
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export function mapSetPlayer<V>(
|
|
108
|
+
map: Map<PlayerIndex, V>,
|
|
109
|
+
player: EntityPlayer,
|
|
110
|
+
value: V,
|
|
111
|
+
): void {
|
|
112
|
+
const playerIndex = getPlayerIndex(player);
|
|
113
|
+
map.set(playerIndex, value);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Helper function to make using sets with an type of `PlayerIndex` easier. Use this instead of the
|
|
118
|
+
* `Set.add` method if you have a set of this type.
|
|
119
|
+
*/
|
|
120
|
+
export function setAddPlayer(
|
|
121
|
+
set: Set<PlayerIndex>,
|
|
122
|
+
player: EntityPlayer,
|
|
123
|
+
): Set<PlayerIndex> {
|
|
124
|
+
const playerIndex = getPlayerIndex(player);
|
|
125
|
+
return set.add(playerIndex);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Helper function to make using sets with an type of `PlayerIndex` easier. Use this instead of the
|
|
130
|
+
* `Set.delete` method if you have a set of this type.
|
|
131
|
+
*/
|
|
132
|
+
export function setDeletePlayer(
|
|
133
|
+
set: Set<PlayerIndex>,
|
|
134
|
+
player: EntityPlayer,
|
|
135
|
+
): boolean {
|
|
136
|
+
const playerIndex = getPlayerIndex(player);
|
|
137
|
+
return set.delete(playerIndex);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Helper function to make using sets with an type of `PlayerIndex` easier. Use this instead of the
|
|
142
|
+
* `Set.has` method if you have a set of this type.
|
|
143
|
+
*/
|
|
144
|
+
export function setHasPlayer(
|
|
145
|
+
set: Set<PlayerIndex>,
|
|
146
|
+
player: EntityPlayer,
|
|
147
|
+
): boolean {
|
|
148
|
+
const playerIndex = getPlayerIndex(player);
|
|
149
|
+
return set.has(playerIndex);
|
|
150
|
+
}
|
|
@@ -22,7 +22,6 @@ local getPlayerSoulHearts = ____player.getPlayerSoulHearts
|
|
|
22
22
|
local isCharacter = ____player.isCharacter
|
|
23
23
|
local setActiveItem = ____player.setActiveItem
|
|
24
24
|
local ____utils = require("functions.utils")
|
|
25
|
-
local ensureAllCases = ____utils.ensureAllCases
|
|
26
25
|
local ____repeat = ____utils["repeat"]
|
|
27
26
|
function ____exports.removeAllPlayerHealth(self, player)
|
|
28
27
|
local goldenHearts = player:GetGoldenHearts()
|
|
@@ -126,68 +125,63 @@ function ____exports.addPlayerHealthType(self, player, healthType, numHearts)
|
|
|
126
125
|
if ____cond3 then
|
|
127
126
|
do
|
|
128
127
|
player:AddHearts(numHearts)
|
|
129
|
-
|
|
128
|
+
break
|
|
130
129
|
end
|
|
131
130
|
end
|
|
132
131
|
____cond3 = ____cond3 or ____switch3 == HealthType.SOUL
|
|
133
132
|
if ____cond3 then
|
|
134
133
|
do
|
|
135
134
|
player:AddSoulHearts(numHearts)
|
|
136
|
-
|
|
135
|
+
break
|
|
137
136
|
end
|
|
138
137
|
end
|
|
139
138
|
____cond3 = ____cond3 or ____switch3 == HealthType.ETERNAL
|
|
140
139
|
if ____cond3 then
|
|
141
140
|
do
|
|
142
141
|
player:AddEternalHearts(numHearts)
|
|
143
|
-
|
|
142
|
+
break
|
|
144
143
|
end
|
|
145
144
|
end
|
|
146
145
|
____cond3 = ____cond3 or ____switch3 == HealthType.BLACK
|
|
147
146
|
if ____cond3 then
|
|
148
147
|
do
|
|
149
148
|
player:AddBlackHearts(numHearts)
|
|
150
|
-
|
|
149
|
+
break
|
|
151
150
|
end
|
|
152
151
|
end
|
|
153
152
|
____cond3 = ____cond3 or ____switch3 == HealthType.GOLDEN
|
|
154
153
|
if ____cond3 then
|
|
155
154
|
do
|
|
156
155
|
player:AddGoldenHearts(numHearts)
|
|
157
|
-
|
|
156
|
+
break
|
|
158
157
|
end
|
|
159
158
|
end
|
|
160
159
|
____cond3 = ____cond3 or ____switch3 == HealthType.BONE
|
|
161
160
|
if ____cond3 then
|
|
162
161
|
do
|
|
163
162
|
player:AddBoneHearts(numHearts)
|
|
164
|
-
|
|
163
|
+
break
|
|
165
164
|
end
|
|
166
165
|
end
|
|
167
166
|
____cond3 = ____cond3 or ____switch3 == HealthType.ROTTEN
|
|
168
167
|
if ____cond3 then
|
|
169
168
|
do
|
|
170
169
|
player:AddRottenHearts(numHearts)
|
|
171
|
-
|
|
170
|
+
break
|
|
172
171
|
end
|
|
173
172
|
end
|
|
174
173
|
____cond3 = ____cond3 or ____switch3 == HealthType.BROKEN
|
|
175
174
|
if ____cond3 then
|
|
176
175
|
do
|
|
177
176
|
player:AddBrokenHearts(numHearts)
|
|
178
|
-
|
|
177
|
+
break
|
|
179
178
|
end
|
|
180
179
|
end
|
|
181
180
|
____cond3 = ____cond3 or ____switch3 == HealthType.MAX_HEARTS
|
|
182
181
|
if ____cond3 then
|
|
183
182
|
do
|
|
184
183
|
player:AddMaxHearts(numHearts, false)
|
|
185
|
-
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
do
|
|
189
|
-
do
|
|
190
|
-
ensureAllCases(nil, healthType)
|
|
184
|
+
break
|
|
191
185
|
end
|
|
192
186
|
end
|
|
193
187
|
until true
|
|
@@ -261,66 +255,61 @@ function ____exports.getPlayerHealth(self, player)
|
|
|
261
255
|
end
|
|
262
256
|
function ____exports.getPlayerHealthType(self, player, healthType)
|
|
263
257
|
repeat
|
|
264
|
-
local
|
|
265
|
-
local
|
|
266
|
-
if
|
|
258
|
+
local ____switch24 = healthType
|
|
259
|
+
local ____cond24 = ____switch24 == HealthType.RED
|
|
260
|
+
if ____cond24 then
|
|
267
261
|
do
|
|
268
262
|
return getPlayerHearts(nil, player)
|
|
269
263
|
end
|
|
270
264
|
end
|
|
271
|
-
|
|
272
|
-
if
|
|
265
|
+
____cond24 = ____cond24 or ____switch24 == HealthType.SOUL
|
|
266
|
+
if ____cond24 then
|
|
273
267
|
do
|
|
274
268
|
return getPlayerSoulHearts(nil, player)
|
|
275
269
|
end
|
|
276
270
|
end
|
|
277
|
-
|
|
278
|
-
if
|
|
271
|
+
____cond24 = ____cond24 or ____switch24 == HealthType.ETERNAL
|
|
272
|
+
if ____cond24 then
|
|
279
273
|
do
|
|
280
274
|
return player:GetEternalHearts()
|
|
281
275
|
end
|
|
282
276
|
end
|
|
283
|
-
|
|
284
|
-
if
|
|
277
|
+
____cond24 = ____cond24 or ____switch24 == HealthType.BLACK
|
|
278
|
+
if ____cond24 then
|
|
285
279
|
do
|
|
286
280
|
return getPlayerBlackHearts(nil, player)
|
|
287
281
|
end
|
|
288
282
|
end
|
|
289
|
-
|
|
290
|
-
if
|
|
283
|
+
____cond24 = ____cond24 or ____switch24 == HealthType.GOLDEN
|
|
284
|
+
if ____cond24 then
|
|
291
285
|
do
|
|
292
286
|
return player:GetGoldenHearts()
|
|
293
287
|
end
|
|
294
288
|
end
|
|
295
|
-
|
|
296
|
-
if
|
|
289
|
+
____cond24 = ____cond24 or ____switch24 == HealthType.BONE
|
|
290
|
+
if ____cond24 then
|
|
297
291
|
do
|
|
298
292
|
return player:GetBoneHearts()
|
|
299
293
|
end
|
|
300
294
|
end
|
|
301
|
-
|
|
302
|
-
if
|
|
295
|
+
____cond24 = ____cond24 or ____switch24 == HealthType.ROTTEN
|
|
296
|
+
if ____cond24 then
|
|
303
297
|
do
|
|
304
298
|
return player:GetRottenHearts()
|
|
305
299
|
end
|
|
306
300
|
end
|
|
307
|
-
|
|
308
|
-
if
|
|
301
|
+
____cond24 = ____cond24 or ____switch24 == HealthType.BROKEN
|
|
302
|
+
if ____cond24 then
|
|
309
303
|
do
|
|
310
304
|
return player:GetBrokenHearts()
|
|
311
305
|
end
|
|
312
306
|
end
|
|
313
|
-
|
|
314
|
-
if
|
|
307
|
+
____cond24 = ____cond24 or ____switch24 == HealthType.MAX_HEARTS
|
|
308
|
+
if ____cond24 then
|
|
315
309
|
do
|
|
316
310
|
return player:GetMaxHearts()
|
|
317
311
|
end
|
|
318
312
|
end
|
|
319
|
-
do
|
|
320
|
-
do
|
|
321
|
-
return ensureAllCases(nil, healthType)
|
|
322
|
-
end
|
|
323
|
-
end
|
|
324
313
|
until true
|
|
325
314
|
end
|
|
326
315
|
--- Returns a `PlayerHealth` object with all 0s.
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ActiveSlot,
|
|
3
|
+
CollectibleType,
|
|
4
|
+
HeartSubType,
|
|
5
|
+
PlayerType,
|
|
6
|
+
} from "isaac-typescript-definitions";
|
|
7
|
+
import { MAX_PLAYER_HEART_CONTAINERS } from "../constants";
|
|
8
|
+
import { HealthType } from "../enums/HealthType";
|
|
9
|
+
import { PlayerHealth } from "../interfaces/PlayerHealth";
|
|
10
|
+
import { getTotalCharge } from "./charge";
|
|
11
|
+
import { getEnumValues } from "./enums";
|
|
12
|
+
import {
|
|
13
|
+
getPlayerBlackHearts,
|
|
14
|
+
getPlayerHearts,
|
|
15
|
+
getPlayerSoulHearts,
|
|
16
|
+
isCharacter,
|
|
17
|
+
setActiveItem,
|
|
18
|
+
} from "./player";
|
|
19
|
+
import { repeat } from "./utils";
|
|
20
|
+
|
|
21
|
+
export function addPlayerHealthType(
|
|
22
|
+
player: EntityPlayer,
|
|
23
|
+
healthType: HealthType,
|
|
24
|
+
numHearts: int,
|
|
25
|
+
): void {
|
|
26
|
+
switch (healthType) {
|
|
27
|
+
case HealthType.RED: {
|
|
28
|
+
player.AddHearts(numHearts);
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
case HealthType.SOUL: {
|
|
33
|
+
player.AddSoulHearts(numHearts);
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
case HealthType.ETERNAL: {
|
|
38
|
+
player.AddEternalHearts(numHearts);
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
case HealthType.BLACK: {
|
|
43
|
+
player.AddBlackHearts(numHearts);
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
case HealthType.GOLDEN: {
|
|
48
|
+
player.AddGoldenHearts(numHearts);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
case HealthType.BONE: {
|
|
53
|
+
player.AddBoneHearts(numHearts);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
case HealthType.ROTTEN: {
|
|
58
|
+
player.AddRottenHearts(numHearts);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
case HealthType.BROKEN: {
|
|
63
|
+
player.AddBrokenHearts(numHearts);
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
case HealthType.MAX_HEARTS: {
|
|
68
|
+
player.AddMaxHearts(numHearts, false);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Helper function to get an object representing the player's health. You can use this in
|
|
76
|
+
* combination with the `setPlayerHealth` function to restore the player's health back to a certain
|
|
77
|
+
* configuration at a later time.
|
|
78
|
+
*
|
|
79
|
+
* This is based on the `REVEL.StoreHealth` function in the Revelations mod.
|
|
80
|
+
*/
|
|
81
|
+
export function getPlayerHealth(player: EntityPlayer): PlayerHealth {
|
|
82
|
+
const character = player.GetPlayerType();
|
|
83
|
+
const soulHeartTypes: HeartSubType[] = [];
|
|
84
|
+
let maxHearts = player.GetMaxHearts();
|
|
85
|
+
let hearts = getPlayerHearts(player); // We use the helper function to remove rotten hearts
|
|
86
|
+
let soulHearts = player.GetSoulHearts();
|
|
87
|
+
let boneHearts = player.GetBoneHearts();
|
|
88
|
+
const goldenHearts = player.GetGoldenHearts();
|
|
89
|
+
const eternalHearts = player.GetEternalHearts();
|
|
90
|
+
const rottenHearts = player.GetRottenHearts();
|
|
91
|
+
const brokenHearts = player.GetBrokenHearts();
|
|
92
|
+
const subPlayer = player.GetSubPlayer();
|
|
93
|
+
const soulCharges = player.GetEffectiveSoulCharge();
|
|
94
|
+
const bloodCharges = player.GetEffectiveBloodCharge();
|
|
95
|
+
|
|
96
|
+
// The Forgotten and The Soul has special health, so we need to account for this.
|
|
97
|
+
if (character === PlayerType.THE_FORGOTTEN && subPlayer !== undefined) {
|
|
98
|
+
// The Forgotten does not have red heart containers.
|
|
99
|
+
maxHearts = boneHearts * 2;
|
|
100
|
+
boneHearts = 0;
|
|
101
|
+
|
|
102
|
+
// The Forgotten will always have 0 soul hearts; we need to get the soul heart amount from the
|
|
103
|
+
// sub player.
|
|
104
|
+
soulHearts = subPlayer.GetSoulHearts();
|
|
105
|
+
} else if (character === PlayerType.THE_SOUL && subPlayer !== undefined) {
|
|
106
|
+
// The Soul will always have 0 bone hearts; we need to get the bone heart amount from the sub
|
|
107
|
+
// player. We need to store it as "maxHearts" instead of "boneHearts".
|
|
108
|
+
maxHearts = subPlayer.GetBoneHearts() * 2;
|
|
109
|
+
hearts = subPlayer.GetHearts();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// This is the number of individual hearts shown in the HUD, minus heart containers.
|
|
113
|
+
const extraHearts = math.ceil(soulHearts / 2) + boneHearts;
|
|
114
|
+
|
|
115
|
+
// Since bone hearts can be inserted anywhere between soul hearts, we need a separate counter to
|
|
116
|
+
// track which soul heart we're currently at.
|
|
117
|
+
let currentSoulHeart = 0;
|
|
118
|
+
|
|
119
|
+
for (let i = 0; i < extraHearts; i++) {
|
|
120
|
+
let isBoneHeart = player.IsBoneHeart(i);
|
|
121
|
+
if (character === PlayerType.THE_FORGOTTEN && subPlayer !== undefined) {
|
|
122
|
+
isBoneHeart = subPlayer.IsBoneHeart(i);
|
|
123
|
+
}
|
|
124
|
+
if (isBoneHeart) {
|
|
125
|
+
soulHeartTypes.push(HeartSubType.BONE);
|
|
126
|
+
} else {
|
|
127
|
+
// We need to add 1 here because only the second half of a black heart is considered black.
|
|
128
|
+
let isBlackHeart = player.IsBlackHeart(currentSoulHeart + 1);
|
|
129
|
+
if (character === PlayerType.THE_FORGOTTEN && subPlayer !== undefined) {
|
|
130
|
+
isBlackHeart = subPlayer.IsBlackHeart(currentSoulHeart + 1);
|
|
131
|
+
}
|
|
132
|
+
if (isBlackHeart) {
|
|
133
|
+
soulHeartTypes.push(HeartSubType.BLACK);
|
|
134
|
+
} else {
|
|
135
|
+
soulHeartTypes.push(HeartSubType.SOUL);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Move to the next heart.
|
|
139
|
+
currentSoulHeart += 2;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
maxHearts,
|
|
145
|
+
hearts,
|
|
146
|
+
eternalHearts,
|
|
147
|
+
soulHearts,
|
|
148
|
+
boneHearts,
|
|
149
|
+
goldenHearts,
|
|
150
|
+
rottenHearts,
|
|
151
|
+
brokenHearts,
|
|
152
|
+
soulCharges,
|
|
153
|
+
bloodCharges,
|
|
154
|
+
soulHeartTypes,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function getPlayerHealthType(
|
|
159
|
+
player: EntityPlayer,
|
|
160
|
+
healthType: HealthType,
|
|
161
|
+
): int {
|
|
162
|
+
switch (healthType) {
|
|
163
|
+
// 5.10.1
|
|
164
|
+
case HealthType.RED: {
|
|
165
|
+
// We use the standard library helper function since the `EntityPlayer.GetHearts` method
|
|
166
|
+
// returns a value that includes rotten hearts.
|
|
167
|
+
return getPlayerHearts(player);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// 5.10.3
|
|
171
|
+
case HealthType.SOUL: {
|
|
172
|
+
// We use the standard library helper function since the `EntityPlayer.GetSoulHearts` method
|
|
173
|
+
// returns a value that includes black hearts.
|
|
174
|
+
return getPlayerSoulHearts(player);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 5.10.4
|
|
178
|
+
case HealthType.ETERNAL: {
|
|
179
|
+
return player.GetEternalHearts();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// 5.10.6
|
|
183
|
+
case HealthType.BLACK: {
|
|
184
|
+
// We use the standard library helper function since the `EntityPlayer.GetBlackHearts` method
|
|
185
|
+
// returns a bit mask.
|
|
186
|
+
return getPlayerBlackHearts(player);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 5.10.7
|
|
190
|
+
case HealthType.GOLDEN: {
|
|
191
|
+
return player.GetGoldenHearts();
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// 5.10.11
|
|
195
|
+
case HealthType.BONE: {
|
|
196
|
+
return player.GetBoneHearts();
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// 5.10.12
|
|
200
|
+
case HealthType.ROTTEN: {
|
|
201
|
+
return player.GetRottenHearts();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
case HealthType.BROKEN: {
|
|
205
|
+
return player.GetBrokenHearts();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
case HealthType.MAX_HEARTS: {
|
|
209
|
+
return player.GetMaxHearts();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** Returns a `PlayerHealth` object with all 0s. */
|
|
215
|
+
export function newPlayerHealth(): PlayerHealth {
|
|
216
|
+
return {
|
|
217
|
+
maxHearts: 0,
|
|
218
|
+
hearts: 0,
|
|
219
|
+
eternalHearts: 0,
|
|
220
|
+
soulHearts: 0,
|
|
221
|
+
boneHearts: 0,
|
|
222
|
+
goldenHearts: 0,
|
|
223
|
+
rottenHearts: 0,
|
|
224
|
+
brokenHearts: 0,
|
|
225
|
+
soulCharges: 0,
|
|
226
|
+
bloodCharges: 0,
|
|
227
|
+
soulHeartTypes: [],
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export function playerConvertBlackHeartsToSoulHearts(
|
|
232
|
+
player: EntityPlayer,
|
|
233
|
+
): void {
|
|
234
|
+
const playerHealth = getPlayerHealth(player);
|
|
235
|
+
removeAllPlayerHealth(player);
|
|
236
|
+
playerHealth.soulHeartTypes = playerHealth.soulHeartTypes.map(
|
|
237
|
+
(soulHeartType) =>
|
|
238
|
+
soulHeartType === HeartSubType.BLACK ? HeartSubType.SOUL : soulHeartType,
|
|
239
|
+
);
|
|
240
|
+
setPlayerHealth(player, playerHealth);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export function playerConvertSoulHeartsToBlackHearts(
|
|
244
|
+
player: EntityPlayer,
|
|
245
|
+
): void {
|
|
246
|
+
const playerHealth = getPlayerHealth(player);
|
|
247
|
+
removeAllPlayerHealth(player);
|
|
248
|
+
playerHealth.soulHeartTypes = playerHealth.soulHeartTypes.map(
|
|
249
|
+
(soulHeartType) =>
|
|
250
|
+
soulHeartType === HeartSubType.SOUL ? HeartSubType.BLACK : soulHeartType,
|
|
251
|
+
);
|
|
252
|
+
setPlayerHealth(player, playerHealth);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export function removeAllPlayerHealth(player: EntityPlayer): void {
|
|
256
|
+
const goldenHearts = player.GetGoldenHearts();
|
|
257
|
+
const eternalHearts = player.GetEternalHearts();
|
|
258
|
+
const boneHearts = player.GetBoneHearts();
|
|
259
|
+
const brokenHearts = player.GetBrokenHearts();
|
|
260
|
+
|
|
261
|
+
// To avoid bugs, we have to remove the exact amount of certain types of hearts. We remove Golden
|
|
262
|
+
// Hearts first so that they don't break.
|
|
263
|
+
player.AddGoldenHearts(goldenHearts * -1);
|
|
264
|
+
player.AddEternalHearts(eternalHearts * -1);
|
|
265
|
+
player.AddBoneHearts(boneHearts * -1);
|
|
266
|
+
player.AddBrokenHearts(brokenHearts * -1);
|
|
267
|
+
player.AddMaxHearts(MAX_PLAYER_HEART_CONTAINERS * -2, true);
|
|
268
|
+
player.AddSoulHearts(MAX_PLAYER_HEART_CONTAINERS * -2);
|
|
269
|
+
|
|
270
|
+
// If we are The Soul, the `EntityPlayer.AddBoneHearts` method will not remove Forgotten's bone
|
|
271
|
+
// hearts, so we need to explicitly handle this.
|
|
272
|
+
if (isCharacter(player, PlayerType.THE_SOUL)) {
|
|
273
|
+
const forgotten = player.GetSubPlayer();
|
|
274
|
+
if (forgotten !== undefined) {
|
|
275
|
+
const forgottenBoneHearts = forgotten.GetBoneHearts();
|
|
276
|
+
forgotten.AddBoneHearts(forgottenBoneHearts * -1);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Helper function to set a player's health to a specific state. You can use this in combination
|
|
283
|
+
* with the `getPlayerHealth` function to restore the player's health back to a certain
|
|
284
|
+
* configuration at a later time.
|
|
285
|
+
*
|
|
286
|
+
* Based on the `REVEL.LoadHealth` function in the Revelations mod.
|
|
287
|
+
*/
|
|
288
|
+
export function setPlayerHealth(
|
|
289
|
+
player: EntityPlayer,
|
|
290
|
+
playerHealth: PlayerHealth,
|
|
291
|
+
): void {
|
|
292
|
+
const character = player.GetPlayerType();
|
|
293
|
+
const subPlayer = player.GetSubPlayer();
|
|
294
|
+
|
|
295
|
+
removeAllPlayerHealth(player);
|
|
296
|
+
|
|
297
|
+
// Before we add any health, we have to take away Alabaster Box, if present.
|
|
298
|
+
const alabasterBoxes: Array<[slot: ActiveSlot, totalCharge: int]> = [];
|
|
299
|
+
if (player.HasCollectible(CollectibleType.ALABASTER_BOX)) {
|
|
300
|
+
for (const activeSlot of getEnumValues(ActiveSlot)) {
|
|
301
|
+
const activeItem = player.GetActiveItem();
|
|
302
|
+
if (activeItem === CollectibleType.ALABASTER_BOX) {
|
|
303
|
+
const totalCharge = getTotalCharge(player, activeSlot);
|
|
304
|
+
setActiveItem(player, CollectibleType.NULL, activeSlot);
|
|
305
|
+
alabasterBoxes.push([activeSlot, totalCharge]);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Add the red heart containers.
|
|
311
|
+
if (character === PlayerType.THE_SOUL && subPlayer !== undefined) {
|
|
312
|
+
// Adding health to The Soul is a special case.
|
|
313
|
+
subPlayer.AddMaxHearts(playerHealth.maxHearts, false);
|
|
314
|
+
} else {
|
|
315
|
+
player.AddMaxHearts(playerHealth.maxHearts, false);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Add the eternal hearts.
|
|
319
|
+
player.AddEternalHearts(playerHealth.eternalHearts);
|
|
320
|
+
|
|
321
|
+
// Add the soul / black / bone hearts.
|
|
322
|
+
let soulHeartsRemaining = playerHealth.soulHearts;
|
|
323
|
+
playerHealth.soulHeartTypes.forEach((heartType, i) => {
|
|
324
|
+
const isHalf =
|
|
325
|
+
playerHealth.soulHearts + playerHealth.boneHearts * 2 < (i + 1) * 2;
|
|
326
|
+
let addAmount = 2;
|
|
327
|
+
if (isHalf || heartType === HeartSubType.BONE || soulHeartsRemaining < 2) {
|
|
328
|
+
// Fix the bug where a half soul heart to the left of a bone heart will be treated as a full
|
|
329
|
+
// soul heart.
|
|
330
|
+
addAmount = 1;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (heartType === HeartSubType.SOUL) {
|
|
334
|
+
player.AddSoulHearts(addAmount);
|
|
335
|
+
soulHeartsRemaining -= addAmount;
|
|
336
|
+
} else if (heartType === HeartSubType.BLACK) {
|
|
337
|
+
player.AddBlackHearts(addAmount);
|
|
338
|
+
soulHeartsRemaining -= addAmount;
|
|
339
|
+
} else if (heartType === HeartSubType.BONE) {
|
|
340
|
+
player.AddBoneHearts(addAmount);
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Fill in the red heart containers.
|
|
346
|
+
*
|
|
347
|
+
* (Rotten Hearts must be filled in first in order for this to work properly, since they conflict
|
|
348
|
+
* with half red hearts.)
|
|
349
|
+
*
|
|
350
|
+
* The `EntityPlayer.AddRottenHearts` method is not like actually picking up a rotten heart, since
|
|
351
|
+
* it will only grant one rotten heart to Tainted Magdalene (whereas picking up a rotten heart
|
|
352
|
+
* would grant two).
|
|
353
|
+
*/
|
|
354
|
+
player.AddRottenHearts(playerHealth.rottenHearts);
|
|
355
|
+
repeat(playerHealth.hearts, () => {
|
|
356
|
+
player.AddHearts(1);
|
|
357
|
+
|
|
358
|
+
// Adding 1 heart to Tainted Magdalene will actually add two hearts.
|
|
359
|
+
if (character === PlayerType.MAGDALENE_B) {
|
|
360
|
+
player.AddHearts(-1);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
player.AddGoldenHearts(playerHealth.goldenHearts);
|
|
364
|
+
player.AddBrokenHearts(playerHealth.brokenHearts);
|
|
365
|
+
|
|
366
|
+
// Set the Bethany / Tainted Bethany charges.
|
|
367
|
+
if (character === PlayerType.BETHANY) {
|
|
368
|
+
player.SetSoulCharge(playerHealth.soulCharges);
|
|
369
|
+
} else if (character === PlayerType.BETHANY_B) {
|
|
370
|
+
player.SetBloodCharge(playerHealth.bloodCharges);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Re-add the Alabaster Box, if present.
|
|
374
|
+
for (const [activeSlot, totalCharge] of alabasterBoxes) {
|
|
375
|
+
setActiveItem(
|
|
376
|
+
player,
|
|
377
|
+
CollectibleType.ALABASTER_BOX,
|
|
378
|
+
activeSlot,
|
|
379
|
+
totalCharge,
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
}
|