(4.0.0 - 4.21.1) 2.0.2 (4.0.0 - 4.21.1) 2.0.1 (4.0.0 - 4.21.1) 2.0.0 (4.0.0 - 4.21.1) 1.3.0 (4.11.0 - 4.21.1) 2.1.0 (5.0.0 - 5.16.0) 2.2.2
In pm4, hopper blocks were implemented to have an inventory. But the logic for pushing, pulling and picking up items was missing nonetheless. This plugin aims to add this logic to the hopper.
Normally a hopper should run a block update every tick to reduce and check its cooldown if it has expired. Because it is highly inefficient to update all loaded hoppers every tick, just for letting them reduce their cooldown by one, the block update of hoppers is always scheduled to the expiration of their cooldown and not directly the next tick. To prevent any issues with the cooldown, hoppers are saving in which tick they were lastly updated to prevent them from updating too early.
If a hopper did anything, it will be set on transfer cooldown and as explained above, its next update will be on the tick of the transfer. But if the hopper did nothing, it wouldn't be on cooldown and therefore would require an update on the next tick. As it is highly ineffective to schedule hundreds of hoppers for updates, who are not even doing anything, most parts are now event-driven. This means, that hoppers will only be scheduled for another block update, if an item entity landed on them or if any update on the blocks or inventories around them occurred.
Customizations can be done in the config.yml
in the plugin's plugin_data
folder:
hopper.transferCooldown
: 8
hopper.itemsPerUpdate
: 1
hopper.updatesPerTick
: 0
Every information about the logic for pushing, pulling and picking up items came from the minecraft fandom wiki.
Minecraft's hopper logic is very complex. To prevent anybody from getting confused about how certain things were done, most parts were commented to explain what was done and why.
I did, but it was stated that hopper logic won't be implemented in pm4 and because I didn't want to maintain a PR for the time till pm5, I closed it. Still, I wanted to use that logic in a plugin to use it myself and therefore I created this.
Functionality tests
"Performance" tests
Currently, the pushing and pulling methods are not very developer friendly when it comes to customizations, since it is hard to access and overwrite the Hopper::push()
and Hopper::pull()
methods without beeing forced to copy code.
This could be done by implementing a behaviour system which lets developers register custom behaviours for any block.
Since this would include rewriting some parts of the existing core, which would cost much time, what I do not see benefitial at the moment, PLEASE create an issue, if you find yourself needing a better implementation. Till then, this will stay as a TODO.
Normally, hoppers can not only pull items from blocks, but from entities like minecarts too. But since PocketMine-MP does not support them, there is no point in implementing this, since this would be out of the scope of this plugin. Although it should be at least possible to let hoppers also scan for entities when pulling, which is not possible with the current system.
Composters, Brewing Stands and Jukeboxes are currently either not or just poorly supported. This should be changed. But since PocketMine-MP itself does not implement these blocks correctly, there is no reason for us at the moment of writing this.
class EventListener implements Listener
) in your plugin and import (use
keyword) them by their namespace (event name
: namespace
).BlockItemPickupEvent
: pocketmine\event\block\BlockItemPickupEvent
HopperEvent
: ColinHDev\VanillaHopper\events\HopperEvent
HopperPushEvent
: ColinHDev\VanillaHopper\events\HopperPushEvent
HopperPushContainerEvent
: ColinHDev\VanillaHopper\events\HopperPushContainerEvent
HopperPushJukeboxEvent
: ColinHDev\VanillaHopper\events\HopperPushJukeboxEvent
HopperPullEvent
: ColinHDev\VanillaHopper\events\HopperPullEvent
HopperPullContainerEvent
: ColinHDev\VanillaHopper\events\HopperPullContainerEvent
As there is no EntityMoveEvent
, which can easily be listened for, a way to check whether an item entity moved onto a hopper had to be found.
This was done by implementing a custom item entity class that checks only when the entity actually moved. Otherwise, we would have to make a task that constantly checks all item entities and if they moved.
So this method has the most performance benefits. But this method makes this plugin incompatible with other plugins that implement a custom item entity class, as either this or the other plugin will no longer work as intended anymore.