Skip to content

Commit

Permalink
Bugfixes, implement vanilla rendering mode.
Browse files Browse the repository at this point in the history
  • Loading branch information
MerchantPug committed Nov 17, 2024
1 parent 07503a8 commit 597e4cf
Show file tree
Hide file tree
Showing 68 changed files with 789 additions and 313 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## Changes
- Added vanilla rendering mode. Accessible by turning off the automatically enabled Barricade resource pack.

## Bugfixes
- Fixed fences connecting to directional and advanced barrier blocks.
- Fixed operator models not updating upon gamemode switch.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package net.modgarden.barricade.gradle

object Versions {
const val MOD = "1.1.1"
const val MOD = "1.2.0"

const val MINECRAFT = "1.21.1"
const val PARCHMENT_MINECRAFT = "1.21"
Expand Down
28 changes: 6 additions & 22 deletions common/src/main/java/net/modgarden/barricade/Barricade.java
Original file line number Diff line number Diff line change
@@ -1,38 +1,22 @@
package net.modgarden.barricade;

import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.modgarden.barricade.client.BarricadeClient;
import net.modgarden.barricade.client.model.OperatorBakedModelAccess;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

public class Barricade {
public static final String MOD_ID = "barricade";
public static final String MOD_NAME = "Barricade";
public static final Logger LOG = LoggerFactory.getLogger(MOD_NAME);

// The below is only added to on the client, but we don't want to call to it.
private static final List<ResourceLocation> operatorModels = new ArrayList<>();

public static boolean isOperatorModel(Block block) {
return operatorModels.contains(block.builtInRegistryHolder().key().location());
public static boolean isOperatorModel(BlockState state) {
return BarricadeClient.getHelper() != null && Minecraft.getInstance().getModelManager().getBlockModelShaper().getBlockModel(state) instanceof OperatorBakedModelAccess;
}

public static void addToOperatorModelCache(ResourceLocation id) {
operatorModels.add(id.withPath(s -> {
String split = s.split("/", 3)[2];
return split.substring(0, split.length() - 5);
}));
}

public static void removeFromOperatorModelCache(ResourceLocation id) {
operatorModels.remove(id.withPath(s -> {
String split = s.split("/", 3)[2];
return split.substring(0, split.length() - 5);
}));
}
public static ResourceLocation asResource(String path) {
return ResourceLocation.fromNamespaceAndPath(MOD_ID, path);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package net.modgarden.barricade.client.particle;

import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleProvider;
import net.minecraft.client.particle.ParticleRenderType;
import net.minecraft.client.particle.TextureSheetParticle;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.modgarden.barricade.Barricade;
import net.modgarden.barricade.client.util.BarrierRenderUtils;
import net.modgarden.barricade.component.BlockedDirectionsComponent;
import net.modgarden.barricade.particle.AdvancedBarrierParticleOptions;
import org.jetbrains.annotations.Nullable;
import org.joml.Quaternionf;

import java.util.Optional;

public class AdvancedBarrierParticle extends TextureSheetParticle {
private final BlockedDirectionsComponent blockedDirections;
private final BlockedDirectionsComponent relative;
private final ResourceLocation backTextureLocation;
private final Optional<BlockPos> origin;
private int removeTicks = 0;

AdvancedBarrierParticle(BlockedDirectionsComponent blockedDirections, @Nullable ResourceLocation backTextureLocation, Optional<BlockPos> origin, ClientLevel level, double x, double y, double z) {
super(level, x, y, z);
this.gravity = 0.0F;
this.lifetime = 80;
this.hasPhysics = false;
this.blockedDirections = blockedDirections;
this.backTextureLocation = backTextureLocation;
this.origin = origin;
this.relative = origin.map(pos -> BarrierRenderUtils.relativeDirectionsComponent(blockedDirections, pos)).orElse(blockedDirections);
}

@Override
public void render(VertexConsumer buffer, Camera renderInfo, float partialTicks) {
if (blockedDirections != null && origin.isPresent() && !blockedDirections.blocksAll() && !blockedDirections.doesNotBlock() && !relative.equals(BarrierRenderUtils.relativeDirectionsComponent(blockedDirections, origin.get()))) {
if (removeTicks > 4) {
remove();
}
removeTicks++;
return;
}
removeTicks = 0;

Quaternionf quaternionf = new Quaternionf();
this.getFacingCameraMode().setRotation(quaternionf, renderInfo, partialTicks);
if (this.roll != 0.0F) {
quaternionf.rotateZ(Mth.lerp(partialTicks, this.oRoll, this.roll));
}

if (!relative.blocksAll()) {
this.setSprite(Minecraft.getInstance().getModelManager().getAtlas(TextureAtlas.LOCATION_BLOCKS).getSprite(Barricade.asResource("item/barricade/no_barrier")));
this.renderRotatedQuad(buffer, renderInfo, quaternionf, partialTicks);
}
if (backTextureLocation != null) {
try {
this.setSprite(Minecraft.getInstance().getModelManager().getAtlas(TextureAtlas.LOCATION_BLOCKS).getSprite(backTextureLocation));
} catch (IllegalStateException ex) {
this.setSprite(Minecraft.getInstance().getModelManager().getAtlas(TextureAtlas.LOCATION_BLOCKS).getSprite(ResourceLocation.withDefaultNamespace("missingno")));
}
this.renderRotatedQuad(buffer, renderInfo, quaternionf, partialTicks);
}
if (!relative.blocksAll()) {
for (Direction direction : relative.directions()) {
this.setSprite(Minecraft.getInstance().getModelManager().getAtlas(TextureAtlas.LOCATION_BLOCKS).getSprite(Barricade.asResource("item/barricade/direction/" + direction.getName())));
this.renderRotatedQuad(buffer, renderInfo, quaternionf, partialTicks);
}
}

if (relative.blocksAll()) {
this.setSprite(Minecraft.getInstance().getModelManager().getAtlas(TextureAtlas.LOCATION_BLOCKS).getSprite(ResourceLocation.withDefaultNamespace("item/barrier")));
this.renderRotatedQuad(buffer, renderInfo, quaternionf, partialTicks);
}
}

@Override
public ParticleRenderType getRenderType() {
return ParticleRenderType.TERRAIN_SHEET;
}

@Override
public float getQuadSize(float scaleFactor) {
return 0.5F;
}

public static class Provider implements ParticleProvider<AdvancedBarrierParticleOptions> {

@Override
public @Nullable Particle createParticle(AdvancedBarrierParticleOptions type, ClientLevel level, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) {

return new AdvancedBarrierParticle(type.blockedDirections(), type.backTextureLocation(), type.origin(), level, x, y, z);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ public interface BarricadeClientPlatformHelper {

BakedModel createCreativeOnlyModel(BakedModel model, Either<ResourceLocation, ResourceKey<Item>> requiredItem);

String getPackName(String name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.block.Blocks;
import net.modgarden.barricade.Barricade;
import net.modgarden.barricade.block.entity.AdvancedBarrierBlockEntity;
import net.modgarden.barricade.client.BarricadeClient;
Expand All @@ -31,7 +32,7 @@ public class AdvancedBarrierBlockRenderer implements BlockEntityRenderer<Advance
@Override
@SuppressWarnings("ConstantConditions")
public void render(AdvancedBarrierBlockEntity blockEntity, float partialTick, PoseStack pose, MultiBufferSource buffer, int packedLight, int packedOverlay) {
if (!Minecraft.getInstance().player.canUseGameMasterBlocks() || !Minecraft.getInstance().player.isHolding(stack -> stack.is(BarricadeTags.ItemTags.BARRIERS)))
if (!Barricade.isOperatorModel(Blocks.BARRIER.defaultBlockState()) || !Minecraft.getInstance().player.canUseGameMasterBlocks() || !Minecraft.getInstance().player.isHolding(stack -> stack.is(BarricadeTags.ItemTags.BARRIERS)))
return;

AdvancedBarrierComponents components = new AdvancedBarrierComponents(blockEntity.getBlockedEntities(), blockEntity.getBlockedDirections());
Expand All @@ -55,8 +56,6 @@ private static BakedModel createModel(AdvancedBarrierComponents components) {
variant = components.blockedEntities().backTextureLocation() + "," + String.join(",", components.blockedEntities().entities().stream().map(either -> either.map(tagKey -> "#" + tagKey.location(), holder -> holder.unwrapKey().map(ResourceKey::location).orElse(ResourceLocation.withDefaultNamespace("null")).toString())).toList());

if (components.blockedDirections() != null && !components.blockedDirections().doesNotBlock()) {
if (!variant.isEmpty())
variant = variant + ",";
variant = String.join(",", components.blockedDirections().directions().stream().map(Direction::getName).toList());
}
BlockModel blockModel = new AdvancedBarrierBlockUnbakedModel(components.blockedDirections(), components.blockedEntities());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,39 @@
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.SectionPos;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.particles.BlockParticleOption;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.component.BlockItemStateProperties;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.lighting.LightEngine;
import net.minecraft.world.phys.Vec3;
import net.modgarden.barricade.Barricade;
import net.modgarden.barricade.client.model.OperatorBakedModelAccess;
import net.modgarden.barricade.component.BlockedDirectionsComponent;
import net.modgarden.barricade.item.AdvancedBarrierBlockItem;
import net.modgarden.barricade.mixin.client.ClientChunkCacheAccessor;
import net.modgarden.barricade.mixin.client.ClientChunkCacheStorageAccessor;
import net.modgarden.barricade.mixin.client.LevelRendererInvoker;
import net.modgarden.barricade.particle.AdvancedBarrierParticleOptions;
import org.jetbrains.annotations.Nullable;

import java.util.EnumSet;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;

public class BarrierRenderUtils {
public static void refreshOperatorBlocks(ItemStack stack, ItemStack previousStack, ItemStack otherHandStack) {
Expand Down Expand Up @@ -128,4 +139,111 @@ public static boolean isLightBlockId(ResourceLocation location) {
}
return false;
}

public static void createAdvancedParticle(BlockedDirectionsComponent directions, @Nullable ResourceLocation backTexture, Consumer<ParticleOptions> optionsConsumer, BlockPos pos) {
if (directions.doesNotBlock())
optionsConsumer.accept(new AdvancedBarrierParticleOptions(new BlockedDirectionsComponent(EnumSet.noneOf(Direction.class)), null, Optional.of(pos)));
else if (directions.blocksAll())
optionsConsumer.accept(new BlockParticleOption(ParticleTypes.BLOCK_MARKER, Blocks.BARRIER.defaultBlockState()));
else {
optionsConsumer.accept(new AdvancedBarrierParticleOptions(directions, backTexture, Optional.of(pos)));
}
}

public static BlockedDirectionsComponent relativeDirectionsComponent(BlockedDirectionsComponent directions, BlockPos pos) {
Set<Direction> directionSet = new HashSet<>();
Direction relativeHorizontal = getRelativeHorizontalDirectionToPlayer();
Direction relativeVertical = getRelativeVerticalDirectionToPlayer(pos);

Direction relativeNorth;
Direction relativeSouth;
Direction relativeWest;
Direction relativeEast;
Direction relativeUp;
Direction relativeDown;

switch (relativeHorizontal) {
case SOUTH -> {
relativeSouth = Direction.NORTH;
relativeNorth = Direction.SOUTH;
relativeWest = Direction.EAST;
relativeEast = Direction.WEST;
}
case WEST -> {
relativeSouth = Direction.EAST;
relativeNorth = Direction.WEST;
relativeWest = Direction.SOUTH;
relativeEast = Direction.NORTH;
}
case EAST -> {
relativeSouth = Direction.WEST;
relativeNorth = Direction.EAST;
relativeWest = Direction.NORTH;
relativeEast = Direction.SOUTH;
}
default -> {
relativeSouth = Direction.SOUTH;
relativeNorth = Direction.NORTH;
relativeWest = Direction.WEST;
relativeEast = Direction.EAST;
}
}

switch (relativeVertical) {
case UP -> {
relativeSouth = Direction.UP;
relativeNorth = Direction.DOWN;
relativeUp = Direction.SOUTH;
relativeDown = Direction.NORTH;
}
case DOWN -> {
relativeSouth = Direction.DOWN;
relativeNorth = Direction.UP;
relativeUp = Direction.NORTH;
relativeDown = Direction.SOUTH;
}
case null, default -> {
relativeUp = Direction.UP;
relativeDown = Direction.DOWN;
}
}

if (directions.blocks(Direction.NORTH))
directionSet.add(relativeNorth);
if (directions.blocks(Direction.SOUTH))
directionSet.add(relativeSouth);
if (directions.blocks(Direction.WEST))
directionSet.add(relativeWest);
if (directions.blocks(Direction.EAST))
directionSet.add(relativeEast);
if (directions.blocks(Direction.UP))
directionSet.add(relativeUp);
if (directions.blocks(Direction.DOWN))
directionSet.add(relativeDown);

return BlockedDirectionsComponent.of(directionSet.toArray(Direction[]::new));
}

private static Direction getRelativeHorizontalDirectionToPlayer() {
Player player = Minecraft.getInstance().player;
return player.getDirection();
}

private static Direction getRelativeVerticalDirectionToPlayer(BlockPos pos) {
Player player = Minecraft.getInstance().player;

if (player == null)
return null;

Vec3 direction = new Vec3(0, 1, 0);
double dot = direction.dot(player.position().subtract(pos.getCenter()));

if (dot >= (0.5 * (player.position().subtract(pos.getCenter()).length())))
return Direction.UP;

if (dot <= (-0.9 * (player.position().subtract(pos.getCenter()).length())))
return Direction.DOWN;

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@
import net.minecraft.world.phys.shapes.Shapes;

import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

public record BlockedDirectionsComponent(Set<Direction> directions) {
public static final Codec<BlockedDirectionsComponent> CODEC = StringRepresentable.fromEnum(Direction::values).listOf().flatXmap(directions -> DataResult.success(new BlockedDirectionsComponent(Set.copyOf(directions))), component -> DataResult.success(List.copyOf(component.directions)));
public record BlockedDirectionsComponent(EnumSet<Direction> directions) {
public static final Codec<BlockedDirectionsComponent> CODEC = StringRepresentable.fromEnum(Direction::values).listOf().flatXmap(directions -> DataResult.success(BlockedDirectionsComponent.of(directions.toArray(Direction[]::new))), component -> DataResult.success(List.copyOf(component.directions)));
public static final StreamCodec<ByteBuf, BlockedDirectionsComponent> STREAM_CODEC = ByteBufCodecs.fromCodec(CODEC);

public static BlockedDirectionsComponent of(Direction... directions) {
return new BlockedDirectionsComponent(Arrays.stream(directions).collect(Collectors.toUnmodifiableSet()));
return new BlockedDirectionsComponent(EnumSet.copyOf(Arrays.stream(directions).toList()));
}

public Direction blockingDirection(BlockPos pos, CollisionContext context) {
Expand Down Expand Up @@ -70,10 +71,13 @@ public boolean blocks(Direction direction) {
}

@Override
public boolean equals(Object other) {
if (!(other instanceof BlockedDirectionsComponent component))
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof BlockedDirectionsComponent other))
return false;
return component.directions.equals(directions);
// Why do I have to do this?...
return other.directions.size() == directions.size() && other.directions.containsAll(directions);
}

@Override
Expand Down
Loading

0 comments on commit 597e4cf

Please sign in to comment.