diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index 0dac5b15..b816685d 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -2720,12 +2720,14 @@ Here is a list of events that can be handled by scarpet. This list includes pref them, but you can add any function to any event if it accepts required number of parameters:
+// world callbacks
 __on_tick()         // can access blocks and entities in the overworld
 __on_tick_nether()  // can access blocks and entities in the nether
 __on_tick_ender()   // can access blocks and entities in the end
 __on_chunk_generated(x,z) // called after a chunk is promoted to the full chunk,
                           // prodiving lowest x and z coords in the chunk
                           // event will not work with optifine installed in the game
+__on_lightning(pos, mode) // mode is `true` if lightning caused horse trap to spawn
 // player specific callbacks
 __on_player_uses_item(player, item_tuple, hand)  // right click action
 __on_player_releases_item(player, item_tuple, hand)  // client action (e.g. bow)
diff --git a/docs/scarpet/api/Events.md b/docs/scarpet/api/Events.md
index 5df38a5b..488ed040 100644
--- a/docs/scarpet/api/Events.md
+++ b/docs/scarpet/api/Events.md
@@ -14,12 +14,14 @@ Here is a list of events that can be handled by scarpet. This list includes pref
 them, but you can add any function to any event if it accepts required number of parameters:
 
 
+// world callbacks
 __on_tick()         // can access blocks and entities in the overworld
 __on_tick_nether()  // can access blocks and entities in the nether
 __on_tick_ender()   // can access blocks and entities in the end
 __on_chunk_generated(x,z) // called after a chunk is promoted to the full chunk,
                           // prodiving lowest x and z coords in the chunk
                           // event will not work with optifine installed in the game
+__on_lightning(pos, mode) // mode is `true` if lightning caused horse trap to spawn
 // player specific callbacks
 __on_player_uses_item(player, item_tuple, hand)  // right click action
 __on_player_releases_item(player, item_tuple, hand)  // client action (e.g. bow)
diff --git a/src/main/java/carpet/mixins/ServerWorld_scarpetEventMixin.java b/src/main/java/carpet/mixins/ServerWorld_scarpetEventMixin.java
new file mode 100644
index 00000000..a24ac503
--- /dev/null
+++ b/src/main/java/carpet/mixins/ServerWorld_scarpetEventMixin.java
@@ -0,0 +1,29 @@
+package carpet.mixins;
+
+import net.minecraft.server.world.ServerWorld;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.ChunkPos;
+import net.minecraft.util.profiler.Profiler;
+import net.minecraft.world.chunk.WorldChunk;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
+
+import static carpet.script.CarpetEventServer.Event.LIGHTNING;
+
+@Mixin(ServerWorld.class)
+public class ServerWorld_scarpetEventMixin
+{
+    @Inject(method = "tickChunk", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(
+            value = "INVOKE",
+            target = "Lnet/minecraft/server/world/ServerWorld;addLightning(Lnet/minecraft/entity/LightningEntity;)V"
+    ))
+    private void onNaturalLightinig(WorldChunk chunk, int randomTickSpeed, CallbackInfo ci,
+                                    ChunkPos chunkPos, boolean bl, int i, int j, Profiler profiler, BlockPos blockPos, boolean bl2)
+    {
+        if (LIGHTNING.isNeeded()) LIGHTNING.onWorldEventFlag((ServerWorld) (Object)this, blockPos, bl2?1:0);
+    }
+
+}
diff --git a/src/main/java/carpet/script/CarpetEventServer.java b/src/main/java/carpet/script/CarpetEventServer.java
index 5e7dab18..e6c87413 100644
--- a/src/main/java/carpet/script/CarpetEventServer.java
+++ b/src/main/java/carpet/script/CarpetEventServer.java
@@ -502,7 +502,20 @@ public class CarpetEventServer
                         ((c, t) -> new NumericValue(amount))
                 ), player::getCommandSource);
             }
-        }
+        },
+        LIGHTNING("lightning", 2, true)
+        {
+            @Override
+            public void onWorldEventFlag(ServerWorld world, BlockPos pos, int flag)
+            {
+                handler.call(
+                        () -> Arrays.asList(
+                                ((c, t) -> new BlockValue(null, world, pos)),
+                                ((c, t) -> flag>0?Value.TRUE:Value.FALSE)
+                        ), () -> CarpetServer.minecraft_server.getCommandSource().withWorld(world)
+                );
+            }
+        },
         ;
 
         // on projectile thrown (arrow from bows, crossbows, tridents, snoballs, e-pearls
@@ -538,6 +551,8 @@ public class CarpetEventServer
         public void onBlockBroken(ServerPlayerEntity player, BlockPos pos, BlockState previousBS) { }
         public void onBlockPlaced(ServerPlayerEntity player, BlockPos pos, Hand enumhand, ItemStack itemstack) { }
         public void onEntityAction(ServerPlayerEntity player, Entity entity, Hand enumhand) { }
+        public void onWorldEvent(ServerWorld world, BlockPos pos) { }
+        public void onWorldEventFlag(ServerWorld world, BlockPos pos, int flag) { }
     }
 
 
diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json
index 4ee877ca..7da7e2b0 100644
--- a/src/main/resources/carpet.mixins.json
+++ b/src/main/resources/carpet.mixins.json
@@ -146,6 +146,7 @@
     "ServerChunkManager_scarpetMixin",
     "StatType_scarpetMixin",
     "PointOfInterest_scarpetMixin",
+    "ServerWorld_scarpetEventMixin",
 
 
     "PistonBlock_movableTEMixin",