isaacscript-common 20.4.0 → 20.4.1

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/dist/index.d.ts CHANGED
@@ -3123,12 +3123,6 @@ export declare function deserializeRNG(rng: SerializedRNG): RNG;
3123
3123
  */
3124
3124
  export declare function deserializeVector(vector: SerializedVector): Vector;
3125
3125
 
3126
- declare type DespawnedSlotTuple = [
3127
- gameFrame: int,
3128
- position: Vector,
3129
- entityPtr: EntityPtr
3130
- ];
3131
-
3132
3126
  /** For `EntityType.EFFECT` (1000), `EffectVariant.DICE_FLOOR` (76). */
3133
3127
  export declare const DICE_FLOOR_TRIGGER_SQUARE_SIZE = 75;
3134
3128
 
@@ -10211,8 +10205,34 @@ export declare enum ModCallbackCustom {
10211
10205
  */
10212
10206
  POST_SLOT_COLLISION = 87,
10213
10207
  /**
10214
- * Fires from the `POST_RENDER` callback when a slot plays the animation that indicates that it
10215
- * has broken.
10208
+ * Fires from the `POST_SLOT_UPDATE` or the `POST_ENTITY_REMOVE` callback when a slot machine is
10209
+ * destroyed or a beggar is removed.
10210
+ *
10211
+ * This callback will fire in four different kinds of situations:
10212
+ *
10213
+ * 1. When slot machine entities (e.g. `SlotVariant.SLOT_MACHINE` and
10214
+ * `SlotVariant.BLOOD_DONATION_MACHINE`) are destroyed with an explosion. When this happens,
10215
+ * they typically stay in the room and can be pushed around. This state is detected via a
10216
+ * change in the `GridCollisionClass`.
10217
+ * 2. When slot machine entities pay out with a collectible item. When this happens, they
10218
+ * immediately despawn without playing any special animation.
10219
+ * 3. When beggars are destroyed with an explosion. When this happens, they immediately despawn
10220
+ * without playing any special animation.
10221
+ * 4. When beggars pay out with a collectible item. When this happens, they despawn after playing
10222
+ * the "Teleport" animation. (This is not technically a "destruction" event, but the callback
10223
+ * will fire for this to remain consistent with the other types of slot entities.)
10224
+ *
10225
+ * Depending on the specific types of slot removal that you need to detect, you can filter using:
10226
+ *
10227
+ * 1. The `isSlotMachine` helper function to differentiate between slot machines and beggars.
10228
+ * 2. The passed callback argument of `SlotDestructionType` to differentiate between bombed slots
10229
+ * and slots that paid out with a collectible item.
10230
+ *
10231
+ * Note that when a Crane Game explodes after paying out three collectibles, the
10232
+ * `SlotDestructionType` will be equal to `SlotDestructionType.NORMAL` instead of
10233
+ * `SlotDestructionType.COLLECTIBLE_PAYOUT` like you might expect. (This is because it only
10234
+ * explodes after a short delay, and when doing so, it produces rewards in the same way that would
10235
+ * happen if you bombed it.)
10216
10236
  *
10217
10237
  * When registering the callback with the `ModUpgraded.AddCallbackCustom` method:
10218
10238
  * - You can provide an optional third argument that will make the callback only fire if it
@@ -14121,13 +14141,11 @@ declare class SlotDestroyedDetection extends Feature {
14121
14141
  v: {
14122
14142
  room: {
14123
14143
  destroyedSlotSet: Set<PtrHash>;
14124
- despawnedSlots: DespawnedSlotTuple[];
14125
14144
  };
14126
14145
  };
14127
14146
  private postSlotDestroyed;
14128
14147
  private roomHistory;
14129
14148
  constructor(postSlotDestroyed: PostSlotDestroyed, roomHistory: RoomHistory);
14130
- private postPickupInitCollectible;
14131
14149
  private postEntityRemoveSlot;
14132
14150
  private postEntityRemoveSlotMachine;
14133
14151
  private postEntityRemoveBeggar;
@@ -1,6 +1,6 @@
1
1
  --[[
2
2
 
3
- isaacscript-common 20.4.0
3
+ isaacscript-common 20.4.1
4
4
 
5
5
  This is the "isaacscript-common" library, which was created with the IsaacScript tool.
6
6
 
@@ -34209,17 +34209,12 @@ local ____isaac_2Dtypescript_2Ddefinitions = require("lua_modules.isaac-typescri
34209
34209
  local EntityGridCollisionClass = ____isaac_2Dtypescript_2Ddefinitions.EntityGridCollisionClass
34210
34210
  local EntityType = ____isaac_2Dtypescript_2Ddefinitions.EntityType
34211
34211
  local ModCallback = ____isaac_2Dtypescript_2Ddefinitions.ModCallback
34212
- local PickupVariant = ____isaac_2Dtypescript_2Ddefinitions.PickupVariant
34213
- local ____cachedClasses = require("src.core.cachedClasses")
34214
- local game = ____cachedClasses.game
34215
34212
  local ____ModCallbackCustom = require("src.enums.ModCallbackCustom")
34216
34213
  local ModCallbackCustom = ____ModCallbackCustom.ModCallbackCustom
34217
34214
  local ____SlotDestructionType = require("src.enums.SlotDestructionType")
34218
34215
  local SlotDestructionType = ____SlotDestructionType.SlotDestructionType
34219
34216
  local ____slots = require("src.functions.slots")
34220
34217
  local isSlotMachine = ____slots.isSlotMachine
34221
- local ____vector = require("src.functions.vector")
34222
- local vectorEquals = ____vector.vectorEquals
34223
34218
  local ____Feature = require("src.classes.private.Feature")
34224
34219
  local Feature = ____Feature.Feature
34225
34220
  ____exports.SlotDestroyedDetection = __TS__Class()
@@ -34228,23 +34223,7 @@ SlotDestroyedDetection.name = "SlotDestroyedDetection"
34228
34223
  __TS__ClassExtends(SlotDestroyedDetection, Feature)
34229
34224
  function SlotDestroyedDetection.prototype.____constructor(self, postSlotDestroyed, roomHistory)
34230
34225
  Feature.prototype.____constructor(self)
34231
- self.v = {room = {
34232
- destroyedSlotSet = __TS__New(Set),
34233
- despawnedSlots = {}
34234
- }}
34235
- self.postPickupInitCollectible = function(____, pickup)
34236
- local gameFrameCount = game:GetFrameCount()
34237
- for ____, despawnedSlotTuple in ipairs(self.v.room.despawnedSlots) do
34238
- local gameFrame, position, entityPtr = table.unpack(despawnedSlotTuple)
34239
- if gameFrame == gameFrameCount and vectorEquals(nil, position, pickup.Position) then
34240
- local entity = entityPtr.Ref
34241
- if entity ~= nil then
34242
- local slot = entity
34243
- self.postSlotDestroyed:fire(slot, SlotDestructionType.COLLECTIBLE_PAYOUT)
34244
- end
34245
- end
34246
- end
34247
- end
34226
+ self.v = {room = {destroyedSlotSet = __TS__New(Set)}}
34248
34227
  self.postEntityRemoveSlot = function(____, entity)
34249
34228
  local slot = entity
34250
34229
  if self.roomHistory:isLeavingRoom() then
@@ -34264,17 +34243,13 @@ function SlotDestroyedDetection.prototype.____constructor(self, postSlotDestroye
34264
34243
  end
34265
34244
  self:checkDestroyedFromCollisionClass(slot)
34266
34245
  end
34267
- self.callbacksUsed = {{ModCallback.POST_PICKUP_INIT, self.postPickupInitCollectible, {PickupVariant.COLLECTIBLE}}, {ModCallback.POST_ENTITY_REMOVE, self.postEntityRemoveSlot, {EntityType.SLOT}}}
34246
+ self.callbacksUsed = {{ModCallback.POST_ENTITY_REMOVE, self.postEntityRemoveSlot, {EntityType.SLOT}}}
34268
34247
  self.customCallbacksUsed = {{ModCallbackCustom.POST_SLOT_UPDATE, self.postSlotUpdate}}
34269
34248
  self.postSlotDestroyed = postSlotDestroyed
34270
34249
  self.roomHistory = roomHistory
34271
34250
  end
34272
34251
  function SlotDestroyedDetection.prototype.postEntityRemoveSlotMachine(self, slot)
34273
- local gameFrameCount = game:GetFrameCount()
34274
- local entityPtr = EntityPtr(slot)
34275
- local despawnedSlotTuple = {gameFrameCount, slot.Position, entityPtr}
34276
- local ____self_v_room_despawnedSlots_0 = self.v.room.despawnedSlots
34277
- ____self_v_room_despawnedSlots_0[#____self_v_room_despawnedSlots_0 + 1] = despawnedSlotTuple
34252
+ self.postSlotDestroyed:fire(slot, SlotDestructionType.COLLECTIBLE_PAYOUT)
34278
34253
  end
34279
34254
  function SlotDestroyedDetection.prototype.postEntityRemoveBeggar(self, slot)
34280
34255
  local sprite = slot:GetSprite()
@@ -1,25 +1,15 @@
1
- /// <reference types="isaac-typescript-definitions" />
2
- /// <reference types="isaac-typescript-definitions" />
3
- /// <reference types="isaac-typescript-definitions" />
4
1
  import { PostSlotDestroyed } from "../../callbacks/PostSlotDestroyed";
5
2
  import { Feature } from "../../private/Feature";
6
3
  import { RoomHistory } from "../other/RoomHistory";
7
- type DespawnedSlotTuple = [
8
- gameFrame: int,
9
- position: Vector,
10
- entityPtr: EntityPtr
11
- ];
12
4
  export declare class SlotDestroyedDetection extends Feature {
13
5
  v: {
14
6
  room: {
15
7
  destroyedSlotSet: Set<PtrHash>;
16
- despawnedSlots: DespawnedSlotTuple[];
17
8
  };
18
9
  };
19
10
  private postSlotDestroyed;
20
11
  private roomHistory;
21
12
  constructor(postSlotDestroyed: PostSlotDestroyed, roomHistory: RoomHistory);
22
- private postPickupInitCollectible;
23
13
  private postEntityRemoveSlot;
24
14
  private postEntityRemoveSlotMachine;
25
15
  private postEntityRemoveBeggar;
@@ -32,5 +22,4 @@ export declare class SlotDestroyedDetection extends Feature {
32
22
  */
33
23
  private checkDestroyedFromCollisionClass;
34
24
  }
35
- export {};
36
25
  //# sourceMappingURL=SlotDestroyedDetection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SlotDestroyedDetection.d.ts","sourceRoot":"","sources":["../../../../../src/classes/features/callbackLogic/SlotDestroyedDetection.ts"],"names":[],"mappings":";;;AA0BA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,KAAK,kBAAkB,GAAG;IACxB,SAAS,EAAE,GAAG;IACd,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,SAAS;CACrB,CAAC;AAEF,qBAAa,sBAAuB,SAAQ,OAAO;IACjC,CAAC;;;;;MAKf;IAEF,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,WAAW,CAAc;gBAErB,iBAAiB,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW;IA6B1E,OAAO,CAAC,yBAAyB,CAoB/B;IAIF,OAAO,CAAC,oBAAoB,CAc1B;IAEF,OAAO,CAAC,2BAA2B;IAWnC,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,cAAc,CASpB;IAEF;;;;;OAKG;IACH,OAAO,CAAC,gCAAgC;CAOzC"}
1
+ {"version":3,"file":"SlotDestroyedDetection.d.ts","sourceRoot":"","sources":["../../../../../src/classes/features/callbackLogic/SlotDestroyedDetection.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,qBAAa,sBAAuB,SAAQ,OAAO;IACjC,CAAC;;;;MAIf;IAEF,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,WAAW,CAAc;gBAErB,iBAAiB,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW;IAsB1E,OAAO,CAAC,oBAAoB,CAc1B;IAEF,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,cAAc,CASpB;IAEF;;;;;OAKG;IACH,OAAO,CAAC,gCAAgC;CAOzC"}
@@ -8,17 +8,12 @@ local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitio
8
8
  local EntityGridCollisionClass = ____isaac_2Dtypescript_2Ddefinitions.EntityGridCollisionClass
9
9
  local EntityType = ____isaac_2Dtypescript_2Ddefinitions.EntityType
10
10
  local ModCallback = ____isaac_2Dtypescript_2Ddefinitions.ModCallback
11
- local PickupVariant = ____isaac_2Dtypescript_2Ddefinitions.PickupVariant
12
- local ____cachedClasses = require("src.core.cachedClasses")
13
- local game = ____cachedClasses.game
14
11
  local ____ModCallbackCustom = require("src.enums.ModCallbackCustom")
15
12
  local ModCallbackCustom = ____ModCallbackCustom.ModCallbackCustom
16
13
  local ____SlotDestructionType = require("src.enums.SlotDestructionType")
17
14
  local SlotDestructionType = ____SlotDestructionType.SlotDestructionType
18
15
  local ____slots = require("src.functions.slots")
19
16
  local isSlotMachine = ____slots.isSlotMachine
20
- local ____vector = require("src.functions.vector")
21
- local vectorEquals = ____vector.vectorEquals
22
17
  local ____Feature = require("src.classes.private.Feature")
23
18
  local Feature = ____Feature.Feature
24
19
  ____exports.SlotDestroyedDetection = __TS__Class()
@@ -27,23 +22,7 @@ SlotDestroyedDetection.name = "SlotDestroyedDetection"
27
22
  __TS__ClassExtends(SlotDestroyedDetection, Feature)
28
23
  function SlotDestroyedDetection.prototype.____constructor(self, postSlotDestroyed, roomHistory)
29
24
  Feature.prototype.____constructor(self)
30
- self.v = {room = {
31
- destroyedSlotSet = __TS__New(Set),
32
- despawnedSlots = {}
33
- }}
34
- self.postPickupInitCollectible = function(____, pickup)
35
- local gameFrameCount = game:GetFrameCount()
36
- for ____, despawnedSlotTuple in ipairs(self.v.room.despawnedSlots) do
37
- local gameFrame, position, entityPtr = table.unpack(despawnedSlotTuple)
38
- if gameFrame == gameFrameCount and vectorEquals(nil, position, pickup.Position) then
39
- local entity = entityPtr.Ref
40
- if entity ~= nil then
41
- local slot = entity
42
- self.postSlotDestroyed:fire(slot, SlotDestructionType.COLLECTIBLE_PAYOUT)
43
- end
44
- end
45
- end
46
- end
25
+ self.v = {room = {destroyedSlotSet = __TS__New(Set)}}
47
26
  self.postEntityRemoveSlot = function(____, entity)
48
27
  local slot = entity
49
28
  if self.roomHistory:isLeavingRoom() then
@@ -63,17 +42,13 @@ function SlotDestroyedDetection.prototype.____constructor(self, postSlotDestroye
63
42
  end
64
43
  self:checkDestroyedFromCollisionClass(slot)
65
44
  end
66
- self.callbacksUsed = {{ModCallback.POST_PICKUP_INIT, self.postPickupInitCollectible, {PickupVariant.COLLECTIBLE}}, {ModCallback.POST_ENTITY_REMOVE, self.postEntityRemoveSlot, {EntityType.SLOT}}}
45
+ self.callbacksUsed = {{ModCallback.POST_ENTITY_REMOVE, self.postEntityRemoveSlot, {EntityType.SLOT}}}
67
46
  self.customCallbacksUsed = {{ModCallbackCustom.POST_SLOT_UPDATE, self.postSlotUpdate}}
68
47
  self.postSlotDestroyed = postSlotDestroyed
69
48
  self.roomHistory = roomHistory
70
49
  end
71
50
  function SlotDestroyedDetection.prototype.postEntityRemoveSlotMachine(self, slot)
72
- local gameFrameCount = game:GetFrameCount()
73
- local entityPtr = EntityPtr(slot)
74
- local despawnedSlotTuple = {gameFrameCount, slot.Position, entityPtr}
75
- local ____self_v_room_despawnedSlots_0 = self.v.room.despawnedSlots
76
- ____self_v_room_despawnedSlots_0[#____self_v_room_despawnedSlots_0 + 1] = despawnedSlotTuple
51
+ self.postSlotDestroyed:fire(slot, SlotDestructionType.COLLECTIBLE_PAYOUT)
77
52
  end
78
53
  function SlotDestroyedDetection.prototype.postEntityRemoveBeggar(self, slot)
79
54
  local sprite = slot:GetSprite()
@@ -1536,8 +1536,34 @@ export declare enum ModCallbackCustom {
1536
1536
  */
1537
1537
  POST_SLOT_COLLISION = 87,
1538
1538
  /**
1539
- * Fires from the `POST_RENDER` callback when a slot plays the animation that indicates that it
1540
- * has broken.
1539
+ * Fires from the `POST_SLOT_UPDATE` or the `POST_ENTITY_REMOVE` callback when a slot machine is
1540
+ * destroyed or a beggar is removed.
1541
+ *
1542
+ * This callback will fire in four different kinds of situations:
1543
+ *
1544
+ * 1. When slot machine entities (e.g. `SlotVariant.SLOT_MACHINE` and
1545
+ * `SlotVariant.BLOOD_DONATION_MACHINE`) are destroyed with an explosion. When this happens,
1546
+ * they typically stay in the room and can be pushed around. This state is detected via a
1547
+ * change in the `GridCollisionClass`.
1548
+ * 2. When slot machine entities pay out with a collectible item. When this happens, they
1549
+ * immediately despawn without playing any special animation.
1550
+ * 3. When beggars are destroyed with an explosion. When this happens, they immediately despawn
1551
+ * without playing any special animation.
1552
+ * 4. When beggars pay out with a collectible item. When this happens, they despawn after playing
1553
+ * the "Teleport" animation. (This is not technically a "destruction" event, but the callback
1554
+ * will fire for this to remain consistent with the other types of slot entities.)
1555
+ *
1556
+ * Depending on the specific types of slot removal that you need to detect, you can filter using:
1557
+ *
1558
+ * 1. The `isSlotMachine` helper function to differentiate between slot machines and beggars.
1559
+ * 2. The passed callback argument of `SlotDestructionType` to differentiate between bombed slots
1560
+ * and slots that paid out with a collectible item.
1561
+ *
1562
+ * Note that when a Crane Game explodes after paying out three collectibles, the
1563
+ * `SlotDestructionType` will be equal to `SlotDestructionType.NORMAL` instead of
1564
+ * `SlotDestructionType.COLLECTIBLE_PAYOUT` like you might expect. (This is because it only
1565
+ * explodes after a short delay, and when doing so, it produces rewards in the same way that would
1566
+ * happen if you bombed it.)
1541
1567
  *
1542
1568
  * When registering the callback with the `ModUpgraded.AddCallbackCustom` method:
1543
1569
  * - You can provide an optional third argument that will make the callback only fire if it
@@ -1 +1 @@
1
- {"version":3,"file":"ModCallbackCustom.d.ts","sourceRoot":"","sources":["../../../src/enums/ModCallbackCustom.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ModCallbackCustom.d.ts","sourceRoot":"","sources":["../../../src/enums/ModCallbackCustom.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isaacscript-common",
3
- "version": "20.4.0",
3
+ "version": "20.4.1",
4
4
  "description": "Helper functions and features for IsaacScript mods.",
5
5
  "keywords": [
6
6
  "isaac",
@@ -5,9 +5,7 @@
5
5
  // room.
6
6
 
7
7
  // 2) In the specific case of a machine spawning a collectible, the machine will be immediately
8
- // removed. The collectible will not have the `SpawnerEntity` or `Parent` in this case. Thus, we
9
- // store all despawning slots in an array and then cross reference the array when a new pickup
10
- // spawns.
8
+ // removed. Thus, we assume that any despawning slot machine is destroyed in this way.
11
9
 
12
10
  // For beggars, destruction is detected by monitoring for when a beggar despawns mid-room. Beggars
13
11
  // that are paying out with a collectible will always be playing the "Teleport" animation.
@@ -17,28 +15,18 @@ import {
17
15
  EntityGridCollisionClass,
18
16
  EntityType,
19
17
  ModCallback,
20
- PickupVariant,
21
18
  } from "isaac-typescript-definitions";
22
- import { game } from "../../../core/cachedClasses";
23
19
  import { ModCallbackCustom } from "../../../enums/ModCallbackCustom";
24
20
  import { SlotDestructionType } from "../../../enums/SlotDestructionType";
25
21
  import { isSlotMachine } from "../../../functions/slots";
26
- import { vectorEquals } from "../../../functions/vector";
27
22
  import { PostSlotDestroyed } from "../../callbacks/PostSlotDestroyed";
28
23
  import { Feature } from "../../private/Feature";
29
24
  import { RoomHistory } from "../other/RoomHistory";
30
25
 
31
- type DespawnedSlotTuple = [
32
- gameFrame: int,
33
- position: Vector,
34
- entityPtr: EntityPtr,
35
- ];
36
-
37
26
  export class SlotDestroyedDetection extends Feature {
38
27
  public override v = {
39
28
  room: {
40
29
  destroyedSlotSet: new Set<PtrHash>(),
41
- despawnedSlots: [] as DespawnedSlotTuple[],
42
30
  },
43
31
  };
44
32
 
@@ -49,13 +37,6 @@ export class SlotDestroyedDetection extends Feature {
49
37
  super();
50
38
 
51
39
  this.callbacksUsed = [
52
- // 34
53
- [
54
- ModCallback.POST_PICKUP_INIT,
55
- this.postPickupInitCollectible,
56
- [PickupVariant.COLLECTIBLE],
57
- ],
58
-
59
40
  // 67
60
41
  [
61
42
  ModCallback.POST_ENTITY_REMOVE,
@@ -72,30 +53,6 @@ export class SlotDestroyedDetection extends Feature {
72
53
  this.roomHistory = roomHistory;
73
54
  }
74
55
 
75
- // ModCallback.POST_PICKUP_INIT (34)
76
- // PickupVariant.COLLECTIBLE (100)
77
- private postPickupInitCollectible = (pickup: EntityPickup) => {
78
- const gameFrameCount = game.GetFrameCount();
79
-
80
- // Go through the despawning slots to see if they match this pickup.
81
- for (const despawnedSlotTuple of this.v.room.despawnedSlots) {
82
- const [gameFrame, position, entityPtr] = despawnedSlotTuple;
83
- if (
84
- gameFrame === gameFrameCount &&
85
- vectorEquals(position, pickup.Position)
86
- ) {
87
- const entity = entityPtr.Ref;
88
- if (entity !== undefined) {
89
- const slot = entity as EntitySlot;
90
- this.postSlotDestroyed.fire(
91
- slot,
92
- SlotDestructionType.COLLECTIBLE_PAYOUT,
93
- );
94
- }
95
- }
96
- }
97
- };
98
-
99
56
  // ModCallback.POST_ENTITY_REMOVE (67)
100
57
  // EntityType.SLOT (6)
101
58
  private postEntityRemoveSlot = (entity: Entity) => {
@@ -115,14 +72,7 @@ export class SlotDestroyedDetection extends Feature {
115
72
  };
116
73
 
117
74
  private postEntityRemoveSlotMachine(slot: EntitySlot) {
118
- const gameFrameCount = game.GetFrameCount();
119
- const entityPtr = EntityPtr(slot);
120
- const despawnedSlotTuple: DespawnedSlotTuple = [
121
- gameFrameCount,
122
- slot.Position,
123
- entityPtr,
124
- ];
125
- this.v.room.despawnedSlots.push(despawnedSlotTuple);
75
+ this.postSlotDestroyed.fire(slot, SlotDestructionType.COLLECTIBLE_PAYOUT);
126
76
  }
127
77
 
128
78
  private postEntityRemoveBeggar(slot: EntitySlot) {
@@ -1636,8 +1636,34 @@ export enum ModCallbackCustom {
1636
1636
  POST_SLOT_COLLISION,
1637
1637
 
1638
1638
  /**
1639
- * Fires from the `POST_RENDER` callback when a slot plays the animation that indicates that it
1640
- * has broken.
1639
+ * Fires from the `POST_SLOT_UPDATE` or the `POST_ENTITY_REMOVE` callback when a slot machine is
1640
+ * destroyed or a beggar is removed.
1641
+ *
1642
+ * This callback will fire in four different kinds of situations:
1643
+ *
1644
+ * 1. When slot machine entities (e.g. `SlotVariant.SLOT_MACHINE` and
1645
+ * `SlotVariant.BLOOD_DONATION_MACHINE`) are destroyed with an explosion. When this happens,
1646
+ * they typically stay in the room and can be pushed around. This state is detected via a
1647
+ * change in the `GridCollisionClass`.
1648
+ * 2. When slot machine entities pay out with a collectible item. When this happens, they
1649
+ * immediately despawn without playing any special animation.
1650
+ * 3. When beggars are destroyed with an explosion. When this happens, they immediately despawn
1651
+ * without playing any special animation.
1652
+ * 4. When beggars pay out with a collectible item. When this happens, they despawn after playing
1653
+ * the "Teleport" animation. (This is not technically a "destruction" event, but the callback
1654
+ * will fire for this to remain consistent with the other types of slot entities.)
1655
+ *
1656
+ * Depending on the specific types of slot removal that you need to detect, you can filter using:
1657
+ *
1658
+ * 1. The `isSlotMachine` helper function to differentiate between slot machines and beggars.
1659
+ * 2. The passed callback argument of `SlotDestructionType` to differentiate between bombed slots
1660
+ * and slots that paid out with a collectible item.
1661
+ *
1662
+ * Note that when a Crane Game explodes after paying out three collectibles, the
1663
+ * `SlotDestructionType` will be equal to `SlotDestructionType.NORMAL` instead of
1664
+ * `SlotDestructionType.COLLECTIBLE_PAYOUT` like you might expect. (This is because it only
1665
+ * explodes after a short delay, and when doing so, it produces rewards in the same way that would
1666
+ * happen if you bombed it.)
1641
1667
  *
1642
1668
  * When registering the callback with the `ModUpgraded.AddCallbackCustom` method:
1643
1669
  * - You can provide an optional third argument that will make the callback only fire if it