mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-07 22:16:44 +01:00
Add a config option to disable the water plants fix
This commit is contained in:
parent
db8181c45e
commit
5d368d50e9
3 changed files with 107 additions and 52 deletions
|
@ -27,6 +27,8 @@ public class Config extends JsonConfig {
|
|||
"The result will always be what is set by this config file.";*/
|
||||
public final Setting<Boolean> ignoreMineLP = value("client", "ignoreMineLP", false);
|
||||
|
||||
public final Setting<Boolean> disableWaterPlantsFix = value("compatibility", "disableWaterPlantsFix", false);
|
||||
|
||||
public Config() {
|
||||
super(GamePaths.getConfigDirectory().resolve("unicopia.json"));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package com.minelittlepony.unicopia.block.data;
|
||||
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.enums.DoubleBlockHalf;
|
||||
import net.minecraft.fluid.FluidState;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.state.State;
|
||||
import net.minecraft.state.property.Properties;
|
||||
import net.minecraft.state.property.Property;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
|
||||
public class WaterLoggingManager<O, S extends State<O, S>> {
|
||||
private static final WaterLoggingManager<?, ?> INSTANCE = new WaterLoggingManager<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <O, S extends State<O, S>> WaterLoggingManager<O, S> getInstance() {
|
||||
return (WaterLoggingManager<O, S>)INSTANCE;
|
||||
}
|
||||
|
||||
private final boolean enabled;
|
||||
|
||||
public WaterLoggingManager() {
|
||||
enabled = !Unicopia.getConfig().disableWaterPlantsFix.get();
|
||||
}
|
||||
|
||||
public void appendProperties(O owner, StateBuilder builder) {
|
||||
if (appliesTo(owner)) {
|
||||
builder.addIfNotPresent(Properties.WATERLOGGED);
|
||||
}
|
||||
}
|
||||
|
||||
public void getDefaultState(O owner, CallbackInfoReturnable<S> info) {
|
||||
if (appliesTo(owner, info.getReturnValue())) {
|
||||
info.setReturnValue(info.getReturnValue().with(Properties.WATERLOGGED, true));
|
||||
}
|
||||
}
|
||||
|
||||
public void getFluidState(O owner, S state, CallbackInfoReturnable<FluidState> info) {
|
||||
if (appliesTo(owner, state)) {
|
||||
info.setReturnValue((state.get(Properties.WATERLOGGED) ? Fluids.WATER : Fluids.EMPTY).getDefaultState());
|
||||
}
|
||||
}
|
||||
|
||||
public void getUpdatedState(WorldAccess world, BlockPos pos, BlockState oldState, CallbackInfoReturnable<BlockState> info) {
|
||||
if (shouldPreventRemoval(world, pos, oldState, info.getReturnValue())) {
|
||||
info.setReturnValue(oldState);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean appliesTo(O block, S state) {
|
||||
return appliesTo(block) && state.contains(Properties.WATERLOGGED);
|
||||
}
|
||||
|
||||
public boolean appliesTo(O block) {
|
||||
return enabled
|
||||
&& (block instanceof SeagrassBlock
|
||||
|| block instanceof TallSeagrassBlock
|
||||
|| block instanceof KelpBlock
|
||||
|| block instanceof KelpPlantBlock);
|
||||
}
|
||||
|
||||
public boolean shouldPreventRemoval(WorldAccess world, BlockPos pos, AbstractBlock.AbstractBlockState oldState, AbstractBlock.AbstractBlockState newState) {
|
||||
return enabled
|
||||
&& newState.isAir()
|
||||
&& oldState.contains(Properties.WATERLOGGED)
|
||||
&& oldState.getBlock() instanceof TallSeagrassBlock
|
||||
&& oldState.contains(TallPlantBlock.HALF)
|
||||
&& oldState.get(TallPlantBlock.HALF) == DoubleBlockHalf.LOWER
|
||||
&& world.getBlockState(pos.up()).isOf(oldState.getBlock());
|
||||
}
|
||||
|
||||
public interface StateBuilder {
|
||||
void addIfNotPresent(Property<?> property);
|
||||
}
|
||||
}
|
|
@ -8,14 +8,13 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.minelittlepony.unicopia.block.data.WaterLoggingManager;
|
||||
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.enums.DoubleBlockHalf;
|
||||
import net.minecraft.fluid.FluidState;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.state.State;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.state.StateManager.Factory;
|
||||
import net.minecraft.state.property.Properties;
|
||||
import net.minecraft.state.property.Property;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
@ -28,72 +27,46 @@ abstract class MixinStateManager<O, S extends State<O, S>> {
|
|||
|
||||
@Inject(method = "getDefaultState", at = @At("RETURN"), cancellable = true)
|
||||
private void onGetDefaultState(CallbackInfoReturnable<S> info) {
|
||||
if ((owner instanceof SeagrassBlock
|
||||
|| owner instanceof TallSeagrassBlock
|
||||
|| owner instanceof KelpBlock
|
||||
|| owner instanceof KelpPlantBlock
|
||||
) && info.getReturnValue().contains(Properties.WATERLOGGED)) {
|
||||
info.setReturnValue(info.getReturnValue().with(Properties.WATERLOGGED, true));
|
||||
}
|
||||
WaterLoggingManager.<O, S>getInstance().getDefaultState(owner, info);
|
||||
}
|
||||
}
|
||||
|
||||
@Mixin(StateManager.Builder.class)
|
||||
abstract class MixinStateManagerBuilder<O, S extends State<O, S>> {
|
||||
abstract class MixinStateManagerBuilder<O, S extends State<O, S>> implements WaterLoggingManager.StateBuilder {
|
||||
@Shadow
|
||||
private @Final O owner;
|
||||
|
||||
@Shadow
|
||||
private @Final Map<String, Property<?>> namedProperties;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Inject(method = "build", at = @At("HEAD"))
|
||||
private void build(Function<O, S> defaultStateGetter, Factory<O, S> factory, CallbackInfoReturnable<StateManager<O, S>> info) {
|
||||
if (owner instanceof SeagrassBlock
|
||||
|| owner instanceof TallSeagrassBlock
|
||||
|| owner instanceof KelpBlock
|
||||
|| owner instanceof KelpPlantBlock
|
||||
) {
|
||||
if (!namedProperties.containsValue(Properties.WATERLOGGED)) {
|
||||
((StateManager.Builder<O, S>)(Object)this).add(Properties.WATERLOGGED);
|
||||
}
|
||||
WaterLoggingManager.<O, S>getInstance().appendProperties(owner, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void addIfNotPresent(Property<?> property) {
|
||||
if (!namedProperties.containsValue(property)) {
|
||||
((StateManager.Builder<O, S>)(Object)this).add(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Mixin(BlockState.class)
|
||||
abstract class MixinBlockState extends AbstractBlock.AbstractBlockState {
|
||||
protected MixinBlockState() {
|
||||
super(null, null, null);
|
||||
@Mixin(AbstractBlock.AbstractBlockState.class)
|
||||
abstract class MixinBlockState extends State<Block, BlockState> {
|
||||
MixinBlockState() {super(null, null, null);}
|
||||
|
||||
@Shadow
|
||||
protected abstract BlockState asBlockState();
|
||||
|
||||
@Inject(method = "getFluidState", at = @At("HEAD"), cancellable = true)
|
||||
private void onGetFluidState(CallbackInfoReturnable<FluidState> info) {
|
||||
WaterLoggingManager.<Block, BlockState>getInstance().getFluidState(owner, asBlockState(), info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidState getFluidState() {
|
||||
if (contains(Properties.WATERLOGGED) && (
|
||||
getBlock() instanceof SeagrassBlock
|
||||
|| getBlock() instanceof TallSeagrassBlock
|
||||
|| getBlock() instanceof KelpBlock
|
||||
|| getBlock() instanceof KelpPlantBlock
|
||||
)) {
|
||||
return (get(Properties.WATERLOGGED) ? Fluids.WATER : Fluids.EMPTY).getDefaultState();
|
||||
}
|
||||
return super.getFluidState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForNeighborUpdate(Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
|
||||
BlockState newState = super.getStateForNeighborUpdate(direction, neighborState, world, pos, neighborPos);
|
||||
if (newState.isAir()
|
||||
&& contains(Properties.WATERLOGGED)
|
||||
&& getBlock() instanceof TallSeagrassBlock
|
||||
&& contains(TallPlantBlock.HALF)
|
||||
&& get(TallPlantBlock.HALF) == DoubleBlockHalf.LOWER) {
|
||||
|
||||
BlockState above = world.getBlockState(pos.up());
|
||||
if (above.isOf(getBlock())) {
|
||||
return asBlockState();
|
||||
}
|
||||
}
|
||||
return newState;
|
||||
@Inject(method = "getStateForNeighborUpdate", at = @At("RETURN"), cancellable = true)
|
||||
private void onGetStateForNeighborUpdate(Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos, CallbackInfoReturnable<BlockState> info) {
|
||||
WaterLoggingManager.<Block, BlockState>getInstance().getUpdatedState(world, pos, asBlockState(), info);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue