Skip to content

Commit

Permalink
Reach Behind Bag More Settings + Shoulder Support (closes #300)
Browse files Browse the repository at this point in the history
  • Loading branch information
hammy275 committed Sep 24, 2023
1 parent 3239542 commit 08d3a2a
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.hammy275.immersivemc.common.config.ActiveConfig;
import com.hammy275.immersivemc.common.config.BackpackMode;
import com.hammy275.immersivemc.common.config.ImmersiveMCConfig;
import com.hammy275.immersivemc.common.config.PlacementMode;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import net.minecraft.client.Minecraft;
Expand All @@ -25,8 +24,6 @@
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/*
Thanks to https://leo3418.github.io/2021/03/31/forge-mod-config-screen-1-16.html for a guide that was very
Expand Down Expand Up @@ -71,7 +68,6 @@ protected void initOptionsList() {
() -> Arrays.asList(BackpackMode.values()),
Optional::of,
null

),
ActiveConfig.backpackMode,
(newMode) -> {
Expand All @@ -85,7 +81,25 @@ protected void initOptionsList() {
}
)
);
this.list.addBig(ScreenUtils.createOption("reach_behind_backpack", ImmersiveMCConfig.reachBehindBackpack));
this.list.addBig(
new OptionInstance<>(
"config.immersivemc.reach_behind_backpack_mode",
mc -> reachBehindBackpackMode -> Minecraft.getInstance().font.split(
Component.translatable("config.immersivemc.reach_behind_backpack_mode." + reachBehindBackpackMode.ordinal() + ".desc"), 200),
(component, reachBehindBackpackMode) -> Component.translatable("config.immersivemc.reach_behind_backpack_mode." + reachBehindBackpackMode.ordinal()),
new OptionInstance.LazyEnum<>(
() -> Arrays.asList(BackpackMode.values()),
Optional::of,
null
),
ActiveConfig.reachBehindBackpackMode,
(newMode) -> {
ImmersiveMCConfig.reachBehindBackpackMode.set(newMode.ordinal());
ImmersiveMCConfig.reachBehindBackpackMode.save();
ActiveConfig.loadConfigFromFile();
}
)
);
if (ActiveConfig.backpackMode.colorable) {
this.list.addBig(ScreenUtils.createIntSlider(
"config.immersivemc.backpack_r",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
public class ImmersiveHitboxes extends AbstractImmersive<ImmersiveHitboxesInfo> {

private static final double backpackHeight = 0.625;
private static final Vec3 DOWN = new Vec3(0, -1, 0);
private int backpackCooldown = 0;

public ImmersiveHitboxes() {
Expand All @@ -38,9 +39,11 @@ public ImmersiveHitboxes() {
@Override
protected void renderTick(ImmersiveHitboxesInfo info, boolean isInVR) {
super.renderTick(info, isInVR);
if (ActiveConfig.reachBehindBackpack && VRPluginVerify.clientInVR()) {
if (ActiveConfig.reachBehindBackpackMode.usesBehindBack() && VRPluginVerify.clientInVR()) {
// centerPos is the center of the back of the player
IVRData hmdData = VRPlugin.API.getRenderVRPlayer().getHMD();
IVRData hmdData = Platform.isDevelopmentEnvironment() ?
VRPlugin.API.getVRPlayer(Minecraft.getInstance().player).getHMD() :
VRPlugin.API.getRenderVRPlayer().getHMD();
Vec3 centerPos = hmdData.position().add(0, -0.5, 0).add(hmdData.getLookAngle().scale(-0.15));
Vec3 headLook;
// Even though it's VR-Only, let's try to get something for desktop testing purposes
Expand All @@ -55,24 +58,40 @@ protected void renderTick(ImmersiveHitboxesInfo info, boolean isInVR) {
// Back is 0.5 blocks across from center, making size 0.35 for x and z (full back has funny accidental detections).
// We swap x and z since if we're looking along z, we want it to be big on the x axis and vice-versa
// Add 0.2 to have some sane minimum
info.setHitbox(ImmersiveHitboxesInfo.BACKPACK_INDEX,
info.setHitbox(ImmersiveHitboxesInfo.BACKPACK_BACK_INDEX,
AABB.ofSize(centerPos,
Math.max(Math.abs(headLook.z) * 0.35, 0.2),
backpackHeight,
Math.max(Math.abs(headLook.x) * 0.35, 0.2)
));
if (VRPluginVerify.clientInVR() && VRPlugin.API.playerInVR(Minecraft.getInstance().player)) {
IVRData secondaryController = VRPlugin.API.getVRPlayer(Minecraft.getInstance().player).getController1();
if (info.getHitbox(ImmersiveHitboxesInfo.BACKPACK_INDEX)
.contains(secondaryController.position())) {
if (Platform.isDevelopmentEnvironment()) {
hmdData = VRPlugin.API.getVRPlayer(Minecraft.getInstance().player).getHMD();
}
}
}
} else {
// In case setting changes mid-game
info.setHitbox(ImmersiveHitboxesInfo.BACKPACK_INDEX, null);
info.setHitbox(ImmersiveHitboxesInfo.BACKPACK_BACK_INDEX, null);
}

if (ActiveConfig.reachBehindBackpackMode.usesOverShoulder() && VRPluginVerify.clientInVR()) {
IVRData hmdData = Platform.isDevelopmentEnvironment() ?
VRPlugin.API.getVRPlayer(Minecraft.getInstance().player).getHMD() :
VRPlugin.API.getRenderVRPlayer().getHMD();
IVRData c1Data = Platform.isDevelopmentEnvironment() ?
VRPlugin.API.getVRPlayer(Minecraft.getInstance().player).getController1() :
VRPlugin.API.getRenderVRPlayer().getController1();

Vec3 hmdDir = hmdData.getLookAngle();
Vec3 hmdPos = hmdData.position();
Vec3 c1Dir = c1Data.getLookAngle();
Vec3 c1Pos = c1Data.position();

Vec3 c1ToHMDDir = c1Pos.subtract(hmdPos).normalize(); // Angle for c1 to "look at" HMD.

double angleToDown = Math.acos(DOWN.dot(c1Dir)); // Angle in radians between straight down and the controller dir
boolean pointingDown = angleToDown < Math.PI / 2d;
double c1HMDAngleDiff = Math.acos(c1ToHMDDir.dot(hmdDir));
boolean behindHMD = c1HMDAngleDiff > 2 * Math.PI / 3d;

if (pointingDown && behindHMD) {
doBagOpen(Minecraft.getInstance().player);
}
}
}

Expand All @@ -91,7 +110,7 @@ public boolean shouldRender(ImmersiveHitboxesInfo info, boolean isInVR) {

@Override
protected void render(ImmersiveHitboxesInfo info, PoseStack stack, boolean isInVR) {
AABB backpackHitbox = info.getHitbox(ImmersiveHitboxesInfo.BACKPACK_INDEX);
AABB backpackHitbox = info.getHitbox(ImmersiveHitboxesInfo.BACKPACK_BACK_INDEX);
if (backpackHitbox != null) {
renderHitbox(stack, backpackHitbox, backpackHitbox.getCenter());
if (VRPluginVerify.hasAPI && VRPlugin.API.playerInVR(Minecraft.getInstance().player)
Expand Down Expand Up @@ -144,11 +163,8 @@ protected void initInfo(ImmersiveHitboxesInfo info) {
@Override
public void handleRightClick(AbstractImmersiveInfo info, Player player, int closest, InteractionHand hand) {
if (info instanceof ImmersiveHitboxesInfo hInfo) {
if (closest == ImmersiveHitboxesInfo.BACKPACK_INDEX && hand == InteractionHand.OFF_HAND
&& backpackCooldown <= 0) {
VRRumble.rumbleIfVR(null, 1, CommonConstants.vibrationTimePlayerActionAlert);
ClientUtil.openBag(player);
backpackCooldown = 50;
if (closest == ImmersiveHitboxesInfo.BACKPACK_BACK_INDEX && hand == InteractionHand.OFF_HAND) {
doBagOpen(player);
}
}

Expand All @@ -160,8 +176,16 @@ public BlockPos getLightPos(ImmersiveHitboxesInfo info) {
}

public void initImmersiveIfNeeded() {
if (this.infos.size() == 0) {
if (this.infos.isEmpty()) {
this.infos.add(new ImmersiveHitboxesInfo());
}
}

private void doBagOpen(Player player) {
if (backpackCooldown <= 0) {
VRRumble.rumbleIfVR(null, 1, CommonConstants.vibrationTimePlayerActionAlert);
ClientUtil.openBag(player);
backpackCooldown = 50;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class ImmersiveHitboxesInfo extends AbstractImmersiveInfo implements Info

// NOTE: This class should have the regular hitboxes and trigger hitboxes share the same
// index numbers. Have the actual immersive handle both behaviors.
public static final int BACKPACK_INDEX = 0;
public static final int BACKPACK_BACK_INDEX = 0;

private AABB backpackBackHitbox = null;

Expand All @@ -26,10 +26,11 @@ public void setInputSlots() {

@Override
public AABB getHitbox(int slot) {
if (slot == BACKPACK_INDEX) {
if (slot == BACKPACK_BACK_INDEX) {
return backpackBackHitbox;
}
throw new IllegalArgumentException("Can only get slot 0 of ImmersiveHitboxes");
throw new IllegalArgumentException(String.format("ImmersiveHitboxes: " +
"%d out of range for %d hitboxes.", slot, getAllHitboxes().length));
}

@Override
Expand All @@ -39,7 +40,7 @@ public AABB[] getAllHitboxes() {

@Override
public void setHitbox(int slot, AABB hitbox) {
if (slot == BACKPACK_INDEX) {
if (slot == BACKPACK_BACK_INDEX) {
this.backpackBackHitbox = hitbox;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class ActiveConfig {
public static RGBA itemGuideSelectedColor = new RGBA(0x3300ff00L);
public static RGBA rangedGrabColor = new RGBA(0xff00ffffL);
public static boolean disableVanillaGUIs = false;
public static boolean reachBehindBackpack = false;
public static ReachBehindBackpackMode reachBehindBackpackMode = ReachBehindBackpackMode.BEHIND_BACK;

// For changing config values in-game
public static FriendlyByteBuf serverCopy = null;
Expand Down Expand Up @@ -187,7 +187,7 @@ public static void loadConfigFromFile(boolean forceLoadServerSettings) {
itemGuideSelectedColor = new RGBA(ImmersiveMCConfig.itemGuideSelectedColor.get());
rangedGrabColor = new RGBA(ImmersiveMCConfig.rangedGrabColor.get());
disableVanillaGUIs = ImmersiveMCConfig.disableVanillaGUIs.get();
reachBehindBackpack = ImmersiveMCConfig.reachBehindBackpack.get();
reachBehindBackpackMode = ReachBehindBackpackMode.values()[ImmersiveMCConfig.reachBehindBackpackMode.get()];
ImmersiveMC.LOGGER.debug("Loaded config from file: \n" + asString());
}

Expand Down Expand Up @@ -279,12 +279,12 @@ public static String asString() {
"Ranged Grab Color: " + rangedGrabColor + "\n" +
"Use Hopper Immersion: " + useHopperImmersion + "\n" +
"Disable Vanilla GUIs: " + disableVanillaGUIs + "\n" +
"Reach Behind Backpack: " + reachBehindBackpack + "\n" +
"Use Smithing Table Immersion: " + useSmithingTableImmersion + "\n" +
"Do Rumble: " + doRumble + "\n" +
"Return Items: " + returnItems + "\n" +
"Use Written Book Immersion: " + useWrittenBookImmersion + "\n" +
"Use Cauldron Immersion: " + useCauldronImmersion;
"Use Cauldron Immersion: " + useCauldronImmersion + "\n" +
"Reach Behind Backpack Mode: " + reachBehindBackpackMode;
return stringOut;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public class ImmersiveMCConfig {
public static ForgeConfigSpec.LongValue itemGuideSelectedColor;
public static ForgeConfigSpec.LongValue rangedGrabColor;
public static ForgeConfigSpec.BooleanValue disableVanillaGUIs;
public static ForgeConfigSpec.BooleanValue reachBehindBackpack;
public static ForgeConfigSpec.IntValue reachBehindBackpackMode;



Expand Down Expand Up @@ -221,9 +221,10 @@ protected static void setupConfig(ForgeConfigSpec.Builder builder) {
disableVanillaGUIs = builder
.comment("Disable vanilla GUIs when their respective immersive is enabled")
.define("disable_vanilla_interactions", false);
reachBehindBackpack = builder
.comment("Allow reaching behind you to grab your bag. Disables similar functionatliy from regular Vivecraft.")
.define("reach_behind_backpack", false);
reachBehindBackpackMode = builder
.comment("Reach behind bag mode.")
.defineInRange("reach_behind_bag_mode",
0, 0, ReachBehindBackpackMode.values().length - 1);



Expand Down Expand Up @@ -320,8 +321,7 @@ public static void resetToDefault() {
itemGuideSelectedColor.set(0x3300ff00L);
rangedGrabColor.set(0xff00ffffL);
disableVanillaGUIs.set(false);
reachBehindBackpack.set(false);

reachBehindBackpackMode.set(0);
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.hammy275.immersivemc.common.config;

public enum ReachBehindBackpackMode {
BEHIND_BACK,
OVER_SHOULDER,
BOTH,
NONE;

public boolean usesOverShoulder() {
return this == OVER_SHOULDER || this == BOTH;
}

public boolean usesBehindBack() {
return this == BEHIND_BACK || this == BOTH;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public class BackpackTrackerMixin {
@Inject(method = "isActive", at = @At("HEAD"), cancellable = true)
public void notActiveIfUsingBag(LocalPlayer p, CallbackInfoReturnable<Boolean> cir) {
if (ActiveConfig.reachBehindBackpack) {
if (ActiveConfig.reachBehindBackpackMode.usesOverShoulder()) {
cir.setReturnValue(false);
}
}
Expand Down
11 changes: 9 additions & 2 deletions common/src/main/resources/assets/immersivemc/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,15 @@
"config.immersivemc.backpack_mode.2.desc": "ImmersiveMC's original bag, shaped like a bucket.",
"config.immersivemc.backpack_mode.3": "Low Detail Bucket Bag",
"config.immersivemc.backpack_mode.3.desc": "A low detail version of the Bucket Bag.",
"config.immersivemc.reach_behind_backpack": "Reach Behind Bag",
"config.immersivemc.reach_behind_backpack.desc": "When enabled, move your non-primary hand behind your back and press 'break block' to grab or put away your bag! Disables similar functionality from Vivecraft while enabled.",
"config.immersivemc.reach_behind_backpack_mode": "Reach Behind Bag",
"config.immersivemc.reach_behind_backpack_mode.0": "Behind Your Back",
"config.immersivemc.reach_behind_backpack_mode.0.desc": "Allows opening/closing the bag by reaching behind your back.",
"config.immersivemc.reach_behind_backpack_mode.1": "Over Your Shoulder",
"config.immersivemc.reach_behind_backpack_mode.1.desc": "Allows opening/closing the bag by reaching over your shoulder. When active, disables the selected item switching done via the same movement in Vivecraft.",
"config.immersivemc.reach_behind_backpack_mode.2": "Behind Your Back and Over Your Shoulder",
"config.immersivemc.reach_behind_backpack_mode.2.desc": "Allows opening/closing the bag by reaching behind your back and over your shoulder. When active, disables the selected item switching done via reaching over your shoulder in Vivecraft.",
"config.immersivemc.reach_behind_backpack_mode.3": "Disabled",
"config.immersivemc.reach_behind_backpack_mode.3.desc": "Disables the ability to open/close the bag via movement.",
"config.immersivemc.backpack_r": "Bag Red Value",
"config.immersivemc.backpack_g": "Bag Green Value",
"config.immersivemc.backpack_b": "Bag Blue Value",
Expand Down

0 comments on commit 08d3a2a

Please sign in to comment.