Skip to content

Commit

Permalink
Added functionality for the block detector
Browse files Browse the repository at this point in the history
Klemmbaustein committed Aug 31, 2024
1 parent 26186e3 commit 6836624
Showing 9 changed files with 503 additions and 337 deletions.
27 changes: 22 additions & 5 deletions src/client/java/com/luna/jetoverlay/JetOverlayClient.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package com.luna.jetoverlay;

import com.luna.jetoverlay.blocks.CollisionDetectorEntity;
import com.luna.jetoverlay.blocks.DistanceSensorEntity;
import com.luna.jetoverlay.client.DistanceSensorScreen;
import com.luna.jetoverlay.client.GogglesReceiverScreen;
import com.luna.jetoverlay.client.HudOverlay;
import com.luna.jetoverlay.client.JetOverlayHud;
import com.luna.jetoverlay.client.*;
import com.mojang.blaze3d.platform.InputConstants;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.MenuScreens;
@@ -48,6 +45,17 @@ private static void createDistanceSensorScreen(BlockPos __block, int __initialRa
Minecraft.getInstance().setScreen(new DistanceSensorScreen(__block, __initialRange, __onlyPlayers));
}

private static void createBlockDetectorScreen(BlockPos __block, int __range, int __width) {
if (Minecraft.getInstance().level == null)
return;

BlockEntity ent = Minecraft.getInstance().level.getBlockEntity(__block);
if (!(ent instanceof CollisionDetectorEntity))
return;

Minecraft.getInstance().setScreen(new BlockDetectorScreen(__block, __range, __width));
}

@Override
public void onInitializeClient() {
HudRenderCallback.EVENT.register(new JetOverlayHud());
@@ -63,5 +71,14 @@ public void onInitializeClient() {
boolean onlyPlayers = buf.readBoolean();
client.execute(() -> createDistanceSensorScreen(pos, range, onlyPlayers));
});

ClientPlayNetworking.registerGlobalReceiver(ModNetworking.OPEN_BLOCK_DETECTOR_PACKET_ID,
(client, handler, buf, responseSender) -> {
BlockPos pos = buf.readBlockPos();
int range = buf.readInt();
int width = buf.readInt();
client.execute(() -> createBlockDetectorScreen(pos, range, width));
});

}
}
128 changes: 128 additions & 0 deletions src/client/java/com/luna/jetoverlay/client/BlockDetectorScreen.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package com.luna.jetoverlay.client;

import com.luna.jetoverlay.ModNetworking;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractSliderButton;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;

public class BlockDetectorScreen extends Screen {

public static final ResourceLocation _background = new ResourceLocation("jetoverlay", "textures/block_detector_ui.png");

int _range;
int _maxRange = 10;
int _width;
int _maxWidth = 4;
BlockPos _blockDetectorPos;

BlockDetectorSlider _rangeSlider = new BlockDetectorSlider(0, 0, 110, 20,
_maxRange, 1, 0, "Collider range: ", this);
BlockDetectorSlider _widthSlider = new BlockDetectorSlider(0, 0, 110, 20,
_maxWidth, 0, 1, "Collider width: ", this);

public BlockDetectorScreen(BlockPos __screenBlock, int __range, int __width) {
super(Component.literal("Block Detector"));
_blockDetectorPos = __screenBlock;
_range = __range;
_width = __width;
}

@Override
protected void init() {
int leftPos = (this.width - 256) / 2;
int topPos = (this.height - 50) / 2;

_rangeSlider.setPosition(leftPos + 10, topPos + 20);
_widthSlider.setPosition(leftPos + 130, topPos + 20);

_rangeSlider.update(_range);
_widthSlider.update(_width);
addRenderableWidget(_rangeSlider);
addRenderableWidget(_widthSlider);
}

@Override
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
int leftPos = (this.width - 256) / 2;
int topPos = (this.height - 50) / 2;

guiGraphics.blit(_background, leftPos, topPos, 0, 0, 0, 256, 50, 256, 50);

guiGraphics.drawString(Minecraft.getInstance().font, getTitle(), leftPos + 10, topPos + 6, 0x202020, false);

super.render(guiGraphics, mouseX, mouseY, partialTick);
}

public void setRange(int __value, int __id) {
if (__id == 0) {
if (_range == __value)
return;
_range = __value;

FriendlyByteBuf buffer = PacketByteBufs.create();
buffer.writeBlockPos(_blockDetectorPos);
buffer.writeInt(_range);

ClientPlayNetworking.send(ModNetworking.BLOCK_DETECTOR_SET_RANGE_PACKET_ID, buffer);
}
else {
if (_width == __value)
return;
_width = __value;

FriendlyByteBuf buffer = PacketByteBufs.create();
buffer.writeBlockPos(_blockDetectorPos);
buffer.writeInt(_width);

ClientPlayNetworking.send(ModNetworking.BLOCK_DETECTOR_SET_THICKNESS_PACKET_ID, buffer);
}
}

private static class BlockDetectorSlider extends AbstractSliderButton {
BlockDetectorScreen _parent;
int _valueRange;
int _maxValue;
int _minValue;
int _id;
String _text;

private int getIntValue() {
return (int) Math.round(value * _valueRange);
}

public BlockDetectorSlider(int x, int y, int width, int height,
int __maxValue, int __minValue, int __id, String __text, BlockDetectorScreen parent) {
super(x, y, width, height, Component.literal(""), 0);
_parent = parent;
_valueRange = __maxValue - _minValue;
_maxValue = __maxValue;
_minValue = __minValue;
_text = __text;
_id = __id;
}

public void update(int __value) {
_valueRange = _maxValue - _minValue;
value = (double) (__value - _minValue) / _valueRange;
updateMessage();
}

@Override
protected void updateMessage() {
setMessage(Component.literal(_text + (getIntValue() + _minValue)));
}

@Override
protected void applyValue() {
value = (float) getIntValue() / (float) _valueRange;
_parent.setRange((int) (value * _valueRange) + _minValue, _id);
}
}
}

This file was deleted.

6 changes: 4 additions & 2 deletions src/main/java/com/luna/jetoverlay/ModItems.java
Original file line number Diff line number Diff line change
@@ -44,12 +44,14 @@ public class ModItems {


public static final Block COLLISION_DETECTOR = Registry.register(BuiltInRegistries.BLOCK, new ResourceLocation(
"jetoverlay", "collision_detector"), new CollisionDetector(FabricBlockSettings.create().strength(4)));
"jetoverlay", "collision_detector"),
new CollisionDetector(FabricBlockSettings.create().strength(4)));

public static final BlockEntityType<CollisionDetectorEntity> COLLISION_DETECTOR_ENTITY =
Registry.register(BuiltInRegistries.BLOCK_ENTITY_TYPE, new ResourceLocation("jetoverlay",
"collision_detector"),
BlockEntityType.Builder.of(CollisionDetectorEntity::new, COLLISION_DETECTOR).build(null));
BlockEntityType.Builder.of(CollisionDetectorEntity::new, COLLISION_DETECTOR)
.build(null));

public static Item registerItem(Item item, String id) {
return Registry.register(BuiltInRegistries.ITEM, new ResourceLocation("jetoverlay", id), item);
49 changes: 44 additions & 5 deletions src/main/java/com/luna/jetoverlay/ModNetworking.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.luna.jetoverlay;

import com.luna.jetoverlay.armor.JetGoggles;
import com.luna.jetoverlay.blocks.CollisionDetectorEntity;
import com.luna.jetoverlay.blocks.DistanceSensor;
import com.luna.jetoverlay.blocks.DistanceSensorEntity;
import com.luna.jetoverlay.blocks.RotationToRedstoneEntity;
@@ -15,6 +16,9 @@ public class ModNetworking {
public static final ResourceLocation OPEN_SENSOR_PACKET_ID = new ResourceLocation("jetgoggles", "packets/open_sensor");
public static final ResourceLocation SET_SENSOR_RANGE_PACKET_ID = new ResourceLocation("jetgoggles", "packets/sensor_range");
public static final ResourceLocation SENSOR_INCLUDE_PLAYERS_PACKET_ID = new ResourceLocation("jetgoggles", "packets/sensor_include_players");
public static final ResourceLocation OPEN_BLOCK_DETECTOR_PACKET_ID = new ResourceLocation("jetgoggles", "packets/open_block_detector");
public static final ResourceLocation BLOCK_DETECTOR_SET_RANGE_PACKET_ID = new ResourceLocation("jetgoggles", "packets/block_detector_set_range");
public static final ResourceLocation BLOCK_DETECTOR_SET_THICKNESS_PACKET_ID = new ResourceLocation("jetgoggles", "packets/block_detector_set_thickness");

private static void handleLinkPacket(BlockPos pos, ServerPlayer player) {
var entity = player.level().getBlockEntity(pos);
@@ -43,7 +47,6 @@ private static void handleSetDirectionPacket(BlockPos pos, CameraRotationDirecti
}

receiverEntity._boundDirection = direction;
JetOverlay.LOGGER.info("New block direction: " + direction);
receiverEntity.setChanged();
}

@@ -56,23 +59,40 @@ private static void handleSetSensorRangePacket(BlockPos pos, int newRange, Serve
return;
}

JetOverlay.LOGGER.info("new block range: " + newRange);

sensorEntity.range = newRange;
sensorEntity.setChanged();
}

private static void handleSensorIncludePlayersPacket(BlockPos pos, boolean newValue, ServerPlayer player) {
var entity = player.level().getBlockEntity(pos);
if (!(entity instanceof DistanceSensorEntity sensorEntity)) {
return;
}

JetOverlay.LOGGER.info("Sensor includes players: " + newValue);

sensorEntity.onlyIncludePlayers = newValue;
sensorEntity.setChanged();
}

private static void handleBlockDetectorSetRangePacket(BlockPos pos, int newValue, ServerPlayer player) {
var entity = player.level().getBlockEntity(pos);
if (!(entity instanceof CollisionDetectorEntity blockDetectorEntity)) {
return;
}

blockDetectorEntity.range = newValue;
blockDetectorEntity.setChanged();
}

private static void handleBlockDetectorSetWidthPacket(BlockPos pos, int newValue, ServerPlayer player) {
var entity = player.level().getBlockEntity(pos);
if (!(entity instanceof CollisionDetectorEntity blockDetectorEntity)) {
return;
}

blockDetectorEntity.width = newValue;
blockDetectorEntity.setChanged();
}

public static void initialize() {
ServerPlayNetworking.registerGlobalReceiver(LINK_GOGGLES_PACKET_ID, (server, player, handler, buf, responseSender) -> {
BlockPos pos = buf.readBlockPos();
@@ -106,5 +126,24 @@ public static void initialize() {
// Make sure we're on the main server thread before accessing any of the block entity stuff.
server.execute(() -> handleSensorIncludePlayersPacket(pos, include, player));
});

ServerPlayNetworking.registerGlobalReceiver(BLOCK_DETECTOR_SET_RANGE_PACKET_ID, (server, player, handler, buf, responseSender) -> {
BlockPos pos = buf.readBlockPos();

int range = buf.readInt();
// Receiving packets happens on a different thread.
// Make sure we're on the main server thread before accessing any of the block entity stuff.
server.execute(() -> handleBlockDetectorSetRangePacket(pos, range, player));
});

ServerPlayNetworking.registerGlobalReceiver(BLOCK_DETECTOR_SET_THICKNESS_PACKET_ID, (server, player, handler, buf, responseSender) -> {
BlockPos pos = buf.readBlockPos();

int width = buf.readInt();
// Receiving packets happens on a different thread.
// Make sure we're on the main server thread before accessing any of the block entity stuff.
server.execute(() -> handleBlockDetectorSetWidthPacket(pos, width, player));
});

}
}
82 changes: 59 additions & 23 deletions src/main/java/com/luna/jetoverlay/blocks/CollisionDetector.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package com.luna.jetoverlay.blocks;

import com.luna.jetoverlay.ModNetworking;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
@@ -10,32 +18,60 @@
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.phys.BlockHitResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;

public class CollisionDetector extends Block implements EntityBlock {
public CollisionDetector (Properties properties) {
super(properties);
}

@Override
public int getSignal (BlockState state, BlockGetter level, BlockPos pos, Direction direction) {
byte _value = ((CollisionDetectorEntity) Objects.requireNonNull(level.getBlockEntity(pos)))._redstonePower;
return _value;
}

@Override
public @Nullable BlockEntity newBlockEntity (BlockPos pos, BlockState state) {
return new CollisionDetectorEntity(pos, state);
}

@Override
public @Nullable <T extends BlockEntity> BlockEntityTicker<T> getTicker (Level level, BlockState state, BlockEntityType<T> blockEntityType) {
if (level.isClientSide())
return null;
return CollisionDetectorEntity::tick;
}


public CollisionDetector(Properties properties) {
super(properties);
registerDefaultState(defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.SOUTH));
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
return Objects.requireNonNull(super.getStateForPlacement(ctx))
.setValue(BlockStateProperties.HORIZONTAL_FACING, ctx.getHorizontalDirection().getOpposite());
}

@Override
public int getSignal(BlockState state, BlockGetter level, BlockPos pos, Direction direction) {
return ((CollisionDetectorEntity) Objects.requireNonNull(level.getBlockEntity(pos)))._redstonePower;
}

@Override
public @Nullable BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
return new CollisionDetectorEntity(pos, state);
}

@Override
public @NotNull InteractionResult use(BlockState state, Level level, BlockPos pos,
Player player, InteractionHand hand, BlockHitResult hit) {
if (!level.isClientSide()) {
var buf = PacketByteBufs.create();
buf.writeBlockPos(pos);
buf.writeInt(((CollisionDetectorEntity) Objects.requireNonNull(level.getBlockEntity(pos))).range);
buf.writeInt(((CollisionDetectorEntity) Objects.requireNonNull(level.getBlockEntity(pos))).width);
ServerPlayNetworking.send((ServerPlayer) player, ModNetworking.OPEN_BLOCK_DETECTOR_PACKET_ID, buf);
}
return InteractionResult.SUCCESS;
}

@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(BlockStateProperties.HORIZONTAL_FACING);
}

@Override
public @Nullable <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> blockEntityType) {
if (level.isClientSide())
return null;
return CollisionDetectorEntity::tick;
}


}
168 changes: 71 additions & 97 deletions src/main/java/com/luna/jetoverlay/blocks/CollisionDetectorEntity.java
Original file line number Diff line number Diff line change
@@ -1,110 +1,84 @@
package com.luna.jetoverlay.blocks;

import com.luna.jetoverlay.ModItems;
import it.unimi.dsi.fastutil.doubles.DoubleList;
import com.mojang.datafixers.util.Pair;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.core.Vec3i;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.DiscreteVoxelShape;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;

import java.util.Arrays;
import java.util.Objects;

public class CollisionDetectorEntity extends BlockEntity {
public static byte _redstonePower = 0;
public CollisionDetectorEntity (BlockPos pos, BlockState blockState) {
super(ModItems.COLLISION_DETECTOR_ENTITY, pos, blockState);
}
static long _lastRotationUpdateTick;
public static <T extends BlockEntity> void tick (Level __level, BlockPos __blockPos, BlockState __blockState, T __entity) {
long currentTick = __level.getGameTime();
System.out.println("yippe");
if (currentTick != _lastRotationUpdateTick) {
_lastRotationUpdateTick = currentTick;
boolean blockDetected = false;
Direction direction = Direction.SOUTH; // Replace with the desired direction

AABB bb = new AABB(new BlockPos(__blockPos.getX(), __blockPos.getY(), __blockPos.getZ() + 1),
new BlockPos(0,0,0)).inflate(0,0,5);

BlockPos minPos = new BlockPos((int)bb.minX, (int)bb.minY, (int)bb.minZ);
BlockPos maxPos = new BlockPos((int)bb.maxX, (int)bb.maxY, (int)bb.maxZ);

// Iterate over all positions within the bounding box
for (BlockPos pos : BlockPos.betweenClosed(minPos, maxPos)) {
BlockState blockState = __level.getBlockState(pos);
if (!blockState.isAir()) { // Check if there's a block (not air)
blockDetected = true;
}
else {
blockDetected = false;
}
}

if(blockDetected) {
_redstonePower = 15;
System.out.println("Block found");
}
else {
_redstonePower = 0;
System.out.println("Block not found");
}
Objects.requireNonNull(__level).blockUpdated(__blockPos, __blockState.getBlock());


}
}
private static AABB createDirectionalBoundingBox(BlockPos pos, Direction direction) {
double expansion = 2.0; // The length of the hitbox

switch (direction) {
case NORTH:
return new AABB(
pos.getX() - 2, pos.getY() - 2, pos.getZ() - 2 + expansion,
pos.getX() + 2, pos.getY() + 2, pos.getZ() + 2
);
case SOUTH:
return new AABB(
pos.getX() - 2, pos.getY() - 2, pos.getZ() - 2,
pos.getX() + 2, pos.getY() + 2, pos.getZ() - 2 - expansion
);
case WEST:
return new AABB(
pos.getX() - 2 - expansion, pos.getY() - 2, pos.getZ() - 2,
pos.getX() + 2, pos.getY() + 2, pos.getZ() + 2
);
case EAST:
return new AABB(
pos.getX() - 2, pos.getY() - 2, pos.getZ() - 2,
pos.getX() + 2 + expansion, pos.getY() + 2, pos.getZ() + 2
);
default:
return new AABB(
pos.getX() - 2, pos.getY() - 2, pos.getZ() - 2,
pos.getX() + 2, pos.getY() + 2, pos.getZ() + 2
);
}
}

private static boolean detectBlocksInBoundingBox(Level level, AABB bb) {
// Convert AABB to BlockPos range
BlockPos minPos = new BlockPos((int)bb.minX, (int)bb.minY, (int)bb.minZ);
BlockPos maxPos = new BlockPos((int)bb.maxX, (int)bb.maxY, (int)bb.maxZ);

// Iterate over all positions within the bounding box
for (BlockPos pos : BlockPos.betweenClosed(minPos, maxPos)) {
BlockState blockState = level.getBlockState(pos);
if (!blockState.isAir()) { // Check if there's a block (not air)
return true; // Block detected
}
}
return false; // No blocks detected
}
public int _redstonePower = 0;
public int width = 0;
public int range = 3;

public CollisionDetectorEntity(BlockPos pos, BlockState blockState) {
super(ModItems.COLLISION_DETECTOR_ENTITY, pos, blockState);
}

static Pair<BlockPos, BlockPos> getDetectionMinMax(BlockPos __at, Direction __dir, int __length, int __thickness) {
Vec3i normal = __dir.getNormal();
Vec3i absNormal = new Vec3i(Math.abs(normal.getX()), Math.abs(normal.getY()), Math.abs(normal.getZ()));
Vec3i facingAway = new Vec3i(1, 1, 1).subtract(absNormal).multiply(__thickness);

Vec3i min = __at.subtract(facingAway).offset(normal);
Vec3i max = __at.offset(facingAway).relative(__dir, __length);

return new Pair<>(new BlockPos(min.getX(), min.getY(), min.getZ()),
new BlockPos(max.getX(), max.getY(), max.getZ()));
}

public static <T extends BlockEntity> void tick(Level __level, BlockPos __blockPos, BlockState __blockState, T __entity) {
// Only update every 4 game ticks
if (__level.getGameTime() % 4 == 0) {
return;
}

if (!(__entity instanceof CollisionDetectorEntity collisionBlock)) {
return;
}

boolean blockDetected = false;
Direction direction = __blockState.getValue(BlockStateProperties.HORIZONTAL_FACING);

Pair<BlockPos, BlockPos> minMax = getDetectionMinMax(__blockPos, direction, collisionBlock.range, collisionBlock.width);

// Iterate over all positions within the bounding box
for (BlockPos pos : BlockPos.betweenClosed(minMax.getFirst(), minMax.getSecond())) {
BlockState blockState = __level.getBlockState(pos);
if (!blockState.isAir()) { // Check if there's a block (not air)
blockDetected = true;
}
}

int newRedstonePower = blockDetected ? 15 : 0;
if (newRedstonePower != collisionBlock._redstonePower) {
collisionBlock._redstonePower = newRedstonePower;
Objects.requireNonNull(__level).blockUpdated(__blockPos, __blockState.getBlock());
}
}

@Override
public void load(CompoundTag __nbt) {
super.load(__nbt);
if (__nbt.contains("range"))
range = __nbt.getInt("range");
if (__nbt.contains("width"))
width = __nbt.getInt("width");
}

@Override
public void saveAdditional(CompoundTag __nbt) {
super.saveAdditional(__nbt);
// Save the current value of the number to the nbt
__nbt.putInt("range", range);
__nbt.putInt("width", width);
}

}
358 changes: 175 additions & 183 deletions src/main/java/com/luna/jetoverlay/blocks/RotationToRedstoneEntity.java
Original file line number Diff line number Diff line change
@@ -27,188 +27,180 @@
import java.util.Objects;

public class RotationToRedstoneEntity extends BaseContainerBlockEntity
implements ExtendedScreenHandlerFactory, MenuProvider {
public RotationToRedstoneEntity(BlockPos pos, BlockState blockState) {
super(ModItems.JET_GOGGLES_RECEIVER_ENTITY, pos, blockState);
}

ItemStack insertedItem = ItemStack.EMPTY;
public GogglesReceiverScreenHandler _currentScreen = null;
public CameraRotationDirection _boundDirection = CameraRotationDirection.RIGHT;
private byte _redstoneValue = 0;
private static long _lastRotationUpdateTick = 0;
private static HashMap<Player, Vec2> _oldPlayerRotations = new HashMap<>();

@Override
public @NotNull Component getDisplayName() {
return Component.literal("Goggles Receiver");
}

@Override
protected @NotNull Component getDefaultName() {
return getDisplayName();
}

@Override
public @Nullable AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) {
_currentScreen = new GogglesReceiverScreenHandler(i, inventory, this);
return _currentScreen;
}

@Override
protected @NotNull AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
_currentScreen = new GogglesReceiverScreenHandler(containerId, inventory, (FriendlyByteBuf) null);
return _currentScreen;
}

@Override
public int getContainerSize() {
return 1;
}

@Override
public boolean isEmpty() {
return false;
}

@Override
public @NotNull ItemStack getItem(int slot) {
if (slot == 0)
return insertedItem;
return ItemStack.EMPTY;
}

@Override
public @NotNull ItemStack removeItem(int slot, int amount) {
ItemStack newStack = insertedItem.copy();
newStack.setCount(amount);
insertedItem.setCount(insertedItem.getCount() - amount);
if (insertedItem.getCount() <= 0) {
insertedItem = ItemStack.EMPTY;
}
return newStack;
}

@Override
public @NotNull ItemStack removeItemNoUpdate(int slot) {
insertedItem = ItemStack.EMPTY;
return insertedItem;
}

@Override
public void setItem(int slot, ItemStack stack) {
if (slot == 0)
insertedItem = stack;
}

@Override
public boolean stillValid(Player player) {
return true;
}

@Override
public void writeScreenOpeningData(ServerPlayer serverPlayerEntity, FriendlyByteBuf packetByteBuf) {
//The pos field is a public field from BlockEntity
packetByteBuf.writeBlockPos(getBlockPos());
packetByteBuf.writeInt(_boundDirection.ordinal());
}

@Override
public void clearContent() {
insertedItem = ItemStack.EMPTY;
}

@Override
public void load(CompoundTag __nbt) {
super.load(__nbt);
_boundDirection = CameraRotationDirection.values()[__nbt.getInt("Direction")];
if (_boundDirection == null) {
_boundDirection = CameraRotationDirection.RIGHT;
}
}

@Override
public void saveAdditional(CompoundTag __nbt) {
super.saveAdditional(__nbt);
// Save the current value of the number to the nbt
__nbt.putInt("Direction", _boundDirection.ordinal());
}

private void setRedstoneValueFromRotation(float rotationValue) {
byte newValue = (byte) Math.max(rotationValue / 5.0f, 0.0f);
if (newValue == 0 && rotationValue > 0) {
newValue = 1;
}

if (newValue == _redstoneValue)
return;

_redstoneValue = newValue;
Objects.requireNonNull(getLevel()).blockUpdated(getBlockPos(), getBlockState().getBlock());
}
public byte getRedstoneValue() {
return _redstoneValue;
}

private static void sendRotationToBlock(Level __level, BlockPos __block, Vec2 __rotation) {
var entity = __level.getBlockEntity(__block);
if (entity == null)
return;

if (!(entity instanceof RotationToRedstoneEntity receiverEntity))
return;

switch (receiverEntity._boundDirection) {
case RIGHT -> {
receiverEntity.setRedstoneValueFromRotation(-__rotation.y);
}
case LEFT -> {
receiverEntity.setRedstoneValueFromRotation(__rotation.y);
}
case UP -> {
receiverEntity.setRedstoneValueFromRotation(__rotation.x);
}
case DOWN -> {
receiverEntity.setRedstoneValueFromRotation(-__rotation.x);
}
case NOTHING -> {
}
}
}

private static void updateGlobalRotations(Level __level) {
var players = __level.players();

for (Player player : players) {
var headItem = player.getInventory().getArmor(3);

if (!headItem.is(ModItems.JET_GOGGLES))
continue;

Vec2 rotation = player.getRotationVector();

if (!_oldPlayerRotations.containsKey(player)) {
_oldPlayerRotations.put(player, rotation);
continue;
}

Vec2 oldRotation = _oldPlayerRotations.get(player);
_oldPlayerRotations.put(player, rotation);

Vec2 difference = oldRotation.add(rotation.negated());

for (BlockPos block : JetGoggles.itemGetBlocks(headItem)) {
sendRotationToBlock(__level, block, difference);
}
}
}

public static <T extends BlockEntity> void tick(Level __level, BlockPos __blockPos, BlockState __blockState, T __entity) {
long currentTick = __level.getGameTime();
if (currentTick != _lastRotationUpdateTick) {
_lastRotationUpdateTick = currentTick;
updateGlobalRotations(__level);
}
}
implements ExtendedScreenHandlerFactory, MenuProvider {
public RotationToRedstoneEntity(BlockPos pos, BlockState blockState) {
super(ModItems.JET_GOGGLES_RECEIVER_ENTITY, pos, blockState);
}

ItemStack insertedItem = ItemStack.EMPTY;
public GogglesReceiverScreenHandler _currentScreen = null;
public CameraRotationDirection _boundDirection = CameraRotationDirection.RIGHT;
private byte _redstoneValue = 0;
private static long _lastRotationUpdateTick = 0;
private static final HashMap<Player, Vec2> _oldPlayerRotations = new HashMap<>();

@Override
public @NotNull Component getDisplayName() {
return Component.literal("Goggles Receiver");
}

@Override
protected @NotNull Component getDefaultName() {
return getDisplayName();
}

@Override
public @Nullable AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) {
_currentScreen = new GogglesReceiverScreenHandler(i, inventory, this);
return _currentScreen;
}

@Override
protected @NotNull AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
_currentScreen = new GogglesReceiverScreenHandler(containerId, inventory, (FriendlyByteBuf) null);
return _currentScreen;
}

@Override
public int getContainerSize() {
return 1;
}

@Override
public boolean isEmpty() {
return false;
}

@Override
public @NotNull ItemStack getItem(int slot) {
if (slot == 0)
return insertedItem;
return ItemStack.EMPTY;
}

@Override
public @NotNull ItemStack removeItem(int slot, int amount) {
ItemStack newStack = insertedItem.copy();
newStack.setCount(amount);
insertedItem.setCount(insertedItem.getCount() - amount);
if (insertedItem.getCount() <= 0) {
insertedItem = ItemStack.EMPTY;
}
return newStack;
}

@Override
public @NotNull ItemStack removeItemNoUpdate(int slot) {
insertedItem = ItemStack.EMPTY;
return insertedItem;
}

@Override
public void setItem(int slot, ItemStack stack) {
if (slot == 0)
insertedItem = stack;
}

@Override
public boolean stillValid(Player player) {
return true;
}

@Override
public void writeScreenOpeningData(ServerPlayer serverPlayerEntity, FriendlyByteBuf packetByteBuf) {
//The pos field is a public field from BlockEntity
packetByteBuf.writeBlockPos(getBlockPos());
packetByteBuf.writeInt(_boundDirection.ordinal());
}

@Override
public void clearContent() {
insertedItem = ItemStack.EMPTY;
}

@Override
public void load(CompoundTag __nbt) {
super.load(__nbt);
_boundDirection = CameraRotationDirection.values()[__nbt.getInt("Direction")];
if (_boundDirection == null) {
_boundDirection = CameraRotationDirection.RIGHT;
}
}

@Override
public void saveAdditional(CompoundTag __nbt) {
super.saveAdditional(__nbt);
// Save the current value of the number to the nbt
__nbt.putInt("Direction", _boundDirection.ordinal());
}

private void setRedstoneValueFromRotation(float rotationValue) {
byte newValue = (byte) Math.max(rotationValue / 5.0f, 0.0f);
if (newValue == 0 && rotationValue > 0) {
newValue = 1;
}

if (newValue == _redstoneValue)
return;

_redstoneValue = newValue;
Objects.requireNonNull(getLevel()).blockUpdated(getBlockPos(), getBlockState().getBlock());
}

public byte getRedstoneValue() {
return _redstoneValue;
}

private static void sendRotationToBlock(Level __level, BlockPos __block, Vec2 __rotation) {
var entity = __level.getBlockEntity(__block);
if (entity == null)
return;

if (!(entity instanceof RotationToRedstoneEntity receiverEntity))
return;

switch (receiverEntity._boundDirection) {
case RIGHT -> receiverEntity.setRedstoneValueFromRotation(-__rotation.y);
case LEFT -> receiverEntity.setRedstoneValueFromRotation(__rotation.y);
case UP -> receiverEntity.setRedstoneValueFromRotation(__rotation.x);
case DOWN -> receiverEntity.setRedstoneValueFromRotation(-__rotation.x);
case NOTHING -> {}
}
}

private static void updateGlobalRotations(Level __level) {
var players = __level.players();

for (Player player : players) {
var headItem = player.getInventory().getArmor(3);

if (!headItem.is(ModItems.JET_GOGGLES))
continue;

Vec2 rotation = player.getRotationVector();

if (!_oldPlayerRotations.containsKey(player)) {
_oldPlayerRotations.put(player, rotation);
continue;
}

Vec2 oldRotation = _oldPlayerRotations.get(player);
_oldPlayerRotations.put(player, rotation);

Vec2 difference = oldRotation.add(rotation.negated());

for (BlockPos block : JetGoggles.itemGetBlocks(headItem)) {
sendRotationToBlock(__level, block, difference);
}
}
}

public static <T extends BlockEntity> void tick(Level __level, BlockPos __blockPos, BlockState __blockState, T __entity) {
long currentTick = __level.getGameTime();
if (currentTick != _lastRotationUpdateTick) {
_lastRotationUpdateTick = currentTick;
updateGlobalRotations(__level);
}
}

}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 6836624

Please sign in to comment.