5 files changed
+200
-17
No files matched your search
@@ -0,0 +1,11 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface RedstoneWireBlockInterface {
|
||||
BlockState updateLogicPublic(World world_1, BlockPos blockPos_1, BlockState blockState_1);
|
||||
void setWiresGivePower(boolean wiresGivePower);
|
||||
boolean getWiresGivePower();
|
||||
}
|
||||
+21
-15
@@ -7,11 +7,17 @@ import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import carpet.fakes.RedstoneWireBlockInterface;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.RedstoneWireBlock;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.loot.context.LootContext;
|
||||
import net.minecraft.world.loot.context.LootContextParameter;
|
||||
import net.minecraft.world.loot.context.LootContextParameters;
|
||||
|
||||
public class RedstoneWireTurbo
|
||||
{
|
||||
@@ -319,10 +325,10 @@ public class RedstoneWireTurbo
|
||||
// others are processed internally by the breadth first search
|
||||
// algorithm. To preserve this game behavior, this check must
|
||||
// be replicated here.
|
||||
if (!oldState.isValidPosition(worldIn, pos)) {
|
||||
if (!oldState.canPlaceAt(worldIn, pos)) {
|
||||
// Pop off the redstone dust
|
||||
oldState.dropBlockAsItem(worldIn, pos, 0);
|
||||
worldIn.removeBlock(pos);
|
||||
Block.dropStacks(oldState, worldIn, pos);
|
||||
worldIn.clearBlockState(pos, false);
|
||||
|
||||
// Mark this position as not being redstone wire
|
||||
upd1.type = UpdateNode.Type.OTHER;
|
||||
@@ -436,7 +442,7 @@ public class RedstoneWireTurbo
|
||||
// UpdateNode object.
|
||||
BlockState newState;
|
||||
if (old_current_change) {
|
||||
newState = wire.func_212568_b(worldIn, pos, oldState);
|
||||
newState = ((RedstoneWireBlockInterface)wire).updateLogicPublic(worldIn, pos, oldState);
|
||||
} else {
|
||||
// Looking up block state is slow. This accelerator includes a version of
|
||||
// calculateCurrentChanges that uses cahed wire values for a
|
||||
@@ -661,7 +667,7 @@ public class RedstoneWireTurbo
|
||||
// already keeping track of all of the neighbor positions
|
||||
// that need to be updated. All on its own, handling neighbors
|
||||
// this way reduces block updates by 1/3 (24 instead of 36).
|
||||
worldIn.neighborChanged(upd.self, wire, upd.parent);
|
||||
worldIn.updateNeighbor(upd.self, wire, upd.parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,7 +771,7 @@ public class RedstoneWireTurbo
|
||||
// Check this block's neighbors and see if its power level needs to change
|
||||
// Use the calculateCurrentChanges method in RedstoneWireBlock since we have no
|
||||
// cached block states at this point.
|
||||
final BlockState newState = wire.func_212568_b(worldIn, pos, state);
|
||||
final BlockState newState = ((RedstoneWireBlockInterface)wire).updateLogicPublic(worldIn, pos, state);
|
||||
|
||||
// If no change, exit
|
||||
if (newState == state) {
|
||||
@@ -835,17 +841,17 @@ public class RedstoneWireTurbo
|
||||
BlockState state = upd.currentState;
|
||||
final int i = state.get(RedstoneWireBlock.POWER);
|
||||
int j = 0;
|
||||
j = this.getMaxCurrentStrength(upd, j);
|
||||
j = getMaxCurrentStrength(upd, j);
|
||||
int l = 0;
|
||||
|
||||
wire.setCanProvidePower(false);
|
||||
((RedstoneWireBlockInterface)wire).setWiresGivePower(false);
|
||||
// Unfortunately, World.isBlockIndirectlyGettingPowered is complicated,
|
||||
// and I'm not ready to try to replicate even more functionality from
|
||||
// elsewhere in Minecraft into this accelerator. So sadly, we must
|
||||
// suffer the performance hit of this very expensive call. If there
|
||||
// is consistency to what this call returns, we may be able to cache it.
|
||||
final int k = worldIn.getRedstonePowerFromNeighbors(upd.self);
|
||||
wire.setCanProvidePower(true);
|
||||
final int k = worldIn.getReceivedRedstonePower(upd.self);
|
||||
((RedstoneWireBlockInterface)wire).setWiresGivePower(true);
|
||||
|
||||
// The variable 'k' holds the maximum redstone power value of any adjacent blocks.
|
||||
// If 'k' has the highest level of all neighbors, then the power level of this
|
||||
@@ -863,7 +869,7 @@ public class RedstoneWireTurbo
|
||||
// position directly above the node being calculated is always
|
||||
// at index 1.
|
||||
UpdateNode center_up = upd.neighbor_nodes[1];
|
||||
boolean center_up_is_cube = center_up.currentState.isNormalCube();
|
||||
boolean center_up_is_cube = center_up.currentState.isSimpleFullBlock(worldIn, center_up.self);
|
||||
|
||||
for (int m=0; m<4; m++) {
|
||||
// Get the neighbor array index of each of the four cardinal
|
||||
@@ -873,18 +879,18 @@ public class RedstoneWireTurbo
|
||||
// Get the max redstone power level of each of the cardinal
|
||||
// neighbors
|
||||
UpdateNode neighbor = upd.neighbor_nodes[n];
|
||||
l = this.getMaxCurrentStrength(neighbor, l);
|
||||
l = getMaxCurrentStrength(neighbor, l);
|
||||
|
||||
// Also check the positions above and below the cardinal
|
||||
// neighbors
|
||||
boolean neighbor_is_cube = neighbor.currentState.isNormalCube();
|
||||
boolean neighbor_is_cube = neighbor.currentState.isSimpleFullBlock(worldIn, neighbor.self);
|
||||
if (!neighbor_is_cube) {
|
||||
UpdateNode neighbor_down = upd.neighbor_nodes[rs_neighbors_dn[m]];
|
||||
l = this.getMaxCurrentStrength(neighbor_down, l);
|
||||
l = getMaxCurrentStrength(neighbor_down, l);
|
||||
} else
|
||||
if (!center_up_is_cube) {
|
||||
UpdateNode neighbor_up = upd.neighbor_nodes[rs_neighbors_up[m]];
|
||||
l = this.getMaxCurrentStrength(neighbor_up, l);
|
||||
l = getMaxCurrentStrength(neighbor_up, l);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.settings.CarpetSettings;
|
||||
import carpet.fakes.RedstoneWireBlockInterface;
|
||||
import carpet.helpers.RedstoneWireTurbo;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.RedstoneWireBlock;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import static net.minecraft.block.RedstoneWireBlock.POWER;
|
||||
|
||||
@Mixin(RedstoneWireBlock.class)
|
||||
public abstract class RedstoneWireBlockMixin implements RedstoneWireBlockInterface {
|
||||
// =
|
||||
|
||||
@Shadow
|
||||
private boolean wiresGivePower;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private Set<BlockPos> affectedNeighbors;
|
||||
|
||||
@Shadow
|
||||
private int increasePower(int int_1, BlockState blockState_1) { return 0; };
|
||||
|
||||
@Shadow
|
||||
private BlockState update(World world_1, BlockPos blockPos_1, BlockState blockState_1) { return null; };
|
||||
|
||||
// =
|
||||
|
||||
@Override
|
||||
public BlockState updateLogicPublic(World world_1, BlockPos blockPos_1, BlockState blockState_1) {
|
||||
return updateLogic(world_1, blockPos_1, blockState_1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Accessor("wiresGivePower")
|
||||
public abstract void setWiresGivePower(boolean wiresGivePower);
|
||||
|
||||
@Override
|
||||
@Accessor("wiresGivePower")
|
||||
public abstract boolean getWiresGivePower();
|
||||
|
||||
// =
|
||||
|
||||
private RedstoneWireTurbo wireTurbo = null;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void onRedstoneWireBlockCTOR(Block.Settings settings, CallbackInfo ci) {
|
||||
//noinspection ConstantConditions
|
||||
wireTurbo = new RedstoneWireTurbo((RedstoneWireBlock) (Object) this);
|
||||
}
|
||||
|
||||
// =
|
||||
|
||||
public BlockState fastUpdate(World world, BlockPos pos, BlockState state, BlockPos source) {
|
||||
// [CM] fastRedstoneDust -- update based on carpet rule
|
||||
if (CarpetSettings.fastRedstoneDust) {
|
||||
return wireTurbo.updateSurroundingRedstone(world, pos, state, source);
|
||||
}
|
||||
return update(world, pos, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author theosib, soykaf, gnembon
|
||||
*/
|
||||
@Overwrite
|
||||
private BlockState updateLogic(World world_1, BlockPos blockPos_1, BlockState blockState_1) {
|
||||
BlockState blockState_2 = blockState_1;
|
||||
int int_1 = (Integer)blockState_1.get(POWER); // i
|
||||
this.wiresGivePower = false;
|
||||
int int_2 = world_1.getReceivedRedstonePower(blockPos_1); // k
|
||||
this.wiresGivePower = true;
|
||||
int int_3 = 0; // l
|
||||
if (!CarpetSettings.fastRedstoneDust || int_2 < 15) {
|
||||
Iterator var8 = Direction.Type.HORIZONTAL.iterator();
|
||||
|
||||
label43:
|
||||
while(true) {
|
||||
while(true) {
|
||||
if (!var8.hasNext()) {
|
||||
break label43;
|
||||
}
|
||||
|
||||
Direction direction_1 = (Direction)var8.next();
|
||||
BlockPos blockPos_2 = blockPos_1.offset(direction_1);
|
||||
BlockState blockState_3 = world_1.getBlockState(blockPos_2);
|
||||
int_3 = this.increasePower(int_3, blockState_3);
|
||||
BlockPos blockPos_3 = blockPos_1.up();
|
||||
if (blockState_3.isSimpleFullBlock(world_1, blockPos_2) && !world_1.getBlockState(blockPos_3).isSimpleFullBlock(world_1, blockPos_3)) {
|
||||
int_3 = this.increasePower(int_3, world_1.getBlockState(blockPos_2.up()));
|
||||
} else if (!blockState_3.isSimpleFullBlock(world_1, blockPos_2)) {
|
||||
int_3 = this.increasePower(int_3, world_1.getBlockState(blockPos_2.down()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int int_4 = int_3 - 1;
|
||||
if (int_2 > int_4) int_4 = int_2;
|
||||
|
||||
|
||||
if (int_1 != int_4) {
|
||||
blockState_1 = (BlockState)blockState_1.with(POWER, int_4);
|
||||
if (world_1.getBlockState(blockPos_1) == blockState_2) {
|
||||
world_1.setBlockState(blockPos_1, blockState_1, 2);
|
||||
}
|
||||
|
||||
if (!CarpetSettings.fastRedstoneDust) {
|
||||
this.affectedNeighbors.add(blockPos_1);
|
||||
Direction[] var14 = Direction.values();
|
||||
int var15 = var14.length;
|
||||
|
||||
for (int var16 = 0; var16 < var15; ++var16) {
|
||||
Direction direction_2 = var14[var16];
|
||||
this.affectedNeighbors.add(blockPos_1.offset(direction_2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return blockState_1;
|
||||
}
|
||||
|
||||
// =
|
||||
|
||||
|
||||
@Redirect(method = "onBlockAdded", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/RedstoneWireBlock;update(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Lnet/minecraft/block/BlockState;"))
|
||||
private BlockState redirectOnBlockAddedUpdate(RedstoneWireBlock self, World world_1, BlockPos blockPos_1, BlockState blockState_1) {
|
||||
return fastUpdate(world_1, blockPos_1, blockState_1, null);
|
||||
}
|
||||
|
||||
@Redirect(method = "onBlockRemoved", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/RedstoneWireBlock;update(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Lnet/minecraft/block/BlockState;"))
|
||||
private BlockState redirectOnBlockRemovedUpdate(RedstoneWireBlock self, World world_1, BlockPos blockPos_1, BlockState blockState_1) {
|
||||
return fastUpdate(world_1, blockPos_1, blockState_1, null);
|
||||
}
|
||||
|
||||
@Redirect(method = "neighborUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/RedstoneWireBlock;update(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Lnet/minecraft/block/BlockState;"))
|
||||
private BlockState redirectNeighborUpdateUpdate(
|
||||
RedstoneWireBlock self,
|
||||
World world_1,
|
||||
BlockPos blockPos_1,
|
||||
BlockState blockState_1,
|
||||
BlockState blockState_2,
|
||||
World world_2,
|
||||
BlockPos blockPos_2,
|
||||
Block block_1,
|
||||
BlockPos blockPos_3,
|
||||
boolean boolean_1) {
|
||||
return fastUpdate(world_1, blockPos_1, blockState_1, blockPos_3);
|
||||
}
|
||||
}
|
||||
@@ -92,8 +92,7 @@ public class CarpetSettings
|
||||
@Rule(
|
||||
desc = "Lag optimizations for redstone dust",
|
||||
extra = "by Theosib",
|
||||
category = {EXPERIMENTAL, OPTIMIZATION},
|
||||
validate = Validator.WIP.class
|
||||
category = {EXPERIMENTAL, OPTIMIZATION}
|
||||
)
|
||||
public static boolean fastRedstoneDust = false;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"PlayerActionC2SPacketMixin",
|
||||
"ServerPlayerEntityMixin",
|
||||
"PlayerManagerMixin",
|
||||
"RedstoneWireBlockMixin",
|
||||
"CarpetBlockMixin",
|
||||
"SummonCommandMixin",
|
||||
"PistonHandler_pushLimitMixin",
|
||||
|
||||
Reference in new issue
Block a user