4 files changed
+229
-15
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();
|
||||||
|
}
|
||||||
+30
-15
@@ -7,11 +7,17 @@ import java.util.Map;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
import carpet.fakes.RedstoneWireBlockInterface;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.RedstoneWireBlock;
|
import net.minecraft.block.RedstoneWireBlock;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.ItemEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
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
|
public class RedstoneWireTurbo
|
||||||
{
|
{
|
||||||
@@ -319,10 +325,19 @@ public class RedstoneWireTurbo
|
|||||||
// others are processed internally by the breadth first search
|
// others are processed internally by the breadth first search
|
||||||
// algorithm. To preserve this game behavior, this check must
|
// algorithm. To preserve this game behavior, this check must
|
||||||
// be replicated here.
|
// be replicated here.
|
||||||
if (!oldState.isValidPosition(worldIn, pos)) {
|
if (!oldState.canPlaceAt(worldIn, pos)) {
|
||||||
// Pop off the redstone dust
|
// Pop off the redstone dust
|
||||||
oldState.dropBlockAsItem(worldIn, pos, 0);
|
// aurieh: there must be a better way to do this
|
||||||
worldIn.removeBlock(pos);
|
LootContext.Builder ctx = new LootContext
|
||||||
|
.Builder(worldIn.getServer().getWorld(worldIn.dimension.getType()))
|
||||||
|
.put(LootContextParameters.POSITION, pos)
|
||||||
|
.put(LootContextParameters.TOOL, ItemStack.EMPTY);
|
||||||
|
List<ItemStack> stacks = oldState.getDroppedStacks(ctx);
|
||||||
|
for (ItemStack stack : stacks) {
|
||||||
|
ItemEntity itemEntity = new ItemEntity(worldIn, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
|
||||||
|
worldIn.spawnEntity(itemEntity);
|
||||||
|
}
|
||||||
|
worldIn.clearBlockState(pos, false);
|
||||||
|
|
||||||
// Mark this position as not being redstone wire
|
// Mark this position as not being redstone wire
|
||||||
upd1.type = UpdateNode.Type.OTHER;
|
upd1.type = UpdateNode.Type.OTHER;
|
||||||
@@ -436,7 +451,7 @@ public class RedstoneWireTurbo
|
|||||||
// UpdateNode object.
|
// UpdateNode object.
|
||||||
BlockState newState;
|
BlockState newState;
|
||||||
if (old_current_change) {
|
if (old_current_change) {
|
||||||
newState = wire.func_212568_b(worldIn, pos, oldState);
|
newState = ((RedstoneWireBlockInterface)wire).updateLogicPublic(worldIn, pos, oldState);
|
||||||
} else {
|
} else {
|
||||||
// Looking up block state is slow. This accelerator includes a version of
|
// Looking up block state is slow. This accelerator includes a version of
|
||||||
// calculateCurrentChanges that uses cahed wire values for a
|
// calculateCurrentChanges that uses cahed wire values for a
|
||||||
@@ -661,7 +676,7 @@ public class RedstoneWireTurbo
|
|||||||
// already keeping track of all of the neighbor positions
|
// already keeping track of all of the neighbor positions
|
||||||
// that need to be updated. All on its own, handling neighbors
|
// that need to be updated. All on its own, handling neighbors
|
||||||
// this way reduces block updates by 1/3 (24 instead of 36).
|
// 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 +780,7 @@ public class RedstoneWireTurbo
|
|||||||
// Check this block's neighbors and see if its power level needs to change
|
// Check this block's neighbors and see if its power level needs to change
|
||||||
// Use the calculateCurrentChanges method in RedstoneWireBlock since we have no
|
// Use the calculateCurrentChanges method in RedstoneWireBlock since we have no
|
||||||
// cached block states at this point.
|
// 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 no change, exit
|
||||||
if (newState == state) {
|
if (newState == state) {
|
||||||
@@ -835,17 +850,17 @@ public class RedstoneWireTurbo
|
|||||||
BlockState state = upd.currentState;
|
BlockState state = upd.currentState;
|
||||||
final int i = state.get(RedstoneWireBlock.POWER);
|
final int i = state.get(RedstoneWireBlock.POWER);
|
||||||
int j = 0;
|
int j = 0;
|
||||||
j = this.getMaxCurrentStrength(upd, j);
|
j = getMaxCurrentStrength(upd, j);
|
||||||
int l = 0;
|
int l = 0;
|
||||||
|
|
||||||
wire.setCanProvidePower(false);
|
((RedstoneWireBlockInterface)wire).setWiresGivePower(false);
|
||||||
// Unfortunately, World.isBlockIndirectlyGettingPowered is complicated,
|
// Unfortunately, World.isBlockIndirectlyGettingPowered is complicated,
|
||||||
// and I'm not ready to try to replicate even more functionality from
|
// and I'm not ready to try to replicate even more functionality from
|
||||||
// elsewhere in Minecraft into this accelerator. So sadly, we must
|
// elsewhere in Minecraft into this accelerator. So sadly, we must
|
||||||
// suffer the performance hit of this very expensive call. If there
|
// 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.
|
// is consistency to what this call returns, we may be able to cache it.
|
||||||
final int k = worldIn.getRedstonePowerFromNeighbors(upd.self);
|
final int k = worldIn.getReceivedRedstonePower(upd.self);
|
||||||
wire.setCanProvidePower(true);
|
((RedstoneWireBlockInterface)wire).setWiresGivePower(true);
|
||||||
|
|
||||||
// The variable 'k' holds the maximum redstone power value of any adjacent blocks.
|
// 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
|
// If 'k' has the highest level of all neighbors, then the power level of this
|
||||||
@@ -863,7 +878,7 @@ public class RedstoneWireTurbo
|
|||||||
// position directly above the node being calculated is always
|
// position directly above the node being calculated is always
|
||||||
// at index 1.
|
// at index 1.
|
||||||
UpdateNode center_up = upd.neighbor_nodes[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++) {
|
for (int m=0; m<4; m++) {
|
||||||
// Get the neighbor array index of each of the four cardinal
|
// Get the neighbor array index of each of the four cardinal
|
||||||
@@ -873,18 +888,18 @@ public class RedstoneWireTurbo
|
|||||||
// Get the max redstone power level of each of the cardinal
|
// Get the max redstone power level of each of the cardinal
|
||||||
// neighbors
|
// neighbors
|
||||||
UpdateNode neighbor = upd.neighbor_nodes[n];
|
UpdateNode neighbor = upd.neighbor_nodes[n];
|
||||||
l = this.getMaxCurrentStrength(neighbor, l);
|
l = getMaxCurrentStrength(neighbor, l);
|
||||||
|
|
||||||
// Also check the positions above and below the cardinal
|
// Also check the positions above and below the cardinal
|
||||||
// neighbors
|
// neighbors
|
||||||
boolean neighbor_is_cube = neighbor.currentState.isNormalCube();
|
boolean neighbor_is_cube = neighbor.currentState.isSimpleFullBlock(worldIn, neighbor.self);
|
||||||
if (!neighbor_is_cube) {
|
if (!neighbor_is_cube) {
|
||||||
UpdateNode neighbor_down = upd.neighbor_nodes[rs_neighbors_dn[m]];
|
UpdateNode neighbor_down = upd.neighbor_nodes[rs_neighbors_dn[m]];
|
||||||
l = this.getMaxCurrentStrength(neighbor_down, l);
|
l = getMaxCurrentStrength(neighbor_down, l);
|
||||||
} else
|
} else
|
||||||
if (!center_up_is_cube) {
|
if (!center_up_is_cube) {
|
||||||
UpdateNode neighbor_up = upd.neighbor_nodes[rs_neighbors_up[m]];
|
UpdateNode neighbor_up = upd.neighbor_nodes[rs_neighbors_up[m]];
|
||||||
l = this.getMaxCurrentStrength(neighbor_up, l);
|
l = getMaxCurrentStrength(neighbor_up, l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
package carpet.mixins;
|
||||||
|
|
||||||
|
import carpet.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.b_fastRedstoneDust) {
|
||||||
|
wireTurbo.updateSurroundingRedstone(world, pos, state, source);
|
||||||
|
}
|
||||||
|
return update(world, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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
|
||||||
|
int int_4 = increasePower(0, blockState_2); // j
|
||||||
|
this.wiresGivePower = false;
|
||||||
|
int int_2 = world_1.getReceivedRedstonePower(blockPos_1); // k
|
||||||
|
this.wiresGivePower = true;
|
||||||
|
int int_3 = 0; // l
|
||||||
|
|
||||||
|
// [CM] fastRedstoneDust -- if statement around unnecessary check
|
||||||
|
if (!CarpetSettings.b_fastRedstoneDust) {
|
||||||
|
if (int_2 > 0 && int_2 > int_4 - 1) {
|
||||||
|
int_4 = int_2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CarpetSettings.b_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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// [CM] fastRedstoneDust -- if statement around unnecessary check
|
||||||
|
if (!CarpetSettings.b_fastRedstoneDust) {
|
||||||
|
if (int_3 > int_4) {
|
||||||
|
int_4 = int_3 - 1;
|
||||||
|
} else if (int_4 > 0) {
|
||||||
|
--int_4;
|
||||||
|
} else {
|
||||||
|
int_4 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int_2 > int_4 - 1) {
|
||||||
|
int_4 = int_2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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.b_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =
|
||||||
|
|
||||||
|
private static final String updateTarget = "Lnet/minecraft/block/RedstoneWireBlock;update(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Lnet/minecraft/block/BlockState;";
|
||||||
|
|
||||||
|
@Redirect(method = "onBlockAdded", at = @At(value = "INVOKE", target = updateTarget))
|
||||||
|
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 = updateTarget))
|
||||||
|
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 = updateTarget))
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
"PlayerActionC2SPacketMixin",
|
"PlayerActionC2SPacketMixin",
|
||||||
"ServerPlayerEntityMixin",
|
"ServerPlayerEntityMixin",
|
||||||
"PlayerManagerMixin",
|
"PlayerManagerMixin",
|
||||||
|
"RedstoneWireBlockMixin",
|
||||||
"CarpetBlockMixin",
|
"CarpetBlockMixin",
|
||||||
"SummonCommandMixin",
|
"SummonCommandMixin",
|
||||||
"PistonHandler_pushLimitMixin",
|
"PistonHandler_pushLimitMixin",
|
||||||
|
|||||||
Reference in new issue
Block a user