1# Events 2 3Commander introduces a new data pack event system, which allows data packs to listen to events just like mods. 4 5The best practice is to have a generic Fabric event and register Commander as one of its listeners. 6 7## Creating event types 8 9To implement event support for your mod you must first register an event type for Commander to dispatch. You can build and register events with the `EventType.Builder` class. 10 11```java 12public static final EventType CUSTOM_EVENT = EventType.builder().build(new Identifier("modid", "custom_event")); 13``` 14 15If your event requires a return type, you can specify a cancel term codec with `cancelTerm()`. 16 17```java 18EventType.builder() 19 .cancelTerm(Codec.INT) 20 .build(new Identifier("modid", "custom_event")); 21``` 22 23Events can accept additional parameters using `extension()`. After specifying an extension you can return a custom type. 24 25```java 26EventType.builder() 27 .extension(Codec.STRING, subscriptions -> { 28 //handle data. 29 return /*Return listeners*/; 30 }) 31 .build(new Identifier("modid", "custom_event")); 32``` 33 34The default return type is `List<Command.Conditioned>`. 35 36## Invoking the event 37 38If you didn't specify an extension, or opted to return a `List<Command.Conditioned>`, you can use the included `EventExecutors` util. 39 40To use the util, you have to pass the event type, the execution world, and a loot context supplier. 41 42```java 43CustomEvent.EVENT.register((world, entity) -> runVoid(CUSTOM_EVENT, world, () -> makeContext(world, entity, entity.getPos()))); 44``` 45 46```java 47private static LootContext makeContext(ServerWorld world, Entity entity, Vec3d origin) { 48 LootContextParameterSet.Builder builder = new LootContextParameterSet.Builder(world); 49 builder.add(THIS_ENTITY, entity).add(ORIGIN, origin); 50 return new LootContext.Builder(builder.build(LootContextTypes.COMMAND)).build(null /*Optional.empty() in 1.20.4*/); 51} 52``` 53 54If you did specify an extension, or are using an unsupported return type, you'll have to write custom resolution logic. 55 56To do that you'll simply have to create an `EventContext`. `EventContext` is used to pass execution parameters to commands. 57 58```java 59EventContext context = EventContext.builder(type) 60 .addParameter(EventKey.LOOT_CONTEXT, /*instance of loot context*/) 61 .build(); 62for (Command.Conditioned subscriber : subscribers) subscriber.execute(context); 63``` 64To get the return value, you can call `getReturnValue(def)`, the default value can be null. The return type is generic. 65 66```java 67boolean val = context.getReturnValue(def); 68if (val != def) return val; 69```