Files
fabric-carpet/src/main/java/carpet/mixins/ServerLevel_scarpetMixin.java
T
2026-09-17 17:11:07 +02:00

98 lines
5.0 KiB
Java

package carpet.mixins;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.particles.ExplosionParticleInfo;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.util.random.WeightedList;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LightningBolt;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.ExplosionDamageCalculator;
import net.minecraft.world.level.gamerules.GameRule;
import net.minecraft.world.level.gamerules.GameRules;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.entity.LevelEntityGetter;
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
import net.minecraft.world.level.storage.ServerLevelData;
import net.minecraft.world.level.storage.WritableLevelData;
import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
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.EXPLOSION;
import static carpet.script.CarpetEventServer.Event.LIGHTNING;
import static carpet.script.CarpetEventServer.Event.CHUNK_UNLOADED;
@Mixin(ServerLevel.class)
public abstract class ServerLevel_scarpetMixin extends Level
{
@Shadow public abstract GameRules getGameRules();
protected ServerLevel_scarpetMixin(WritableLevelData writableLevelData, ResourceKey<Level> resourceKey, RegistryAccess registryAccess, Holder<DimensionType> holder, boolean bl, boolean bl2, long l, int i)
{
super(writableLevelData, resourceKey, registryAccess, holder, bl, bl2, l, i);
}
@Inject(method = "tickThunder", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(
value = "INVOKE",
target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z",
shift = At.Shift.BEFORE,
ordinal = 1
))
private void onNaturalLightinig(LevelChunk chunk, CallbackInfo ci,
//ChunkPos chunkPos, boolean bl, int i, int j, Profiler profiler, BlockPos blockPos, boolean bl2)
ChunkPos chunkPos, boolean bl, int i, int j, ProfilerFiller profiler, BlockPos blockPos, DifficultyInstance localDifficulty, boolean bl2, LightningBolt lightningEntity)
{
if (LIGHTNING.isNeeded()) LIGHTNING.onWorldEventFlag((ServerLevel) (Object)this, blockPos, bl2?1:0);
}
private Explosion.BlockInteraction getCMDestroyType(final GameRule<Boolean> rule) {
return getGameRules().get(rule) ? Explosion.BlockInteraction.DESTROY_WITH_DECAY : Explosion.BlockInteraction.DESTROY;
}
@Inject(method = "explode", at = @At("HEAD"), cancellable = true)
private void handleExplosion(Entity source, DamageSource damageSource, ExplosionDamageCalculator damageCalculator, double x, double y, double z, float r, boolean fire, ExplosionInteraction interactionType, ParticleOptions smallExplosionParticles, ParticleOptions largeExplosionParticles, WeightedList<ExplosionParticleInfo> blockParticles, Holder<SoundEvent> explosionSound, CallbackInfo ci)
{
if (EXPLOSION.isNeeded()) {
Explosion.BlockInteraction var10000 = switch (interactionType) {
case NONE -> Explosion.BlockInteraction.KEEP;
case BLOCK -> this.getCMDestroyType(GameRules.BLOCK_EXPLOSION_DROP_DECAY);
case MOB -> this.getGameRules().get(GameRules.MOB_GRIEFING) ? this.getCMDestroyType(GameRules.MOB_EXPLOSION_DROP_DECAY) : Explosion.BlockInteraction.KEEP;
case TNT -> this.getCMDestroyType(GameRules.TNT_EXPLOSION_DROP_DECAY);
case TRIGGER -> Explosion.BlockInteraction.TRIGGER_BLOCK;
};
boolean cancelled = EXPLOSION.onExplosion((ServerLevel) (Object) this, source, null, new Vec3(x, y, z), r, fire, null, null, var10000);
if (cancelled) ci.cancel();
}
}
@Inject(method = "unload", at = @At("HEAD"))
private void handleChunkUnload(LevelChunk levelChunk, CallbackInfo ci)
{
if (CHUNK_UNLOADED.isNeeded())
{
ServerLevel level = (ServerLevel)((Object)this);
CHUNK_UNLOADED.onChunkEvent(level, levelChunk.getPos(), false);
}
}
}