mirror of
https://github.com/TeamMidnightDust/MidnightControls.git
synced 2025-12-13 15:25:08 +01:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c53575d17 | ||
|
|
24f7054eff |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,11 +1,13 @@
|
||||
#
|
||||
# LambdAurora's ignore file
|
||||
#
|
||||
# v0.12
|
||||
# v0.13
|
||||
|
||||
# JetBrains
|
||||
.idea/
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
## Intellij IDEA
|
||||
out/
|
||||
## CLion
|
||||
|
||||
@@ -21,12 +21,14 @@ This mod adds a controller support (and an experimental touchscreen support).
|
||||
- Touchscreen support (very experimental and buggy).
|
||||
- Keyboard controls to look around.
|
||||
- Toggleable on screen button indicator (like in Bedrock Edition).
|
||||
- Vertical reacharound.
|
||||
- Many Bedrock Edition features:
|
||||
- Toggleable fly drifting
|
||||
- Front block placing (be careful with this one)
|
||||
- New controls settings!
|
||||
- Many options in config to change to your liking.
|
||||
- Many controllers supported and in a simply way your own controller mappings.
|
||||
- An easy API for developers to add their own button bindings.
|
||||
|
||||
## 🎮 Supported Controllers:
|
||||
|
||||
|
||||
14
build.gradle
14
build.gradle
@@ -27,6 +27,20 @@ allprojects {
|
||||
classifier = "sources"
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven {
|
||||
name = "GithubPackages"
|
||||
url = uri("https://maven.pkg.github.com/LambdAurora/LambdaControls")
|
||||
credentials {
|
||||
username = project.findProperty("gpr.user") ?: System.getenv("USERNAME")
|
||||
password = project.findProperty("gpr.key") ?: System.getenv("TOKEN")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
plugins {
|
||||
id 'java-library'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
archivesBaseName = project.archives_base_name + "-core"
|
||||
@@ -15,3 +16,17 @@ java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
// add all the jars that should be included when publishing to maven
|
||||
artifact(jar) {
|
||||
builtBy jar
|
||||
}
|
||||
artifact(sourcesJar) {
|
||||
builtBy sourcesJar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,15 @@ import java.util.Optional;
|
||||
* Represents a feature.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.2.0
|
||||
* @version 1.3.2
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class LambdaControlsFeature implements Nameable
|
||||
{
|
||||
private static final List<LambdaControlsFeature> FEATURES = new ArrayList<>();
|
||||
public static final LambdaControlsFeature FRONT_BLOCK_PLACING = new LambdaControlsFeature("front_block_placing", true, false);
|
||||
public static final LambdaControlsFeature FAST_BLOCK_PLACING = new LambdaControlsFeature("fast_block_placing", true, true);
|
||||
private static final List<LambdaControlsFeature> FEATURES = new ArrayList<>();
|
||||
public static final LambdaControlsFeature FAST_BLOCK_PLACING = new LambdaControlsFeature("fast_block_placing", true, true);
|
||||
public static final LambdaControlsFeature FRONT_BLOCK_PLACING = new LambdaControlsFeature("front_block_placing", true, false);
|
||||
public static final LambdaControlsFeature VERTICAL_REACHAROUND = new LambdaControlsFeature("vertical_reacharound", true, false);
|
||||
|
||||
private final String key;
|
||||
private final boolean defaultAllowed;
|
||||
@@ -155,7 +156,8 @@ public class LambdaControlsFeature implements Nameable
|
||||
}
|
||||
|
||||
static {
|
||||
FEATURES.add(FRONT_BLOCK_PLACING);
|
||||
FEATURES.add(FAST_BLOCK_PLACING);
|
||||
FEATURES.add(FRONT_BLOCK_PLACING);
|
||||
FEATURES.add(VERTICAL_REACHAROUND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ plugins {
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
version = "${project.mod_version}+${project.minecraft_version}"
|
||||
archivesBaseName = project.archives_base_name + "-fabric"
|
||||
|
||||
minecraft {
|
||||
@@ -91,4 +92,20 @@ jar {
|
||||
}
|
||||
}
|
||||
|
||||
// configure the maven publication
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
// add all the jars that should be included when publishing to maven
|
||||
artifact(remapJar) {
|
||||
builtBy remapJar
|
||||
}
|
||||
artifact(sourcesJar) {
|
||||
builtBy remapSourcesJar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
build.dependsOn(":core:build")
|
||||
publish.dependsOn(":core:publish")
|
||||
|
||||
@@ -23,7 +23,6 @@ import me.lambdaurora.spruceui.event.OpenScreenCallback;
|
||||
import me.lambdaurora.spruceui.hud.HudManager;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
@@ -40,7 +39,7 @@ import org.lwjgl.glfw.GLFW;
|
||||
* Represents the LambdaControls client mod.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.3.0
|
||||
* @version 1.3.2
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class LambdaControlsClient extends LambdaControls implements ClientModInitializer
|
||||
@@ -59,6 +58,7 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
|
||||
public static final Identifier CURSOR_TEXTURE = new Identifier(LambdaControlsConstants.NAMESPACE, "textures/gui/cursor.png");
|
||||
public final LambdaControlsConfig config = new LambdaControlsConfig(this);
|
||||
public final LambdaInput input = new LambdaInput(this);
|
||||
public final LambdaReacharound reacharound = new LambdaReacharound();
|
||||
private LambdaControlsHud hud;
|
||||
private ControlsMode previousControlsMode;
|
||||
|
||||
@@ -79,6 +79,7 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
|
||||
LambdaControlsFeature.fromName(name).ifPresent(feature -> context.getTaskQueue().execute(() -> feature.setAllowed(allowed)));
|
||||
});
|
||||
|
||||
ClientTickEvents.START_CLIENT_TICK.register(this.reacharound::tick);
|
||||
ClientTickEvents.END_CLIENT_TICK.register(this::onTick);
|
||||
|
||||
OpenScreenCallback.EVENT.register((client, screen) -> {
|
||||
|
||||
@@ -34,37 +34,39 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y;
|
||||
public class LambdaControlsConfig
|
||||
{
|
||||
// General
|
||||
private static final ControlsMode DEFAULT_CONTROLS_MODE = ControlsMode.DEFAULT;
|
||||
private static final boolean DEFAULT_AUTO_SWITCH_MODE = false;
|
||||
private static final ControlsMode DEFAULT_CONTROLS_MODE = ControlsMode.DEFAULT;
|
||||
private static final boolean DEFAULT_AUTO_SWITCH_MODE = false;
|
||||
// HUD
|
||||
private static final boolean DEFAULT_HUD_ENABLE = true;
|
||||
private static final HudSide DEFAULT_HUD_SIDE = HudSide.LEFT;
|
||||
private static final boolean DEFAULT_HUD_ENABLE = true;
|
||||
private static final HudSide DEFAULT_HUD_SIDE = HudSide.LEFT;
|
||||
// Gameplay
|
||||
private static final boolean DEFAULT_FAST_BLOCK_INTERACTION = true;
|
||||
private static final boolean DEFAULT_FLY_DRIFTING = false;
|
||||
private static final boolean DEFAULT_FLY_VERTICAL_DRIFTING = true;
|
||||
private static final boolean DEFAULT_FRONT_BLOCK_PLACING = false;
|
||||
private static final boolean DEFAULT_FRONT_BLOCK_OUTLINE = true;
|
||||
private static final boolean DEFAULT_FAST_BLOCK_INTERACTION = true;
|
||||
private static final boolean DEFAULT_FLY_DRIFTING = false;
|
||||
private static final boolean DEFAULT_FLY_VERTICAL_DRIFTING = true;
|
||||
private static final boolean DEFAULT_FRONT_BLOCK_PLACING = false;
|
||||
private static final boolean DEFAULT_VERTICAL_REACHAROUND = false;
|
||||
private static final boolean DEFAULT_REACHAROUND_OUTLINE = true;
|
||||
private static final int[] DEFAULT_REACHAROUND_OUTLINE_COLOR = new int[]{255, 255, 255, 102};
|
||||
// Controller
|
||||
private static final ControllerType DEFAULT_CONTROLLER_TYPE = ControllerType.DEFAULT;
|
||||
private static final double DEFAULT_DEAD_ZONE = 0.25;
|
||||
private static final double DEFAULT_ROTATION_SPEED = 40.0;
|
||||
private static final double DEFAULT_MOUSE_SPEED = 25.0;
|
||||
private static final boolean DEFAULT_UNFOCUSED_INPUT = false;
|
||||
private static final boolean DEFAULT_VIRTUAL_MOUSE = false;
|
||||
private static final VirtualMouseSkin DEFAULT_VIRTUAL_MOUSE_SKIN = VirtualMouseSkin.DEFAULT_LIGHT;
|
||||
private static final ControllerType DEFAULT_CONTROLLER_TYPE = ControllerType.DEFAULT;
|
||||
private static final double DEFAULT_DEAD_ZONE = 0.25;
|
||||
private static final double DEFAULT_ROTATION_SPEED = 40.0;
|
||||
private static final double DEFAULT_MOUSE_SPEED = 25.0;
|
||||
private static final boolean DEFAULT_UNFOCUSED_INPUT = false;
|
||||
private static final boolean DEFAULT_VIRTUAL_MOUSE = false;
|
||||
private static final VirtualMouseSkin DEFAULT_VIRTUAL_MOUSE_SKIN = VirtualMouseSkin.DEFAULT_LIGHT;
|
||||
|
||||
private static final Pattern BUTTON_BINDING_PATTERN = Pattern.compile("(-?\\d+)\\+?");
|
||||
|
||||
protected final FileConfig config = FileConfig.builder("config/lambdacontrols.toml").concurrent().defaultResource("/config.toml").build();
|
||||
private final LambdaControlsClient mod;
|
||||
private ControlsMode controlsMode;
|
||||
private ControllerType controllerType;
|
||||
private ControllerType controllerType;
|
||||
// Gameplay.
|
||||
private boolean shouldRenderFrontBlockOutline;
|
||||
private int[] frontBlockOutlineColor;
|
||||
private boolean shouldRenderReacharoundOutline;
|
||||
private int[] reacharoundOutlineColor;
|
||||
// Controller settings
|
||||
private double deadZone;
|
||||
private double deadZone;
|
||||
private double rotationSpeed;
|
||||
private double mouseSpeed;
|
||||
private boolean unfocusedInput;
|
||||
@@ -93,9 +95,10 @@ public class LambdaControlsConfig
|
||||
this.hudSide = HudSide.byId(this.config.getOrElse("hud.side", DEFAULT_HUD_SIDE.getName())).orElse(DEFAULT_HUD_SIDE);
|
||||
// Gameplay
|
||||
LambdaControlsFeature.FAST_BLOCK_PLACING.setEnabled(this.config.getOrElse("gameplay.fast_block_placing", DEFAULT_FAST_BLOCK_INTERACTION));
|
||||
LambdaControlsFeature.FRONT_BLOCK_PLACING.setEnabled(this.config.getOrElse("gameplay.front_block_placing.enabled", DEFAULT_FRONT_BLOCK_PLACING));
|
||||
this.shouldRenderFrontBlockOutline = this.config.getOrElse("gameplay.front_block_placing.outline", DEFAULT_FRONT_BLOCK_OUTLINE);
|
||||
this.frontBlockOutlineColor = this.config.getOptional("gameplay.front_block_placing.outline_color").map(hex -> parseColor((String) hex)).orElse(new int[]{255, 255, 255, 102});
|
||||
LambdaControlsFeature.FRONT_BLOCK_PLACING.setEnabled(this.config.getOrElse("gameplay.reacharound.horizontal", DEFAULT_FRONT_BLOCK_PLACING));
|
||||
LambdaControlsFeature.VERTICAL_REACHAROUND.setEnabled(this.config.getOrElse("gameplay.reacharound.vertical", DEFAULT_VERTICAL_REACHAROUND));
|
||||
this.shouldRenderReacharoundOutline = this.config.getOrElse("gameplay.reacharound.outline", DEFAULT_REACHAROUND_OUTLINE);
|
||||
this.reacharoundOutlineColor = this.config.getOptional("gameplay.reacharound.outline_color").map(hex -> parseColor((String) hex)).orElse(DEFAULT_REACHAROUND_OUTLINE_COLOR);
|
||||
// Controller settings.
|
||||
this.controllerType = ControllerType.byId(this.config.getOrElse("controller.type", DEFAULT_CONTROLLER_TYPE.getName())).orElse(DEFAULT_CONTROLLER_TYPE);
|
||||
this.deadZone = this.config.getOrElse("controller.dead_zone", DEFAULT_DEAD_ZONE);
|
||||
@@ -133,10 +136,19 @@ public class LambdaControlsConfig
|
||||
}
|
||||
});
|
||||
|
||||
// This shouldn't happen if the configuration is new.
|
||||
if (!this.config.contains("gameplay.front_block_placing.enabled") && this.config.contains("gameplay.front_block_placing")) {
|
||||
this.config.remove("gameplay.front_block_placing");
|
||||
this.config.set("gameplay.front_block_placing.enabled", DEFAULT_FRONT_BLOCK_PLACING);
|
||||
if (this.config.contains("gameplay.front_block_placing.enabled")) {
|
||||
this.setFrontBlockPlacing(this.config.getOrElse("gameplay.front_block_placing.enabled", DEFAULT_FRONT_BLOCK_PLACING));
|
||||
this.config.remove("gameplay.front_block_placing.enabled");
|
||||
}
|
||||
|
||||
if (this.config.contains("gameplay.front_block_placing.outline")) {
|
||||
this.setRenderReacharoundOutline(this.config.getOrElse("gameplay.front_block_placing.outline", DEFAULT_REACHAROUND_OUTLINE));
|
||||
this.config.remove("gameplay.front_block_placing.outline");
|
||||
}
|
||||
|
||||
if (this.config.contains("gameplay.front_block_placing.outline_color")) {
|
||||
this.config.getOptional("gameplay.front_block_placing.outline_color").ifPresent(color -> this.config.set("gameplay.reacharound.outline_color", color));
|
||||
this.config.remove("gameplay.front_block_placing.outline_color");
|
||||
}
|
||||
|
||||
this.renamed("controller.controls.tab_left", "controller.controls.tab_back");
|
||||
@@ -165,7 +177,8 @@ public class LambdaControlsConfig
|
||||
this.setFlyDrifting(DEFAULT_FLY_DRIFTING);
|
||||
this.setFlyVerticalDrifting(DEFAULT_FLY_VERTICAL_DRIFTING);
|
||||
this.setFrontBlockPlacing(DEFAULT_FRONT_BLOCK_PLACING);
|
||||
this.setRenderFrontBlockOutline(DEFAULT_FRONT_BLOCK_OUTLINE);
|
||||
this.setVerticalReacharound(DEFAULT_VERTICAL_REACHAROUND);
|
||||
this.setRenderReacharoundOutline(DEFAULT_REACHAROUND_OUTLINE);
|
||||
// Controller
|
||||
this.setControllerType(DEFAULT_CONTROLLER_TYPE);
|
||||
this.setDeadZone(DEFAULT_DEAD_ZONE);
|
||||
@@ -352,7 +365,28 @@ public class LambdaControlsConfig
|
||||
public void setFrontBlockPlacing(boolean enable)
|
||||
{
|
||||
LambdaControlsFeature.FRONT_BLOCK_PLACING.setEnabled(enable);
|
||||
this.config.set("gameplay.front_block_placing.enabled", enable);
|
||||
this.config.set("gameplay.reacharound.horizontal", enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether vertical reacharound is enabled or not.
|
||||
*
|
||||
* @return True if vertical reacharound is enabled, else false.
|
||||
*/
|
||||
public boolean hasVerticalReacharound()
|
||||
{
|
||||
return LambdaControlsFeature.VERTICAL_REACHAROUND.isEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether vertical reacharound is enabled or not.
|
||||
*
|
||||
* @param enable True if vertical reacharound is enabled, else false.
|
||||
*/
|
||||
public void setVerticalReacharound(boolean enable)
|
||||
{
|
||||
LambdaControlsFeature.VERTICAL_REACHAROUND.setEnabled(enable);
|
||||
this.config.set("gameplay.reacharound.vertical", enable);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -360,9 +394,9 @@ public class LambdaControlsConfig
|
||||
*
|
||||
* @return True if front block placing outline is enabled, else false.
|
||||
*/
|
||||
public boolean shouldRenderFrontBlockOutline()
|
||||
public boolean shouldRenderReacharoundOutline()
|
||||
{
|
||||
return this.shouldRenderFrontBlockOutline;
|
||||
return this.shouldRenderReacharoundOutline;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -370,9 +404,9 @@ public class LambdaControlsConfig
|
||||
*
|
||||
* @param render True if front block placing outline is enabled, else false.
|
||||
*/
|
||||
public void setRenderFrontBlockOutline(boolean render)
|
||||
public void setRenderReacharoundOutline(boolean render)
|
||||
{
|
||||
this.config.set("gameplay.front_block_placing.outline", this.shouldRenderFrontBlockOutline = render);
|
||||
this.config.set("gameplay.reacharound.outline", this.shouldRenderReacharoundOutline = render);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -382,9 +416,9 @@ public class LambdaControlsConfig
|
||||
*
|
||||
* @return The color as a RGBA integer array.
|
||||
*/
|
||||
public int[] getFrontBlockOutlineColor()
|
||||
public int[] getReacharoundOutlineColor()
|
||||
{
|
||||
return this.frontBlockOutlineColor;
|
||||
return this.reacharoundOutlineColor;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
package me.lambdaurora.lambdacontrols.client;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.LambdaControlsFeature;
|
||||
import me.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat;
|
||||
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.client.controller.Controller;
|
||||
@@ -22,10 +21,6 @@ import me.lambdaurora.lambdacontrols.client.mixin.EntryListWidgetAccessor;
|
||||
import me.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor;
|
||||
import me.lambdaurora.lambdacontrols.client.util.MouseAccessor;
|
||||
import me.lambdaurora.spruceui.SpruceLabelWidget;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.FluidBlock;
|
||||
import net.minecraft.block.SlabBlock;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.gui.ParentElement;
|
||||
@@ -42,14 +37,8 @@ import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget;
|
||||
import net.minecraft.client.gui.widget.EntryListWidget;
|
||||
import net.minecraft.client.gui.widget.SliderWidget;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.screen.slot.SlotActionType;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -72,24 +61,24 @@ import static org.lwjgl.glfw.GLFW.*;
|
||||
* Represents the LambdaControls' input handler.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.3.0
|
||||
* @version 1.3.2
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class LambdaInput
|
||||
{
|
||||
private static final Map<Integer, Integer> BUTTON_COOLDOWNS = new HashMap<>();
|
||||
private static final Map<Integer, Integer> BUTTON_COOLDOWNS = new HashMap<>();
|
||||
private final LambdaControlsConfig config;
|
||||
// Cooldowns
|
||||
private int actionGuiCooldown = 0;
|
||||
private int ignoreNextA = 0;
|
||||
private double targetYaw = 0.0;
|
||||
private double targetPitch = 0.0;
|
||||
private float prevXAxis = 0.F;
|
||||
private float prevYAxis = 0.F;
|
||||
private int targetMouseX = 0;
|
||||
private int targetMouseY = 0;
|
||||
private float mouseSpeedX = 0.F;
|
||||
private float mouseSpeedY = 0.F;
|
||||
private int actionGuiCooldown = 0;
|
||||
private boolean ignoreNextARelease = false;
|
||||
private double targetYaw = 0.0;
|
||||
private double targetPitch = 0.0;
|
||||
private float prevXAxis = 0.F;
|
||||
private float prevYAxis = 0.F;
|
||||
private int targetMouseX = 0;
|
||||
private int targetMouseY = 0;
|
||||
private float mouseSpeedX = 0.F;
|
||||
private float mouseSpeedY = 0.F;
|
||||
|
||||
public LambdaInput(@NotNull LambdaControlsClient mod)
|
||||
{
|
||||
@@ -156,9 +145,6 @@ public class LambdaInput
|
||||
if (allowInput)
|
||||
InputManager.updateBindings(client);
|
||||
|
||||
if (this.ignoreNextA > 0)
|
||||
this.ignoreNextA--;
|
||||
|
||||
if (client.currentScreen instanceof ControllerControlsScreen && InputManager.STATES.entrySet().parallelStream().map(Map.Entry::getValue).allMatch(ButtonState::isUnpressed)) {
|
||||
ControllerControlsScreen screen = (ControllerControlsScreen) client.currentScreen;
|
||||
if (screen.focusedBinding != null && !screen.waiting) {
|
||||
@@ -321,50 +307,96 @@ public class LambdaInput
|
||||
}
|
||||
}
|
||||
|
||||
if (client.currentScreen instanceof HandledScreen && client.interactionManager != null && client.player != null) {
|
||||
double x = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
|
||||
double y = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
|
||||
Slot slot = ((HandledScreenAccessor) client.currentScreen).lambdacontrols_getSlotAt(x, y);
|
||||
SlotActionType slotAction = SlotActionType.PICKUP;
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && slot != null) {
|
||||
if (client.currentScreen instanceof CreativeInventoryScreen) {
|
||||
if (((CreativeInventoryScreenAccessor) client.currentScreen).lambdacontrols_isCreativeInventorySlot(slot))
|
||||
slotAction = SlotActionType.CLONE;
|
||||
}
|
||||
client.interactionManager.clickSlot(((HandledScreen) client.currentScreen).getScreenHandler().syncId, slot.id, GLFW.GLFW_MOUSE_BUTTON_1, slotAction, client.player);
|
||||
client.player.playerScreenHandler.sendContentUpdates();
|
||||
this.actionGuiCooldown = 5;
|
||||
return;
|
||||
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) {
|
||||
client.player.closeHandledScreen();
|
||||
return;
|
||||
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_X && slot != null) {
|
||||
client.interactionManager.clickSlot(((HandledScreen) client.currentScreen).getScreenHandler().syncId, slot.id, GLFW.GLFW_MOUSE_BUTTON_2, SlotActionType.PICKUP, client.player);
|
||||
return;
|
||||
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_Y && slot != null) {
|
||||
client.interactionManager.clickSlot(((HandledScreen) client.currentScreen).getScreenHandler().syncId, slot.id, GLFW.GLFW_MOUSE_BUTTON_1, SlotActionType.QUICK_MOVE, client.player);
|
||||
return;
|
||||
}
|
||||
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) {
|
||||
if (this.handleInventory(client, button)) {
|
||||
this.ignoreNextARelease = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) {
|
||||
if (client.currentScreen != null) {
|
||||
client.currentScreen.onClose();
|
||||
if (!LambdaControlsCompat.handleMenuBack(client, client.currentScreen))
|
||||
client.currentScreen.onClose();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !isScreenInteractive(client.currentScreen) && this.actionGuiCooldown == 0 && this.ignoreNextA == 0) {
|
||||
double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
|
||||
double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
|
||||
if (action == 0) {
|
||||
client.currentScreen.mouseClicked(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_1);
|
||||
} else if (action == 1) {
|
||||
client.currentScreen.mouseReleased(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_1);
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !isScreenInteractive(client.currentScreen) && this.actionGuiCooldown == 0) {
|
||||
if (!this.ignoreNextARelease) {
|
||||
double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
|
||||
double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
|
||||
if (action == 0) {
|
||||
client.currentScreen.mouseClicked(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_1);
|
||||
} else if (action == 1) {
|
||||
client.currentScreen.mouseReleased(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_1);
|
||||
}
|
||||
this.actionGuiCooldown = 5;
|
||||
} else {
|
||||
this.ignoreNextARelease = false;
|
||||
}
|
||||
this.actionGuiCooldown = 5;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles inventory interaction.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param button The button pressed.
|
||||
* @return True if an inventory interaction was done.
|
||||
*/
|
||||
private boolean handleInventory(@NotNull MinecraftClient client, int button)
|
||||
{
|
||||
if (!(client.currentScreen instanceof HandledScreen))
|
||||
return false;
|
||||
|
||||
if (client.interactionManager == null || client.player == null)
|
||||
return false;
|
||||
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) {
|
||||
client.player.closeHandledScreen();
|
||||
return true;
|
||||
}
|
||||
|
||||
double x = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
|
||||
double y = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
|
||||
|
||||
HandledScreen screen = (HandledScreen) client.currentScreen;
|
||||
HandledScreenAccessor accessor = (HandledScreenAccessor) screen;
|
||||
Slot slot = ((HandledScreenAccessor) client.currentScreen).lambdacontrols_getSlotAt(x, y);
|
||||
|
||||
int slotId;
|
||||
if (slot == null) {
|
||||
if (client.player.inventory.getCursorStack().isEmpty())
|
||||
return false;
|
||||
slotId = accessor.lambdacontrols_isClickOutsideBounds(x, y, accessor.getX(), accessor.getY(), GLFW_MOUSE_BUTTON_1) ? -999 : -1;
|
||||
} else {
|
||||
slotId = slot.id;
|
||||
}
|
||||
|
||||
SlotActionType actionType = SlotActionType.PICKUP;
|
||||
int clickData = GLFW.GLFW_MOUSE_BUTTON_1;
|
||||
switch (button) {
|
||||
case GLFW_GAMEPAD_BUTTON_A:
|
||||
if (screen instanceof CreativeInventoryScreen)
|
||||
if (((CreativeInventoryScreenAccessor) screen).lambdacontrols_isCreativeInventorySlot(slot))
|
||||
actionType = SlotActionType.CLONE;
|
||||
if (slot != null && LambdaControlsCompat.streamCompatHandlers().anyMatch(handler -> handler.isCreativeSlot(screen, slot)))
|
||||
actionType = SlotActionType.CLONE;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_X:
|
||||
clickData = GLFW_MOUSE_BUTTON_2;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_Y:
|
||||
actionType = SlotActionType.QUICK_MOVE;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
accessor.lambdacontrols_onMouseClick(slot, slotId, clickData, actionType);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void handleAxe(@NotNull MinecraftClient client, int axis, float value, float absValue, int state)
|
||||
{
|
||||
int asButtonState = value > 0.5F ? 1 : (value < -0.5F ? 2 : 0);
|
||||
@@ -680,71 +712,4 @@ public class LambdaInput
|
||||
this.mouseSpeedY = 0.F;
|
||||
}
|
||||
}
|
||||
|
||||
public static Direction getMoveDirection(@Nullable BlockPos lastPos, @NotNull BlockPos newPos)
|
||||
{
|
||||
if (lastPos == null)
|
||||
return null;
|
||||
BlockPos vector = newPos.subtract(lastPos);
|
||||
if (vector.getX() > 0)
|
||||
return Direction.EAST;
|
||||
else if (vector.getX() < 0)
|
||||
return Direction.WEST;
|
||||
else if (vector.getZ() > 0)
|
||||
return Direction.SOUTH;
|
||||
else if (vector.getZ() < 0)
|
||||
return Direction.NORTH;
|
||||
else if (vector.getY() > 0)
|
||||
return Direction.UP;
|
||||
else if (vector.getY() < 0)
|
||||
return Direction.DOWN;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a nullable block hit result if front placing is possible.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @return A block hit result if front placing is possible.
|
||||
*/
|
||||
public static @Nullable BlockHitResult tryFrontPlace(@NotNull MinecraftClient client)
|
||||
{
|
||||
if (!LambdaControlsFeature.FRONT_BLOCK_PLACING.isAvailable())
|
||||
return null;
|
||||
if (client.player != null && client.crosshairTarget != null && client.crosshairTarget.getType() == HitResult.Type.MISS && client.player.isOnGround() && client.player.pitch > 35.0F) {
|
||||
if (client.player.isRiding())
|
||||
return null;
|
||||
BlockPos playerPos = client.player.getBlockPos().down();
|
||||
BlockPos targetPos = new BlockPos(client.crosshairTarget.getPos()).subtract(playerPos);
|
||||
BlockPos vector = new BlockPos(MathHelper.clamp(targetPos.getX(), -1, 1), 0, MathHelper.clamp(targetPos.getZ(), -1, 1));
|
||||
BlockPos blockPos = playerPos.add(vector);
|
||||
|
||||
Direction direction = client.player.getHorizontalFacing();
|
||||
|
||||
BlockState state = client.world.getBlockState(blockPos);
|
||||
if (!state.isAir())
|
||||
return null;
|
||||
BlockState adjacentBlockState = client.world.getBlockState(blockPos.offset(direction.getOpposite()));
|
||||
if (adjacentBlockState.isAir() || adjacentBlockState.getBlock() instanceof FluidBlock || (vector.getX() == 0 && vector.getZ() == 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BlockHitResult(client.crosshairTarget.getPos(), direction, blockPos, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static @NotNull BlockHitResult withSideForFrontPlace(@NotNull BlockHitResult result, @Nullable ItemStack stack)
|
||||
{
|
||||
if (stack == null || stack.isEmpty() || !(stack.getItem() instanceof BlockItem))
|
||||
return result;
|
||||
return withSideForFrontPlace(result, Block.getBlockFromItem(stack.getItem()));
|
||||
}
|
||||
|
||||
public static @NotNull BlockHitResult withSideForFrontPlace(@NotNull BlockHitResult result, @NotNull Block block)
|
||||
{
|
||||
if (block instanceof SlabBlock)
|
||||
result = result.withSide(Direction.DOWN);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package me.lambdaurora.lambdacontrols.client;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.LambdaControlsFeature;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.FluidBlock;
|
||||
import net.minecraft.block.SlabBlock;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.RayTraceContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents the reacharound API of LambdaControls.
|
||||
*
|
||||
* @version 1.3.2
|
||||
* @since 1.3.2
|
||||
*/
|
||||
public class LambdaReacharound
|
||||
{
|
||||
private BlockHitResult lastReacharoundResult = null;
|
||||
private boolean lastReacharoundVertical = false;
|
||||
|
||||
public void tick(@NotNull MinecraftClient client)
|
||||
{
|
||||
this.lastReacharoundResult = this.tryVerticalReachAround(client);
|
||||
if (this.lastReacharoundResult == null) {
|
||||
this.lastReacharoundResult = this.tryFrontPlace(client);
|
||||
this.lastReacharoundVertical = false;
|
||||
} else this.lastReacharoundVertical = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last reach around result.
|
||||
*
|
||||
* @return The last reach around result.
|
||||
*/
|
||||
public @Nullable BlockHitResult getLastReacharoundResult()
|
||||
{
|
||||
return this.lastReacharoundResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the last reach around is vertical.
|
||||
*
|
||||
* @return True if the reach around is vertical.
|
||||
*/
|
||||
public boolean isLastReacharoundVertical()
|
||||
{
|
||||
return this.lastReacharoundVertical;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether reacharound is available or not.
|
||||
*
|
||||
* @return True if reacharound is available, else false.
|
||||
*/
|
||||
public boolean isReacharoundAvailable()
|
||||
{
|
||||
return LambdaControlsFeature.FRONT_BLOCK_PLACING.isAvailable() || LambdaControlsFeature.VERTICAL_REACHAROUND.isAvailable();
|
||||
}
|
||||
|
||||
private float getPlayerRange(@NotNull MinecraftClient client)
|
||||
{
|
||||
return client.interactionManager != null ? client.interactionManager.getReachDistance() : 0.f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a nullable block hit result if vertical reacharound is possible.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @return A block hit result if vertical reacharound is possible, else null.
|
||||
*/
|
||||
public @Nullable BlockHitResult tryVerticalReachAround(@NotNull MinecraftClient client)
|
||||
{
|
||||
if (!LambdaControlsFeature.VERTICAL_REACHAROUND.isAvailable())
|
||||
return null;
|
||||
if (client.player == null || client.world == null || client.crosshairTarget == null || client.crosshairTarget.getType() != HitResult.Type.MISS
|
||||
|| !client.player.isOnGround() || client.player.pitch < 80.0F
|
||||
|| client.player.isRiding())
|
||||
return null;
|
||||
|
||||
Vec3d pos = client.player.getCameraPosVec(1.0F);
|
||||
Vec3d rotationVec = client.player.getRotationVec(1.0F);
|
||||
float range = getPlayerRange(client);
|
||||
Vec3d rayVec = pos.add(rotationVec.x * range, rotationVec.y * range, rotationVec.z * range).add(0, 0.75, 0);
|
||||
BlockHitResult result = client.world.rayTrace(new RayTraceContext(pos, rayVec, RayTraceContext.ShapeType.OUTLINE, RayTraceContext.FluidHandling.NONE, client.player));
|
||||
|
||||
if (result.getType() == HitResult.Type.BLOCK) {
|
||||
BlockPos blockPos = result.getBlockPos().down();
|
||||
BlockState state = client.world.getBlockState(blockPos);
|
||||
|
||||
if (client.player.getBlockPos().getY() - blockPos.getY() > 1 && (client.world.isAir(blockPos) || state.getMaterial().isReplaceable())) {
|
||||
return new BlockHitResult(result.getPos(), Direction.DOWN, blockPos, false);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a nullable block hit result if front placing is possible.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @return A block hit result if front placing is possible.
|
||||
*/
|
||||
public @Nullable BlockHitResult tryFrontPlace(@NotNull MinecraftClient client)
|
||||
{
|
||||
if (!LambdaControlsFeature.FRONT_BLOCK_PLACING.isAvailable())
|
||||
return null;
|
||||
if (client.player != null && client.crosshairTarget != null && client.crosshairTarget.getType() == HitResult.Type.MISS && client.player.isOnGround() && client.player.pitch > 35.0F) {
|
||||
if (client.player.isRiding())
|
||||
return null;
|
||||
BlockPos playerPos = client.player.getBlockPos().down();
|
||||
BlockPos targetPos = new BlockPos(client.crosshairTarget.getPos()).subtract(playerPos);
|
||||
BlockPos vector = new BlockPos(MathHelper.clamp(targetPos.getX(), -1, 1), 0, MathHelper.clamp(targetPos.getZ(), -1, 1));
|
||||
BlockPos blockPos = playerPos.add(vector);
|
||||
|
||||
Direction direction = client.player.getHorizontalFacing();
|
||||
|
||||
BlockState state = client.world.getBlockState(blockPos);
|
||||
if (!state.isAir())
|
||||
return null;
|
||||
BlockState adjacentBlockState = client.world.getBlockState(blockPos.offset(direction.getOpposite()));
|
||||
if (adjacentBlockState.isAir() || adjacentBlockState.getBlock() instanceof FluidBlock || (vector.getX() == 0 && vector.getZ() == 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BlockHitResult(client.crosshairTarget.getPos(), direction, blockPos, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static @NotNull BlockHitResult withSideForReacharound(@NotNull BlockHitResult result, @Nullable ItemStack stack)
|
||||
{
|
||||
if (stack == null || stack.isEmpty() || !(stack.getItem() instanceof BlockItem))
|
||||
return result;
|
||||
return withSideForReacharound(result, Block.getBlockFromItem(stack.getItem()));
|
||||
}
|
||||
|
||||
public static @NotNull BlockHitResult withSideForReacharound(@NotNull BlockHitResult result, @NotNull Block block)
|
||||
{
|
||||
if (block instanceof SlabBlock)
|
||||
result = result.withSide(Direction.DOWN);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -10,14 +10,20 @@
|
||||
package me.lambdaurora.lambdacontrols.client.compat;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a compatibility handler for a mod.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.2.0
|
||||
* @version 1.3.2
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public interface CompatHandler
|
||||
@@ -33,10 +39,58 @@ public interface CompatHandler
|
||||
* Returns whether the mouse is required on the specified screen.
|
||||
*
|
||||
* @param screen The screen.
|
||||
* @return True if the mouse is requried on the specified screen, else false.
|
||||
* @return True if the mouse is required on the specified screen, else false.
|
||||
*/
|
||||
default boolean requireMouseOnScreen(Screen screen)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current slot is a creative slot or not.
|
||||
*
|
||||
* @param screen The screen.
|
||||
* @param slot The slot to check.
|
||||
* @return True if the slot is a creative slot, else false.
|
||||
*/
|
||||
default boolean isCreativeSlot(@NotNull HandledScreen screen, @NotNull Slot slot)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a custom translation key to make custom attack action strings on the HUD.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param placeResult The last place block result.
|
||||
* @return Null if untouched, else a translation key.
|
||||
*/
|
||||
default String getAttackActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a custom translation key to make custom use action strings on the HUD.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param placeResult The last place block result.
|
||||
* @return Null if untouched, else a translation key.
|
||||
*/
|
||||
default String getUseActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the menu back button.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param screen The screen.
|
||||
* @return True if the handle was fired and succeed, else false.
|
||||
*/
|
||||
default boolean handleMenuBack(@NotNull MinecraftClient client, @NotNull Screen screen)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package me.lambdaurora.lambdacontrols.client.compat;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import org.aperlambda.lambdacommon.utils.LambdaReflection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents HQM compatibility handler.
|
||||
*
|
||||
* This is bad.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.3.2
|
||||
* @since 1.3.2
|
||||
*/
|
||||
public class HQMCompat implements CompatHandler
|
||||
{
|
||||
public static final String GUI_BASE_CLASS_PATH = "hardcorequesting.client.interfaces.GuiBase";
|
||||
private Optional<Class<?>> guiBaseClass;
|
||||
|
||||
@Override
|
||||
public void handle(@NotNull LambdaControlsClient mod)
|
||||
{
|
||||
this.guiBaseClass = LambdaReflection.getClass(GUI_BASE_CLASS_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requireMouseOnScreen(Screen screen)
|
||||
{
|
||||
return this.guiBaseClass.map(clazz -> clazz.isInstance(screen)).orElse(false);
|
||||
}
|
||||
}
|
||||
@@ -12,18 +12,23 @@ package me.lambdaurora.lambdacontrols.client.compat;
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import me.lambdaurora.lambdacontrols.client.controller.InputManager;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import org.aperlambda.lambdacommon.utils.LambdaReflection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Represents a compatibility handler.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
* @version 1.3.2
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class LambdaControlsCompat
|
||||
@@ -45,10 +50,34 @@ public class LambdaControlsCompat
|
||||
mod.log("Adding REI compatiblity...");
|
||||
HANDLERS.add(new ReiCompat());
|
||||
}
|
||||
if (FabricLoader.getInstance().isModLoaded("hardcorequesting") && LambdaReflection.doesClassExist(HQMCompat.GUI_BASE_CLASS_PATH)) {
|
||||
mod.log("Adding HQM compatibility...");
|
||||
HANDLERS.add(new HQMCompat());
|
||||
}
|
||||
HANDLERS.forEach(handler -> handler.handle(mod));
|
||||
InputManager.loadButtonBindings(mod.config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new compatibility handler.
|
||||
*
|
||||
* @param handler The compatibility handler to register.
|
||||
*/
|
||||
public static void registerCompatHandler(@NotNull CompatHandler handler)
|
||||
{
|
||||
HANDLERS.add(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Streams through compatibility handlers.
|
||||
*
|
||||
* @return A stream of compatibility handlers.
|
||||
*/
|
||||
public static Stream<CompatHandler> streamCompatHandlers()
|
||||
{
|
||||
return HANDLERS.stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the mouse is required on the specified screen.
|
||||
*
|
||||
@@ -60,6 +89,57 @@ public class LambdaControlsCompat
|
||||
return HANDLERS.stream().anyMatch(handler -> handler.requireMouseOnScreen(screen));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a custom translation key to make custom attack action strings on the HUD.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param placeResult The last place block result.
|
||||
* @return Null if untouched, else a translation key.
|
||||
*/
|
||||
public static String getAttackActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult)
|
||||
{
|
||||
for (CompatHandler handler : HANDLERS) {
|
||||
String action = handler.getAttackActionAt(client, placeResult);
|
||||
if (action != null) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a custom translation key to make custom use action strings on the HUD.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param placeResult The last place block result.
|
||||
* @return Null if untouched, else a translation key.
|
||||
*/
|
||||
public static String getUseActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult)
|
||||
{
|
||||
for (CompatHandler handler : HANDLERS) {
|
||||
String action = handler.getUseActionAt(client, placeResult);
|
||||
if (action != null) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the menu back button.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param screen The screen.
|
||||
* @return True if the handle was fired and succeed, else false.
|
||||
*/
|
||||
public static boolean handleMenuBack(@NotNull MinecraftClient client, @NotNull Screen screen) {
|
||||
for (CompatHandler handler : HANDLERS) {
|
||||
if (handler.handleMenuBack(client, screen))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether Roughly Enough Items is present.
|
||||
*
|
||||
|
||||
@@ -17,12 +17,14 @@ import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.client.controller.InputHandlers;
|
||||
import me.lambdaurora.lambdacontrols.client.controller.InputManager;
|
||||
import me.lambdaurora.lambdacontrols.client.controller.PressAction;
|
||||
import me.shedaniel.rei.api.REIHelper;
|
||||
import me.shedaniel.rei.api.RecipeCategory;
|
||||
import me.shedaniel.rei.gui.ContainerScreenOverlay;
|
||||
import me.shedaniel.rei.gui.RecipeViewingScreen;
|
||||
import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
|
||||
import me.shedaniel.rei.gui.widget.EntryListWidget;
|
||||
import me.shedaniel.rei.impl.ScreenHelper;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.aperlambda.lambdacommon.utils.LambdaReflection;
|
||||
@@ -37,13 +39,12 @@ import static org.lwjgl.glfw.GLFW.*;
|
||||
* Represents a compatibility handler for REI.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.3.0
|
||||
* @version 1.3.2
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class ReiCompat implements CompatHandler
|
||||
{
|
||||
private static EntryListWidget ENTRY_LIST_WIDGET;
|
||||
public static ButtonBinding TAB_BACK;
|
||||
|
||||
@Override
|
||||
public void handle(@NotNull LambdaControlsClient mod)
|
||||
@@ -106,6 +107,17 @@ public class ReiCompat implements CompatHandler
|
||||
return screen instanceof RecipeViewingScreen || screen instanceof VillagerRecipeViewingScreen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMenuBack(@NotNull MinecraftClient client, @NotNull Screen screen)
|
||||
{
|
||||
if (!isViewingScreen(screen))
|
||||
return false;
|
||||
|
||||
MinecraftClient.getInstance().openScreen(REIHelper.getInstance().getPreviousContainerScreen());
|
||||
ScreenHelper.getLastOverlay().init();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static EntryListWidget getEntryListWidget()
|
||||
{
|
||||
if (ENTRY_LIST_WIDGET == null) {
|
||||
|
||||
@@ -13,11 +13,12 @@ import me.lambdaurora.lambdacontrols.ControlsMode;
|
||||
import me.lambdaurora.lambdacontrols.LambdaControlsConstants;
|
||||
import me.lambdaurora.lambdacontrols.client.HudSide;
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaInput;
|
||||
import me.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat;
|
||||
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
|
||||
import me.lambdaurora.spruceui.hud.Hud;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.util.Window;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -31,26 +32,27 @@ import org.jetbrains.annotations.Nullable;
|
||||
* Represents the LambdaControls HUD.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.3.0
|
||||
* @version 1.3.2
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class LambdaControlsHud extends Hud
|
||||
{
|
||||
private final LambdaControlsClient mod;
|
||||
private MinecraftClient client;
|
||||
private int attackWidth = 0;
|
||||
private int attackButtonWidth = 0;
|
||||
private int dropItemWidth = 0;
|
||||
private int dropItemButtonWidth = 0;
|
||||
private int inventoryWidth = 0;
|
||||
private int inventoryButtonWidth = 0;
|
||||
private int swapHandsWidth = 0;
|
||||
private int swapHandsButtonWidth = 0;
|
||||
private int useWidth = 0;
|
||||
private int useButtonWidth = 0;
|
||||
private int attackWidth = 0;
|
||||
private int attackButtonWidth = 0;
|
||||
private int dropItemWidth = 0;
|
||||
private int dropItemButtonWidth = 0;
|
||||
private int inventoryWidth = 0;
|
||||
private int inventoryButtonWidth = 0;
|
||||
private int swapHandsWidth = 0;
|
||||
private int swapHandsButtonWidth = 0;
|
||||
private int useWidth = 0;
|
||||
private int useButtonWidth = 0;
|
||||
private BlockHitResult placeHitResult;
|
||||
private String attackAction = "";
|
||||
private String placeAction = "";
|
||||
private String attackAction = "";
|
||||
private String placeAction = "";
|
||||
private int ticksDisplayedCrosshair = 0;
|
||||
|
||||
public LambdaControlsHud(@NotNull LambdaControlsClient mod)
|
||||
{
|
||||
@@ -86,6 +88,19 @@ public class LambdaControlsHud extends Hud
|
||||
this.renderFirstSection(matrices, this.mod.config.getHudSide() == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y);
|
||||
this.renderSecondSection(matrices, this.mod.config.getHudSide() == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y);
|
||||
}
|
||||
|
||||
if (this.mod.reacharound.isLastReacharoundVertical()) {
|
||||
// Render crosshair indicator.
|
||||
Window window = this.client.getWindow();
|
||||
String text = "[ ]";
|
||||
|
||||
float scale = Math.min(5, this.ticksDisplayedCrosshair + tickDelta) / 5F;
|
||||
scale *= scale;
|
||||
int opacity = ((int) (255 * scale)) << 24;
|
||||
|
||||
this.client.textRenderer.draw(matrices, text, window.getScaledWidth() / 2.f - this.client.textRenderer.getWidth(text) / 2.f,
|
||||
window.getScaledHeight() / 2.f - 4, 0xCCCCCC | opacity);
|
||||
}
|
||||
}
|
||||
|
||||
public void renderFirstIcons(MatrixStack matrices, int x, int y)
|
||||
@@ -177,7 +192,7 @@ public class LambdaControlsHud extends Hud
|
||||
|
||||
// Update "Use" tip status.
|
||||
if (this.client.crosshairTarget.getType() == HitResult.Type.MISS) {
|
||||
this.placeHitResult = LambdaInput.tryFrontPlace(this.client);
|
||||
this.placeHitResult = this.mod.reacharound.getLastReacharoundResult();
|
||||
this.attackAction = "";
|
||||
this.attackWidth = 0;
|
||||
} else {
|
||||
@@ -190,8 +205,26 @@ public class LambdaControlsHud extends Hud
|
||||
this.attackWidth = this.width(attackAction);
|
||||
}
|
||||
|
||||
ItemStack stack = this.client.player.getMainHandStack();
|
||||
if ((stack == null || stack.isEmpty()) && ((stack = this.client.player.getOffHandStack()) == null || stack.isEmpty())) {
|
||||
if (this.mod.reacharound.isLastReacharoundVertical()) {
|
||||
if (this.ticksDisplayedCrosshair < 5)
|
||||
this.ticksDisplayedCrosshair++;
|
||||
} else {
|
||||
this.ticksDisplayedCrosshair = 0;
|
||||
}
|
||||
|
||||
String customAttackAction = LambdaControlsCompat.getAttackActionAt(this.client, this.placeHitResult);
|
||||
if (customAttackAction != null) {
|
||||
this.attackAction = customAttackAction;
|
||||
this.attackWidth = this.width(customAttackAction);
|
||||
}
|
||||
|
||||
ItemStack stack = null;
|
||||
if (this.client.player != null) {
|
||||
stack = this.client.player.getMainHandStack();
|
||||
if (stack == null || stack.isEmpty())
|
||||
stack = this.client.player.getOffHandStack();
|
||||
}
|
||||
if (stack == null || stack.isEmpty()) {
|
||||
placeAction = "";
|
||||
} else {
|
||||
if (this.placeHitResult != null && stack.getItem() instanceof BlockItem) {
|
||||
@@ -201,6 +234,10 @@ public class LambdaControlsHud extends Hud
|
||||
}
|
||||
}
|
||||
|
||||
String customUseAction = LambdaControlsCompat.getUseActionAt(this.client, this.placeHitResult);
|
||||
if (customUseAction != null)
|
||||
placeAction = customUseAction;
|
||||
|
||||
this.placeAction = placeAction;
|
||||
|
||||
// Cache the "Use" tip width.
|
||||
|
||||
@@ -11,6 +11,7 @@ package me.lambdaurora.lambdacontrols.client.gui;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaInput;
|
||||
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
@@ -24,14 +25,11 @@ import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents the LambdaControls renderer.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.3.0
|
||||
* @version 1.3.2
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class LambdaControlsRenderer
|
||||
@@ -231,7 +229,7 @@ public class LambdaControlsRenderer
|
||||
|
||||
public static void renderVirtualCursor(@NotNull MatrixStack matrices, @NotNull MinecraftClient client)
|
||||
{
|
||||
if (!LambdaControlsClient.get().config.hasVirtualMouse() || client.currentScreen == null)
|
||||
if (!LambdaControlsClient.get().config.hasVirtualMouse() || (client.currentScreen == null || LambdaInput.isScreenInteractive(client.currentScreen)))
|
||||
return;
|
||||
|
||||
int mouseX = (int) (client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth());
|
||||
@@ -240,27 +238,13 @@ public class LambdaControlsRenderer
|
||||
boolean hoverSlot = false;
|
||||
|
||||
if (client.currentScreen instanceof HandledScreen) {
|
||||
HandledScreen inventoryScreen = (HandledScreen) client.currentScreen;
|
||||
HandledScreenAccessor accessor = (HandledScreenAccessor) inventoryScreen;
|
||||
int guiLeft = accessor.getX();
|
||||
int guiTop = accessor.getY();
|
||||
HandledScreenAccessor inventoryScreen = (HandledScreenAccessor) client.currentScreen;
|
||||
int guiLeft = inventoryScreen.getX();
|
||||
int guiTop = inventoryScreen.getY();
|
||||
|
||||
// Finds the closest slot in the GUI within 14 pixels.
|
||||
int finalMouseX = mouseX;
|
||||
int finalMouseY = mouseY;
|
||||
Optional<Pair<Slot, Double>> closestSlot = inventoryScreen.getScreenHandler().slots.parallelStream()
|
||||
.map(slot -> {
|
||||
int x = guiLeft + slot.x + 8;
|
||||
int y = guiTop + slot.y + 8;
|
||||
Slot slot = inventoryScreen.lambdacontrols_getSlotAt(mouseX, mouseY);
|
||||
|
||||
// Distance between the slot and the cursor.
|
||||
double distance = Math.sqrt(Math.pow(x - finalMouseX, 2) + Math.pow(y - finalMouseY, 2));
|
||||
return Pair.of(slot, distance);
|
||||
}).filter(entry -> entry.value <= 9.0)
|
||||
.min(Comparator.comparingDouble(p -> p.value));
|
||||
|
||||
if (closestSlot.isPresent()) {
|
||||
Slot slot = closestSlot.get().key;
|
||||
if (slot != null) {
|
||||
mouseX = guiLeft + slot.x;
|
||||
mouseY = guiTop + slot.y;
|
||||
hoverSlot = true;
|
||||
|
||||
@@ -51,6 +51,7 @@ public class LambdaControlsSettingsScreen extends Screen
|
||||
private final Option autoJumpOption;
|
||||
private final Option fastBlockPlacingOption;
|
||||
private final Option frontBlockPlacingOption;
|
||||
private final Option verticalReacharoundOption;
|
||||
private final Option flyDriftingOption;
|
||||
private final Option flyVerticalDriftingOption;
|
||||
// Controller options
|
||||
@@ -104,8 +105,10 @@ public class LambdaControlsSettingsScreen extends Screen
|
||||
this.autoJumpOption = SpruceBooleanOption.fromVanilla("options.autoJump", Option.AUTO_JUMP, null, true);
|
||||
this.fastBlockPlacingOption = new SpruceBooleanOption("lambdacontrols.menu.fast_block_placing", this.mod.config::hasFastBlockPlacing,
|
||||
this.mod.config::setFastBlockPlacing, new TranslatableText("lambdacontrols.tooltip.fast_block_placing"), true);
|
||||
this.frontBlockPlacingOption = new SpruceBooleanOption("lambdacontrols.menu.front_block_placing", this.mod.config::hasFrontBlockPlacing,
|
||||
this.mod.config::setFrontBlockPlacing, new TranslatableText("lambdacontrols.tooltip.front_block_placing"), true);
|
||||
this.frontBlockPlacingOption = new SpruceBooleanOption("lambdacontrols.menu.reacharound.horizontal", this.mod.config::hasFrontBlockPlacing,
|
||||
this.mod.config::setFrontBlockPlacing, new TranslatableText("lambdacontrols.tooltip.reacharound.horizontal"), true);
|
||||
this.verticalReacharoundOption = new SpruceBooleanOption("lambdacontrols.menu.reacharound.vertical", this.mod.config::hasVerticalReacharound,
|
||||
this.mod.config::setVerticalReacharound, new TranslatableText("lambdacontrols.tooltip.reacharound.vertical"), true);
|
||||
this.flyDriftingOption = new SpruceBooleanOption("lambdacontrols.menu.fly_drifting", this.mod.config::hasFlyDrifting,
|
||||
this.mod.config::setFlyDrifting, new TranslatableText("lambdacontrols.tooltip.fly_drifting"), true);
|
||||
this.flyVerticalDriftingOption = new SpruceBooleanOption("lambdacontrols.menu.fly_drifting_vertical", this.mod.config::hasFlyVerticalDrifting,
|
||||
@@ -239,8 +242,8 @@ public class LambdaControlsSettingsScreen extends Screen
|
||||
this.list.addSingleOptionEntry(this.autoSwitchModeOption);
|
||||
// Gameplay options
|
||||
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.gameplay", true, null));
|
||||
this.list.addSingleOptionEntry(this.autoJumpOption);
|
||||
this.list.addOptionEntry(this.fastBlockPlacingOption, this.frontBlockPlacingOption);
|
||||
this.list.addOptionEntry(this.autoJumpOption, this.fastBlockPlacingOption);
|
||||
this.list.addOptionEntry(this.frontBlockPlacingOption, this.verticalReacharoundOption);
|
||||
this.list.addSingleOptionEntry(this.flyDriftingOption);
|
||||
this.list.addSingleOptionEntry(this.flyVerticalDriftingOption);
|
||||
// Controller options
|
||||
|
||||
@@ -18,14 +18,19 @@ import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.screen.slot.SlotActionType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Represents the mixin for the class ContainerScreen.
|
||||
*/
|
||||
@@ -41,6 +46,12 @@ public abstract class HandledScreenMixin implements HandledScreenAccessor
|
||||
@Invoker("getSlotAt")
|
||||
public abstract Slot lambdacontrols_getSlotAt(double posX, double posY);
|
||||
|
||||
@Invoker("isClickOutsideBounds")
|
||||
public abstract boolean lambdacontrols_isClickOutsideBounds(double mouseX, double mouseY, int x, int y, int button);
|
||||
|
||||
@Invoker("onMouseClick")
|
||||
public abstract void lambdacontrols_onMouseClick(@Nullable Slot slot, int slotId, int clickData, SlotActionType actionType);
|
||||
|
||||
@Inject(method = "render", at = @At("RETURN"))
|
||||
public void onRender(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci)
|
||||
{
|
||||
|
||||
@@ -11,9 +11,8 @@ package me.lambdaurora.lambdacontrols.client.mixin;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.LambdaControlsFeature;
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaInput;
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaReacharound;
|
||||
import me.lambdaurora.lambdacontrols.client.gui.LambdaControlsRenderer;
|
||||
import me.lambdaurora.lambdacontrols.client.util.FrontBlockPlaceResultAccessor;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
@@ -40,7 +39,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(MinecraftClient.class)
|
||||
public abstract class MinecraftClientMixin implements FrontBlockPlaceResultAccessor
|
||||
public abstract class MinecraftClientMixin
|
||||
{
|
||||
@Shadow
|
||||
@Nullable
|
||||
@@ -65,18 +64,10 @@ public abstract class MinecraftClientMixin implements FrontBlockPlaceResultAcces
|
||||
@Shadow
|
||||
private int itemUseCooldown;
|
||||
|
||||
private BlockHitResult lambdacontrols_frontBlockPlaceResult = null;
|
||||
|
||||
private BlockPos lambdacontrols_lastTargetPos;
|
||||
private Vec3d lambdacontrols_lastPos;
|
||||
private Direction lambdacontrols_lastTargetSide;
|
||||
|
||||
@Override
|
||||
public @Nullable BlockHitResult lambdacontrols_getFrontBlockPlaceResult()
|
||||
{
|
||||
return this.lambdacontrols_frontBlockPlaceResult;
|
||||
}
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void onInit(CallbackInfo ci)
|
||||
{
|
||||
@@ -88,7 +79,7 @@ public abstract class MinecraftClientMixin implements FrontBlockPlaceResultAcces
|
||||
{
|
||||
if (this.player == null)
|
||||
return;
|
||||
this.lambdacontrols_frontBlockPlaceResult = LambdaInput.tryFrontPlace(((MinecraftClient) (Object) this));
|
||||
|
||||
if (!LambdaControlsFeature.FAST_BLOCK_PLACING.isAvailable())
|
||||
return;
|
||||
if (this.lambdacontrols_lastPos == null)
|
||||
@@ -131,7 +122,8 @@ public abstract class MinecraftClientMixin implements FrontBlockPlaceResultAcces
|
||||
}
|
||||
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/GameRenderer;render(FJZ)V", shift = At.Shift.AFTER))
|
||||
private void renderVirtualCursor(boolean fullRender, CallbackInfo ci) {
|
||||
private void renderVirtualCursor(boolean fullRender, CallbackInfo ci)
|
||||
{
|
||||
LambdaControlsRenderer.renderVirtualCursor(new MatrixStack(), (MinecraftClient) (Object) this);
|
||||
}
|
||||
|
||||
@@ -144,15 +136,15 @@ public abstract class MinecraftClientMixin implements FrontBlockPlaceResultAcces
|
||||
@Inject(method = "doItemUse()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/hit/HitResult;getType()Lnet/minecraft/util/hit/HitResult$Type;"), locals = LocalCapture.CAPTURE_FAILEXCEPTION, cancellable = true)
|
||||
private void onItemUse(CallbackInfo ci, Hand[] hands, int handCount, int handIndex, Hand hand, ItemStack stackInHand)
|
||||
{
|
||||
if (!stackInHand.isEmpty() && this.player.pitch > 35.0F && LambdaControlsFeature.FRONT_BLOCK_PLACING.isAvailable()) {
|
||||
if (!stackInHand.isEmpty() && this.player.pitch > 35.0F && LambdaControlsClient.get().reacharound.isReacharoundAvailable()) {
|
||||
if (this.crosshairTarget != null && this.crosshairTarget.getType() == HitResult.Type.MISS && this.player.isOnGround()) {
|
||||
if (!stackInHand.isEmpty() && stackInHand.getItem() instanceof BlockItem) {
|
||||
BlockHitResult hitResult = LambdaInput.tryFrontPlace(((MinecraftClient) (Object) this));
|
||||
BlockHitResult hitResult = LambdaControlsClient.get().reacharound.getLastReacharoundResult();
|
||||
|
||||
if (hitResult == null)
|
||||
return;
|
||||
|
||||
hitResult = LambdaInput.withSideForFrontPlace(hitResult, stackInHand);
|
||||
hitResult = LambdaReacharound.withSideForReacharound(hitResult, stackInHand);
|
||||
|
||||
int previousStackCount = stackInHand.getCount();
|
||||
ActionResult result = this.interactionManager.interactBlock(this.player, this.world, hand, hitResult);
|
||||
|
||||
@@ -13,12 +13,16 @@ import me.lambdaurora.lambdacontrols.ControlsMode;
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaControlsConfig;
|
||||
import me.lambdaurora.lambdacontrols.client.util.MouseAccessor;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.Mouse;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
/**
|
||||
* Adds extra access to the mouse.
|
||||
@@ -26,14 +30,31 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@Mixin(Mouse.class)
|
||||
public abstract class MouseMixin implements MouseAccessor
|
||||
{
|
||||
@Shadow
|
||||
@Final
|
||||
private MinecraftClient client;
|
||||
|
||||
@Invoker("onCursorPos")
|
||||
public abstract void lambdacontrols_onCursorPos(long window, double x, double y);
|
||||
|
||||
@Inject(method = "isCursorLocked", at = @At("HEAD"), cancellable = true)
|
||||
private void isCursorLocked(CallbackInfoReturnable<Boolean> ci)
|
||||
{
|
||||
if (client.currentScreen == null) {
|
||||
LambdaControlsConfig config = LambdaControlsClient.get().config;
|
||||
if (config.getControlsMode() == ControlsMode.CONTROLLER && config.hasVirtualMouse()) {
|
||||
ci.setReturnValue(true);
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "lockCursor", at = @At("HEAD"), cancellable = true)
|
||||
private void onMouseLocked(CallbackInfo ci)
|
||||
private void onCursorLocked(CallbackInfo ci)
|
||||
{
|
||||
LambdaControlsConfig config = LambdaControlsClient.get().config;
|
||||
if (config.getControlsMode() == ControlsMode.TOUCHSCREEN || config.hasVirtualMouse())
|
||||
if (config.getControlsMode() == ControlsMode.TOUCHSCREEN
|
||||
|| (config.getControlsMode() == ControlsMode.CONTROLLER && config.hasVirtualMouse()))
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
package me.lambdaurora.lambdacontrols.client.mixin;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaInput;
|
||||
import me.lambdaurora.lambdacontrols.client.util.FrontBlockPlaceResultAccessor;
|
||||
import me.lambdaurora.lambdacontrols.client.LambdaReacharound;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
@@ -74,9 +73,9 @@ public abstract class WorldRendererMixin
|
||||
Profiler profiler, Vec3d cameraPos, double x, double y, double z, Matrix4f modelMatrix, boolean bl, Frustum frustum2, boolean bl3,
|
||||
VertexConsumerProvider.Immediate immediate)
|
||||
{
|
||||
if (this.client.crosshairTarget == null || this.client.crosshairTarget.getType() != HitResult.Type.MISS || !LambdaControlsClient.get().config.shouldRenderFrontBlockOutline())
|
||||
if (this.client.crosshairTarget == null || this.client.crosshairTarget.getType() != HitResult.Type.MISS || !LambdaControlsClient.get().config.shouldRenderReacharoundOutline())
|
||||
return;
|
||||
BlockHitResult result = ((FrontBlockPlaceResultAccessor) client).lambdacontrols_getFrontBlockPlaceResult();
|
||||
BlockHitResult result = LambdaControlsClient.get().reacharound.getLastReacharoundResult();
|
||||
if (result == null)
|
||||
return;
|
||||
BlockPos blockPos = result.getBlockPos();
|
||||
@@ -85,14 +84,14 @@ public abstract class WorldRendererMixin
|
||||
if (stack == null || !(stack.getItem() instanceof BlockItem))
|
||||
return;
|
||||
Block block = ((BlockItem) stack.getItem()).getBlock();
|
||||
result = LambdaInput.withSideForFrontPlace(result, block);
|
||||
result = LambdaReacharound.withSideForReacharound(result, block);
|
||||
ItemPlacementContext context = new ItemPlacementContext(new ItemUsageContext(this.client.player, Hand.MAIN_HAND, result));
|
||||
VertexConsumer vertexConsumer = immediate.getBuffer(RenderLayer.getLines());
|
||||
BlockState placementState = block.getPlacementState(context);
|
||||
if (placementState == null)
|
||||
return;
|
||||
VoxelShape outlineShape = placementState.getOutlineShape(this.client.world, blockPos, ShapeContext.of(camera.getFocusedEntity()));
|
||||
int[] color = LambdaControlsClient.get().config.getFrontBlockOutlineColor();
|
||||
int[] color = LambdaControlsClient.get().config.getReacharoundOutlineColor();
|
||||
drawShapeOutline(matrices, vertexConsumer, outlineShape, (double) blockPos.getX() - x, (double) blockPos.getY() - y, (double) blockPos.getZ() - z, color[0] / 255.f, color[1] / 255.f, color[2] / 255.f, color[3] / 255.f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package me.lambdaurora.lambdacontrols.client.ring;
|
||||
|
||||
/**
|
||||
* Represents a key binding ring.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.4.0
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public class KeyBindingRing
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package me.lambdaurora.lambdacontrols.client.util;
|
||||
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents an accessor of the BlockHitResult for the front block placing feature.
|
||||
* <p>
|
||||
* It is implemented by {@link net.minecraft.client.MinecraftClient}.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.2.0
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public interface FrontBlockPlaceResultAccessor
|
||||
{
|
||||
/**
|
||||
* Returns the {@link BlockHitResult} if a block can be placed with the front block placing feature.
|
||||
*
|
||||
* @return If possible a {@link BlockHitResult}, else a null value.
|
||||
*/
|
||||
@Nullable BlockHitResult lambdacontrols_getFrontBlockPlaceResult();
|
||||
}
|
||||
@@ -10,6 +10,8 @@
|
||||
package me.lambdaurora.lambdacontrols.client.util;
|
||||
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.screen.slot.SlotActionType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents an accessor to AbstractContainerScreen.
|
||||
@@ -38,4 +40,16 @@ public interface HandledScreenAccessor
|
||||
* @return The slot at the specified position.
|
||||
*/
|
||||
Slot lambdacontrols_getSlotAt(double pos_x, double pos_y);
|
||||
|
||||
boolean lambdacontrols_isClickOutsideBounds(double mouseX, double mouseY, int x, int y, int button);
|
||||
|
||||
/**
|
||||
* Handles a mouse click on the specified slot.
|
||||
*
|
||||
* @param slot The slot instance.
|
||||
* @param slotId The slot id.
|
||||
* @param clickData The click data.
|
||||
* @param actionType The action type.
|
||||
*/
|
||||
void lambdacontrols_onMouseClick(@Nullable Slot slot, int slotId, int clickData, SlotActionType actionType);
|
||||
}
|
||||
|
||||
@@ -82,13 +82,14 @@
|
||||
"lambdacontrols.menu.fast_block_placing": "Fast Block Placing",
|
||||
"lambdacontrols.menu.fly_drifting": "Fly Drifting",
|
||||
"lambdacontrols.menu.fly_drifting_vertical": "Vertical Fly Drifting",
|
||||
"lambdacontrols.menu.front_block_placing": "Front Block Placing",
|
||||
"lambdacontrols.menu.hud_enable": "Enable HUD",
|
||||
"lambdacontrols.menu.hud_side": "HUD Side",
|
||||
"lambdacontrols.menu.invert_right_x_axis": "Invert Right X",
|
||||
"lambdacontrols.menu.invert_right_y_axis": "Invert Right Y",
|
||||
"lambdacontrols.menu.keyboard_controls": "Keyboard Controls...",
|
||||
"lambdacontrols.menu.mouse_speed": "Mouse Speed",
|
||||
"lambdacontrols.menu.reacharound.horizontal": "Front Block Placing",
|
||||
"lambdacontrols.menu.reacharound.vertical": "Vertical Reacharound",
|
||||
"lambdacontrols.menu.reload_controller_mappings": "Reload Controller Mappings",
|
||||
"lambdacontrols.menu.rotation_speed": "Rotation Speed",
|
||||
"lambdacontrols.menu.title": "LambdaControls - Settings",
|
||||
@@ -111,12 +112,13 @@
|
||||
"lambdacontrols.tooltip.fast_block_placing": "While flying in creative mode, enables fast block placing depending on your speed. §cOn some servers this might be considered as cheating.",
|
||||
"lambdacontrols.tooltip.fly_drifting": "While flying, enables Vanilla drifting/inertia.",
|
||||
"lambdacontrols.tooltip.fly_drifting_vertical": "While flying, enables Vanilla vertical drifting/intertia.",
|
||||
"lambdacontrols.tooltip.front_block_placing": "Enables front block placing, §cmight be considered cheating on some servers§r.",
|
||||
"lambdacontrols.tooltip.hud_enable": "Toggles the on-screen controller button indicator.",
|
||||
"lambdacontrols.tooltip.hud_side": "The position of the HUD.",
|
||||
"lambdacontrols.tooltip.mouse_speed": "The controller's emulated mouse speed.",
|
||||
"lambdacontrols.tooltip.rotation_speed": "The camera rotation speed in controller mode.",
|
||||
"lambdacontrols.tooltip.reacharound.horizontal": "Enables front block placing, §cmight be considered cheating on some servers§r.",
|
||||
"lambdacontrols.tooltip.reacharound.vertical": "Enables vertical reacharound, §cmight be considered cheating on some servers§r.",
|
||||
"lambdacontrols.tooltip.reload_controller_mappings": "Reloads the controller mappings file.",
|
||||
"lambdacontrols.tooltip.rotation_speed": "The camera rotation speed in controller mode.",
|
||||
"lambdacontrols.tooltip.unfocused_input": "Allow controller input when the window is not focused.",
|
||||
"lambdacontrols.tooltip.virtual_mouse": "Enable the virtual mouse which is handful in the case of a splitscreen.",
|
||||
"lambdacontrols.virtual_mouse.skin.default_light": "Default Light",
|
||||
|
||||
@@ -81,13 +81,14 @@
|
||||
"lambdacontrols.menu.dead_zone": "Zone morte",
|
||||
"lambdacontrols.menu.fly_drifting": "Inertie de vol",
|
||||
"lambdacontrols.menu.fly_drifting_vertical": "Inertie verticale de vol",
|
||||
"lambdacontrols.menu.front_block_placing": "Placement avant de bloc",
|
||||
"lambdacontrols.menu.hud_enable": "Activer le HUD",
|
||||
"lambdacontrols.menu.hud_side": "Côté du HUD",
|
||||
"lambdacontrols.menu.invert_right_x_axis": "Inverser le stick droit (X)",
|
||||
"lambdacontrols.menu.invert_right_y_axis": "Inverser le stick droit (Y)",
|
||||
"lambdacontrols.menu.keyboard_controls": "Contrôles clavier...",
|
||||
"lambdacontrols.menu.mouse_speed": "Vitesse de la souris",
|
||||
"lambdacontrols.menu.reacharound.horizontal": "Placement avant de bloc",
|
||||
"lambdacontrols.menu.reacharound.vertical": "Placement vertical",
|
||||
"lambdacontrols.menu.reload_controller_mappings": "Recharge la configuration des manettes",
|
||||
"lambdacontrols.menu.rotation_speed": "Vitesse de rotation",
|
||||
"lambdacontrols.menu.title": "LambdaControls - Paramètres",
|
||||
@@ -107,14 +108,16 @@
|
||||
"lambdacontrols.tooltip.controller_type": "Le type de contrôle n'influe que sur les boutons affichés.",
|
||||
"lambdacontrols.tooltip.controls_mode": "Change le mode de contrôle.",
|
||||
"lambdacontrols.tooltip.dead_zone": "Zone morte des axes de la manette.",
|
||||
"lambdacontrols.tooltip.fast_block_placing": "Active le placement rapide de blocs en vol.",
|
||||
"lambdacontrols.tooltip.fly_drifting": "Pendant que le joueur vole, active le glissement Vanilla.",
|
||||
"lambdacontrols.tooltip.fly_drifting_vertical": "Pendant que le joueur vole, active le glissement vertical Vanilla.",
|
||||
"lambdacontrols.tooltip.front_block_placing": "Active le placement avant de blocs, §cpeut être considérer comme de la trice sur certains serveurs§r.",
|
||||
"lambdacontrols.tooltip.hud_enable": "Détermine si l'indicateur des buttons de la manette doit être affiché ou non.",
|
||||
"lambdacontrols.tooltip.hud_side": "Change la position du HUD.",
|
||||
"lambdacontrols.tooltip.mouse_speed": "Change la vitesse de la souris émulée par la manette.",
|
||||
"lambdacontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.",
|
||||
"lambdacontrols.tooltip.reacharound.horizontal": "Active le placement avant de blocs, §cpeut être considérer comme de la triche sur certains serveurs§r.",
|
||||
"lambdacontrols.tooltip.reacharound.vertical": "Active le placement vertical de blocs, c'est-à-dire de blocs en dessous du bloc sur lequel vous êtes placé, §cpeut être considérer comme de la triche sur certains serveurs§r.",
|
||||
"lambdacontrols.tooltip.reload_controller_mappings": "Recharge le fichier de configuration des manettes.",
|
||||
"lambdacontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.",
|
||||
"lambdacontrols.tooltip.unfocused_input": "Autorise les entrées manette quand la fenêtre n'est pas sélectionnée.",
|
||||
"lambdacontrols.tooltip.virtual_mouse": "Active la souris virtuelle qui est pratique dans le cas d'un écran partagé.",
|
||||
"lambdacontrols.virtual_mouse.skin.default_light": "défaut clair",
|
||||
|
||||
@@ -81,13 +81,14 @@
|
||||
"lambdacontrols.menu.dead_zone": "Zone morte",
|
||||
"lambdacontrols.menu.fly_drifting": "Inertie de vol",
|
||||
"lambdacontrols.menu.fly_drifting_vertical": "Inertie verticale de vol",
|
||||
"lambdacontrols.menu.front_block_placing": "Placement avant de bloc",
|
||||
"lambdacontrols.menu.hud_enable": "Activer le HUD",
|
||||
"lambdacontrols.menu.hud_side": "Côté du HUD",
|
||||
"lambdacontrols.menu.invert_right_x_axis": "Inverser le stick droit (X)",
|
||||
"lambdacontrols.menu.invert_right_y_axis": "Inverser le stick droit (Y)",
|
||||
"lambdacontrols.menu.keyboard_controls": "Contrôles clavier...",
|
||||
"lambdacontrols.menu.mouse_speed": "Vitesse de la souris",
|
||||
"lambdacontrols.menu.reacharound.horizontal": "Placement avant de bloc",
|
||||
"lambdacontrols.menu.reacharound.vertical": "Placement vertical",
|
||||
"lambdacontrols.menu.reload_controller_mappings": "Recharge la configuration des manettes",
|
||||
"lambdacontrols.menu.rotation_speed": "Vitesse de rotation",
|
||||
"lambdacontrols.menu.title": "LambdaControls - Paramètres",
|
||||
@@ -107,14 +108,16 @@
|
||||
"lambdacontrols.tooltip.controller_type": "Le type de contrôle n'influe que sur les boutons affichés.",
|
||||
"lambdacontrols.tooltip.controls_mode": "Change le mode de contrôle.",
|
||||
"lambdacontrols.tooltip.dead_zone": "Zone morte des axes de la manette.",
|
||||
"lambdacontrols.tooltip.fast_block_placing": "Active le placement rapide de blocs en vol.",
|
||||
"lambdacontrols.tooltip.fly_drifting": "Pendant que le joueur vole, active le glissement Vanilla.",
|
||||
"lambdacontrols.tooltip.fly_drifting_vertical": "Pendant que le joueur vole, active le glissement vertical Vanilla.",
|
||||
"lambdacontrols.tooltip.front_block_placing": "Active le placement avant de blocs, §cpeut être considérer comme de la trice sur certains serveurs§r.",
|
||||
"lambdacontrols.tooltip.hud_enable": "Détermine si l'indicateur des buttons de la manette doit être affiché ou non.",
|
||||
"lambdacontrols.tooltip.hud_side": "Change la position du HUD.",
|
||||
"lambdacontrols.tooltip.mouse_speed": "Change la vitesse de la souris émulée par la manette.",
|
||||
"lambdacontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.",
|
||||
"lambdacontrols.tooltip.reacharound.horizontal": "Active le placement avant de blocs, §cpeut être considérer comme de la triche sur certains serveurs§r.",
|
||||
"lambdacontrols.tooltip.reacharound.vertical": "Active le placement vertical de blocs, c'est-à-dire de blocs en dessous du bloc sur lequel vous êtes placé, §cpeut être considérer comme de la triche sur certains serveurs§r.",
|
||||
"lambdacontrols.tooltip.reload_controller_mappings": "Recharge le fichier de configuration des manettes.",
|
||||
"lambdacontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.",
|
||||
"lambdacontrols.tooltip.unfocused_input": "Autorise les entrées manette quand la fenêtre n'est pas sélectionnée.",
|
||||
"lambdacontrols.tooltip.virtual_mouse": "Active la souris virtuelle qui est pratique dans le cas d'un écran partagé.",
|
||||
"lambdacontrols.virtual_mouse.skin.default_light": "défaut clair",
|
||||
|
||||
@@ -21,9 +21,11 @@ auto_switch_mode = false
|
||||
drifting = false
|
||||
# Enables vertical fly drifting.
|
||||
vertical_drifting = true
|
||||
[gameplay.front_block_placing]
|
||||
[gameplay.reacharound]
|
||||
# Enables front block placing like in Bedrock Edition.
|
||||
enabled = false
|
||||
horizontal = false
|
||||
# Enables vertical reacharound.
|
||||
vertical = false
|
||||
# Enables front block placing outline.
|
||||
outline = true
|
||||
# The color in a hexadecimal format of the outline.
|
||||
|
||||
@@ -34,21 +34,25 @@
|
||||
"fabricloader": ">=0.8.0",
|
||||
"fabric": "*",
|
||||
"minecraft": ">=1.16",
|
||||
"spruceui": ">=1.5.1"
|
||||
"spruceui": ">=1.5.2"
|
||||
},
|
||||
"recommends": {
|
||||
"modmenu": ">=1.12.2",
|
||||
"okzoomer": ">=4.0.0"
|
||||
"modmenu": ">=1.12.2"
|
||||
},
|
||||
"suggests": {
|
||||
"flamingo": "*",
|
||||
"roughlyenoughitems": ">=4.5.5"
|
||||
"roughlyenoughitems": ">=4.5.5",
|
||||
"okzoomer": ">=4.0.0"
|
||||
},
|
||||
"breaks": {
|
||||
"modmenu": "<1.12.2",
|
||||
"optifabric": "*"
|
||||
},
|
||||
"custom": {
|
||||
"modmenu:clientsideOnly": true
|
||||
"modmenu:clientsideOnly": true,
|
||||
"modupdater": {
|
||||
"strategy": "curseforge",
|
||||
"projectID": 354231
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ org.gradle.jvmargs=-Xmx1G
|
||||
loader_version=0.8.8+build.202
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.3.0
|
||||
maven_group = me.lambdaurora
|
||||
mod_version = 1.3.2
|
||||
maven_group = me.lambdaurora.lambdacontrols
|
||||
archives_base_name = lambdacontrols
|
||||
|
||||
# Dependencies
|
||||
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
|
||||
fabric_version=0.14.0+build.371-1.16
|
||||
spruceui_version=1.5.1
|
||||
spruceui_version=1.5.2
|
||||
modmenu_version=1.12.2+build.17
|
||||
|
||||
Reference in New Issue
Block a user