Ravenwolf397
Members-
Posts
13 -
Joined
-
Last visited
Everything posted by Ravenwolf397
-
[1.16][solved] Detecting Block Break/Place
Ravenwolf397 replied to Ravenwolf397's topic in Modder Support
Do you know what time it is? IT'S CORE MODDING TIME! *screeches hysterically* </hysteria> (I spend like 14 hours on this what am I doing with my life) So yeah, that's what you have to do to detect block changes client-side. I won't go into details since the devs appear to be somewhat hostile towards anything to do with coremods, short of outright banning them. In my case, I hooked my own custom event into the network manager and checked for SChangeBlockPacket s and SMultiBlockChangePacket s. But yeah, as far as vanilla Forge goes, this is impossible. Note that there *are* events for when the player breaks/places blocks though, so if that's all you need then you can use those. It's just if you need to know when other things move blocks (pistons, falling blocks, etc.) that you need to break into the core. OR, you could bite the bullet and send your own packets from the server. That would probably have been much much easier. And more efficient. But. I like this. -
[1.16][solved] Detecting Block Break/Place
Ravenwolf397 replied to Ravenwolf397's topic in Modder Support
Alas, no. It does in single player, weirdly (even sets world.isRemote to true, which might be a bug), but I started a LAN server with my normal account and joined using my mod (with all the server stuff commented out), and it didn't fire. Also, if you check the comments above NeighborNotifyEvent, it says "This event is only called on the server", which is pretty unambiguous about the intended behavior =S -
I am working on an echolocation helmet that shows the player nearby ores. For performance, I just scan each chunk for the specific ores I need when it is loaded. I can subscribe to BlockEvent.EntityPlaceEvent and BlockEvent.BreakEvent to detect when the player places/breaks ores... but this doesn't detect when eg. a piston pushes an ore block. While it's unlikely anyone will really care about this sort of situation, it's still incorrect behavior and I'd like to detect this. I've thought about subscribing to BlockEvent.NeighborNotifyEvent on the server and then sending a packet to inform the player, but that seems like an unclean solution given that the server is already informing us about where the blocks are; asking it to tell the client again is a bit silly. Nothing popped out at me during a skim through all the `Event` subclasses. I've found recommendations that I use "IWorldEventListener", but I think that was removed in 1.14-ish? So my question is: is there a way to detect all block-place/break events (even when eg. pistons, other players are the ones doing them) without having to send my own packets? Or if there isn't a proper interface, can I tap into the vanilla packets and just read which blocks are being set from those? (I might be going through a bit much effort to avoid sending packets, but it feels like packets really shouldn't be necessary)
-
Okay, I got it working 100%. Compensates for screen resolution, view bobbing, fov changes, and even dynamic fov like from sprinting and speed potions. public static FinalTriple<Float, Float, Boolean> projectToPlayerView(double target_x, double target_y, double target_z, float partialTicks) { /* The (centered) location on the screen of the given 3d point in the world. * Result is <dist right of center screen, dist up from center screen, is target in front of viewing plane> */ ActiveRenderInfo ari = getActiveRenderInfo(); Vector3d camera_pos = ari.getProjectedView(); Quaternion camera_rotation_conj = ari.getRotation().copy(); camera_rotation_conj.conjugate(); Vector3f result3f = new Vector3f((float) (camera_pos.x - target_x), (float) (camera_pos.y - target_y), (float) (camera_pos.z - target_z)); result3f.transform(camera_rotation_conj); // ----- compensate for view bobbing (if active) ----- // the following code adapted from GameRenderer::applyBobbing (to invert it) Minecraft mc = getMinecraft(); if (mc.gameSettings.viewBobbing) { Entity renderViewEntity = mc.getRenderViewEntity(); if (renderViewEntity instanceof PlayerEntity) { PlayerEntity playerentity = (PlayerEntity) renderViewEntity; float distwalked_modified = playerentity.distanceWalkedModified; float f = distwalked_modified - playerentity.prevDistanceWalkedModified; float f1 = -(distwalked_modified + f * partialTicks); float f2 = MathHelper.lerp(partialTicks, playerentity.prevCameraYaw, playerentity.cameraYaw); Quaternion q2 = new Quaternion(Vector3f.XP, Math.abs(MathHelper.cos(f1 * (float) Math.PI - 0.2F) * f2) * 5.0F, true); q2.conjugate(); result3f.transform(q2); Quaternion q1 = new Quaternion(Vector3f.ZP, MathHelper.sin(f1 * (float) Math.PI) * f2 * 3.0F, true); q1.conjugate(); result3f.transform(q1); Vector3f bob_translation = new Vector3f((MathHelper.sin(f1 * (float) Math.PI) * f2 * 0.5F), (-Math.abs(MathHelper.cos(f1 * (float) Math.PI) * f2)), 0.0f); bob_translation.setY(-bob_translation.getY()); // this is weird but hey, if it works result3f.add(bob_translation); } } // ----- adjust for fov ----- Method m; float fov; GameRenderer gameRenderer = mc.gameRenderer; try { m = gameRenderer.getClass().getDeclaredMethod("getFOVModifier", ActiveRenderInfo.class, float.class, boolean.class); } catch (NoSuchMethodException e) { LOGGER.error(e); throw new Error("getFOVModifier method not present on GameRenderer class; cannot project to player screen.", e); } m.setAccessible(true); try { fov = ((Double) m.invoke(gameRenderer, ari, partialTicks, true)).floatValue(); } catch (IllegalAccessException | InvocationTargetException e) { LOGGER.error(e); throw new Error("getFOVModifier invocation caused error.", e); } float half_height = (float) mc.getMainWindow().getScaledHeight() / 2; float scale_factor = half_height / (result3f.getZ() * (float) Math.tan(Math.toRadians(fov / 2))); return new FinalTriple<>(-result3f.getX() * scale_factor, result3f.getY() * scale_factor, result3f.getZ() < 0); } There are couple of self-explanatory methods (getActiveRenderInfo, getMinecraft) and a class (FinalTriple) that should be obvious to implement yourself.
-
Thank you! Quaternions were the answer; I just apply the ActiveRenderInfo::getRotation() as a transformation to the relative position of the point and the camera, then scale by some factor `scale_factor` (180 works well at the default fov of 70). Through a bit of finagling, I even managed to compensate for the effects of view bobbing. However, I now face a new but related conundrum: changing the fov away from 70 makes the calculated point become scaled incorrectly. Specifically, if the fov is high then it is too far from the screen center, and if the fov is low then it is too close to the screen center. The problem seems pretty clearly to do with my scaling factor of 180 above. I tried multiplying `scale_factor` by (70 / fov), but that didn't change it enough; the result was still too close to center at low fov, and too far from center at high fov. It was closer to what it should be, but still not correct. Since the function appeared to be trigonometric, I attempted multiplying `scale_factor` by `-1 / Math.tan(fov / 2)` (essentially treating it as focal length), but that produced very odd behavior with no discernable pattern. How does Minecraft's fov affect this situation? I would have though that `scaling_factor` was just the focal length, but the multiplier above involving tangent should have worked in that case, so I'm not sure. Updated code: public static Vector2f projectToPlayerView(Vector3d target, float partialTicks) { /* The (centered) location on the screen of the given 3d point in the world. */ float scale_factor = 180; ActiveRenderInfo ari = getActiveRenderInfo(); Vector3d camera_pos = ari.getProjectedView(); Quaternion camera_rotation_conj = ari.getRotation().copy(); camera_rotation_conj.conjugate(); Vector3f result3f = new Vector3f((float) (camera_pos.x - target.x), (float) (camera_pos.y - target.y), (float) (camera_pos.z - target.z)); result3f.transform(camera_rotation_conj); // compensate for view bobbing (if active) // this isn't relevant to the question, I just put it here in case anyone wants it // the following code adapted from GameRenderer::applyBobbing (to invert it) Minecraft mc = getMinecraft(); if (mc.gameSettings.viewBobbing) { Entity renderViewEntity = mc.getRenderViewEntity(); if (renderViewEntity instanceof PlayerEntity) { PlayerEntity playerentity = (PlayerEntity) renderViewEntity; float distwalked_modified = playerentity.distanceWalkedModified; float f = distwalked_modified - playerentity.prevDistanceWalkedModified; float f1 = -(distwalked_modified + f * partialTicks); float f2 = MathHelper.lerp(partialTicks, playerentity.prevCameraYaw, playerentity.cameraYaw); Quaternion q2 = new Quaternion(Vector3f.XP, Math.abs(MathHelper.cos(f1 * (float) Math.PI - 0.2F) * f2) * 5.0F, true); q2.conjugate(); result3f.transform(q2); Quaternion q1 = new Quaternion(Vector3f.ZP, MathHelper.sin(f1 * (float) Math.PI) * f2 * 3.0F, true); q1.conjugate(); result3f.transform(q1); Vector3f bob_translation = new Vector3f((MathHelper.sin(f1 * (float) Math.PI) * f2 * 0.5F), (-Math.abs(MathHelper.cos(f1 * (float) Math.PI) * f2)), 0.0f); bob_translation.setY(-bob_translation.getY()); // this is weird but hey, if it works result3f.add(bob_translation); } } // handle alteration due to fov double fov = mc.gameSettings.fov; // neither of these are correct: // scale_factor *= (70 / fov); // scale_factor *= -1 / Math.tan(fov / 2); // todo include fov modifier from sprinting, speed, etc. Vector2f result = new Vector2f(-result3f.getX(), result3f.getY()); result = new Vector2f(scale_factor * result.x / result3f.getZ(), scale_factor * result.y / result3f.getZ()); return result; }
-
I need to take a 3d point in the world (eg. "The cow is at (12, 63, -19)") and project it to 2d screen coordinates (eg. "The cow is 243 pixels from the left of the screen, and 87 pixels from the top of the screen"). I found this: https://forums.minecraftforge.net/topic/75508-how-do-i-convert-a-3d-point-to-screen-coordinates/ but it is non-functional. I tried figuring out the rotations on my own, but that also didn't work. Both produce incorrect projections, that don't seem to correlate with the correct point in any noticable way. My math (`MiscUtil.projectToPlayerView`): public static Vector2f projectToPlayerView(Vector3d target) { double fov = 70; ActiveRenderInfo ari = Minecraft.getMinecraft().gameRenderer.getActiveRenderInfo(); Vector3d camera_pos = ari.getProjectedView(); double x = camera_pos.x, y = camera_pos.y, z = camera_pos.z; double yaw = Math.toRadians(ari.getYaw()), pitch = Math.toRadians(ari.getPitch()); x = target.x - x; y = target.y - y; z = target.z - z; // my rotations (doesn't work) // rotate so camera is on yz-plane // x = (x * Math.cos(yaw) - z * Math.sin(yaw)); // z = (x * Math.sin(yaw) + z * Math.cos(yaw)); // rotate so camera is on z axis // y = (y * Math.cos(pitch) - z * Math.sin(pitch)); // z = (y * Math.sin(pitch) + z * Math.cos(pitch)); // rotations given in linked post z = z * Math.cos(yaw) * Math.cos(pitch); x = x * Math.sin(yaw); y = y * Math.sin(pitch); // apply fov x = x / z * fov; y = y / z * fov; return new Vector2f((float) x, (float) y); }
-
can someone tell me what this means in english
Ravenwolf397 replied to coderboy_yt's topic in Modder Support
ctrl+f "error" -> "cannot find symbol net.minecraft.util.math.Vec3d". No such class exists. You probably mean `Vector3d`. If you use an IDE it will not only tell you this succinctly, but also tell you the exact location of the error before you even need to compile. -
[1.15.2][solved] Render through blocks
Ravenwolf397 replied to Ravenwolf397's topic in Modder Support
It appears that this requires both `RenderSystem.disableDepthTest()` and `RenderSystem.depthMask(false)`.- 1 reply
-
- 1
-
I am making an "echolocation" helmet that shows wireframes around specific nearby blocks when you wear it (mostly ores). I have the helmet detection code, but when I render wireframes they are obscured by the intervening blocks (I want them visible through those blocks). I tried using both `RenderSystem` and `GlStateManager`'s methods `disableDepthTest` and `disableCull`, in all combinations, but none of them produce this effect. How can I make my changes visible on top of everything else? Code: @SubscribeEvent public void onRenderWorldLast(RenderWorldLastEvent event) { // only run if wearing helmet // if (!echolocation_active) return; ActiveRenderInfo renderInfo = Minecraft.getInstance().gameRenderer.getActiveRenderInfo(); Vector3d pv = renderInfo.getProjectedView(); double x = pv.getX(), y = pv.getY(), z = pv.getZ(); IRenderTypeBuffer.Impl buffer = Minecraft.getInstance().getRenderTypeBuffers().getBufferSource(); IVertexBuilder builder = buffer.getBuffer(RenderType.LINES); MatrixStack matrixStack = event.getMatrixStack(); matrixStack.push(); matrixStack.translate(-x, -y, -z); // disable depth here, somehow // for debugging: put wireframe around 0,0,0 WorldRenderer.drawBoundingBox(matrixStack, builder, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1); buffer.finish(RenderType.LINES); matrixStack.pop(); }
-
I am attempting to port Lunatrius' `GeometryTessellator` code to 1.16 (https://github.com/Lunatrius/LunatriusCore/blob/master/src/main/java/com/github/lunatrius/core/client/renderer/GeometryTessellator.java). The code for 1.16's `Tessellator` and `BufferBuilder` classes are fully deobfuscated, but there's been some implementation changes that I do not understand. What happened to translation? I cannot find any reference to it, and this was pretty important (or annoying) in previous versions. What's happening with the multiple buffers and multiple draw modes? Previously you would just call `getDrawMode()` to get the current draw mode, but now there are multiple buffers in a list, each with a `DrawState`. How does this work?
-
Aha! LookController is what I was looking (pun intended) for. Thank you!
-
I want to cause a player to be "captivated" by a particular block. The idea is that every so-many ticks they will reorient to face the block, without changing their position. (I realize this may cause the camera to jerk around; I've got that bit covered) However, all the raytracing functions I have found so far go the other direction - they tell me where they player *is* looking, and what their angles currently are, but not what the angles *should* be to make the player look at a particular thing. Are there any functions available that, given the player's position and a point P, tell you what the yaw/pitch should be to make the player look at P?
-
I need to respond when the player's armor or equipped weapons break, on the client side. I am aware of PlayerDestroyItemEvent, but that only triggers when a tool or weapon breaks while used on its intended material - it does not fire for armor, or eg. a pickaxe that breaks while mining sand. There's LivingEquipmentChangeEvent, but that also triggers when the player changes their armor on purpose, and doesn't cover tools or weapons. I tried LivingAttackEvent, LivingHurtEvent, and LivingDamageEvent for the armor, but they also do not always fire when the player's armor breaks (for example, if the armor breaks due to a cactus but blocks all of the damage). Lastly, monitoring the player's inventory every tick will also not work, because as with LivingEquipmentChangeEvent I can't distinguish between the armor/tools breaking and the player just unequipping/dropping it intentionally. I did find ItemDurabilityTrigger, which appears to do exactly what I want (though I'm not sure about server/client side) ... but it's not an event, and therefore seems to require that I do some reflection/ASM stuff, which I am wary of. Is there a way do this?