Pigman Party Pooper

Pigman Party Pooper

v1.3.0


Hello Sponge Community! I can’t stand Zombie Pigmen spawning in the Nether at all light levels. They get on your tracks, in your fortresses, everywhere! I made this plugin to learn the API and share it with those looking to get a start on plugin development. It could likely use some optimization and efficiency, but it gets the job done!

This plugin is designed to crash zombie pigmen parties and to tell them to stop frolicking. The plugin has three functions presently.

  • The plugin makes pigmen only spawn at light levels of 7 or lower by removing all pigmen spawns above a light level of 7.
  • The plugin makes it so that Endermen that pickup blocks do not destroy the blocks they pickup by cancelling the event.
  • It disables fires started by lightning bolts by clearing the transactions of the event.

Source Code: GitHub - thw26/PigmanPartyPooper: A Minecraft Sponge Plugin that alters mob behavior and does some anti-mob griefing.

Plugin Download: https://github.com/thw26/PigmanPartyPooper/releases/download/1.3.0/pigmanpartypooper.jar


Known Issues

Endermen don’t destroy blocks they pickup (good) but the blocks still appear in their hands (bad).


##To-Do

  • Optimize Code/Efficiency. Feedback welcome!
  • Fix Endermen block pickups.
  • Create a config file.
  • Create commands to control plugin.

looking at the code,

I’d maybe replace the e.getCause().contains(EntityTypes.PIG_ZOMBIE) with a check to the entity being spawned instead.

Also checking to see if the cause contains a GroundLuminanceProperty.greaterThan(7) I’m not sure if that’s actually testing the property against the one found in the cause, or checking for equality…

This is just first thoughts after looking at the code, I’d need to run it through a debugger to be sure.

This won’t work. The implementation of Cause#contains(Object) will check if any of its object in a cause chain equal each other. In this case, because greaterThan(7) has a value of 7, it will only match other properties with 7, even if they are greater (due to how the equals function is implemented on DoubleProperty.

@gabizou perhaps the equals function could be implemented on these operator types so that it looks at compareTo rather than the values?

This seems odd - why would you ignore the event if any of the entities spawned are a player? Wouldn’t it be better to wrap the entire thing in a for loop, so that each entity is individually checked and removed if they meet the criteria?

Finally, this is not required. By default, an event listener is not called if an event is already cancelled.

@ZephireNZ @ryantheleach Thanks guys for the critique; I appreciate it! Here is a modification based off what you have said. Does this seem more in line with what you have both suggested?

  1. Checking for whether there are entities.
  2. Then cycling through the event’s entities and checking for WORLD_SPAWNER pigmen.
  3. Needing to acquire the light level.
  4. Cancelling if all conditions met.
@Listener
    public void onSpawn (SpawnEntityEvent e) {
        if (e.getEntities().isEmpty()) return;
        for (Entity entity : e.getEntities()) {
            if (entity.getType() == EntityTypes.PIG_ZOMBIE) {
                if (e.getCause().contains(SpawnTypes.WORLD_SPANWER)) {
                    if (/*Light Level*/) {
                        e.setCancelled(true);
                    }
                }
            }
        }
    }

A little redundant, for loop will just not continue if there are no entities.

I’m not sure if this would be in the cause, best way would be to use SpawnEntityEvent.Spawner instead.

If this event spawned 5 zombie pigmen and a skeleton, then it would cancel the event for all of them, including the skeleton.

In fact, I think best way is to use AffectEntityEvent#filterEntities(Predicate<Entity>) instead of a for loop - that will iterate for each entity, and allow you to return true or false if that entity should spawn.

Sorry to run you around in circles xD

Not a problem at all!

I was starting to bang my head against my keyboard. I had this basic idea working in Bukkit and it is a great way to learn the API.

I’m not familiar with the AffectEntityEvent (or most of the API); I will have to look into it. I will see what I can whip up.

What would be a way to get at the light level? Taking a look at the available calls, I see I can retrieve the Location of the entity.

I’m not certain, but I believe best way to check is:

  1. get Location the entities is being spawned to
  2. get the BlockState in that location
  3. Using data API, get the GroundLuminanceProperty from the block, and compare it with GroundLuminancePropery.greaterThan(7)

Initial release uploaded to GitHub.