Fixes and tweaks

- Add #create:blaze_burner_capturable entity type tag
- Make it so blocks that do not implement IWrenchable and that are
tagged can only be picked up with a wrench while sneaking
- Fix AnalogLeverInstance not rendering indicator on 1.18 and 1.19 and
rendering indicator at wrong place in 1.20
- Change AirCurrent entity distance calculation to fix issues with some
items not being processed
- Simplify AirCurrent max VoxelShape depth calculation by using min and
max instead of raycasting
- Fix pipe cobblestone generation
- Fix vertical smart observers outputting redstone signal from wrong
sides
- Fix smart observer using wrong bottom texture
This commit is contained in:
PepperCode1 2023-10-28 13:58:40 -07:00
parent 26c9af50a7
commit 8bf42ffa6f
22 changed files with 135 additions and 114 deletions

View file

@ -5340,6 +5340,7 @@ ad8fa04f7bbbafd70d0ce158af78a35e899301e2 data/create/tags/blocks/tracks.json
50936b211d94167a35ec78c89954082a336b6269 data/create/tags/blocks/valve_handles.json
eac71740fb12bdb38b5dfaa2268613d7ba82b809 data/create/tags/blocks/windmill_sails.json
9851b3bef451f326ef322a31f85b9a970859590d data/create/tags/blocks/wrench_pickup.json
cf85bc6b8b9d3fe2baf408731225de9c050763b8 data/create/tags/entity_types/blaze_burner_capturable.json
74700d556ca80c7a1db5fd4efb09c3ddb26cad66 data/create/tags/entity_types/ignore_seat.json
a8bdc387cfa6296ebcc4af14323e2ddb632234dc data/create/tags/fluids/bottomless/allow.json
74700d556ca80c7a1db5fd4efb09c3ddb26cad66 data/create/tags/fluids/bottomless/deny.json

View file

@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"minecraft:blaze"
]
}

View file

@ -92,7 +92,6 @@ import com.simibubi.create.foundation.networking.SimplePacketBase;
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.infrastructure.command.HighlightPacket;
import com.simibubi.create.infrastructure.command.SConfigureConfigPacket;
import com.simibubi.create.infrastructure.debugInfo.ServerDebugInfoPacket;
import net.minecraft.core.BlockPos;

View file

@ -284,7 +284,8 @@ public class AllTags {
}
public enum AllEntityTags {
BLAZE_BURNER_CAPTURABLE,
IGNORE_SEAT,
;
@ -318,9 +319,12 @@ public class AllTags {
this.alwaysDatagen = alwaysDatagen;
}
public boolean matches(EntityType<?> type) {
return type.is(tag);
}
public boolean matches(Entity entity) {
return entity.getType()
.is(tag);
return matches(entity.getType());
}
private static void init() {}

View file

@ -9,7 +9,7 @@ import net.minecraft.world.level.material.Fluid;
import net.minecraftforge.eventbus.api.Event;
/**
* This Event is fired when a two fluids meet in a pipe ({@link Flow})<br>
* This Event is fired when two fluids meet in a pipe ({@link Flow})<br>
* or when a fluid in a pipe meets with a fluid in the world
* ({@link Spill}).<br>
* <br>

View file

@ -46,7 +46,7 @@ public class WrenchItem extends Item {
Block block = state.getBlock();
if (!(block instanceof IWrenchable)) {
if (canWrenchPickup(state))
if (player.isShiftKeyDown() && canWrenchPickup(state))
return onItemUseOnOther(context);
return super.useOn(context);
}

View file

@ -16,6 +16,7 @@ import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@ -36,7 +37,7 @@ public class FluidReactions {
level.setBlockAndUpdate(pos, event.getState());
}
@SubscribeEvent
@SubscribeEvent(priority = EventPriority.HIGH)
public static void handlePipeFlowCollisionFallback(PipeCollisionEvent.Flow event) {
Fluid f1 = event.getFirstFluid();
Fluid f2 = event.getSecondFluid();
@ -67,7 +68,7 @@ public class FluidReactions {
}
}
@SubscribeEvent
@SubscribeEvent(priority = EventPriority.HIGH)
public static void handlePipeSpillCollisionFallback(PipeCollisionEvent.Spill event) {
Fluid pf = event.getPipeFluid();
Fluid wf = event.getWorldFluid();
@ -78,7 +79,7 @@ public class FluidReactions {
event.setState(Blocks.COBBLESTONE.defaultBlockState());
} else if (pf == Fluids.LAVA && wf == Fluids.WATER) {
event.setState(Blocks.STONE.defaultBlockState());
} else if (pf == Fluids.LAVA && wf == Fluids.FLOWING_LAVA) {
} else if (pf == Fluids.LAVA && wf == Fluids.FLOWING_WATER) {
event.setState(Blocks.COBBLESTONE.defaultBlockState());
}

View file

@ -32,9 +32,7 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist;
@ -62,21 +60,20 @@ public class AirCurrent {
if (direction == null)
rebuild();
Level world = source.getAirCurrentWorld();
Direction facing = direction;
if (world != null && world.isClientSide) {
float offset = pushing ? 0.5f : maxDistance + .5f;
Vec3 pos = VecHelper.getCenterOf(source.getAirCurrentPos())
.add(Vec3.atLowerCornerOf(facing.getNormal())
.add(Vec3.atLowerCornerOf(direction.getNormal())
.scale(offset));
if (world.random.nextFloat() < AllConfigs.client().fanParticleDensity.get())
world.addParticle(new AirFlowParticleData(source.getAirCurrentPos()), pos.x, pos.y, pos.z, 0, 0, 0);
}
tickAffectedEntities(world, facing);
tickAffectedEntities(world);
tickAffectedHandlers();
}
protected void tickAffectedEntities(Level world, Direction facing) {
protected void tickAffectedEntities(Level world) {
for (Iterator<Entity> iterator = caughtEntities.iterator(); iterator.hasNext();) {
Entity entity = iterator.next();
if (!entity.isAlive() || !entity.getBoundingBox()
@ -85,14 +82,14 @@ public class AirCurrent {
continue;
}
Vec3 center = VecHelper.getCenterOf(source.getAirCurrentPos());
Vec3i flow = (pushing ? facing : facing.getOpposite()).getNormal();
float sneakModifier = entity.isShiftKeyDown() ? 4096f : 512f;
Vec3i flow = (pushing ? direction : direction.getOpposite()).getNormal();
float speed = Math.abs(source.getSpeed());
double entityDistance = entity.position()
.distanceTo(center);
float acceleration = (float) (speed / sneakModifier / (entityDistance / maxDistance));
float sneakModifier = entity.isShiftKeyDown() ? 4096f : 512f;
double entityDistance = VecHelper.alignedDistanceToFace(entity.position(), source.getAirCurrentPos(), direction);
// entityDistanceOld should be removed eventually. Remember that entityDistanceOld cannot be 0 while entityDistance can,
// so division by 0 must be avoided.
double entityDistanceOld = entity.position().distanceTo(VecHelper.getCenterOf(source.getAirCurrentPos()));
float acceleration = (float) (speed / sneakModifier / (entityDistanceOld / maxDistance));
Vec3 previousMotion = entity.getDeltaMovement();
float maxAcceleration = 5;
@ -108,7 +105,6 @@ public class AirCurrent {
if (entity instanceof ServerPlayer)
((ServerPlayer) entity).connection.aboveGroundTickCount = 0;
entityDistance -= .5f;
FanProcessingType processingType = getTypeAt((float) entityDistance);
if (processingType == AllFanProcessingTypes.NONE)
@ -229,57 +225,75 @@ public class AirCurrent {
}
public static float getFlowLimit(Level world, BlockPos start, float max, Direction facing) {
Vec3 directionVec = Vec3.atLowerCornerOf(facing.getNormal());
Vec3 planeVec = VecHelper.axisAlingedPlaneOf(directionVec);
for (int i = 0; i < max; i++) {
BlockPos currentPos = start.relative(facing, i + 1);
if (!world.isLoaded(currentPos)) {
return i;
}
// 4 Rays test for holes in the shapes blocking the flow
float offsetDistance = .25f;
Vec3[] offsets = new Vec3[] { planeVec.multiply(offsetDistance, offsetDistance, offsetDistance),
planeVec.multiply(-offsetDistance, -offsetDistance, offsetDistance),
planeVec.multiply(offsetDistance, -offsetDistance, -offsetDistance),
planeVec.multiply(-offsetDistance, offsetDistance, -offsetDistance), };
float limitedDistance = 0;
// Determine the distance of the air flow
Outer: for (int i = 1; i <= max; i++) {
BlockPos currentPos = start.relative(facing, i);
if (!world.isLoaded(currentPos))
break;
BlockState state = world.getBlockState(currentPos);
BlockState copycatState = CopycatBlock.getMaterial(world, currentPos);
if (shouldAlwaysPass(copycatState.isAir() ? state : copycatState))
if (shouldAlwaysPass(copycatState.isAir() ? state : copycatState)) {
continue;
VoxelShape voxelshape = state.getCollisionShape(world, currentPos, CollisionContext.empty());
if (voxelshape.isEmpty())
continue;
if (voxelshape == Shapes.block()) {
max = i - 1;
break;
}
for (Vec3 offset : offsets) {
Vec3 rayStart = VecHelper.getCenterOf(currentPos)
.subtract(directionVec.scale(.5f + 1 / 32f))
.add(offset);
Vec3 rayEnd = rayStart.add(directionVec.scale(1 + 1 / 32f));
BlockHitResult blockraytraceresult =
world.clipWithInteractionOverride(rayStart, rayEnd, currentPos, voxelshape, state);
if (blockraytraceresult == null)
continue Outer;
double distance = i - 1 + blockraytraceresult.getLocation()
.distanceTo(rayStart);
if (limitedDistance < distance)
limitedDistance = (float) distance;
VoxelShape shape = state.getCollisionShape(world, currentPos);
if (shape.isEmpty()) {
continue;
}
max = limitedDistance;
break;
if (shape == Shapes.block()) {
return i;
}
double shapeDepth = findMaxDepth(shape, facing);
if (shapeDepth == Double.POSITIVE_INFINITY) {
continue;
}
return Math.min((float) (i + shapeDepth + 1/32d), max);
}
return max;
}
private static final double[][] DEPTH_TEST_COORDINATES = {
{ 0.25, 0.25 },
{ 0.25, 0.75 },
{ 0.5, 0.5 },
{ 0.75, 0.25 },
{ 0.75, 0.75 }
};
// Finds the maximum depth of the shape when traveling in the given direction.
// The result is always positive.
// If there is a hole, the result will be Double.POSITIVE_INFINITY.
private static double findMaxDepth(VoxelShape shape, Direction direction) {
Direction.Axis axis = direction.getAxis();
Direction.AxisDirection axisDirection = direction.getAxisDirection();
double maxDepth = 0;
for (double[] coordinates : DEPTH_TEST_COORDINATES) {
double depth;
if (axisDirection == Direction.AxisDirection.POSITIVE) {
double min = shape.min(axis, coordinates[0], coordinates[1]);
if (min == Double.POSITIVE_INFINITY) {
return Double.POSITIVE_INFINITY;
}
depth = min;
} else {
double max = shape.max(axis, coordinates[0], coordinates[1]);
if (max == Double.NEGATIVE_INFINITY) {
return Double.POSITIVE_INFINITY;
}
depth = 1 - max;
}
if (depth > maxDepth) {
maxDepth = depth;
}
}
return maxDepth;
}
private static boolean shouldAlwaysPass(BlockState state) {
return AllTags.AllBlockTags.FAN_TRANSPARENT.matches(state);
}

View file

@ -3,10 +3,12 @@ package com.simibubi.create.content.processing.burner;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.annotation.ParametersAreNonnullByDefault;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTags.AllEntityTags;
import com.simibubi.create.foundation.utility.RegisteredObjects;
import com.simibubi.create.foundation.utility.VecHelper;
@ -14,7 +16,6 @@ import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.random.WeightedEntry.Wrapper;
@ -22,7 +23,6 @@ import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.monster.Blaze;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.CreativeModeTab;
@ -100,11 +100,9 @@ public class BlazeBurnerBlockItem extends BlockItem {
possibleSpawns.add(spawner.nextSpawnData);
}
ResourceLocation blazeId = RegisteredObjects.getKeyOrThrow(EntityType.BLAZE);
for (SpawnData e : possibleSpawns) {
ResourceLocation spawnerEntityId = new ResourceLocation(e.entityToSpawn()
.getString("id"));
if (!spawnerEntityId.equals(blazeId))
Optional<EntityType<?>> optionalEntity = EntityType.by(e.entityToSpawn());
if (optionalEntity.isEmpty() || !AllEntityTags.BLAZE_BURNER_CAPTURABLE.matches(optionalEntity.get()))
continue;
spawnCaptureEffects(world, VecHelper.getCenterOf(pos));
@ -123,7 +121,7 @@ public class BlazeBurnerBlockItem extends BlockItem {
InteractionHand hand) {
if (hasCapturedBlaze())
return InteractionResult.PASS;
if (!(entity instanceof Blaze))
if (!AllEntityTags.BLAZE_BURNER_CAPTURABLE.matches(entity))
return InteractionResult.PASS;
Level world = player.level;

View file

@ -33,12 +33,11 @@ public class AnalogLeverInstance extends BlockEntityInstance<AnalogLeverBlockEnt
indicator = mat.getModel(AllPartialModels.ANALOG_LEVER_INDICATOR, blockState)
.createInstance();
transform(indicator);
AttachFace face = blockState.getValue(AnalogLeverBlock.FACE);
rX = face == AttachFace.FLOOR ? 0 : face == AttachFace.WALL ? 90 : 180;
rY = AngleHelper.horizontalAngle(blockState.getValue(AnalogLeverBlock.FACING));
transform(indicator.loadIdentity());
animateLever();
}

View file

@ -103,7 +103,7 @@ public class SmartObserverBlock extends DirectedDirectionalBlock implements IBE<
@Override
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
return isSignalSource(blockState) && (side == null || side != blockState.getValue(FACING)
return isSignalSource(blockState) && (side == null || side != getTargetDirection(blockState)
.getOpposite()) ? 15 : 0;
}

View file

@ -2,7 +2,6 @@ package com.simibubi.create.foundation.events;
import com.simibubi.create.AllFluids;
import com.simibubi.create.Create;
import com.simibubi.create.api.event.PipeCollisionEvent;
import com.simibubi.create.content.contraptions.ContraptionHandler;
import com.simibubi.create.content.contraptions.actors.trainControls.ControlsServerHandler;
import com.simibubi.create.content.contraptions.minecart.CouplingPhysics;
@ -36,11 +35,8 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
import net.minecraftforge.event.AddPackFindersEvent;
import net.minecraftforge.event.AddReloadListenerEvent;

View file

@ -23,7 +23,7 @@ import net.minecraft.world.level.saveddata.maps.MapDecoration;
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
// random priority to prevent networking conflicts
@Mixin(value = ClientboundMapItemDataPacket.class, priority = 826)
@Mixin(value = ClientboundMapItemDataPacket.class, priority = 426)
public class ClientboundMapItemDataPacketMixin {
@Shadow
@Final

View file

@ -1,11 +1,11 @@
package com.simibubi.create.foundation.mixin.accessor;
import net.minecraft.SystemReport;
import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.Map;
import net.minecraft.SystemReport;
@Mixin(SystemReport.class)
public interface SystemReportAccessor {

View file

@ -351,4 +351,9 @@ public class VecHelper {
return new double[] { t, u };
}
public static double alignedDistanceToFace(Vec3 pos, BlockPos blockPos, Direction face) {
Axis axis = face.getAxis();
return Math.abs(getCoordinate(pos, axis) - (blockPos.get(axis) + (face.getAxisDirection() == Direction.AxisDirection.POSITIVE ? 1 : 0)));
}
}

View file

@ -211,7 +211,9 @@ public class CreateRegistrateTags {
}
private static void genEntityTags(RegistrateTagsProvider<EntityType<?>> prov) {
prov.tag(AllEntityTags.BLAZE_BURNER_CAPTURABLE.tag)
.add(EntityType.BLAZE);
// VALIDATE
for (AllEntityTags tag : AllEntityTags.values()) {

View file

@ -1,26 +1,5 @@
package com.simibubi.create.infrastructure.debugInfo;
import com.google.common.collect.ImmutableMap;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.Backend;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.mixin.accessor.SystemReportAccessor;
import com.simibubi.create.infrastructure.debugInfo.element.DebugInfoSection;
import net.minecraft.SharedConstants;
import net.minecraft.SystemReport;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import com.simibubi.create.infrastructure.debugInfo.element.InfoElement;
import com.simibubi.create.infrastructure.debugInfo.element.InfoEntry;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.forgespi.language.IModInfo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@ -29,7 +8,24 @@ import java.util.stream.Stream;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableMap;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.Backend;
import com.mojang.blaze3d.platform.GlUtil;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.mixin.accessor.SystemReportAccessor;
import com.simibubi.create.infrastructure.debugInfo.element.DebugInfoSection;
import com.simibubi.create.infrastructure.debugInfo.element.InfoElement;
import com.simibubi.create.infrastructure.debugInfo.element.InfoEntry;
import net.minecraft.SharedConstants;
import net.minecraft.SystemReport;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.forgespi.language.IModInfo;
/**
* Allows for providing easily accessible debugging information.

View file

@ -2,10 +2,10 @@ package com.simibubi.create.infrastructure.debugInfo;
import java.util.Objects;
import net.minecraft.world.entity.player.Player;
import javax.annotation.Nullable;
import net.minecraft.world.entity.player.Player;
/**
* A supplier of debug information. May be queried on the client or server.
*/

View file

@ -1,11 +1,11 @@
package com.simibubi.create.infrastructure.debugInfo.element;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Player;
import java.util.function.Consumer;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Player;
public sealed interface InfoElement permits DebugInfoSection, InfoEntry {
void write(Player player, FriendlyByteBuf buffer);

View file

@ -1,17 +1,17 @@
package com.simibubi.create.infrastructure.debugInfo.element;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jetbrains.annotations.Nullable;
import com.simibubi.create.infrastructure.debugInfo.DebugInformation;
import com.simibubi.create.infrastructure.debugInfo.InfoProvider;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public record InfoEntry(String name, InfoProvider provider) implements InfoElement {
public InfoEntry(String name, String info) {
this(name, player -> info);

View file

@ -5,7 +5,7 @@
"0": "create:block/smart_observer",
"2": "create:block/smart_observer_front",
"4": "create:block/smart_observer_top",
"6": "block/observer_top",
"6": "create:block/smart_observer_bottom",
"7": "create:block/smart_observer_side",
"particle": "create:block/smart_observer"
},