Skip to content

Commit

Permalink
Handle explosion event and pass to Bukkit properly (#908)
Browse files Browse the repository at this point in the history
* Handle explosion event and pass to Bukkit properly

* Add config

---------

Co-authored-by: Luohuayu <i@qqq.moe>
  • Loading branch information
HaHaWTH and Luohuayu authored Dec 31, 2024
1 parent 375da46 commit 4168d84
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
3 changes: 2 additions & 1 deletion patches/net/minecraft/world/Explosion.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@
private final double y;
private final double z;
- private final Entity exploder;
- private final float size;
+ public final Entity exploder;
private final float size;
+ public float size; // CatServer - private final -> public
private final List<BlockPos> affectedBlockPositions;
private final Map<EntityPlayer, Vec3d> playerKnockbackMap;
+ private final Vec3d position;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/catserver/server/CatServerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class CatServerConfig {
public boolean disableAsyncCatchWarn = false;
public boolean versionCheck = true;

public boolean bridgeForgeExplosionEventToBukkit = false;
public boolean callConstructCapabilityEventOnRespawn = false;

public CatServerConfig(String file) {
Expand Down Expand Up @@ -106,6 +107,7 @@ public void loadConfig() {
disableFMLHandshake = getOrWriteBooleanConfig("network.fml.disableHandshake", config.getBoolean("disableFMLHandshake", disableFMLHandshake));
disableFMLStatusModInfo = getOrWriteBooleanConfig("network.fml.disableStatusModInfo", config.getBoolean("disableFMLStatusModInfo", disableFMLStatusModInfo));
// compatibility
bridgeForgeExplosionEventToBukkit = getOrWriteBooleanConfig("compatibility.bridgeForgeExplosionEventToBukkit", bridgeForgeExplosionEventToBukkit);
callConstructCapabilityEventOnRespawn = getOrWriteBooleanConfig("compatibility.callConstructCapabilityEventOnRespawn", callConstructCapabilityEventOnRespawn);
// general
disableUpdateGameProfile = getOrWriteBooleanConfig("disableUpdateGameProfile", disableUpdateGameProfile);
Expand Down
60 changes: 60 additions & 0 deletions src/main/java/catserver/server/CatServerEventHandler.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
package catserver.server;

import com.google.common.collect.Lists;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.Explosion;
import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.event.world.ExplosionEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.block.CraftBlockState;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.event.Event;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent;

import java.util.ArrayList;
Expand Down Expand Up @@ -66,6 +77,55 @@ public void onBlockPlace(BlockEvent.PlaceEvent event) {
}
}

@SubscribeEvent(priority = EventPriority.HIGHEST)
public void onExplode(ExplosionEvent.Detonate event) {
if (!CatServer.getConfig().bridgeForgeExplosionEventToBukkit) return;
Explosion explosion = event.getExplosion();
if (explosion.getClass() != Explosion.class) {
Entity exploder = explosion.exploder;
World bworld = event.getWorld().getWorld();
Vec3d explosionPos = explosion.getPosition();
Location location = new Location(bworld, explosionPos.x, explosionPos.y, explosionPos.z);
List<Block> bukkitBlocks;
boolean cancelled;
float yield;
final List<Block> blockList = Lists.newArrayList();
List<BlockPos> affectedBlockPositions = event.getAffectedBlocks();
for (int i1 = affectedBlockPositions.size() - 1; i1 >= 0; i1--) {
BlockPos cpos = affectedBlockPositions.get(i1);
Block bblock = bworld.getBlockAt(cpos.getX(), cpos.getY(), cpos.getZ());
if (bblock.getType() != Material.AIR) {
blockList.add(bblock);
}
}
if (exploder != null) {
EntityExplodeEvent bukkitEvent = new EntityExplodeEvent(exploder.getBukkitEntity(), location , blockList, 1.0F / explosion.size);
Bukkit.getServer().getPluginManager().callEvent(bukkitEvent);
cancelled = bukkitEvent.isCancelled();
bukkitBlocks = bukkitEvent.blockList();
yield = bukkitEvent.getYield();
} else {
BlockExplodeEvent bukkitEvent = new BlockExplodeEvent(location.getBlock(), blockList, 1.0F / explosion.size);
Bukkit.getServer().getPluginManager().callEvent(bukkitEvent);
cancelled = bukkitEvent.isCancelled();
bukkitBlocks = bukkitEvent.blockList();
yield = bukkitEvent.getYield();
}
explosion.getAffectedBlockPositions().clear();

if (cancelled) {
event.getAffectedEntities().clear();
explosion.wasCanceled = true;
} else {
for (Block bblock : bukkitBlocks) {
BlockPos coords = new BlockPos(bblock.getX(), bblock.getY(), bblock.getZ());
explosion.getAffectedBlockPositions().add(coords);
}
explosion.size = yield * explosion.size;
}
}
}

@SubscribeEvent(priority = EventPriority.HIGHEST)
public void onLeftClickBlock(PlayerInteractEvent.LeftClickBlock event) {
if (!event.isVanilla) {
Expand Down

0 comments on commit 4168d84

Please sign in to comment.