User Tools

Site Tools


tutorial:events

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
tutorial:events [2019/07/03 00:31] – tell people to return PASS in listeners draylartutorial:events [2020/06/09 23:16] – formatting changes draylar
Line 1: Line 1:
 ====== Custom Events ====== ====== Custom Events ======
-Events here, event there! Everyone and everything gets an event! +Fabric API provides system that allows mods to react to events that occur in the game. Events are hooks that satisfy common use cases and/or provide enhanced compatibility and performance between mods that hook into the same areas of the codeThe use of events often substitutes the use of mixins. Fabric API provides events for important areas in the Minecraft codebase that multiple modders may be interested in hooking into. Some areas do not have hooksso you can opt to use a mixin, or create your own event.
- +
-Events are formalized hook you can use to respond to actions in the game. They serve as a way to prevent 20 mixins in the same spot (because everyone wants to hook after the same thing)In this tutorialwe'll look at creating your own event which is triggered when sheep are shearedThe process of creating an event is:+
  
 +In this tutorial, we'll look at creating an event that is triggered when sheep are sheared. The process of creating an event is:
   * creating the event callback interface   * creating the event callback interface
-  * triggering the event from a mixin+  * triggering the event from a Mixin
   * creating a test implementation   * creating a test implementation
  
 ==== Creating a Callback Interface ==== ==== Creating a Callback Interface ====
-The callback interface is the core of your event. It stores list of all registered listeners (which are like responses to an event) and calls them all when the action occursEach listener can then say "cancel this," "approve this," or "don't care, leave it to the next guy,while doing whatever response they need to.+The callback interface describes what must be implemented by event listeners that will listen to your event. The callback interface also describes how the event will be called from our mixin. It is conventional to place an Event object as field in the callback interface, which will identify our actual event. 
 + 
 +For our Event implementation we will choose to use an array backed event. The array will contain all event listeners that are listening to the eventOur implementation will call the event listeners in order until one of them does not return ''ActionResult.PASS''. This means that a listener can say "cancel this""approve this" or "don't care, leave it to the next event listenerusing its return value. Using ActionResult as a return value is a conventional way to make event handlers cooperate in this fashion.
  
 You'll need to create an interface that has an ''Event'' instance and method for response implementation. A basic setup for our sheep shear callback is: You'll need to create an interface that has an ''Event'' instance and method for response implementation. A basic setup for our sheep shear callback is:
  
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
-public interface SheepShearCallback +public interface SheepShearCallback { 
-{+
     Event<SheepShearCallback> EVENT = EventFactory.createArrayBacked(SheepShearCallback.class,     Event<SheepShearCallback> EVENT = EventFactory.createArrayBacked(SheepShearCallback.class,
         (listeners) -> (player, sheep) -> {         (listeners) -> (player, sheep) -> {
-            for (SheepShearCallback event : listeners) { +            for (SheepShearCallback listener : listeners) { 
-                ActionResult result = event.interact(player, sheep);+                ActionResult result = listener.interact(player, sheep); 
 +                
                 if(result != ActionResult.PASS) {                 if(result != ActionResult.PASS) {
                     return result;                     return result;
Line 28: Line 30:
     });     });
  
-ActionResult interact(PlayerEntity player, SheepEntity sheep);+    ActionResult interact(PlayerEntity player, SheepEntity sheep);
 } }
 </code> </code>
Line 37: Line 39:
     for (SheepShearCallback event : listeners) {     for (SheepShearCallback event : listeners) {
 </code> </code>
-We then call our method (in this case, ''interact'') on the listener to get it'response:+We then call our method (in this case, ''interact'') on the listener to get its response:
 <code java [enable_line_numbers="false"]> <code java [enable_line_numbers="false"]>
 ActionResult result = event.interact(player, sheep); ActionResult result = event.interact(player, sheep);
Line 64: Line 66:
 </code> </code>
  
-==== Triggering the event from a mixin ====+==== Triggering the event from a Mixin ====
 We now have the basic event skeleton, but we need to trigger it. Because we want to have the event called when a player attempts to shear a sheep, we call the event invoker in ''SheepEntity#interactMob'' when ''dropItems()'' is called (ie. sheep can be sheared and player is holding shears): We now have the basic event skeleton, but we need to trigger it. Because we want to have the event called when a player attempts to shear a sheep, we call the event invoker in ''SheepEntity#interactMob'' when ''dropItems()'' is called (ie. sheep can be sheared and player is holding shears):
 <code java [enable_line_numbers="false"]> <code java [enable_line_numbers="false"]>
 @Mixin(SheepEntity.class) @Mixin(SheepEntity.class)
-public class SheepShearMixin +public class SheepShearMixin { 
-{+
     @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/SheepEntity;dropItems()V"), method = "interactMob", cancellable = true)     @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/SheepEntity;dropItems()V"), method = "interactMob", cancellable = true)
     private void onShear(final PlayerEntity player, final Hand hand, final CallbackInfoReturnable<Boolean> info) {     private void onShear(final PlayerEntity player, final Hand hand, final CallbackInfoReturnable<Boolean> info) {
         ActionResult result = SheepShearCallback.EVENT.invoker().interact(player, (SheepEntity) (Object) this);         ActionResult result = SheepShearCallback.EVENT.invoker().interact(player, (SheepEntity) (Object) this);
 +        
         if(result == ActionResult.FAIL) {         if(result == ActionResult.FAIL) {
             info.cancel();             info.cancel();
Line 84: Line 87:
 Now we need to test our event. You can register a listener in your initialization method (or other areas if you prefer) and add custom logic there. Here's an example that drops a diamond instead of wool at the sheep's feet: Now we need to test our event. You can register a listener in your initialization method (or other areas if you prefer) and add custom logic there. Here's an example that drops a diamond instead of wool at the sheep's feet:
 <code java [enable_line_numbers="false"]> <code java [enable_line_numbers="false"]>
-SheepShearCallback.EVENT.register((player, sheep) -> +SheepShearCallback.EVENT.register((player, sheep) -> {
-{+
     sheep.setSheared(true);     sheep.setSheared(true);
  
Line 99: Line 101:
  
 If you enter into your game and shear a sheep, a diamond should drop instead of wool. If you enter into your game and shear a sheep, a diamond should drop instead of wool.
 +
 {{https://i.imgur.com/dG73Z6G.mp4?400|}} {{https://i.imgur.com/dG73Z6G.mp4?400|}}
tutorial/events.txt · Last modified: 2021/05/28 00:31 by 127.0.0.1