laser pointer work

This commit is contained in:
GiantLuigi4 2023-06-05 15:58:32 -04:00
parent c066176c79
commit 78160917eb
11 changed files with 375 additions and 278 deletions

View File

@ -64,7 +64,6 @@ import net.montoyo.wd.client.gui.*;
import net.montoyo.wd.client.gui.loading.GuiLoader;
import net.montoyo.wd.client.renderers.*;
import net.montoyo.wd.config.ClientConfig;
import net.montoyo.wd.core.DefaultUpgrade;
import net.montoyo.wd.core.HasAdvancement;
import net.montoyo.wd.core.JSServerRequest;
import net.montoyo.wd.data.GuiData;
@ -77,8 +76,6 @@ import net.montoyo.wd.item.ItemMinePad2;
import net.montoyo.wd.item.WDItem;
import net.montoyo.wd.miniserv.client.Client;
import net.montoyo.wd.net.WDNetworkRegistry;
import net.montoyo.wd.net.client_bound.S2CMessageScreenUpdate;
import net.montoyo.wd.net.server_bound.C2SMessageScreenCtrl;
import net.montoyo.wd.net.server_bound.C2SMinepadUrl;
import net.montoyo.wd.utilities.*;
import org.lwjgl.glfw.GLFW;
@ -130,8 +127,8 @@ public class ClientProxy extends SharedProxy implements IDisplayHandler, IJSQuer
if (!(stack.getItem() instanceof ItemLaserPointer ||
stack1.getItem() instanceof ItemLaserPointer))
return;
if (!INSTANCE.laserPointerRenderer.isOn) {
if (!LaserPointerRenderer.isOn()) {
RenderSystem.setShaderTexture(0, new ResourceLocation(
"webdisplays:textures/gui/cursors.png"
));
@ -220,11 +217,6 @@ public class ClientProxy extends SharedProxy implements IDisplayHandler, IJSQuer
private ClientAdvancements lastAdvMgr;
private Map advancementToProgress;
//Laser pointer
private TileEntityScreen pointedScreen;
private BlockSide pointedScreenSide;
private long lastPointPacket;
//Tracking
private final ArrayList<TileEntityScreen> screenTracking = new ArrayList<>();
private int lastTracked = 0;
@ -667,54 +659,54 @@ public class ClientProxy extends SharedProxy implements IDisplayHandler, IJSQuer
@SubscribeEvent
public void onTick(TickEvent.ClientTickEvent ev) {
if(ev.phase != TickEvent.Phase.END) return;
if (ev.phase != TickEvent.Phase.END) return;
//Help
if(InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), GLFW.GLFW_KEY_F1)) {
if(!isF1Down) {
if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), GLFW.GLFW_KEY_F1)) {
if (!isF1Down) {
isF1Down = true;
String wikiName = null;
if(mc.screen instanceof WDScreen)
if (mc.screen instanceof WDScreen)
wikiName = ((WDScreen) mc.screen).getWikiPageName();
else if(mc.screen instanceof ContainerScreen) {
else if (mc.screen instanceof ContainerScreen) {
Slot slot = ((ContainerScreen) mc.screen).getSlotUnderMouse();
if(slot != null && slot.hasItem() && slot.getItem().getItem() instanceof WDItem)
if (slot != null && slot.hasItem() && slot.getItem().getItem() instanceof WDItem)
wikiName = ((WDItem) slot.getItem().getItem()).getWikiName(slot.getItem());
}
if(wikiName != null)
if (wikiName != null)
mcef.openExampleBrowser("https://montoyo.net/wdwiki/index.php/" + wikiName);
}
} else if(isF1Down)
} else if (isF1Down)
isF1Down = false;
//Workaround cuz chat sux
if(nextScreen != null && mc.screen == null) {
if (nextScreen != null && mc.screen == null) {
mc.setScreen(nextScreen);
nextScreen = null;
}
//Load/unload minePads depending on which item is in the player's hand
if(++minePadTickCounter >= 10) {
if (++minePadTickCounter >= 10) {
minePadTickCounter = 0;
Player ep = mc.player;
for(PadData pd: padList)
for (PadData pd : padList)
pd.isInHotbar = false;
if(ep != null) {
if (ep != null) {
updateInventory(ep.getInventory().items, ep.getItemInHand(InteractionHand.MAIN_HAND), 9);
updateInventory(ep.getInventory().offhand, ep.getItemInHand(InteractionHand.OFF_HAND), 1); //Is this okay?
}
//TODO: Check for GuiContainer.draggedStack
for(int i = padList.size() - 1; i >= 0; i--) {
for (int i = padList.size() - 1; i >= 0; i--) {
PadData pd = padList.get(i);
if(!pd.isInHotbar) {
if (!pd.isInHotbar) {
pd.view.close();
pd.view = null; //This is for GuiMinePad, in case the player dies with the GUI open
padList.remove(i);
@ -722,52 +714,21 @@ public class ClientProxy extends SharedProxy implements IDisplayHandler, IJSQuer
}
}
}
//Laser pointer raycast
if(mc.player != null && mc.level != null && ItemInit.itemLaserPointer.isPresent() && mc.player.getItemInHand(InteractionHand.MAIN_HAND).getItem().equals(ItemInit.itemLaserPointer.get())
&& mc.options.keyUse.isDown()
&& (mc.hitResult == null || mc.hitResult.getType() == HitResult.Type.BLOCK || mc.hitResult.getType() == HitResult.Type.MISS)) {
BlockHitResult result = raycast(64.0); //TODO: Make that distance configurable
BlockPos bpos = result.getBlockPos();
if(result.getType() == HitResult.Type.BLOCK && mc.level.getBlockState(bpos).getBlock() == BlockInit.blockScreen.get()) {
laserPointerRenderer.isOn = true;
Vector3i pos = new Vector3i(result.getBlockPos());
BlockSide side = BlockSide.values()[result.getDirection().ordinal()];
Multiblock.findOrigin(mc.level, pos, side, null);
TileEntityScreen te = (TileEntityScreen) mc.level.getBlockEntity(pos.toBlock());
if(te != null && te.hasUpgrade(side, DefaultUpgrade.LASERMOUSE)) { //hasUpgrade returns false is there's no screen on side 'side'
//Since rights aren't synchronized, let the server check them for us...
TileEntityScreen.Screen scr = te.getScreen(side);
if(scr.browser != null) {
float hitX = ((float) result.getLocation().x) - (float) pos.x;
float hitY = ((float) result.getLocation().y) - (float) pos.y;
float hitZ = ((float) result.getLocation().z) - (float) pos.z;
Vector2i tmp = new Vector2i();
if(BlockScreen.hit2pixels(side, bpos, new Vector3i(result.getBlockPos()), scr, hitX, hitY, hitZ, tmp)) {
laserClick(te, side, scr, tmp);
}
}
}
}
if (LaserPointerRenderer.isOn()) {
ItemLaserPointer.tick(mc);
} else {
laserPointerRenderer.isOn = false;
deselectScreen();
//Handle JS queries
jsDispatcher.handleQueries();
//Miniserv
if (msClientStarted && mc.player == null) {
msClientStarted = false;
Client.getInstance().stop();
}
ItemLaserPointer.deselect(mc, jsDispatcher);
}
//Handle JS queries
jsDispatcher.handleQueries();
//Miniserv
if (msClientStarted && mc.player == null) {
msClientStarted = false;
Client.getInstance().stop();
}
}
@ -805,39 +766,7 @@ public class ClientProxy extends SharedProxy implements IDisplayHandler, IJSQuer
}
}
/**************************************** OTHER METHODS ****************************************/
private void laserClick(TileEntityScreen tes, BlockSide side, TileEntityScreen.Screen scr, Vector2i hit) {
tes.handleMouseEvent(side, S2CMessageScreenUpdate.MOUSE_MOVE, hit);
if(pointedScreen == tes && pointedScreenSide == side) {
long t = System.currentTimeMillis();
if(t - lastPointPacket >= 100) {
lastPointPacket = t;
if (Minecraft.getInstance().player.isShiftKeyDown()) {
tes.handleMouseEvent(side, S2CMessageScreenUpdate.MOUSE_CLICK, hit);
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserDown(tes, side, hit));
} else {
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserMove(tes, side, hit));
}
}
} else {
deselectScreen();
pointedScreen = tes;
pointedScreenSide = side;
// WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserDown(tes, side, hit));
}
}
private void deselectScreen() {
if(pointedScreen != null && pointedScreenSide != null) {
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserUp(pointedScreen, pointedScreenSide));
pointedScreen = null;
pointedScreenSide = null;
}
}
private static BlockHitResult raycast(double dist) {
public static BlockHitResult raycast(double dist) {
Minecraft mc = Minecraft.getInstance();
Vec3 start = mc.player.getEyePosition(1.0f);

View File

@ -151,13 +151,11 @@ public class GuiKeyboard extends WDScreen {
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if(quitOnEscape && keyCode == GLFW.GLFW_KEY_ESCAPE) {
if(quitOnEscape && keyCode == GLFW.GLFW_KEY_ESCAPE)
Minecraft.getInstance().setScreen(null);
}
evStack.add(new TypeData(TypeData.Action.PRESS, keyCode, modifiers));
if (!evStack.isEmpty() && !syncRequested())
requestSync();
sync();
return super.keyPressed(keyCode, scanCode, modifiers);
}
@ -166,7 +164,6 @@ public class GuiKeyboard extends WDScreen {
evStack.add(new TypeData(TypeData.Action.TYPE, codePoint, modifiers));
if (!evStack.isEmpty() && !syncRequested())
requestSync();
sync();
return super.charTyped(codePoint, modifiers);
}
@ -175,7 +172,6 @@ public class GuiKeyboard extends WDScreen {
evStack.add(new TypeData(TypeData.Action.RELEASE, keyCode, modifiers));
if (!evStack.isEmpty() && !syncRequested())
requestSync();
sync();
return super.keyPressed(keyCode, scanCode, modifiers);
}

View File

@ -4,110 +4,127 @@
package net.montoyo.wd.client.renderers;
import com.mojang.blaze3d.platform.InputConstants;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Matrix4f;
import com.mojang.math.Vector3f;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.montoyo.wd.init.ItemInit;
import net.montoyo.wd.item.ItemLaserPointer;
import org.lwjgl.glfw.GLFW;
@OnlyIn(Dist.CLIENT)
public final class LaserPointerRenderer implements IItemRenderer {
private final Tesselator t = Tesselator.getInstance();
private final BufferBuilder bb = t.getBuilder();
public boolean isOn = false;
public LaserPointerRenderer() {}
@Override
public boolean render(PoseStack poseStack, ItemStack is, float handSideSign, float swingProgress, float equipProgress, MultiBufferSource multiBufferSource, int packedLight) {
RenderSystem.disableCull();
RenderSystem.disableTexture();
RenderSystem.enableDepthTest();
RenderSystem.enableBlend();
float PI = (float) Math.PI;
float sqrtSwingProg = (float) Math.sqrt(swingProgress);
float sinSqrtSwingProg1 = (float) Math.sin(sqrtSwingProg * PI);
RenderSystem.setShader(GameRenderer::getPositionColorShader);
var matrix0 = poseStack.last().pose();
//Laser pointer
poseStack.pushPose();
poseStack.translate(handSideSign * -0.4f * sinSqrtSwingProg1, (float) (0.2f * Math.sin(sqrtSwingProg * PI * 2.0f)), (float) (-0.2f * Math.sin(swingProgress * PI)));
poseStack.translate(handSideSign * 0.56f, -0.52f - equipProgress * 0.6f, -0.72f);
poseStack.mulPose(Vector3f.YP.rotationDegrees((float) (handSideSign * (45.0f - Math.sin(swingProgress * swingProgress * PI) * 20.0f))));
poseStack.mulPose(Vector3f.ZP.rotationDegrees(handSideSign * sinSqrtSwingProg1 * -20.0f));
poseStack.mulPose(Vector3f.XP.rotationDegrees(sinSqrtSwingProg1 * -80.0f));
poseStack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * -30.0f));
poseStack.translate(0.0f, 0.2f, 0.0f);
poseStack.mulPose(Vector3f.XP.rotationDegrees(10.0f));
poseStack.scale(1.0f / 16.0f, 1.0f / 16.0f, 1.0f / 16.0f);
var matrix = poseStack.last().pose();
bb.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
bb.vertex(matrix, 0.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 1.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 1.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, -1.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix,1.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix,1.0f, -1.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix,1.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix,1.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 1.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 1.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
if (isOn) {
drawLineBetween(bb, matrix0, matrix, new Vec3(0.5f, -0.5f, 0.5f), new Vec3(-40.0f, 4000.5f, -100.0f));
}
t.end();
RenderSystem.disableBlend();
RenderSystem.disableDepthTest();
RenderSystem.enableTexture(); //Fix for shitty minecraft fire
RenderSystem.enableCull();
poseStack.popPose();
return true;
}
private static void drawLineBetween(BufferBuilder bb, Matrix4f matrix0, Matrix4f matrix, Vec3 local, Vec3 target)
{
//Calculate distance between points -> length of the line
float distance = (float) local.distanceTo(target) / 2;
float quarterWidth = 0.25f;
float biggerWidth = 10;
bb.vertex(matrix, 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix, quarterWidth + 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix0, biggerWidth - 6f, 3f, - distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix0, -6f, 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix, 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix, 0.25f, -quarterWidth - 0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix0, -6f, -biggerWidth + 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix0, -6f, 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix,quarterWidth + 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix,quarterWidth + 0.25f, -quarterWidth - 0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix0,biggerWidth - 6f, -biggerWidth + 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix0,biggerWidth - 6f, 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
}
private final Tesselator t = Tesselator.getInstance();
private final BufferBuilder bb = t.getBuilder();
public LaserPointerRenderer() {
}
public static boolean isOn() {
if (Minecraft.getInstance().screen != null) return false;
Minecraft mc = Minecraft.getInstance();
return mc.player != null && mc.level != null &&
(
InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), GLFW.GLFW_KEY_LEFT_ALT) ||
ItemLaserPointer.isOn()
) &&
mc.player.getItemInHand(InteractionHand.MAIN_HAND).getItem().equals(ItemInit.itemLaserPointer.get()) &&
(mc.hitResult == null || mc.hitResult.getType() == HitResult.Type.BLOCK || mc.hitResult.getType() == HitResult.Type.MISS);
}
@Override
public boolean render(PoseStack poseStack, ItemStack is, float handSideSign, float swingProgress, float equipProgress, MultiBufferSource multiBufferSource, int packedLight) {
RenderSystem.disableCull();
RenderSystem.disableTexture();
RenderSystem.enableDepthTest();
RenderSystem.enableBlend();
float PI = (float) Math.PI;
float sqrtSwingProg = (float) Math.sqrt(swingProgress);
float sinSqrtSwingProg1 = (float) Math.sin(sqrtSwingProg * PI);
RenderSystem.setShader(GameRenderer::getPositionColorShader);
var matrix0 = poseStack.last().pose();
//Laser pointer
poseStack.pushPose();
poseStack.translate(handSideSign * -0.4f * sinSqrtSwingProg1, (float) (0.2f * Math.sin(sqrtSwingProg * PI * 2.0f)), (float) (-0.2f * Math.sin(swingProgress * PI)));
poseStack.translate(handSideSign * 0.56f, -0.52f - equipProgress * 0.6f, -0.72f);
poseStack.mulPose(Vector3f.YP.rotationDegrees((float) (handSideSign * (45.0f - Math.sin(swingProgress * swingProgress * PI) * 20.0f))));
poseStack.mulPose(Vector3f.ZP.rotationDegrees(handSideSign * sinSqrtSwingProg1 * -20.0f));
poseStack.mulPose(Vector3f.XP.rotationDegrees(sinSqrtSwingProg1 * -80.0f));
poseStack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * -30.0f));
poseStack.translate(0.0f, 0.2f, 0.0f);
poseStack.mulPose(Vector3f.XP.rotationDegrees(10.0f));
poseStack.scale(1.0f / 16.0f, 1.0f / 16.0f, 1.0f / 16.0f);
var matrix = poseStack.last().pose();
bb.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
bb.vertex(matrix, 0.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 1.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 1.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, -1.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 1.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 1.0f, -1.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 1.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 1.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 1.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 1.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
bb.vertex(matrix, 0.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
if (isOn()) drawLineBetween(bb, matrix0, matrix, new Vec3(0.5f, -0.5f, 0.5f), new Vec3(-40.0f, 4000.5f, -100.0f));
t.end();
RenderSystem.disableBlend();
RenderSystem.disableDepthTest();
RenderSystem.enableTexture(); //Fix for shitty minecraft fire
RenderSystem.enableCull();
poseStack.popPose();
return true;
}
private static void drawLineBetween(BufferBuilder bb, Matrix4f matrix0, Matrix4f matrix, Vec3 local, Vec3 target) {
//Calculate distance between points -> length of the line
float distance = (float) local.distanceTo(target) / 2;
float quarterWidth = 0.25f;
float biggerWidth = 10;
bb.vertex(matrix, 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix, quarterWidth + 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix0, biggerWidth - 6f, 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix0, -6f, 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix, 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix, 0.25f, -quarterWidth - 0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix0, -6f, -biggerWidth + 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix0, -6f, 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix, quarterWidth + 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix, quarterWidth + 0.25f, -quarterWidth - 0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix0, biggerWidth - 6f, -biggerWidth + 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
bb.vertex(matrix0, biggerWidth - 6f, 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
}
}

View File

@ -13,7 +13,6 @@ import net.montoyo.wd.config.annoconfg.annotation.value.IntRange;
public class ClientConfig {
@SuppressWarnings("unused")
private static final AnnoCFG CFG = new AnnoCFG(FMLJavaModLoadingContext.get().getModEventBus(), ClientConfig.class);
public static void init() {
// loads the class
}
@ -55,6 +54,13 @@ public class ClientConfig {
@Default(valueBoolean = true)
public static boolean sidePad = true;
@Name("switch_buttons")
@Comment("If the left and right buttons should be swapped when using a laser")
@Translation("config.webdisplays.switch_buttons")
@DoubleRange(minV = 0, maxV = Double.MAX_VALUE)
@Default(valueD = 30)
public static boolean switchButtons = true;
@Comment({
"AutoVolume makes audio fade off based on distance",
"Currently, this seems to not work"

View File

@ -24,11 +24,17 @@ public class LaserControl extends ScreenControl {
ControlType type;
Vector2i coord;
int button;
public LaserControl(ControlType type, Vector2i coord) {
this(type, coord, -1);
}
public LaserControl(ControlType type, Vector2i coord, int button) {
super(id);
this.type = type;
this.coord = coord;
this.button = button;
}
public LaserControl(FriendlyByteBuf buf) {
@ -36,12 +42,15 @@ public class LaserControl extends ScreenControl {
type = ControlType.values()[buf.readByte()];
if (!type.equals(ControlType.UP))
coord = new Vector2i(buf);
if (!type.equals(ControlType.MOVE))
button = buf.readInt();
}
@Override
public void write(FriendlyByteBuf buf) {
buf.writeByte(type.ordinal());
if (coord != null) coord.writeTo(buf);
if (type != ControlType.MOVE) buf.writeInt(button);
}
@Override
@ -50,9 +59,9 @@ public class LaserControl extends ScreenControl {
// checkPerms(ScreenRights.INTERACT, permissionChecker, ctx.getSender());
ServerPlayer sender = ctx.getSender();
switch (type) {
case UP -> tes.laserUp(side, sender);
case DOWN -> tes.laserDownMove(side, sender, coord, true);
case MOVE -> tes.laserDownMove(side, sender, coord, false);
case UP -> tes.laserUp(side, sender, button);
case DOWN -> tes.laserDownMove(side, sender, coord, true, button);
case MOVE -> tes.laserDownMove(side, sender, coord, false, button);
}
}

View File

@ -4,8 +4,6 @@
package net.montoyo.wd.entity;
import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -44,7 +42,6 @@ import net.montoyo.wd.net.client_bound.S2CMessageCloseGui;
import net.montoyo.wd.net.client_bound.S2CMessageJSResponse;
import net.montoyo.wd.net.client_bound.S2CMessageScreenUpdate;
import net.montoyo.wd.utilities.*;
import org.lwjgl.glfw.GLFW;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -517,17 +514,17 @@ public class TileEntityScreen extends BlockEntity {
if (level.isClientSide)
Log.warning("TileEntityScreen.click() from client side is useless...");
else if (getLaserUser(scr) == null)
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(level, getBlockPos())), S2CMessageScreenUpdate.click(this, side, S2CMessageScreenUpdate.MOUSE_CLICK, vec));
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(level, getBlockPos())), S2CMessageScreenUpdate.click(this, side, S2CMessageScreenUpdate.MOUSE_CLICK, vec, 1));
}
void clickUnsafe(BlockSide side, int action, int x, int y) {
if (level.isClientSide) {
Vector2i vec = (action == S2CMessageScreenUpdate.MOUSE_UP) ? null : new Vector2i(x, y);
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(level, getBlockPos())), S2CMessageScreenUpdate.click(this, side, action, vec));
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(level, getBlockPos())), S2CMessageScreenUpdate.click(this, side, action, vec, 1));
}
}
public void handleMouseEvent(BlockSide side, int event, @Nullable Vector2i vec) {
public void handleMouseEvent(BlockSide side, int event, @Nullable Vector2i vec, int button) {
Screen scr = getScreen(side);
if (scr == null) {
Log.error("Attempt inject mouse events on non-existing screen of side %s", side.toString());
@ -536,23 +533,16 @@ public class TileEntityScreen extends BlockEntity {
if (scr.browser != null) {
if (event == S2CMessageScreenUpdate.MOUSE_CLICK) {
if(InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), GLFW.GLFW_KEY_LEFT_ALT)
|| InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), GLFW.GLFW_KEY_RIGHT_ALT)) {
scr.browser.injectMouseMove(vec.x, vec.y, 0, false); //Move to target
scr.browser.injectMouseButton(vec.x, vec.y, 0, 3, true, 1); //Press
scr.browser.injectMouseButton(vec.x, vec.y, 0, 3, false, 1); //Release
} else {
scr.browser.injectMouseMove(vec.x, vec.y, 0, false); //Move to target
scr.browser.injectMouseButton(vec.x, vec.y, 0, 1, true, 1); //Press
scr.browser.injectMouseButton(vec.x, vec.y, 0, 1, false, 1); //Release
}
scr.browser.injectMouseMove(vec.x, vec.y, 0, false); //Move to target
scr.browser.injectMouseButton(vec.x, vec.y, 0, button, true, 1); //Press
scr.browser.injectMouseButton(vec.x, vec.y, 0, button, false, 1); //Release
} else if (event == S2CMessageScreenUpdate.MOUSE_DOWN) {
scr.browser.injectMouseMove(vec.x, vec.y, 0, false); //Move to target
scr.browser.injectMouseButton(vec.x, vec.y, 0, 1, true, 1); //Press
scr.browser.injectMouseButton(vec.x, vec.y, 0, button, true, 1); //Press
} else if (event == S2CMessageScreenUpdate.MOUSE_MOVE)
scr.browser.injectMouseMove(vec.x, vec.y, 0, false); //Move
else if (event == S2CMessageScreenUpdate.MOUSE_UP)
scr.browser.injectMouseButton(scr.lastMousePos.x, scr.lastMousePos.y, 0, 1, false, 1); //Release
scr.browser.injectMouseButton(scr.lastMousePos.x, scr.lastMousePos.y, 0, button, false, 1); //Release
if (vec != null) {
scr.lastMousePos.x = vec.x;
scr.lastMousePos.y = vec.y;
@ -1073,29 +1063,26 @@ public class TileEntityScreen extends BlockEntity {
return scr; //Okay, go for it...
}
public void laserDownMove(BlockSide side, Player ply, Vector2i pos, boolean down) {
public void laserDownMove(BlockSide side, Player ply, Vector2i pos, boolean down, int button) {
Screen scr = getScreenForLaserOp(side, ply);
if (scr != null) {
if (down) {
//Try to acquire laser lock
// if (getLaserUser(scr) == null) {
scr.laserUser = ply;
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(ply, level, getBlockPos())), S2CMessageScreenUpdate.click(this, side, S2CMessageScreenUpdate.MOUSE_CLICK, pos));
// }
} else
// if (getLaserUser(scr) == ply)
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(ply, level, getBlockPos())), S2CMessageScreenUpdate.click(this, side, S2CMessageScreenUpdate.MOUSE_MOVE, pos));
if (button == -1)
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(ply, level, getBlockPos())), S2CMessageScreenUpdate.click(this, side, S2CMessageScreenUpdate.MOUSE_MOVE, pos, button));
else if (down)
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(ply, level, getBlockPos())), S2CMessageScreenUpdate.click(this, side, S2CMessageScreenUpdate.MOUSE_DOWN, pos, button));
else
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(ply, level, getBlockPos())), S2CMessageScreenUpdate.click(this, side, S2CMessageScreenUpdate.MOUSE_UP, pos, button));
}
}
public void laserUp(BlockSide side, Player ply) {
public void laserUp(BlockSide side, Player ply, int button) {
Screen scr = getScreenForLaserOp(side, ply);
if (scr != null) {
if (getLaserUser(scr) == ply) {
scr.laserUser = null;
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(ply, level, getBlockPos())), S2CMessageScreenUpdate.click(this, side, S2CMessageScreenUpdate.MOUSE_UP, null));
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(ply, level, getBlockPos())), S2CMessageScreenUpdate.click(this, side, S2CMessageScreenUpdate.MOUSE_UP, null, button));
}
}
}

View File

@ -4,44 +4,154 @@
package net.montoyo.wd.item;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraft.world.phys.HitResult;
import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.block.BlockScreen;
import net.montoyo.wd.core.IPeripheral;
import net.montoyo.wd.client.ClientProxy;
import net.montoyo.wd.client.JSQueryDispatcher;
import net.montoyo.wd.config.ClientConfig;
import net.montoyo.wd.core.DefaultUpgrade;
import net.montoyo.wd.entity.TileEntityScreen;
import net.montoyo.wd.init.BlockInit;
import net.montoyo.wd.init.ItemInit;
import net.montoyo.wd.utilities.Util;
import net.montoyo.wd.net.WDNetworkRegistry;
import net.montoyo.wd.net.client_bound.S2CMessageScreenUpdate;
import net.montoyo.wd.net.server_bound.C2SMessageScreenCtrl;
import net.montoyo.wd.utilities.BlockSide;
import net.montoyo.wd.utilities.Multiblock;
import net.montoyo.wd.utilities.Vector2i;
import net.montoyo.wd.utilities.Vector3i;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Objects;
public class ItemLaserPointer extends Item implements WDItem {
public ItemLaserPointer(Properties properties) {
super(properties
//setRegistryName("laserpointer")
.stacksTo(1)
.tab(WebDisplays.CREATIVE_TAB));
}
@Nullable
@Override
public String getWikiName(@Nonnull ItemStack is) {
return is.getItem().getName(is).getString();
}
public ItemLaserPointer(Properties properties) {
super(properties
//setRegistryName("laserpointer")
.stacksTo(1)
.tab(WebDisplays.CREATIVE_TAB));
}
//Laser pointer
private static TileEntityScreen pointedScreen;
private static BlockSide pointedScreenSide;
private static long lastPointPacket;
private static boolean mouseDown = false;
private static boolean left;
private static boolean middle;
private static boolean right;
public static void tick(Minecraft mc) {
BlockHitResult result = ClientProxy.raycast(64.0); //TODO: Make that distance configurable
BlockPos bpos = result.getBlockPos();
if (result.getType() == HitResult.Type.BLOCK && mc.level.getBlockState(bpos).getBlock() == BlockInit.blockScreen.get()) {
Vector3i pos = new Vector3i(result.getBlockPos());
BlockSide side = BlockSide.values()[result.getDirection().ordinal()];
Multiblock.findOrigin(mc.level, pos, side, null);
TileEntityScreen te = (TileEntityScreen) mc.level.getBlockEntity(pos.toBlock());
if (te != null && te.hasUpgrade(side, DefaultUpgrade.LASERMOUSE)) { //hasUpgrade returns false is there's no screen on side 'side'
//Since rights aren't synchronized, let the server check them for us...
TileEntityScreen.Screen scr = te.getScreen(side);
if (scr.browser != null) {
float hitX = ((float) result.getLocation().x) - (float) pos.x;
float hitY = ((float) result.getLocation().y) - (float) pos.y;
float hitZ = ((float) result.getLocation().z) - (float) pos.z;
Vector2i tmp = new Vector2i();
if (BlockScreen.hit2pixels(side, bpos, new Vector3i(result.getBlockPos()), scr, hitX, hitY, hitZ, tmp)) {
laserClick(te, side, scr, tmp);
}
}
}
}
}
public static void deselect(Minecraft mc, JSQueryDispatcher jsDispatcher) {
deselectScreen();
}
private static void laserClick(TileEntityScreen tes, BlockSide side, TileEntityScreen.Screen scr, Vector2i hit) {
tes.handleMouseEvent(side, S2CMessageScreenUpdate.MOUSE_MOVE, hit, -1);
if (pointedScreen == tes && pointedScreenSide == side) {
long t = System.currentTimeMillis();
if (t - lastPointPacket >= 100) {
lastPointPacket = t;
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserMove(tes, side, hit));
}
} else {
deselectScreen();
pointedScreen = tes;
pointedScreenSide = side;
}
}
private static void deselectScreen() {
if (pointedScreen != null && pointedScreenSide != null) {
pointedScreen = null;
pointedScreenSide = null;
}
}
public static void press(boolean press, int button) {
if (button <= 1 && ClientConfig.switchButtons)
button = 1 - button;
if (button == 0) left = press;
else if (button == 1) right = press;
else if (button == 2) middle = press;
Minecraft mc = Minecraft.getInstance();
BlockHitResult result = ClientProxy.raycast(64.0); //TODO: Make that distance configurable
Vector3i pos = new Vector3i(result.getBlockPos());
BlockSide side = BlockSide.values()[result.getDirection().ordinal()];
Multiblock.findOrigin(mc.level, pos, side, null);
float hitX = ((float) result.getLocation().x) - (float) pos.x;
float hitY = ((float) result.getLocation().y) - (float) pos.y;
float hitZ = ((float) result.getLocation().z) - (float) pos.z;
Vector2i tmp = new Vector2i();
TileEntityScreen te = (TileEntityScreen) mc.level.getBlockEntity(pos.toBlock());
if (te != null && te.hasUpgrade(side, DefaultUpgrade.LASERMOUSE)) { //hasUpgrade returns false is there's no screen on side 'side'
//Since rights aren't synchronized, let the server check them for us...
TileEntityScreen.Screen scr = te.getScreen(side);
if (scr.browser != null) {
if (BlockScreen.hit2pixels(side, result.getBlockPos(), new Vector3i(result.getBlockPos()), scr, hitX, hitY, hitZ, tmp)) {
te.handleMouseEvent(side, S2CMessageScreenUpdate.MOUSE_MOVE, tmp, -1);
te.handleMouseEvent(side, press ? S2CMessageScreenUpdate.MOUSE_DOWN : S2CMessageScreenUpdate.MOUSE_UP, tmp, button);
if (press)
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserDown(te, side, tmp, button));
else
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserUp(te, side, button));
}
}
}
}
public static boolean isOn() {
return left || right || middle;
}
@Nullable
@Override
public String getWikiName(@Nonnull ItemStack is) {
return is.getItem().getName(is).getString();
}
}

View File

@ -0,0 +1,35 @@
package net.montoyo.wd.mixins;
import net.minecraft.client.Minecraft;
import net.minecraft.client.MouseHandler;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.phys.HitResult;
import net.montoyo.wd.init.ItemInit;
import net.montoyo.wd.item.ItemLaserPointer;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MouseHandler.class)
public class MouseHandlerMixin {
@Shadow @Final private Minecraft minecraft;
@Inject(at = @At("HEAD"), method = "onPress", cancellable = true)
public void prePress(long p_91531_, int p_91532_, int p_91533_, int p_91534_, CallbackInfo ci) {
boolean flag = p_91533_ == 1;
if (Minecraft.getInstance().screen == null) {
if (
minecraft.player != null && minecraft.level != null &&
minecraft.player.getItemInHand(InteractionHand.MAIN_HAND).getItem().equals(ItemInit.itemLaserPointer.get()) &&
(minecraft.hitResult == null || minecraft.hitResult.getType() == HitResult.Type.BLOCK || minecraft.hitResult.getType() == HitResult.Type.MISS)
) {
ItemLaserPointer.press(flag, p_91532_);
ci.cancel();
}
}
}
}

View File

@ -45,6 +45,7 @@ public class S2CMessageScreenUpdate extends Packet {
private String string;
private Vector2i vec2i;
private int mouseEvent;
private int button;
private ItemStack[] upgrades;
private int redstoneLevel;
private NameUUIDPair owner;
@ -74,13 +75,15 @@ public class S2CMessageScreenUpdate extends Packet {
return ret;
}
public static S2CMessageScreenUpdate click(TileEntityScreen tes, BlockSide side, int mouseEvent, @Nullable Vector2i pos) {
public static S2CMessageScreenUpdate click(TileEntityScreen tes, BlockSide side, int mouseEvent, @Nullable Vector2i pos, int button) {
S2CMessageScreenUpdate ret = new S2CMessageScreenUpdate();
ret.pos = new Vector3i(tes.getBlockPos());
ret.side = side;
ret.action = UPDATE_MOUSE;
ret.mouseEvent = mouseEvent;
ret.vec2i = pos;
ret.button = button;
return ret;
}
@ -185,6 +188,8 @@ public class S2CMessageScreenUpdate extends Packet {
message.mouseEvent = buf.readByte();
if (message.mouseEvent != MOUSE_UP)
message.vec2i = new Vector2i(buf);
if (message.mouseEvent != MOUSE_MOVE)
message.button = buf.readInt();
}
case UPDATE_RESOLUTION -> message.vec2i = new Vector2i(buf);
case UPDATE_UPGRADES -> {
@ -215,6 +220,8 @@ public class S2CMessageScreenUpdate extends Packet {
if(mouseEvent != MOUSE_UP)
vec2i.writeTo(buf);
if (mouseEvent != MOUSE_MOVE)
buf.writeInt(button);
} else if(action == UPDATE_RESOLUTION)
vec2i.writeTo(buf);
else if(action == UPDATE_UPGRADES) {
@ -259,7 +266,7 @@ public class S2CMessageScreenUpdate extends Packet {
throw new RuntimeException(e);
}
}
case UPDATE_MOUSE -> tes.handleMouseEvent(side, mouseEvent, vec2i);
case UPDATE_MOUSE -> tes.handleMouseEvent(side, mouseEvent, vec2i, button);
case UPDATE_DELETE -> tes.removeScreen(side);
case UPDATE_RESOLUTION -> tes.setResolution(side, vec2i);
case UPDATE_TYPE -> tes.type(side, string, null);

View File

@ -105,16 +105,16 @@ public class C2SMessageScreenCtrl extends Packet {
return ret;
}
public static C2SMessageScreenCtrl laserDown(TileEntityScreen tes, BlockSide side, Vector2i vec) {
public static C2SMessageScreenCtrl laserDown(TileEntityScreen tes, BlockSide side, Vector2i vec, int button) {
C2SMessageScreenCtrl ret = base(tes, side);
ret.control = new LaserControl(LaserControl.ControlType.DOWN, vec);
ret.control = new LaserControl(LaserControl.ControlType.DOWN, vec, button);
return ret;
}
@Deprecated(forRemoval = true)
public static C2SMessageScreenCtrl laserUp(TileEntityScreen tes, BlockSide side) {
public static C2SMessageScreenCtrl laserUp(TileEntityScreen tes, BlockSide side, int button) {
C2SMessageScreenCtrl ret = base(tes, side);
ret.control = new LaserControl(LaserControl.ControlType.UP, null);
ret.control = new LaserControl(LaserControl.ControlType.UP, null, button);
return ret;
}

View File

@ -7,6 +7,7 @@
"mixins": [
],
"client": [
"MouseHandlerMixin",
"OverlayMixin"
],
"injectors": {