diff --git a/core/src/main/java/mrtjp/projectred/core/FaceLookup.java b/core/src/main/java/mrtjp/projectred/core/FaceLookup.java index 7429ea5cf..60a41e3ad 100644 --- a/core/src/main/java/mrtjp/projectred/core/FaceLookup.java +++ b/core/src/main/java/mrtjp/projectred/core/FaceLookup.java @@ -19,6 +19,7 @@ public class FaceLookup { public final BlockPos pos; public final int side; public final int r; + public final int dir; //Located objects public final BlockState state; @@ -30,12 +31,14 @@ public class FaceLookup { public final BlockPos otherPos; public final int otherSide; public final int otherRotation; + public final int otherDir; public FaceLookup(Level world, BlockPos pos, int side, int r, BlockState state, @Nullable BlockEntity tile, @Nullable MultiPart part, BlockPos otherPos, int otherSide, int otherRotation) { this.world = world; this.pos = pos; this.side = side; this.r = r; + this.dir = r == -1 ? side ^ 1 : Rotation.rotateSide(side, r); this.state = state; this.block = state.getBlock(); this.tile = tile; @@ -43,6 +46,8 @@ public FaceLookup(Level world, BlockPos pos, int side, int r, BlockState state, this.otherPos = otherPos; this.otherSide = otherSide; this.otherRotation = otherRotation; + // When otherSide == -1, otherRotation is already otherDir + this.otherDir = otherSide == -1 ? otherRotation : Rotation.rotateSide(otherSide, otherRotation); } public static FaceLookup lookupCorner(Level world, BlockPos pos, int side, int r) { @@ -87,14 +92,14 @@ public static FaceLookup lookupInsideFace(Level world, BlockPos pos, int side, i } public static FaceLookup lookupInsideCenter(Level world, BlockPos pos, int side) { - int otherSide = side; - int otherRotation = -1; // Part is not on face + int otherSide = -1; // Center part not on side + int otherRotation = side; // For this case, rotation is used as direction BlockState state = world.getBlockState(pos); BlockEntity tile = getBlockEntityForState(world, pos, state); MultiPart part = tile instanceof TileMultipart tmp ? tmp.getSlottedPart(6) : null; - return new FaceLookup(world, pos, side, -1, state, tile, part, pos, otherRotation, otherSide); + return new FaceLookup(world, pos, side, -1, state, tile, part, pos, otherSide, otherRotation); } /** diff --git a/core/src/main/java/mrtjp/projectred/core/RedstoneCenterLookup.java b/core/src/main/java/mrtjp/projectred/core/RedstoneCenterLookup.java new file mode 100644 index 000000000..5250ced84 --- /dev/null +++ b/core/src/main/java/mrtjp/projectred/core/RedstoneCenterLookup.java @@ -0,0 +1,35 @@ +package mrtjp.projectred.core; + +import codechicken.multipart.api.RedstoneInteractions; +import codechicken.multipart.api.part.MultiPart; +import codechicken.multipart.api.part.redstone.RedstonePart; +import mrtjp.projectred.core.part.IRedwireEmitter; +import mrtjp.projectred.core.part.IRedwirePart; + +public class RedstoneCenterLookup { + + public static int resolveSignal(CenterLookup lookup, boolean diminishRedwire) { + if (lookup.part instanceof IRedwirePart rw) { + + int signal = rw.getRedwireSignal(lookup.otherDirection); + if (diminishRedwire && rw.diminishOnSide(lookup.otherDirection)) { + signal--; + } + return Math.max(0, signal); + } + + if (lookup.part instanceof IRedwireEmitter rwe) { + return rwe.getRedwireSignal(lookup.otherDirection); + } + + if (lookup.part instanceof RedstonePart rw) { + return Math.max(rw.strongPowerLevel(lookup.otherDirection), rw.weakPowerLevel(lookup.otherDirection)); + } + + return 0; + } + + public static int resolveVanillaSignal(CenterLookup lookup, MultiPart part) { + return RedstoneInteractions.getPowerTo(part, lookup.direction) * 17; + } +} diff --git a/core/src/main/java/mrtjp/projectred/core/RedstoneFaceLookup.java b/core/src/main/java/mrtjp/projectred/core/RedstoneFaceLookup.java new file mode 100644 index 000000000..2e29729b8 --- /dev/null +++ b/core/src/main/java/mrtjp/projectred/core/RedstoneFaceLookup.java @@ -0,0 +1,60 @@ +package mrtjp.projectred.core; + +import codechicken.multipart.api.RedstoneInteractions; +import codechicken.multipart.api.part.MultiPart; +import codechicken.multipart.api.part.redstone.FaceRedstonePart; +import mrtjp.projectred.core.part.IRedwireEmitter; +import mrtjp.projectred.core.part.IRedwirePart; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.RedStoneWireBlock; + +public class RedstoneFaceLookup { + + public static int resolveSignal(FaceLookup lookup, boolean diminishRedwire) { + + if (lookup.part instanceof IRedwirePart rp) { + int signal = rp.getRedwireSignal(lookup.otherRotation); + if (diminishRedwire && rp.diminishOnSide(lookup.otherRotation)) { + signal--; + } + return Math.max(0, signal); + } + + if (lookup.part instanceof IRedwireEmitter rwe) { + return rwe.getRedwireSignal(lookup.otherRotation); + } + + if (lookup.part instanceof FaceRedstonePart fp) { + int s = lookup.otherDir; + return Math.max(fp.strongPowerLevel(s), fp.weakPowerLevel(s)) * 17; + } + + return 0; + } + + public static int resolveVanillaSignal(FaceLookup lookup, MultiPart part, boolean strong, boolean limitDust) { + int signal; + + // Dust signal + if (lookup.block == Blocks.REDSTONE_WIRE) { + signal = Math.max(lookup.state.getValue(RedStoneWireBlock.POWER) - 1, 0); + if (limitDust) { + return signal; + } + } + + // Strong signal + signal = RedstoneInteractions.getPowerTo(part, lookup.dir) * 17; + if (signal > 0 || strong) { + return signal; + } + + // Weak signal + if (lookup.state.isRedstoneConductor(lookup.world, lookup.otherPos)) { + signal = lookup.world.getBestNeighborSignal(lookup.otherPos) * 17; + } + + return signal; + } + +} diff --git a/integration/src/main/java/mrtjp/projectred/integration/part/ArrayGatePart.java b/integration/src/main/java/mrtjp/projectred/integration/part/ArrayGatePart.java index b6022f648..c9de94882 100644 --- a/integration/src/main/java/mrtjp/projectred/integration/part/ArrayGatePart.java +++ b/integration/src/main/java/mrtjp/projectred/integration/part/ArrayGatePart.java @@ -7,23 +7,20 @@ import codechicken.lib.vec.Rotation; import codechicken.lib.vec.Transformation; import codechicken.lib.vec.Vector3; -import codechicken.multipart.api.RedstoneInteractions; import codechicken.multipart.api.part.MultiPart; -import codechicken.multipart.api.part.redstone.FaceRedstonePart; import codechicken.multipart.block.BlockMultipart; import codechicken.multipart.util.MultipartPlaceContext; import com.google.common.collect.ImmutableSet; import mrtjp.projectred.api.IConnectable; import mrtjp.projectred.core.Configurator; import mrtjp.projectred.core.FaceLookup; +import mrtjp.projectred.core.RedstoneFaceLookup; import mrtjp.projectred.core.RedstonePropagator; import mrtjp.projectred.core.part.*; import mrtjp.projectred.integration.GateType; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.RedStoneWireBlock; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; @@ -124,16 +121,29 @@ public int calculateSignal() { int signal = 0; for (int r = 0; r < 4; r++) { if ((propagationMask & 1 << r) == 0) { continue; } + int s; if (maskConnectsCorner(r)) { - signal = Math.max(calcCornerSignal(r), signal); + FaceLookup lookup = FaceLookup.lookupCorner(level(), pos(), getSide(), r); + s = RedstoneFaceLookup.resolveSignal(lookup, true); + } else if (maskConnectsStraight(r)) { - signal = Math.max(calcStraightSignal(r), signal); + FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); + s = RedstoneFaceLookup.resolveSignal(lookup, true); + if (s == 0) { + s = RedstoneFaceLookup.resolveVanillaSignal(lookup, this, true, true); + } + } else if (maskConnectsInside(r)) { - signal = Math.max(calcInsideSignal(r), signal); - } else { - signal = Math.max(getVanillaSignal(r, true, true), signal); + FaceLookup lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), r); + s = RedstoneFaceLookup.resolveSignal(lookup, true); + + } else { // For non-connected sides, just do a vanilla signal lookup + FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); + s = RedstoneFaceLookup.resolveVanillaSignal(lookup, this, true, true); } + + signal = Math.max(s, signal); } RedstonePropagator.setDustProvidesPower(true); @@ -141,47 +151,6 @@ public int calculateSignal() { return signal; } - protected int calcCornerSignal(int r) { - FaceLookup lookup = FaceLookup.lookupCorner(level(), pos(), getSide(), r); - return resolveSignal(lookup); - } - - protected int calcStraightSignal(int r) { - FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); - int signal = resolveSignal(lookup); - if (signal > 0) { - return signal; - } - return getVanillaSignal(r, true, true); - } - - protected int calcInsideSignal(int r) { - FaceLookup lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), r); - return resolveSignal(lookup); - } - - protected int resolveSignal(FaceLookup lookup) { - - // Part signal resolution - if (lookup.part instanceof IRedwirePart redwirePart) { - if (redwirePart.diminishOnSide(lookup.otherRotation)) { - return redwirePart.getRedwireSignal(lookup.otherRotation) - 1; - } - } - - if (lookup.part instanceof IRedwireEmitter) { - return ((IRedwireEmitter) lookup.part).getRedwireSignal(lookup.otherRotation); - } - - // Shouldn't matter, no space for a face part inside - if (lookup.part instanceof FaceRedstonePart faceRsPart) { - int s = Rotation.rotateSide(lookup.otherSide, lookup.otherRotation); - return Math.max(faceRsPart.strongPowerLevel(s), faceRsPart.weakPowerLevel(s)) * 17; - } - - return super.resolveSignal(lookup); - } - @Override public void onSignalUpdate() { tile().setChanged(); diff --git a/integration/src/main/java/mrtjp/projectred/integration/part/RedstoneGatePart.java b/integration/src/main/java/mrtjp/projectred/integration/part/RedstoneGatePart.java index 0c67d1307..6234cefde 100644 --- a/integration/src/main/java/mrtjp/projectred/integration/part/RedstoneGatePart.java +++ b/integration/src/main/java/mrtjp/projectred/integration/part/RedstoneGatePart.java @@ -2,13 +2,13 @@ import codechicken.lib.data.MCDataInput; import codechicken.lib.data.MCDataOutput; -import codechicken.multipart.api.RedstoneInteractions; import codechicken.multipart.api.part.AnimateTickPart; import codechicken.multipart.api.part.redstone.FaceRedstonePart; import codechicken.multipart.init.CBMultipartModContent; import mrtjp.projectred.api.IConnectable; import mrtjp.projectred.core.Configurator; import mrtjp.projectred.core.FaceLookup; +import mrtjp.projectred.core.RedstoneFaceLookup; import mrtjp.projectred.core.part.IRedwireEmitter; import mrtjp.projectred.integration.GateType; import mrtjp.projectred.integration.client.GateModelRenderer; @@ -18,10 +18,6 @@ import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.util.RandomSource; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.RedStoneWireBlock; - -import java.util.Random; public abstract class RedstoneGatePart extends GatePart implements FaceRedstonePart, AnimateTickPart { @@ -158,46 +154,18 @@ protected int getRedstoneInput(int r) { lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), ar); } - return lookup == null ? getVanillaSignal(ar, true, false) : resolveSignal(lookup); + if (lookup != null) { + return RedstoneFaceLookup.resolveSignal(lookup, false); + } + + // Vanilla signal resolution + lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), ar); + return RedstoneFaceLookup.resolveVanillaSignal(lookup, this, true, false); } protected int getAnalogRedstoneInput(int r) { return (getRedstoneInput(r) + 16) / 17; } - - protected int resolveSignal(FaceLookup lookup) { - if (lookup.part instanceof IRedwireEmitter) { - return ((IRedwireEmitter) lookup.part).getRedwireSignal(lookup.otherRotation); - } - return 0; - } - - protected int getVanillaSignal(int r, boolean strong, boolean limitDust) { - FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); - int signal = 0; - - // Dust signal - if (lookup.block == Blocks.REDSTONE_WIRE) { - signal = Math.max(lookup.state.getValue(RedStoneWireBlock.POWER) - 1, 0); - if (limitDust) { - return signal; - } - } - - // Strong signal - int dir = absoluteDir(r); - signal = RedstoneInteractions.getPowerTo(this, dir) * 17; - if (signal > 0 || strong) { - return signal; - } - - // Weak signal - if (lookup.state.isRedstoneConductor(level(), lookup.otherPos)) { - signal = level().getBestNeighborSignal(lookup.otherPos) * 17; - } - - return signal; - } //endregion //region Gate logic diff --git a/transmission/src/main/java/mrtjp/projectred/transmission/part/FramedRedwirePart.java b/transmission/src/main/java/mrtjp/projectred/transmission/part/FramedRedwirePart.java index b3a314d87..5649b9b88 100644 --- a/transmission/src/main/java/mrtjp/projectred/transmission/part/FramedRedwirePart.java +++ b/transmission/src/main/java/mrtjp/projectred/transmission/part/FramedRedwirePart.java @@ -9,10 +9,10 @@ import mrtjp.projectred.api.IConnectable; import mrtjp.projectred.core.CenterLookup; import mrtjp.projectred.core.Configurator; +import mrtjp.projectred.core.RedstoneCenterLookup; import mrtjp.projectred.core.RedstonePropagator; import mrtjp.projectred.core.part.IPropagationCenterPart; import mrtjp.projectred.core.part.IRedstonePropagationPart; -import mrtjp.projectred.core.part.IRedwireEmitter; import mrtjp.projectred.core.part.IRedwirePart; import mrtjp.projectred.transmission.WireType; import net.minecraft.core.BlockPos; @@ -182,11 +182,20 @@ public int calculateSignal() { int signal = 0; for (int s = 0; s < 6; s++) { + int sig = 0; if (maskConnectsIn(s)) { - signal = Math.max(signal, calculateInternalSignal(s)); + CenterLookup lookup = CenterLookup.lookupInsideFace(level(), pos(), s); + sig = resolveSignal(lookup); + } else if (maskConnectsOut(s)) { - signal = Math.max(signal, calculateStraightSignal(s)); + CenterLookup lookup = CenterLookup.lookupStraightCenter(level(), pos(), s); + sig = resolveSignal(lookup); + if (sig == 0) { + sig = RedstoneCenterLookup.resolveVanillaSignal(lookup, this); + } } + + signal = Math.max(sig, signal); } RedstonePropagator.setDustProvidesPower(true); @@ -216,44 +225,7 @@ public boolean diminishOnSide(int side) { } //endregion - protected int calculateStraightSignal(int s) { - CenterLookup lookup = CenterLookup.lookupStraightCenter(level(), pos(), s); - if (lookup.part != null) { - return resolveSignal(lookup); - } - - // If no part, get generic strong signal - return RedstoneInteractions.getPowerTo(this, s) * 17; - } - - protected int calculateInternalSignal(int s) { - CenterLookup lookup = CenterLookup.lookupInsideFace(level(), pos(), s); - int signal = resolveSignal(lookup); - if (signal > 0) { - return signal; - } - - if (lookup.part instanceof RedstonePart rw) { - return Math.max(rw.strongPowerLevel(lookup.otherDirection), rw.weakPowerLevel(lookup.otherDirection)); - } - - return 0; - } - protected int resolveSignal(CenterLookup lookup) { - if (lookup.part instanceof IRedwirePart rw) { - - int signal = rw.getRedwireSignal(lookup.otherDirection); - if (rw.diminishOnSide(lookup.otherDirection)) { - signal--; - } - return signal; - } - - if (lookup.part instanceof IRedwireEmitter) { - return ((IRedwireEmitter) lookup.part).getRedwireSignal(lookup.otherDirection); - } - - return 0; + return RedstoneCenterLookup.resolveSignal(lookup, true); } } diff --git a/transmission/src/main/java/mrtjp/projectred/transmission/part/RedwirePart.java b/transmission/src/main/java/mrtjp/projectred/transmission/part/RedwirePart.java index 98cc56680..3e85201da 100644 --- a/transmission/src/main/java/mrtjp/projectred/transmission/part/RedwirePart.java +++ b/transmission/src/main/java/mrtjp/projectred/transmission/part/RedwirePart.java @@ -11,14 +11,13 @@ import mrtjp.projectred.api.IConnectable; import mrtjp.projectred.core.Configurator; import mrtjp.projectred.core.FaceLookup; +import mrtjp.projectred.core.RedstoneFaceLookup; import mrtjp.projectred.core.RedstonePropagator; import mrtjp.projectred.core.part.*; import mrtjp.projectred.transmission.WireType; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.RedStoneWireBlock; import javax.annotation.Nullable; @@ -196,21 +195,36 @@ public int calculateSignal() { int signal = 0; for (int r = 0; r < 4; r++) { + int s = 0; if (maskConnectsCorner(r)) { - signal = Math.max(calcCornerSignal(r), signal); + FaceLookup lookup = FaceLookup.lookupCorner(level(), pos(), getSide(), r); + s = resolveSignal(lookup); + } else if (maskConnectsStraight(r)) { - signal = Math.max(calcStraightSignal(r), signal); + FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); + s = resolveSignal(lookup); + if (s <= 0) { + s = RedstoneFaceLookup.resolveVanillaSignal(lookup, this, true, true); + } + } else if (maskConnectsInside(r)) { - signal = Math.max(calcInsideSignal(r), signal); + FaceLookup lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), r); + s = resolveSignal(lookup); } + + signal = Math.max(s, signal); } if (powerUnderside()) { - signal = Math.max(calcUndersideSignal(), signal); + Direction face = Direction.values()[getSide()]; + int s = level().getSignal(pos().relative(face), face) * 17; + signal = Math.max(s, signal); } if (maskConnectsCenter()) { - signal = Math.max(calcCenterSignal(), signal); + FaceLookup lookup = FaceLookup.lookupInsideCenter(level(), pos(), getSide()); + int s = resolveSignal(lookup); + signal = Math.max(s, signal); } RedstonePropagator.setDustProvidesPower(true); @@ -232,81 +246,8 @@ public boolean diminishOnSide(int side) { } //endregion - protected int calcCornerSignal(int r) { - FaceLookup lookup = FaceLookup.lookupCorner(level(), pos(), getSide(), r); - return resolveSignal(lookup); - } - - protected int calcStraightSignal(int r) { - FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); - int signal = resolveSignal(lookup); - if (signal > 0) { - return signal; - } - return getVanillaSignal(r, true, true); - } - - protected int calcInsideSignal(int r) { - FaceLookup lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), r); - return resolveSignal(lookup); - } - - protected int calcUndersideSignal() { - Direction face = Direction.values()[getSide()]; - return level().getSignal(pos().relative(face), face) * 17; - } - - protected int calcCenterSignal() { - FaceLookup lookup = FaceLookup.lookupInsideCenter(level(), pos(), getSide()); - return resolveSignal(lookup); - } - protected int resolveSignal(FaceLookup lookup) { - - // Part signal resolution - if (lookup.part instanceof IRedwirePart redwirePart) { - if (redwirePart.diminishOnSide(lookup.otherRotation)) { - return redwirePart.getRedwireSignal(lookup.otherRotation) - 1; - } - } - - if (lookup.part instanceof IRedwireEmitter) { - return ((IRedwireEmitter) lookup.part).getRedwireSignal(lookup.otherRotation); - } - - if (lookup.part instanceof FaceRedstonePart faceRsPart) { - int s = Rotation.rotateSide(lookup.otherSide, lookup.otherRotation); - return Math.max(faceRsPart.strongPowerLevel(s), faceRsPart.weakPowerLevel(s)) * 17; - } - - return 0; - } - - protected int getVanillaSignal(int r, boolean strong, boolean limitDust) { - FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); - int signal = 0; - - // Dust signal - if (lookup.block == Blocks.REDSTONE_WIRE) { - signal = Math.max(lookup.state.getValue(RedStoneWireBlock.POWER) - 1, 0); - if (limitDust) { - return signal; - } - } - - // Strong signal - int dir = IConnectableFacePart.absoluteDir(this, r); - signal = RedstoneInteractions.getPowerTo(this, dir) * 17; - if (signal > 0 || strong) { - return signal; - } - - // Weak signal - if (lookup.state.isRedstoneConductor(level(), lookup.otherPos)) { - signal = level().getBestNeighborSignal(lookup.otherPos) * 17; - } - - return signal; + return RedstoneFaceLookup.resolveSignal(lookup, true); } protected abstract boolean powerUnderside();