Skip to content

Commit

Permalink
Reimplements the behavior of the previous "soft" fibs, now known as "…
Browse files Browse the repository at this point in the history
…lenient". Also adds some descriptive javadocs to BlockFib and removes @nullable, since the player should always be available.
  • Loading branch information
Haven-King committed Feb 20, 2021
1 parent c0b14e5 commit 95feeef
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 37 deletions.
69 changes: 51 additions & 18 deletions src/main/java/dev/hephaestus/fiblib/api/BlockFib.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,42 @@
import dev.hephaestus.fiblib.impl.BlockStateFib;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerActionResponseS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import org.jetbrains.annotations.Nullable;

import java.util.function.Function;
import java.util.function.BiFunction;
import java.util.function.Predicate;

public interface BlockFib {
/**
* Whether or not this BlockFib is lenient.
*
* If a fib is lenient, it will not be applied when either a {@link PlayerActionResponseS2CPacket} or a
* {@link BlockUpdateS2CPacket} is sent to the client. This means if the block is updated, or the player right
* clicks or begins mining the block, it will be revealed. This can be useful for block fibs that need to hide
* blocks at long ranges (namely: anti x-ray).
*/
boolean isLenient();

/**
* Gets the list of states this block fib applies to.
*
* This list should not change throughout a fibs life.
*/
Iterable<BlockState> getInputs();
BlockState getOutput(BlockState inputState, @Nullable ServerPlayerEntity playerEntity);

/**
* Gets the result of this fib when applied to the given state for the given player.
*
* BlockFibs are expected to return the origin input state if they don't wish to modify it.
*
* @param inputState the state to potentially fib
* @param playerEntity the player the state will be sent to
* @return the new fibbed state, or the original state
*/
BlockState getOutput(BlockState inputState, ServerPlayerEntity playerEntity);

static Builder builder(Block inputBlock, Block outputBlock) {
return new Builder(inputBlock, outputBlock);
Expand All @@ -31,40 +58,46 @@ static Builder builder(BlockState inputState, Block outputBlock) {
}

class Builder {
private final Function<@Nullable Predicate<@Nullable ServerPlayerEntity>, BlockFib> constructor;
private Predicate<@Nullable ServerPlayerEntity> condition = null;
private final BiFunction<@Nullable Predicate<ServerPlayerEntity>, Boolean, BlockFib> constructor;
private Predicate<ServerPlayerEntity> condition = null;
private boolean lenient = false;

public Builder(Block inputBlock, Block outputBlock) {
this.constructor = condition -> condition == null
? new BlockFibImpl(inputBlock, outputBlock)
: new BlockFibImpl.Conditional(inputBlock, outputBlock, condition);
this.constructor = (condition, lenient) -> condition == null
? new BlockFibImpl(inputBlock, outputBlock, lenient)
: new BlockFibImpl.Conditional(inputBlock, outputBlock, lenient, condition);
}

public Builder(BlockState inputState, BlockState outputState) {
this.constructor = condition -> condition == null
? new BlockStateFib(inputState, outputState)
: new BlockStateFib.Conditional(inputState, outputState, condition);
this.constructor = (condition, lenient) -> condition == null
? new BlockStateFib(inputState, outputState, lenient)
: new BlockStateFib.Conditional(inputState, outputState, lenient, condition);
}

public Builder(Block inputBlock, BlockState outputState) {
this.constructor = condition -> condition == null
? new BlockFibImpl(inputBlock, outputState)
: new BlockFibImpl.Conditional(inputBlock, outputState, condition);
this.constructor = (condition, lenient) -> condition == null
? new BlockFibImpl(inputBlock, outputState, lenient)
: new BlockFibImpl.Conditional(inputBlock, outputState, lenient, condition);
}

public Builder(BlockState inputState, Block outputBlock) {
this.constructor = condition -> condition == null
? new BlockStateFib(inputState, outputBlock.getDefaultState())
: new BlockStateFib.Conditional(inputState, outputBlock.getDefaultState(), condition);
this.constructor = (condition, lenient) -> condition == null
? new BlockStateFib(inputState, outputBlock.getDefaultState(), lenient)
: new BlockStateFib.Conditional(inputState, outputBlock.getDefaultState(), lenient, condition);
}

public Builder withCondition(Predicate<@Nullable ServerPlayerEntity> condition) {
public Builder withCondition(Predicate<ServerPlayerEntity> condition) {
this.condition = condition;
return this;
}

public Builder lenient() {
this.lenient = true;
return this;
}

public BlockFib build() {
return this.constructor.apply(this.condition);
return this.constructor.apply(this.condition, this.lenient);
}
}
}
21 changes: 16 additions & 5 deletions src/main/java/dev/hephaestus/fiblib/api/BlockFibRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,12 @@ public static void register(Identifier id, BlockFib blockFib) {
* @param playerEntity the player who we will be fibbing to
* @return the result of the fib.
*/
public static BlockState getBlockState(BlockState inputState, @Nullable ServerPlayerEntity playerEntity) {
public static BlockState getBlockState(BlockState inputState, ServerPlayerEntity playerEntity) {
if (playerEntity != null && playerEntity.getServer() != null) {
return ((LookupTable) playerEntity.getServer()).get(inputState, playerEntity);
} else {
BlockFib blockFib = getBlockFib(inputState, playerEntity);
return blockFib == null ? inputState : blockFib.getOutput(inputState, playerEntity);
}

return inputState;
}

/**
Expand All @@ -80,7 +79,7 @@ public static BlockState getBlockState(BlockState inputState, @Nullable ServerPl
* @param playerEntity the player who we will be fibbing to
* @return the resulting fib.
*/
public static @Nullable BlockFib getBlockFib(BlockState inputState, @Nullable ServerPlayerEntity playerEntity) {
public static @Nullable BlockFib getBlockFib(BlockState inputState, ServerPlayerEntity playerEntity) {
for (BlockFib blockFib : BLOCK_FIBS.get(inputState)) {
if (blockFib.getOutput(inputState, playerEntity) != inputState) {
return blockFib;
Expand Down Expand Up @@ -123,4 +122,16 @@ public static void reset() {
BLOCK_FIBS.clear();
BLOCK_FIBS.putAll(STATIC_BLOCK_FIBS);
}

public static BlockState getBlockStateLenient(BlockState state, ServerPlayerEntity player) {
for (BlockFib fib : BLOCK_FIBS.get(state)) {
BlockState newState;

if (!fib.isLenient() && ((newState = fib.getOutput(state, player)) != state)) {
return newState;
}
}

return state;
}
}
23 changes: 15 additions & 8 deletions src/main/java/dev/hephaestus/fiblib/impl/BlockFibImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,27 @@
public class BlockFibImpl implements BlockFib {
private final Block inputBlock;
private final BlockState outputState;
private final boolean lenient;
private final ImmutableList<BlockState> inputs;

public BlockFibImpl(Block inputBlock, BlockState outputState) {
public BlockFibImpl(Block inputBlock, BlockState outputState, boolean lenient) {
this.inputBlock = inputBlock;
this.outputState = outputState;
this.inputs = inputBlock.getStateManager().getStates();
this.lenient = lenient;
}

public BlockFibImpl(Block inputBlock, Block outputBlock) {
this(inputBlock, outputBlock.getDefaultState());
public BlockFibImpl(Block inputBlock, Block outputBlock, boolean lenient) {
this(inputBlock, outputBlock.getDefaultState(), lenient);
}

@Override
public Iterable<BlockState> getInputs() {
public final boolean isLenient() {
return this.lenient;
}

@Override
public final Iterable<BlockState> getInputs() {
return this.inputs;
}

Expand All @@ -37,12 +44,12 @@ public BlockState getOutput(BlockState inputState, @Nullable ServerPlayerEntity
public static class Conditional extends BlockFibImpl {
private final Predicate<@Nullable ServerPlayerEntity> condition;

public Conditional(Block inputBlock, Block outputBlock, Predicate<@Nullable ServerPlayerEntity> condition) {
this(inputBlock, outputBlock.getDefaultState(), condition);
public Conditional(Block inputBlock, Block outputBlock, boolean lenient, Predicate<@Nullable ServerPlayerEntity> condition) {
this(inputBlock, outputBlock.getDefaultState(), lenient, condition);
}

public Conditional(Block inputBlock, BlockState outputState, Predicate<@Nullable ServerPlayerEntity> condition) {
super(inputBlock, outputState);
public Conditional(Block inputBlock, BlockState outputState, boolean lenient, Predicate<@Nullable ServerPlayerEntity> condition) {
super(inputBlock, outputState, lenient);
this.condition = condition;
}

Expand Down
15 changes: 11 additions & 4 deletions src/main/java/dev/hephaestus/fiblib/impl/BlockStateFib.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,22 @@ public class BlockStateFib implements BlockFib {
private final BlockState inputState;
private final BlockState outputState;
private final ImmutableList<BlockState> inputStates;
private final boolean lenient;

public BlockStateFib(BlockState inputState, BlockState outputState) {
public BlockStateFib(BlockState inputState, BlockState outputState, boolean lenient) {
this.inputState = inputState;
this.outputState = outputState;
this.inputStates = ImmutableList.of(inputState);
this.lenient = lenient;
}

@Override
public Iterable<BlockState> getInputs() {
public final boolean isLenient() {
return this.lenient;
}

@Override
public final Iterable<BlockState> getInputs() {
return this.inputStates;
}

Expand All @@ -32,8 +39,8 @@ public BlockState getOutput(BlockState inputState, @Nullable ServerPlayerEntity
public static class Conditional extends BlockStateFib {
private final Predicate<@Nullable ServerPlayerEntity> condition;

public Conditional(BlockState inputState, BlockState outputState, Predicate<@Nullable ServerPlayerEntity> condition) {
super(inputState, outputState);
public Conditional(BlockState inputState, BlockState outputState, boolean lenient, Predicate<@Nullable ServerPlayerEntity> condition) {
super(inputState, outputState, lenient);
this.condition = condition;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ public class MixinBlockUpdateS2CPacket implements Fixable {

@Override
public void fix(ServerPlayerEntity player) {
this.state = BlockFibRegistry.getBlockState(this.state, player);
this.state = BlockFibRegistry.getBlockStateLenient(this.state, player);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.hephaestus.fiblib.mixin.packets;

import dev.hephaestus.fiblib.api.BlockFib;
import dev.hephaestus.fiblib.api.BlockFibRegistry;
import dev.hephaestus.fiblib.impl.Fixable;
import net.minecraft.block.BlockState;
Expand All @@ -14,6 +15,6 @@ public class MixinPlayerActionResponseS2CPacket implements Fixable {

@Override
public void fix(ServerPlayerEntity player) {
this.state = BlockFibRegistry.getBlockState(state, player);
this.state = BlockFibRegistry.getBlockStateLenient(this.state, player);
}
}

0 comments on commit 95feeef

Please sign in to comment.