Skip to content

Commit

Permalink
internal: move redstone query logic to static libs
Browse files Browse the repository at this point in the history
  • Loading branch information
MrTJP committed May 30, 2024
1 parent 50d11f1 commit b64eaf0
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 215 deletions.
11 changes: 8 additions & 3 deletions core/src/main/java/mrtjp/projectred/core/FaceLookup.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -30,19 +31,23 @@ 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;
this.part = part;
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) {
Expand Down Expand Up @@ -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);
}

/**
Expand Down
35 changes: 35 additions & 0 deletions core/src/main/java/mrtjp/projectred/core/RedstoneCenterLookup.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
65 changes: 65 additions & 0 deletions core/src/main/java/mrtjp/projectred/core/RedstoneFaceLookup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
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
return RedstoneInteractions.getPowerTo(part, lookup.dir) * 17;

// TODO Investigate below. I think RedstoneInteractions already takes care of strong/weak check,
// as it is part of Level#getSignal now.
// // 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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -124,64 +121,36 @@ 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);
RedstonePropagator.setRedwiresProvidePower(true);
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {

Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit b64eaf0

Please sign in to comment.