1
0
forked from Clones/Controlify

reach-around

This commit is contained in:
isXander
2023-03-29 22:40:28 +01:00
parent 0d9ddc27fc
commit 506fe550c8
7 changed files with 116 additions and 1 deletions

View File

@ -1,6 +1,7 @@
package dev.isxander.controlify.config; package dev.isxander.controlify.config;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import dev.isxander.controlify.reacharound.ReachAroundMode;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import java.util.List; import java.util.List;
@ -14,4 +15,5 @@ public class GlobalSettings {
public boolean keyboardMovement = false; public boolean keyboardMovement = false;
public boolean outOfFocusInput = false; public boolean outOfFocusInput = false;
public ReachAroundMode reachAround = ReachAroundMode.OFF;
} }

View File

@ -14,6 +14,7 @@ import dev.isxander.controlify.controller.joystick.JoystickController;
import dev.isxander.controlify.controller.joystick.SingleJoystickController; import dev.isxander.controlify.controller.joystick.SingleJoystickController;
import dev.isxander.controlify.controller.joystick.JoystickState; import dev.isxander.controlify.controller.joystick.JoystickState;
import dev.isxander.controlify.gui.screen.ControllerDeadzoneCalibrationScreen; import dev.isxander.controlify.gui.screen.ControllerDeadzoneCalibrationScreen;
import dev.isxander.controlify.reacharound.ReachAroundMode;
import dev.isxander.yacl.api.*; import dev.isxander.yacl.api.*;
import dev.isxander.yacl.gui.controllers.ActionController; import dev.isxander.yacl.gui.controllers.ActionController;
import dev.isxander.yacl.gui.controllers.BooleanController; import dev.isxander.yacl.gui.controllers.BooleanController;
@ -53,7 +54,14 @@ public class YACLHelper {
.tooltip(Component.translatable("controlify.gui.current_controller.tooltip")) .tooltip(Component.translatable("controlify.gui.current_controller.tooltip"))
.binding(Controlify.instance().currentController(), () -> Controlify.instance().currentController(), v -> Controlify.instance().setCurrentController(v)) .binding(Controlify.instance().currentController(), () -> Controlify.instance().currentController(), v -> Controlify.instance().setCurrentController(v))
.controller(opt -> new CyclingListController<>(opt, Iterables.concat(List.of(Controller.DUMMY), Controller.CONTROLLERS.values().stream().filter(Controller::canBeUsed).toList()), c -> Component.literal(c == Controller.DUMMY ? "Disabled" : c.name()))) .controller(opt -> new CyclingListController<>(opt, Iterables.concat(List.of(Controller.DUMMY), Controller.CONTROLLERS.values().stream().filter(Controller::canBeUsed).toList()), c -> Component.literal(c == Controller.DUMMY ? "Disabled" : c.name())))
.instant(true) .build())
.option(Option.createBuilder(ReachAroundMode.class)
.name(Component.translatable("controlify.gui.reach_around"))
.tooltip(Component.translatable("controlify.gui.reach_around.tooltip"))
.tooltip(Component.translatable("controlify.gui.reach_around.tooltip.parity").withStyle(ChatFormatting.GRAY))
.tooltip(state -> state == ReachAroundMode.EVERYWHERE ? Component.translatable("controlify.gui.reach_around.tooltip.warning").withStyle(ChatFormatting.RED) : Component.empty())
.binding(GlobalSettings.DEFAULT.reachAround, () -> globalSettings.reachAround, v -> globalSettings.reachAround = v)
.controller(EnumController::new)
.build()) .build())
.option(Option.createBuilder(boolean.class) .option(Option.createBuilder(boolean.class)
.name(Component.translatable("controlify.gui.out_of_focus_input")) .name(Component.translatable("controlify.gui.out_of_focus_input"))

View File

@ -0,0 +1,21 @@
package dev.isxander.controlify.mixins.feature.reacharound;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import dev.isxander.controlify.reacharound.ReachAroundHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.world.phys.HitResult;
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;
@Mixin(GameRenderer.class)
public class GameRendererMixin {
@Shadow @Final Minecraft minecraft;
@ModifyExpressionValue(method = "pick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;pick(DFZ)Lnet/minecraft/world/phys/HitResult;"))
private HitResult modifyPick(HitResult hitResult) {
return ReachAroundHandler.getReachAroundHitResult(minecraft.getCameraEntity(), hitResult);
}
}

View File

@ -0,0 +1,43 @@
package dev.isxander.controlify.reacharound;
import dev.isxander.controlify.Controlify;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
public class ReachAroundHandler {
public static HitResult getReachAroundHitResult(Entity entity, HitResult hitResult) {
// if there is already a valid hit, we don't want to override it
if (hitResult.getType() != HitResult.Type.MISS)
return hitResult;
if (!canReachAround(entity))
return hitResult;
// LivingEntity#playBlockFallSound - this is the location where the game determines the footstep noise
// maybe experiment on different values rather than 0.2f from other areas in the game?
int x = Mth.floor(entity.getX());
int y = Mth.floor(entity.getY() - 0.2F);
int z = Mth.floor(entity.getZ());
var floorPos = new BlockPos(x, y, z);
// this allows all interaction with blocks, such as opening containers, ringing bells, etc.
// this is consistent with bedrock edition behaviour, tested
return new BlockHitResult(floorPos.getCenter(), entity.getDirection(), floorPos, false);
}
private static boolean canReachAround(Entity cameraEntity) {
return // don't want to place blocks while riding an entity
cameraEntity.getVehicle() == null
// straight ahead = 0deg, up = -90deg, down = 90deg
// 45deg and above is half between straight ahead and down, must be lower or equal to this threshold
&& cameraEntity.getXRot() >= 45
// if the player is not standing on a block, this is inappropriate
// this also prevents selecting fluids as a valid position
&& cameraEntity.isOnGround()
// must respect config option
&& Controlify.instance().config().globalSettings().reachAround.canReachAround();
}
}

View File

@ -0,0 +1,32 @@
package dev.isxander.controlify.reacharound;
import dev.isxander.controlify.Controlify;
import dev.isxander.yacl.api.NameableEnum;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import java.util.function.BiFunction;
public enum ReachAroundMode implements NameableEnum {
OFF((minecraft, controlify) -> false),
SINGLEPLAYER_ONLY((minecraft, controlify) -> minecraft.isSingleplayer()),
SINGLEPLAYER_AND_LAN((minecraft, controlify) -> minecraft.isLocalServer()),
EVERYWHERE((minecraft, controlify) -> true);
private final BiFunction<Minecraft, Controlify, Boolean> canReachAround;
private final Component displayName;
ReachAroundMode(BiFunction<Minecraft, Controlify, Boolean> canReachAround) {
this.canReachAround = canReachAround;
this.displayName = Component.translatable("controlify.reach_around." + this.name().toLowerCase());
}
public boolean canReachAround() {
return canReachAround.apply(Minecraft.getInstance(), Controlify.instance());
}
@Override
public Component getDisplayName() {
return displayName;
}
}

View File

@ -2,6 +2,14 @@
"controlify.gui.category.global": "Global", "controlify.gui.category.global": "Global",
"controlify.gui.current_controller": "Current Controller", "controlify.gui.current_controller": "Current Controller",
"controlify.gui.current_controller.tooltip": "In Controlify's infancy, only one controller can be used at a time, this selects which one you want to use.", "controlify.gui.current_controller.tooltip": "In Controlify's infancy, only one controller can be used at a time, this selects which one you want to use.",
"controlify.gui.reach_around": "Block Reach Around",
"controlify.gui.reach_around.tooltip": "If enabled, you can interact with the block you are standing on in the direction you are looking.",
"controlify.gui.reach_around.tooltip.parity": "This is parity with bedrock edition where you can also do this.",
"controlify.gui.reach_around.tooltip.warning": "WARNING: This is an unfair advantage over other players without Controlify, and you will likely be flagged by many anti-cheats. This should only be used in situations where everyone playing recognises that you have this ability and are okay with it.",
"controlify.reach_around.off": "Off",
"controlify.reach_around.singleplayer_only": "Singleplayer Only",
"controlify.reach_around.singleplayer_and_lan": "Singleplayer and LAN",
"controlify.reach_around.everywhere": "Everywhere",
"controlify.gui.out_of_focus_input": "Out of Focus Input", "controlify.gui.out_of_focus_input": "Out of Focus Input",
"controlify.gui.out_of_focus_input.tooltip": "If enabled, Controlify will still receive input even if the game window is not focused.", "controlify.gui.out_of_focus_input.tooltip": "If enabled, Controlify will still receive input even if the game window is not focused.",
"controlify.gui.keyboard_movement": "Keyboard-like Movement", "controlify.gui.keyboard_movement": "Keyboard-like Movement",

View File

@ -32,6 +32,7 @@
"feature.guide.screen.AbstractButtonMixin", "feature.guide.screen.AbstractButtonMixin",
"feature.guide.screen.AbstractWidgetMixin", "feature.guide.screen.AbstractWidgetMixin",
"feature.guide.screen.TabNavigationBarMixin", "feature.guide.screen.TabNavigationBarMixin",
"feature.reacharound.GameRendererMixin",
"feature.screenop.MinecraftMixin", "feature.screenop.MinecraftMixin",
"feature.screenop.ScreenMixin", "feature.screenop.ScreenMixin",
"feature.screenop.vanilla.AbstractButtonMixin", "feature.screenop.vanilla.AbstractButtonMixin",