How to setup damage over time using the collision event listener?

Say the player is standing in fire and I want to handle damage taken using the local collision event listener setup for player. To do so: I can setup a switch on_fire=true that is first set in the event.phase==“began” of the localCollision listener, and this can start a separate process in the gameLoop that assigns damage over time until on_fire=false is set in event.phase==“ended” of localCollision…that can indeed all work, but what if the fire goes out aka is deleted? event.phase==“ended” doesn’t proc when a physics body is deleted…is there a way to trigger the “ended” phase manually? What am I supposed to do here?

I can’t just cheat and set on_fire to false before any fire is deleted/extinguished. Cause if I have more than 1 fire happening it might turn off another existing fire u are standing in. Again I’m looking for the solution “with listeners” or whatever method I’m intended to be using here. The methods without listeners are known.

localPostCollision would seem to be the solution…but the fire is set to isSensor=true and isSensor will not function in collisions other than the began and ended phases of local/global collision.
Everything works if I just set isSensor=false …but then the fire object is literally kicking the player out of its aoe. Is there a way I can make a static/dynamic/kinematic whatever physics body that isn’t isSensor=true but doesn’t affect(at least not really) anything it touches like isSensor=true would?..cause that should work.
The solution is seemingly always just out of grasp.

What if you use a table instead of a Boolean? (Adding and removing fire-objects currently touching your character).
I had a similar scenario but I decided to set a time limit on damages from the fire (i.e.: it vanish after 5 seconds, or game over screen)

1 Like

I see what you are saying here and that would work. I should have put it in words, but the point I was trying to get at about ‘not being able to just turn the fire off’ was the idea you can’t justify such an elaborate system for something so trivial… and that there must be something we are missing that we are supposed to be using here…cause this entire problem is literally solved in 1 line if we don’t use event listeners at all. The idea I got to build a pantheon to get it to work with event listeners isn’t on the table, and more importantly is inconceivable as the way we supposed to be solving this problem.

Similar sentiments to your second part: I would never consider changing a game mechanic to fit the listeners(what I always assumed was supposed to be a helper system).

Well, I don’t know if there’s something ready to use, but surely you can define your own method to remove a body and trigger a custom onBodyDeleted event (or use a callback).
Then you only need to use this method instead of the original remove body
(And register your listeners/callbacks).

This would give you full control, no compromises :slightly_smiling_face:

You can handle this by manually triggering the “ended” event when the fire is deleted. Keep track of players in contact with the fire during the “began” phase, and when the fire is extinguished, manually stop the damage over time for those players. This approach ensures that the fire’s deletion doesn’t interfere with ongoing damage processes. You could also explore using custom collision filters or groups to prevent the fire from affecting the player’s movement while still applying damage.

This. How do you do this though?

Can you explain further please, I don’t know what this looks like. I thought you meant groupIndex filters at first, but those willl outright remove the ability to detect or apply anything via the collision listeners.
filter={categoryBits=int,maskBits=int} is the same as with groupIndex.

See the documentation about dispatchEvent method.
You can both use a custom event as I was suggesting or call the collision event.
(I’d differentiate them to not mess with the collision events flow)

obj:dispatchEvent{name="localCollision", phase = "ended"} --not doing anything

What is the syntax supposed to be here? How do I specify event.phase=“ended”? It doesn’t allow ,event.phase. Adding the target=“obj” didn’t fix anything.

Still don’t know what the intended answers above were, but
obj.isBodyActive = false will stop the post-collision and trigger “ended” in collision.

So here’s two solar2d methods if we use the ‘standing in fire’ example:

  1. If you make the fire isSensor and player physics bodies: setup a switch in event collision’s ‘began’ phase activating some code in your gameloop to damage the player every frame. If you delete the fire b4 the player stops standing in it do the extra step of assigning the obj.isBodyActive=false when u delete it. Turn the switch u made off by putting it in event collision’s ‘ended’ phase.

  2. if both are physics bodies but none are isSensor, you instead can solely use postCollision and apply damage directly per frame of touching fire. I can’t get the physics body of the fire to spawn inside the player and avoid pushing the player around without setting it to isSensor though…not sure what is going on there would have thought density=0 would fix that.