ImmersiveMC

ImmersiveMC

683k Downloads

Item Throwing

hammy275 opened this issue ยท 11 comments

commented
commented

For where I'm currently stuck, here are some ideas:

  • Test for the existence of one of the Data Holder classes to see if we're using Mixin Vivecraft or Optifine Vivecraft.
  • In Mixin Vivecraft land, we'll have two options to work with:
    • Before ModifyVariable PR: We can detect the old Mixin using a Mixin config plugin. If we find it, we WON'T inject it, and instead inject our own copy with our modifications on top.
    • After ModifyVariable PR: We can modify the variables later in the shootFromRotation, or do something similar to the Before PR and replace the ModifyVariables with our own. Ideally if it exists, we can put our ModifyVariable after Vivecraft's
  • For Optifine Vivecraft, we'll need to figure out where to Mixin ModifyVariable calls, and modify from there
commented

Entire pivot:

Instead of trying to override shootFromRotation as a whole (since MIxin config plugins can't affect other mods, it seems), instead, we can take advantage of @Redirect. For each individual item, whenever it calls shootFromRotation from its use method (or the other for Tridents), we call our own entire shoot method instead. If we personally don't run, pass control over to the normal shootFromRotation instead.

commented

Part 1 of this is at 9df5660 .

Things left to do:

  • Fine tune throwing velocities, especially for trident.
  • Use very hack-y mixins to render the Trident properly (see https://github.com/ferriarnus/VivecraftMod/blob/Multiloader-1.18/common/src/main/java/org/vivecraft/mixin/client/renderer/ItemInHandRendererVRMixin.java and https://github.com/ferriarnus/VivecraftMod/blob/d09c2512b91bc0eb747d25a22dbc402c41e0f7e3/common/src/main/java/org/vivecraft/render/VivecraftItemRendering.java#L151 ). We'll probably need to mixin just before Vivecraft kicks in item in hand rendering, set some boolean, then for item using check that boolean, and if it's true, return some value to pretend we're using the item. After that rendering pass, set the boolean back to false to get normal values.
  • Add fishing rod. Vivecraft already does some correction on it, so we'll probably just want to add the velocity and let Vivecraft itself handle the rod movement. Looks like at the very end we can just multiply the deltaMovement of it by our velocity factor.
  • Fix left click blocking. It seems the current implementation of it doesn't actually work. That said, we shouldn't block it for the first tick, since we need to be able to hit things with the Trident.
  • Config entry. Should be something both the server and client are on-board with. No need to send the client's preference to the server though, the client can simply not pass a packet along if they don't want to throw
  • Safeguarding and warning for those in Optifine Vivecraft (or a solution for those using it)
  • Dedicated server testing
  • Testing outside of VR, without Vivecraft, and without the API
  • Port to other branches
commented

Trident rendering done (even comes with rumble!)

commented

Velocity tuning is done! Next is a config entry, then we can port to other versions!

commented

Will only support primary hand throwing.

Looks like the way to do this is a mixin into Projectile#shootFromRotation.

We'll want to average the velocity of the hand every tick for the past 3 ticks and use that as our throwing velocity. Might move this to server-side at some future point, but for now, I'll run this client side. On release, we send a packet to the server containing the velocity we should throw at.

From there, the server will call use or releaseUsing (depending on the item) after adding the player to a global HashMap. Call it vrNextThrowData or something, with keys being player names or UUIDs, and values being the velocity from the packet.

In our Mixin, we check if the player is part of the aforementioned HashMap. If so, we use their hand's rotation. Additionally, at the end of shootFromRotation, we check again if they're in the HashMap. If so, we remove them from the map, and use the provided velocity to augment the delta movement of the projectile. This augmentation I'll have to experiment with until I find something that "feels right".

commented

Based on https://minecraft-archive.fandom.com/wiki/Category:Projectiles , we'll support the following items:

  • Bottle o' Enchanting
  • Egg
  • Ender Pearl
  • Potions (Splash/Lingering)
  • Snowballs
  • Tridents

Notable exceptions:

  • Eyes of Ender don't use shootFromRotation, and would just generally feel "weird" to throw due to how they travel in-game.
commented

Also, since people may throw things in a variety of different ways, to determine the direction, we'll do the difference between the current controller pos and the last, then normalize it. To get it to a x and y rotation, we should be able to reverse the calculation done in Entity#calculateViewVector. Note that the constant being multiplied there is pi/180.

EDIT: Also, for throwable items, we always cancel their left click action with the exception of the Trident, which we only cancel if we're not hovering over an Entity at melee range.

commented

It already works identically in Optifine Vivecraft let's gooooo

commented

I don't even need to worry about not blocking it for the first tick; we run at the end of the game tick! :)

commented

This is finally done! Here's all the commits from oldest to newest: