Skip to content

Common API

Crystal Spider edited this page Jul 11, 2024 · 11 revisions

The entire API available for the common module is encapsulated within the HarvestUtils utility class, which offers several useful methods for checking specific properties of crops.

Additionally, the common module includes interfaces implemented by all loader-specific events, allowing you to design logic within the common module and share it across your loader-specific modules when subscribing to these events.

HarvestUtils

Below is a description of each field/method in the class. All methods are also documented with Javadoc comments in the code.

  • TagKey<Block> BLACKLIST:
    Block tag key for HWE blacklist tag, used in conjunction with the blacklist configuration option to determine which crops are excluded from right-click harvesting.

  • isBlacklisted(BlockState):
    Determines if the given block is excluded from right-click harvesting because it's either in the blacklist block tag or in the blacklist configuration option.

  • isCrop(Block):
    Checks whether the given block is considered as a crop for the purpose of right-click harvesting.

  • getAge(BlockState):
    Retrieves the age property from the given block state. Note that this method may throw an exception if the age property is absent or if a property named age exists but is not an IntegerProperty.

  • isMature(BlockState, IntegerProperty):
    Determines if the crop specified by the given block state is mature by comparing its age value to the maximum value of the provided age property.

  • isMature(BlockState):
    An overload of the previous method, this version performs the same function by internally calling getAge(BlockState).

  • isTallCrop(BlockGetter, BlockState, BlockPos):
    Checks whether the crop specified by the given block state is a tall crop, defined as a crop consisting of multiple vertically connected blocks of the same type. Note that, although this is the most common and generalized implementation of a tall crop, other implementations may exist.

  • isTierForMultiHarvest(TieredItem):
    Uses Cobweb Tool Tiers API to check whether the given item can perform multi-harvest.
    Since Minecraft 1.21, uses custom logic based on the mod configuration.

  • getTierLevel(TieredItem):
    Available only since Minecraft 1.21, needed because Minecraft removed the concept of tier levels.
    Returns the tier level based on the mod configuration.

Events

HarvestEvent

All loader-specific events implement the HarvestEvent interface, which declares several methods:

  • getPlayer(): get the player harvesting.
  • getLevel(): get the Level where the interaction is taking place.
  • getCrop(): get the crop being harvested.
  • getPos(): get the crop position.
  • getFace(): get the right-clicked block face.
  • getHitResult(): get the BlockHitResult. Will be null if the crop is being harvested due to multi-harvest.
  • getHand(): get the hand used to harvest.
  • isFirst(): get whether the crop is the right-clicked one or is being harvested due to multi-harvest.

Each of the 4 available events implements a more specific interface that extends the more general interface mentioned above.
These interfaces specify the interaction side (server or both) and may optionally include additional methods.

HarvestCheckEvent

Fired on both sides, determines whether right-click harvesting is permitted.
As soon as any listener returns false/calls preventHarvest(), the event is canceled and so is the harvest.
Therefore, your listener might not always be called and should not produce any side effects.

When the event fires, the right-clicked block is guaranteed to be a crop block, meaning HarvestUtils#isCrop(Block) returns true.
However, the crop's age is not yet determined, so even if this event allows the harvest, the actual harvest may not occur.

BeforeHarvestEvent

Fired server-side only before any harvesting logic happens.
Your listener can produce side effects, and the event cannot be canceled.

HarvestDropsEvent

Fired server-side only while calculating the drops resulting from harvesting.
Your listener should not produce side effects, and the event can be canceled.
With this event you can change the drops that would result from harvesting the crop. To make your modification final, you can cancel the event.

This event includes several additional methods:

  • getDefaultDrops():
    Returns an immutable list of the default drops that would result if no modifications are made.
  • getDrops():
    Returns the current list of drops.
  • didDropsChange():
    Indicates whether the current drops have been modified from the default.
  • cancel():
    Cancels the event and prevents further processing.

The default drops are calculated before firing the event and already have one seed, the one that would be needed to replant, removed.
Be aware that, if drops are changed from their default, any other blocks comprising the crop will not drop anything. This is usually not an issue since most Vanilla and modded crops consist of a single block. However, this becomes significant for tall crops, where only the right-clicked block will drop something if the drops are changed.

If you modify the drops, you should also consider this aspect. You can check if a crop is a multi-block crop by calling HarvestUtils#isTallCrop(BlockGetter, BlockState, BlockPos).

AfterHarvestEvent

Fired server-side only after all the harvesting logic has happened.
Your listener can produce side effects, and the event cannot be canceled.

Multi-harvest

Multi-harvest occurs when a player right-clicks a crop and, if the tool in hand permits, harvests all mature crops within a flat, square area centered on the right-clicked crop.
During multi-harvesting, each event described above is fired for each individual crop.
You can call isFirst() for any event to determine if the current crop was the originally right-clicked one.