Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package net.caffeinemc.mods.lithium.common.block.entity.sleeping_sculk;

public interface GameEventListenerWithCallback {
void lithium$setGameEventCallback(Runnable listener);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.sculk_catalyst;

import net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity;
import net.caffeinemc.mods.lithium.common.block.entity.sleeping_sculk.GameEventListenerWithCallback;
import net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.WrappedBlockEntityTickInvokerAccessor;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.SculkCatalystBlockEntity;
import net.minecraft.world.level.block.entity.TickingBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.ValueInput;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(SculkCatalystBlockEntity.class)
public abstract class SculkCatalystBlockEntityMixin implements SleepingBlockEntity {
private WrappedBlockEntityTickInvokerAccessor tickWrapper = null;
private TickingBlockEntity sleepingTicker = null;

@Shadow
public abstract SculkCatalystBlockEntity.CatalystListener getListener();

@Shadow
@Final
private SculkCatalystBlockEntity.CatalystListener catalystListener;

@Override
public WrappedBlockEntityTickInvokerAccessor lithium$getTickWrapper() {
return tickWrapper;
}

@Override
public void lithium$setTickWrapper(WrappedBlockEntityTickInvokerAccessor tickWrapper) {
this.tickWrapper = tickWrapper;
this.lithium$setSleepingTicker(null);
}

@Override
public TickingBlockEntity lithium$getSleepingTicker() {
return sleepingTicker;
}

@Override
public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) {
this.sleepingTicker = sleepingTicker;
}

@Inject(method = "<init>", at = @At("RETURN"))
private void addCatalystListenerCallback(BlockPos blockPos, BlockState blockState, CallbackInfo ci) {
((GameEventListenerWithCallback) this.catalystListener.getSculkSpreader()).lithium$setGameEventCallback(this::wakeUpNow);
}

@Inject(method = "serverTick", at = @At("RETURN"))
private static void sleepIfNoCursors(Level level, BlockPos blockPos, BlockState blockState, SculkCatalystBlockEntity sculkCatalystBlockEntity, CallbackInfo ci) {
if(sculkCatalystBlockEntity.getListener().getSculkSpreader().getCursors().isEmpty()) {
((SleepingBlockEntity) sculkCatalystBlockEntity).lithium$startSleeping();
}
}

// This is to detect modification by commands
@Inject(method = "loadAdditional", at=@At("RETURN"))
private void wakeupIfLoadedWithData(ValueInput valueInput, CallbackInfo ci) {
if (!this.getListener().getSculkSpreader().getCursors().isEmpty()) {
this.wakeUpNow();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.sculk_catalyst;

import net.caffeinemc.mods.lithium.common.block.entity.sleeping_sculk.GameEventListenerWithCallback;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.SculkSpreader;
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;

@Mixin(SculkSpreader.class)
public class SculkSpreaderMixin implements GameEventListenerWithCallback {
private Runnable listener;

@Inject(method = "addCursors", at = @At("RETURN"))
public void listenToCursorAddition(BlockPos blockPos, int i, CallbackInfo ci) {
if (this.listener != null) {
this.listener.run();
}
}

@Override
public void lithium$setGameEventCallback(Runnable listener) {
this.listener = listener;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@MixinConfigOption(description = "BlockEntity sleeping for inactive sculk catalysts")
package net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.sculk_catalyst;

import net.caffeinemc.gradle.MixinConfigOption;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.sculk_sensor_shrieker;

import net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.CalibratedSculkSensorBlock;
import net.minecraft.world.level.block.entity.*;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.vibrations.VibrationSystem;
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;

@Mixin(CalibratedSculkSensorBlock.class)
public abstract class CalibratedSculkSensorBlockMixin {
@Inject(method = {"method_49813"}, at = @At(value = "RETURN"))
private static void checkSleep(Level level, BlockPos blockPos, BlockState blockState, CalibratedSculkSensorBlockEntity calibratedSculkSensorBlockEntity, CallbackInfo ci) {
final VibrationSystem.Data vibrationData = calibratedSculkSensorBlockEntity.getVibrationData();
if (vibrationData.getCurrentVibration() == null &&
vibrationData.getSelectionStrategy().chosenCandidate(Long.MAX_VALUE).isEmpty()) {
((SleepingBlockEntity) calibratedSculkSensorBlockEntity).lithium$startSleeping();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.sculk_sensor_shrieker;

import net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity;
import net.caffeinemc.mods.lithium.common.block.entity.sleeping_sculk.GameEventListenerWithCallback;
import net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.WrappedBlockEntityTickInvokerAccessor;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.entity.SculkSensorBlockEntity;
import net.minecraft.world.level.block.entity.TickingBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.vibrations.VibrationSystem;
import net.minecraft.world.level.storage.ValueInput;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(SculkSensorBlockEntity.class)
public abstract class SculkSensorBlockEntityMixin implements SleepingBlockEntity, VibrationSystem {
@Shadow
private VibrationSystem.Data vibrationData;

@Shadow
@Final
private Listener vibrationListener;

private WrappedBlockEntityTickInvokerAccessor tickWrapper = null;
private TickingBlockEntity sleepingTicker = null;

@Override
public WrappedBlockEntityTickInvokerAccessor lithium$getTickWrapper() {
return tickWrapper;
}

@Override
public void lithium$setTickWrapper(WrappedBlockEntityTickInvokerAccessor tickWrapper) {
this.tickWrapper = tickWrapper;
this.lithium$setSleepingTicker(null);
}

@Override
public TickingBlockEntity lithium$getSleepingTicker() {
return sleepingTicker;
}

@Override
public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) {
this.sleepingTicker = sleepingTicker;
}

@Inject(method = "<init>(Lnet/minecraft/world/level/block/entity/BlockEntityType;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V", at = @At("RETURN"))
private void setVibrationListenerListener(BlockEntityType blockEntityType, BlockPos blockPos, BlockState blockState, CallbackInfo ci) {
((GameEventListenerWithCallback) this.vibrationListener).lithium$setGameEventCallback(this::wakeUpNow);
}

// This is to detect modification by commands
@Inject(method = "loadAdditional", at=@At("RETURN"))
private void wakeupIfLoadedWithData(ValueInput valueInput, CallbackInfo ci) {
if (vibrationData.getSelectionStrategy().chosenCandidate(Long.MAX_VALUE).isPresent()) {
this.wakeUpNow();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.sculk_sensor_shrieker;

import net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.SculkSensorBlock;
import net.minecraft.world.level.block.entity.SculkSensorBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.vibrations.VibrationSystem;
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;

@Mixin(SculkSensorBlock.class)
public abstract class SculkSensorBlockMixin {
@Inject(method = {"method_32905"}, at = @At(value = "RETURN"))
private static void checkSleep(Level level, BlockPos blockPos, BlockState blockState, SculkSensorBlockEntity sculkSensorBlockEntity, CallbackInfo ci) {
final VibrationSystem.Data vibrationData = sculkSensorBlockEntity.getVibrationData();
if (vibrationData.getCurrentVibration() == null &&
vibrationData.getSelectionStrategy().chosenCandidate(Long.MAX_VALUE).isEmpty()) {
((SleepingBlockEntity) sculkSensorBlockEntity).lithium$startSleeping();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.sculk_sensor_shrieker;

import net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity;
import net.caffeinemc.mods.lithium.common.block.entity.sleeping_sculk.GameEventListenerWithCallback;
import net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.WrappedBlockEntityTickInvokerAccessor;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.entity.SculkShriekerBlockEntity;
import net.minecraft.world.level.block.entity.TickingBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.vibrations.VibrationSystem;
import net.minecraft.world.level.storage.ValueInput;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(SculkShriekerBlockEntity.class)
public abstract class SculkShriekerBlockEntityMixin implements SleepingBlockEntity, VibrationSystem {
@Shadow
private VibrationSystem.Data vibrationData;

@Shadow
@Final
private Listener vibrationListener;

private WrappedBlockEntityTickInvokerAccessor tickWrapper = null;
private TickingBlockEntity sleepingTicker = null;

@Override
public WrappedBlockEntityTickInvokerAccessor lithium$getTickWrapper() {
return tickWrapper;
}

@Override
public void lithium$setTickWrapper(WrappedBlockEntityTickInvokerAccessor tickWrapper) {
this.tickWrapper = tickWrapper;
this.lithium$setSleepingTicker(null);
}

@Override
public TickingBlockEntity lithium$getSleepingTicker() {
return sleepingTicker;
}

@Override
public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) {
this.sleepingTicker = sleepingTicker;
}

@Inject(method = "<init>", at = @At("RETURN"))
private void setVibrationListenerListener(BlockPos blockPos, BlockState blockState, CallbackInfo ci) {
((GameEventListenerWithCallback) this.vibrationListener).lithium$setGameEventCallback(this::wakeUpNow);
}

// This is to detect modification by commands
@Inject(method = "loadAdditional", at=@At("RETURN"))
private void wakeupIfLoadedWithData(ValueInput valueInput, CallbackInfo ci) {
if (this.vibrationData.getSelectionStrategy().chosenCandidate(Long.MAX_VALUE).isPresent()) {
this.wakeUpNow();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.sculk_sensor_shrieker;

import net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.SculkShriekerBlock;
import net.minecraft.world.level.block.entity.SculkShriekerBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.vibrations.VibrationSystem;
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;

@Mixin(SculkShriekerBlock.class)
public abstract class SculkShriekerBlockMixin {
@Inject(method = {"method_42317"}, at = @At(value = "RETURN"))
private static void checkSleep(Level level, BlockPos blockPos, BlockState blockState, SculkShriekerBlockEntity sculkShriekerBlockEntity, CallbackInfo ci) {
final VibrationSystem.Data vibrationData = sculkShriekerBlockEntity.getVibrationData();
if (vibrationData.getCurrentVibration() == null &&
vibrationData.getSelectionStrategy().chosenCandidate(Long.MAX_VALUE).isEmpty()) {
((SleepingBlockEntity) sculkShriekerBlockEntity).lithium$startSleeping();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.sculk_sensor_shrieker;

import net.caffeinemc.mods.lithium.common.block.entity.sleeping_sculk.GameEventListenerWithCallback;
import net.minecraft.core.Holder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.gameevent.vibrations.VibrationSystem;
import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Mixin;
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.CallbackInfoReturnable;

@Mixin(VibrationSystem.Listener.class)
public abstract class VibrationSystemListenerMixin implements GameEventListenerWithCallback {
@Unique
private Runnable listener;

@Override
public void lithium$setGameEventCallback(Runnable listener) {
this.listener = listener;
}

@Inject(method = "handleGameEvent", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/gameevent/vibrations/VibrationSystem$Listener;scheduleVibration(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/gameevent/vibrations/VibrationSystem$Data;Lnet/minecraft/core/Holder;Lnet/minecraft/world/level/gameevent/GameEvent$Context;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;)V"))
private void onCurrentVibrationUpdate(ServerLevel serverLevel, Holder<GameEvent> holder, GameEvent.Context context, Vec3 vec3, CallbackInfoReturnable<Boolean> cir) {
if (this.listener != null) {
this.listener.run();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@MixinConfigOption(description = "BlockEntity sleeping for inactive sculk sensors and sculk shriekers")
package net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping.sculk_sensor_shrieker;

import net.caffeinemc.gradle.MixinConfigOption;
8 changes: 8 additions & 0 deletions common/src/main/resources/lithium.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,14 @@
"world.block_entity_ticking.sleeping.crafter.CrafterBlockEntityMixin",
"world.block_entity_ticking.sleeping.furnace.AbstractFurnaceBlockEntityMixin",
"world.block_entity_ticking.sleeping.hopper.HopperBlockEntityMixin",
"world.block_entity_ticking.sleeping.sculk_catalyst.SculkCatalystBlockEntityMixin",
"world.block_entity_ticking.sleeping.sculk_catalyst.SculkSpreaderMixin",
"world.block_entity_ticking.sleeping.sculk_sensor_shrieker.CalibratedSculkSensorBlockMixin",
"world.block_entity_ticking.sleeping.sculk_sensor_shrieker.SculkSensorBlockEntityMixin",
"world.block_entity_ticking.sleeping.sculk_sensor_shrieker.SculkSensorBlockMixin",
"world.block_entity_ticking.sleeping.sculk_sensor_shrieker.SculkShriekerBlockEntityMixin",
"world.block_entity_ticking.sleeping.sculk_sensor_shrieker.SculkShriekerBlockMixin",
"world.block_entity_ticking.sleeping.sculk_sensor_shrieker.VibrationSystemListenerMixin",
"world.block_entity_ticking.sleeping.shulker_box.ShulkerBoxBlockEntityMixin",
"world.block_entity_ticking.world_border.DirectBlockEntityTickInvokerMixin",
"world.chunk_access.ChunkHolderMixin",
Expand Down
8 changes: 8 additions & 0 deletions lithium-fabric-mixin-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,14 @@ BlockEntity sleeping for inactive furnaces
(default: `true`)
BlockEntity sleeping for locked hoppers

### `mixin.world.block_entity_ticking.sleeping.sculk_catalyst`
(default: `true`)
BlockEntity sleeping for inactive sculk catalysts

### `mixin.world.block_entity_ticking.sleeping.sculk_sensor_shrieker`
(default: `true`)
BlockEntity sleeping for inactive sculk sensors and sculk shriekers

### `mixin.world.block_entity_ticking.sleeping.shulker_box`
(default: `true`)
BlockEntity sleeping for closed shulker boxes
Expand Down
Loading