Skip to content
Open
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
Expand Up @@ -5,5 +5,24 @@
import net.minecraft.world.level.block.state.BlockState;

public interface NeighborChangeListeningBlock {

/**
* Used by the neighbouring blocks to notify this block that that neighbour updated
* @param state Block state at position pos
* @param world The world
* @param pos Block position
* @param neighbor Neighbour position
*/
void onNeighborChange(BlockState state, LevelReader world, BlockPos pos, BlockPos neighbor);

/**
* Check if this block should be notified of weak changes. <br>
* Weak changes are changes 1 block away through a solid block. Similar to comparators.
* @param level The world
* @param pos Block position
* @return true if there are weak changes to check. False otherwise
*/
default boolean getWeakChanges(BlockState state, LevelReader level, BlockPos pos) {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package io.github.fabricators_of_create.porting_lib.extensions;

import io.github.fabricators_of_create.porting_lib.block.NeighborChangeListeningBlock;

public interface ComparatorBlockExtension extends NeighborChangeListeningBlock {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.github.fabricators_of_create.porting_lib.mixin.common;

import io.github.fabricators_of_create.porting_lib.extensions.ComparatorBlockExtension;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.ComparatorBlock;

import net.minecraft.world.level.block.state.BlockState;

import org.spongepowered.asm.mixin.Mixin;

@Mixin(ComparatorBlock.class)
public class ComparatorBlockMixin implements ComparatorBlockExtension {
@Override
public void onNeighborChange(BlockState state, LevelReader world, BlockPos pos, BlockPos neighbor) {
if (pos.getY() == neighbor.getY() && world instanceof Level && !world.isClientSide()) {
state.neighborChanged((Level)world, pos, world.getBlockState(neighbor).getBlock(), neighbor, false);
}
}

@Override
public boolean getWeakChanges(BlockState state, LevelReader level, BlockPos pos) {
return state.is(Blocks.COMPARATOR);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,22 @@
import java.util.LinkedList;
import java.util.List;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;

import io.github.fabricators_of_create.porting_lib.block.LightEmissiveBlock;
import io.github.fabricators_of_create.porting_lib.core.PortingLib;
import io.github.fabricators_of_create.porting_lib.event.common.BlockEvents;
import io.github.fabricators_of_create.porting_lib.event.common.ExplosionEvents;
import io.github.fabricators_of_create.porting_lib.extensions.extensions.BlockEntityExtensions;
import io.github.fabricators_of_create.porting_lib.extensions.extensions.LevelExtensions;
import net.fabricmc.fabric.api.transfer.v1.transaction.base.SnapshotParticipant;
import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.FullChunkStatus;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.ExplosionDamageCalculator;

import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.chunk.LevelChunk;

Expand All @@ -43,7 +40,6 @@
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

import io.github.fabricators_of_create.porting_lib.block.NeighborChangeListeningBlock;
import io.github.fabricators_of_create.porting_lib.block.WeakPowerCheckingBlock;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
Expand Down Expand Up @@ -155,25 +151,45 @@ public SnapshotParticipant<LevelSnapshotData> snapshotParticipant() {
}
}

@Inject(
method = "updateNeighbourForOutputSignal",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;",
shift = Shift.BY,
by = 2,
ordinal = 0
),
locals = LocalCapture.CAPTURE_FAILHARD
/** Force cancel check for comparator and always say it is not. The comparator now implements
* NeighborChangeListeningBlock so code specific for comparators in {@link Level#updateNeighbourForOutputSignal(BlockPos, Block)}
* should be unreachable and instead handled via {@link LevelMixin#port_lib$updateNeighbourForOutputSignal(BlockPos, Block, CallbackInfo, BlockPos, BlockState)}
* and {@link LevelMixin#port_lib$updateNeighbourForOutputSignal2(BlockPos, Block, CallbackInfo, BlockPos, BlockState)}
* which call {@link NeighborChangeListeningBlock#onNeighborChange(BlockState, LevelReader, BlockPos, BlockPos)}
*/
@Redirect(method = "updateNeighbourForOutputSignal",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;is(Lnet/minecraft/world/level/block/Block;)Z")
)
public void port_lib$updateNeighbourForOutputSignal(BlockPos pos, Block block, CallbackInfo ci,
Iterator<?> var3, Direction direction, BlockPos offset,
BlockState state) {
public boolean port_lib$updateNeighbourForOutputSignalCancelCompChk(BlockState instance, Block block) {
return false;
}

/** Runs on first invocation of {@link Level#getBlockState(BlockPos)} in {@link Level#updateNeighbourForOutputSignal(BlockPos, Block)}
*/
@Inject(method = "updateNeighbourForOutputSignal",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;",
shift = Shift.BY, by = 2, ordinal = 0)
)
public void port_lib$updateNeighbourForOutputSignal(BlockPos pos, Block block, CallbackInfo ci, @Local(ordinal = 1) BlockPos offset, @Local BlockState state) {
if (state.getBlock() instanceof NeighborChangeListeningBlock listener) {
listener.onNeighborChange(state, this, offset, pos);
}
}

/** Runs on second invocation of {@link Level#getBlockState(BlockPos)} in {@link Level#updateNeighbourForOutputSignal(BlockPos, Block)}
* (i.e. the one checking for changes through a block. So should only update for weak change listeners only
* (see {@link NeighborChangeListeningBlock#getWeakChanges(BlockState, LevelReader, BlockPos)}))
*/
@Inject(method = "updateNeighbourForOutputSignal",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;",
shift = Shift.BY, by = 2, ordinal = 1)
)
public void port_lib$updateNeighbourForOutputSignal2(BlockPos pos, Block block, CallbackInfo ci, @Local(ordinal = 1) BlockPos offset, @Local BlockState state) {
if (state.getBlock() instanceof NeighborChangeListeningBlock listener && listener.getWeakChanges(state, this, pos)) {
listener.onNeighborChange(state, this, offset, pos);
}
}

@Inject(
method = "explode(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/damagesource/DamageSource;Lnet/minecraft/world/level/ExplosionDamageCalculator;DDDFZLnet/minecraft/world/level/Level$ExplosionInteraction;Z)Lnet/minecraft/world/level/Explosion;",
at = @At(
Expand Down
3 changes: 2 additions & 1 deletion modules/base/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"custom": {
"loom:injected_interfaces": {
"net/minecraft/class_3283": ["io/github/fabricators_of_create/porting_lib/extensions/PackRepositoryExtension"],
"net/minecraft/class_2680": ["io/github/fabricators_of_create/porting_lib/extensions/BaseBlockStateExtension"]
"net/minecraft/class_2680": ["io/github/fabricators_of_create/porting_lib/extensions/BaseBlockStateExtension"],
"net/minecraft/class_2286": ["io/github/fabricators_of_create/porting_lib/extensions/ComparatorBlockExtension"]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"common.ChunkMapMixin",
"common.ChunkStatusMixin",
"common.ClipContextMixin",
"common.ComparatorBlockMixin",
"common.ConnectionMixin",
"common.DeadBushBlockMixin",
"common.DiodeBlockMixin",
Expand Down
1 change: 1 addition & 0 deletions modules/entity/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
portingLib {
addModuleDependency("mixin_extensions")
addModuleDependency("fluids")
enableTestMod()
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.github.fabricators_of_create.porting_lib.entity.extensions;

import io.github.fabricators_of_create.porting_lib.entity.ITeleporter;
import io.github.fabricators_of_create.porting_lib.fluids.FluidType;
import io.github.fabricators_of_create.porting_lib.fluids.PortingLibFluids;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
Expand Down Expand Up @@ -34,4 +36,12 @@ default boolean canRiderInteract() {
default Entity changeDimension(ServerLevel p_20118_, ITeleporter teleporter) {
throw new RuntimeException("this should be overridden via mixin. what?");
}

default FluidType getEyeInFluidType() {
throw new RuntimeException("This should be overridden in the EntityMixin");
}

default boolean isEyeInFluidType(FluidType type) {
return type == this.getEyeInFluidType();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.github.fabricators_of_create.porting_lib.entity.extensions;

import io.github.fabricators_of_create.porting_lib.fluids.FluidType;
import net.minecraft.world.entity.LivingEntity;

import io.github.fabricators_of_create.porting_lib.fluids.PortingLibFluids;

public interface LivingEntityExtensions {
default LivingEntity self() {
return (LivingEntity) this;
}

/**
* Returns whether the entity can drown in the fluid.
*
* @param type the type of the fluid
* @return {@code true} if the entity can drown in the fluid, {@code false} otherwise
*/
default boolean canDrownInFluidType(FluidType type) {
if (type == PortingLibFluids.WATER_TYPE) return !self().canBreatheUnderwater();
return type.canDrownIn(self());
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

import java.util.Collection;

import io.github.fabricators_of_create.porting_lib.fluids.FluidType;
import io.github.fabricators_of_create.porting_lib.fluids.PortingLibFluids;
import net.minecraft.core.BlockPos;
import net.minecraft.tags.FluidTags;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.material.FluidState;

import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
Expand Down Expand Up @@ -41,6 +48,8 @@
import net.minecraft.world.level.Level;
import net.minecraft.world.level.portal.PortalInfo;

import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

@Mixin(Entity.class)
public abstract class EntityMixin implements EntityExtensions {
@Unique
Expand Down Expand Up @@ -124,6 +133,9 @@ public Collection<ItemEntity> captureDrops(Collection<ItemEntity> value) {
@Shadow
private Level level;

@Shadow
protected boolean wasEyeInWater;

@Shadow
public abstract void unRide();

Expand Down Expand Up @@ -158,6 +170,24 @@ public Collection<ItemEntity> captureDrops(Collection<ItemEntity> value) {
@Shadow
public abstract float getEyeHeight();

@Shadow
public abstract double getX();

@Shadow
public abstract double getY();

@Shadow
public abstract double getZ();

@Shadow
public abstract double getEyeY();

@Shadow
public abstract Entity getVehicle();

@Shadow
public abstract Level level();

@Inject(
method = "startRiding(Lnet/minecraft/world/entity/Entity;Z)Z",
at = @At(
Expand Down Expand Up @@ -275,4 +305,22 @@ public void afterSave(CompoundTag nbt, CallbackInfoReturnable<CompoundTag> cir)
public void afterLoad(CompoundTag nbt, CallbackInfo ci) {
EntityDataEvents.LOAD.invoker().onLoad((Entity) (Object) this, nbt);
}

@Unique
private FluidType fluidTypeOnEyes = PortingLibFluids.EMPTY_TYPE;

@Inject(method = "updateFluidOnEyes", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/material/FluidState;getTags()Ljava/util/stream/Stream;"))
private void updateFluidOnEyesSetFluidTypeOnEyes(CallbackInfo ci, @Local FluidState fluidState) {
this.fluidTypeOnEyes = fluidState.getFluidType();
}

@Inject(method = "updateFluidOnEyes", at = @At("HEAD"))
private void updateFluidOnEyesResetFluidTypeOnEyes(CallbackInfo ci) {
this.fluidTypeOnEyes = PortingLibFluids.EMPTY_TYPE;
}

@Override
public FluidType getEyeInFluidType() {
return this.fluidTypeOnEyes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.github.fabricators_of_create.porting_lib.entity.events.living.LivingHurtEvent;

import io.github.fabricators_of_create.porting_lib.entity.events.living.MobEffectEvent;
import io.github.fabricators_of_create.porting_lib.entity.extensions.LivingEntityExtensions;
import net.minecraft.world.effect.MobEffect;

import net.minecraft.world.effect.MobEffectInstance;
Expand Down Expand Up @@ -57,7 +58,7 @@
import net.minecraft.world.level.Level;

@Mixin(LivingEntity.class)
public abstract class LivingEntityMixin extends Entity implements EntityExtensions {
public abstract class LivingEntityMixin extends Entity implements LivingEntityExtensions {
@Shadow
protected int lastHurtByPlayerTime;
@Shadow
Expand Down
3 changes: 2 additions & 1 deletion modules/entity/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"net/minecraft/class_1657": ["io/github/fabricators_of_create/porting_lib/entity/extensions/PlayerExtension"],
"net/minecraft/class_1688": ["io/github/fabricators_of_create/porting_lib/entity/extensions/AbstractMinecartExtensions"],
"net/minecraft/class_1792": ["io/github/fabricators_of_create/porting_lib/entity/extensions/ItemExtensions"],
"net/minecraft/class_1937": ["io/github/fabricators_of_create/porting_lib/entity/extensions/LevelExtensions"]
"net/minecraft/class_1937": ["io/github/fabricators_of_create/porting_lib/entity/extensions/LevelExtensions"],
"net/minecraft/class_1309": ["io/github/fabricators_of_create/porting_lib/entity/extensions/LivingEntityExtensions"]
}
}
}