Paper icon indicating copy to clipboard operation
Paper copied to clipboard

Add dispenserSpawnEntity event (1.19.4)

Open DerToaster98 opened this issue 1 year ago • 15 comments

Adds a cancellable event that gets fired whenever a dispenser would spawn a entity (mainly useful for projectiles and primed tnt).

Workarounds for this would involve cancelling the entire event per item stack which in my opinion is not the best solution. Another workaround would be to use ASM or similar to manually adjust the source code. Or one could use NMS to manually override the dispense behaviors, which would be more effort over all though.

EDIT: Realized i made this on the 1.19.4 branch, will make a new PR for the master one

DerToaster98 avatar May 06 '24 10:05 DerToaster98

I think a new event for that would be unnecessary The item dispense event is enough in my opinion You can easily check whether an item is a spawn egg or a projectile or any other kind of entity when dispensed

NonSwag avatar May 06 '24 14:05 NonSwag

Yes, i could do that, but i will only have access to exactly the item using that approach. And for what i want to do i need access to the entity created when dispensed and the dispenser itself. Correct me if i'm wrong, but ItemDispenseEvent only gives access to the item.

And i would need to replicate the entire logic for entity spawning through dispensed items (e.g. eggs, tnt, arrow and so on) for it to be accurate.

The other way that i'm aware of is using ASM or mixins or similar to achieve this or to use NMS and to re-register all the dispenseBehaviors with altered code.

EDIT: Access to the dispenser is given in the ItemDispenseEvent. Yet that doesn't change anything about the jankiness of that solution.

DerToaster98 avatar May 06 '24 14:05 DerToaster98

you could listen to the entity spawn event caused by dispensers

NonSwag avatar May 06 '24 16:05 NonSwag

Iirc there is just an entity spawn event, no? Haven't seen one specific for dispensers. And iirc the entity spawn event lacks a "reason" or context what spawned the entity or am i missing something here?

DerToaster98 avatar May 06 '24 16:05 DerToaster98

i didn't look at the implementation of this so i am not sure if this is possible but perhaps you could expand on the BlockDispenseEvent by adding a getEntity or something similar

EDIT: also you can just relocate the current pr to the master branch you don't to create a new one

notTamion avatar May 06 '24 16:05 notTamion

Iirc there is just an entity spawn event, no? Haven't seen one specific for dispensers. And iirc the entity spawn event lacks a "reason" or context what spawned the entity or am i missing something here?

Entit#getEntitySpawnReason image

NonSwag avatar May 06 '24 16:05 NonSwag

ok, that gets me the reason, but for what i want to do i need to have access to the dispenser too. And having to scan every of the 8/14 blocks around the entity is not an option

DerToaster98 avatar May 06 '24 17:05 DerToaster98

i didn't look at the implementation of this so i am not sure if this is possible but perhaps you could expand on the BlockDispenseEvent by adding a getEntity or something similar

EDIT: also you can just relocate the current pr to the master branch you don't to create a new one

Hm, good idea

DerToaster98 avatar May 06 '24 17:05 DerToaster98

I think this duplicates a lot of what is proposed in https://github.com/PaperMC/Paper/pull/7377.

Machine-Maker avatar May 06 '24 17:05 Machine-Maker

I think this duplicates a lot of what is proposed in #7377.

Looks like it. Will still keep this open though, cause the PR you mentioned hasn't been touched in quite some time.

EDIT: Wait, according to the description it doesn't fire when projectiles are being fired from dispensers? EDIT 2: Haven't looked in detail but for what i want i need access to the dispenser BE that fired the projectile or spawned the tnt, not having it doesn't help me here.

DerToaster98 avatar May 06 '24 17:05 DerToaster98

The idea of adding an entity to the existing dispense event is actually pretty good. It could return a nonnull entity in every case because the item entity could also be returned.

NonSwag avatar May 07 '24 14:05 NonSwag

EDIT 2: Haven't looked in detail but for what i want i need access to the dispenser BE that fired the projectile or spawned the tnt, not having it doesn't help me here.

The projectile source is on the Projectile entity with https://jd.papermc.io/paper/1.20.6/org/bukkit/projectiles/BlockProjectileSource.html.

Machine-Maker avatar May 13 '24 04:05 Machine-Maker

EDIT 2: Haven't looked in detail but for what i want i need access to the dispenser BE that fired the projectile or spawned the tnt, not having it doesn't help me here.

The projectile source is on the Projectile entity with https://jd.papermc.io/paper/1.20.6/org/bukkit/projectiles/BlockProjectileSource.html.

Interesting, i will take a look, thanks!

DerToaster98 avatar May 13 '24 05:05 DerToaster98

EDIT 2: Haven't looked in detail but for what i want i need access to the dispenser BE that fired the projectile or spawned the tnt, not having it doesn't help me here.

The projectile source is on the Projectile entity with https://jd.papermc.io/paper/1.20.6/org/bukkit/projectiles/BlockProjectileSource.html.

Ok, took a look, I can use that for any projectile, but i still need something for the tnt being dispensed. I know of workarounds but using those is not an option. Guess I'll adjust my solution here and wait for the (probably unlikely) case that it will be merged. Otherwise I need to find a way to compile the jar on my own.

DerToaster98 avatar May 13 '24 11:05 DerToaster98

Ok, took a look, I can use that for any projectile, but i still need something for the tnt being dispensed.

Yes, the mentioned PR does add an event for handling TNT which can't have a projectile source as its not a projectile.

Machine-Maker avatar May 13 '24 13:05 Machine-Maker