mirror of
https://github.com/CompeyDev/elytra-lock-fabric.git
synced 2024-12-12 04:40:41 +00:00
chore(release): elytra-lock v0.1.0+1.20.6
This commit is contained in:
parent
4ea6e94920
commit
7571bd68f6
13 changed files with 298 additions and 30 deletions
|
@ -49,7 +49,7 @@ dependencies {
|
||||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||||
|
|
||||||
modImplementation "dev.isxander.yacl:yet-another-config-lib-fabric:${project.yacl_version}"
|
modImplementation "dev.isxander:yet-another-config-lib:${project.yacl_version}"
|
||||||
modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}"
|
modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ processResources {
|
||||||
inputs.property "version", project.version
|
inputs.property "version", project.version
|
||||||
filesMatching("fabric.mod.json") {
|
filesMatching("fabric.mod.json") {
|
||||||
expand "version": project.version,
|
expand "version": project.version,
|
||||||
"java_version": ">=17",
|
"java_version": ">=21",
|
||||||
"minecraft_version": "~${project.minecraft_version}",
|
"minecraft_version": "~${project.minecraft_version}",
|
||||||
"loader_version": ">=${project.loader_version}"
|
"loader_version": ">=${project.loader_version}"
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ org.gradle.parallel=true
|
||||||
|
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check these on https://fabricmc.net/develop
|
# check these on https://fabricmc.net/develop
|
||||||
minecraft_version=1.20.4
|
minecraft_version=1.20.6
|
||||||
yarn_mappings=1.20.4+build.3
|
yarn_mappings=1.20.6+build.3
|
||||||
loader_version=0.15.11
|
loader_version=0.15.11
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
|
@ -14,6 +14,6 @@ maven_group=xyz.devcomp
|
||||||
archives_base_name=elytra-lock
|
archives_base_name=elytra-lock
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
fabric_version=0.97.0+1.20.4
|
fabric_version=0.99.4+1.20.6
|
||||||
yacl_version=3.3.2+1.20.4
|
yacl_version=3.4.4+1.20.6-fabric
|
||||||
modmenu_version=9.0.0
|
modmenu_version=10.0.0-beta.1
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
[versions]
|
|
||||||
minecraft = "1.20.2"
|
|
||||||
quilt_mappings = "1.20.2+build.3"
|
|
||||||
quilt_loader = "0.26.0-beta.1"
|
|
||||||
|
|
||||||
quilted_fabric_api = "8.0.0-alpha.6+0.91.6-1.20.2"
|
|
||||||
|
|
||||||
mixin_extras = "0.2.0"
|
|
||||||
quilt_parsers = "0.2.1"
|
|
||||||
|
|
||||||
[libraries]
|
|
||||||
minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" }
|
|
||||||
quilt_mappings = { module = "org.quiltmc:quilt-mappings", version.ref = "quilt_mappings" }
|
|
||||||
quilt_loader = { module = "org.quiltmc:quilt-loader", version.ref = "quilt_loader" }
|
|
||||||
|
|
||||||
quilted_fabric_api = { module = "org.quiltmc.quilted-fabric-api:quilted-fabric-api", version.ref = "quilted_fabric_api" }
|
|
||||||
quilted_fabric_api_deprecated = { module = "org.quiltmc.quilted-fabric-api:quilted-fabric-api-deprecated", version.ref = "quilted_fabric_api" }
|
|
||||||
|
|
||||||
[bundles]
|
|
||||||
quilted_fabric_api = ["quilted_fabric_api", "quilted_fabric_api_deprecated"]
|
|
||||||
|
|
||||||
[plugins]
|
|
||||||
quilt_loom = { id = "org.quiltmc.loom", version = "1.6.7" }
|
|
60
remappedSrc/xyz/devcomp/elytralock/ElytraLock.java
Normal file
60
remappedSrc/xyz/devcomp/elytralock/ElytraLock.java
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package xyz.devcomp.elytralock;
|
||||||
|
|
||||||
|
import xyz.devcomp.elytralock.config.ConfigHandler;
|
||||||
|
import xyz.devcomp.elytralock.config.ConfigUtil;
|
||||||
|
import xyz.devcomp.elytralock.events.ClientTickEndHandler;
|
||||||
|
import xyz.devcomp.elytralock.events.HudRenderHandler;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||||
|
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||||
|
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.option.KeyBinding;
|
||||||
|
import net.minecraft.client.util.InputUtil;
|
||||||
|
|
||||||
|
public class ElytraLock implements ClientModInitializer {
|
||||||
|
public static final Logger LOGGER = LoggerFactory.getLogger("Elytra Lock");
|
||||||
|
public static final FabricLoader LOADER = FabricLoader.getInstance();
|
||||||
|
private static KeyBinding lockKeybind;
|
||||||
|
private static boolean locked = false;
|
||||||
|
public static MinecraftClient client;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitializeClient() {
|
||||||
|
LOGGER.info("ElytraLock initializing!");
|
||||||
|
|
||||||
|
lockKeybind = KeyBindingHelper.registerKeyBinding(
|
||||||
|
new KeyBinding("key.elytralock.lock", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_J, "category.elytralock"));
|
||||||
|
LOGGER.info("Registered keybind for locking elytra");
|
||||||
|
|
||||||
|
client = MinecraftClient.getInstance();
|
||||||
|
|
||||||
|
if (ConfigUtil.isYaclLoaded()) {
|
||||||
|
LOGGER.info("YACL_v3 is loaded, loading elytra toggle");
|
||||||
|
locked = new ConfigHandler().getInstance().toggle;
|
||||||
|
} else {
|
||||||
|
LOGGER.warn("YACL_v3 is not loaded, not persisting elytra toggle");
|
||||||
|
}
|
||||||
|
|
||||||
|
HudRenderCallback.EVENT.register(new HudRenderHandler());
|
||||||
|
ClientTickEvents.END_CLIENT_TICK.register(new ClientTickEndHandler());
|
||||||
|
|
||||||
|
LOGGER.info("Registered HUD_RENDER & END_CLIENT_TICK events successfully!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isLocked() {
|
||||||
|
if (lockKeybind.wasPressed()) {
|
||||||
|
locked = !locked;
|
||||||
|
}
|
||||||
|
|
||||||
|
return locked;
|
||||||
|
}
|
||||||
|
}
|
37
remappedSrc/xyz/devcomp/elytralock/config/ConfigHandler.java
Normal file
37
remappedSrc/xyz/devcomp/elytralock/config/ConfigHandler.java
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package xyz.devcomp.elytralock.config;
|
||||||
|
|
||||||
|
import xyz.devcomp.elytralock.ElytraLock;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
import dev.isxander.yacl3.config.v2.api.ConfigClassHandler;
|
||||||
|
import dev.isxander.yacl3.config.v2.api.serializer.GsonConfigSerializerBuilder;
|
||||||
|
|
||||||
|
public class ConfigHandler {
|
||||||
|
private boolean isLoaded = false;
|
||||||
|
public static final ConfigClassHandler<ConfigModel> HANDLER = ConfigClassHandler.createBuilder(ConfigModel.class)
|
||||||
|
.id(new Identifier("elytralock", "config"))
|
||||||
|
.serializer(config -> GsonConfigSerializerBuilder.create(config)
|
||||||
|
.setPath(ElytraLock.LOADER.getConfigDir().resolve("elytra-lock.json"))
|
||||||
|
.setJson5(true)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
private void loadConfig() {
|
||||||
|
if (!this.isLoaded) {
|
||||||
|
ElytraLock.LOGGER.info("ElytraLock config not loaded, loading");
|
||||||
|
this.isLoaded = HANDLER.load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Screen showGui(Screen parent) {
|
||||||
|
this.loadConfig();
|
||||||
|
return HANDLER.generateGui().generateScreen(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigModel getInstance() {
|
||||||
|
this.loadConfig();
|
||||||
|
return HANDLER.instance();
|
||||||
|
}
|
||||||
|
}
|
11
remappedSrc/xyz/devcomp/elytralock/config/ConfigModel.java
Normal file
11
remappedSrc/xyz/devcomp/elytralock/config/ConfigModel.java
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package xyz.devcomp.elytralock.config;
|
||||||
|
|
||||||
|
import dev.isxander.yacl3.config.v2.api.SerialEntry;
|
||||||
|
import dev.isxander.yacl3.config.v2.api.autogen.*;
|
||||||
|
|
||||||
|
public class ConfigModel {
|
||||||
|
@SerialEntry(comment = "The status of the lock toggle")
|
||||||
|
@AutoGen(category = "elytralock")
|
||||||
|
@TickBox
|
||||||
|
public boolean toggle = false;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package xyz.devcomp.elytralock.config;
|
||||||
|
|
||||||
|
import xyz.devcomp.elytralock.ElytraLock;
|
||||||
|
|
||||||
|
public class ConfigUtil {
|
||||||
|
public static boolean isYaclLoaded() {
|
||||||
|
return ElytraLock.LOADER.isModLoaded("yet_another_config_lib_v3");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package xyz.devcomp.elytralock.events;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents.EndTick;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import xyz.devcomp.elytralock.ElytraLock;
|
||||||
|
import xyz.devcomp.elytralock.util.RunOnceOnToggle;
|
||||||
|
|
||||||
|
public class ClientTickEndHandler implements EndTick {
|
||||||
|
private static RunOnceOnToggle<MinecraftClient> impl = new RunOnceOnToggle<MinecraftClient>(
|
||||||
|
new Consumer<MinecraftClient>() {
|
||||||
|
public void accept(MinecraftClient client) {
|
||||||
|
PlayerInventory inventory = client.player.getInventory();
|
||||||
|
|
||||||
|
// 0 -> boots
|
||||||
|
// 1 -> leggings
|
||||||
|
// 2 -> chestplate
|
||||||
|
// 3 -> helmet
|
||||||
|
ItemStack chestArmor = inventory.armor.get(2);
|
||||||
|
if (chestArmor.isOf(Items.ELYTRA)) {
|
||||||
|
ElytraLock.LOGGER.info("Detected player wearing elytra even though it's locked");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public void onEndTick(MinecraftClient client) {
|
||||||
|
impl.run(client);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package xyz.devcomp.elytralock.events;
|
||||||
|
|
||||||
|
import xyz.devcomp.elytralock.ElytraLock;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
||||||
|
import net.minecraft.client.gui.DrawContext;
|
||||||
|
import net.minecraft.client.util.Window;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class HudRenderHandler implements HudRenderCallback {
|
||||||
|
public static final int WIDTH = 16;
|
||||||
|
public static final int HEIGHT = 16;
|
||||||
|
|
||||||
|
public void onHudRender(DrawContext context, float delta) {
|
||||||
|
// FIXME: Perhaps don't check whether the elytra is locked on every frame
|
||||||
|
Identifier icon = new Identifier("elytra-lock",
|
||||||
|
"textures/gui/" + (ElytraLock.isLocked() ? "locked" : "unlocked") + ".png");
|
||||||
|
|
||||||
|
Window window = ElytraLock.client.getWindow();
|
||||||
|
int width = window.getScaledWidth(), height = window.getScaledHeight();
|
||||||
|
|
||||||
|
context.drawTexture(icon, (width / 2) + 95, height - HEIGHT - 3, 0, 0, WIDTH, HEIGHT, WIDTH, HEIGHT);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package xyz.devcomp.elytralock.integrations;
|
||||||
|
|
||||||
|
import xyz.devcomp.elytralock.config.ConfigHandler;
|
||||||
|
import xyz.devcomp.elytralock.config.ConfigUtil;
|
||||||
|
|
||||||
|
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||||
|
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||||
|
|
||||||
|
public class ModMenuIntegration implements ModMenuApi {
|
||||||
|
@Override
|
||||||
|
public ConfigScreenFactory<?> getModConfigScreenFactory() {
|
||||||
|
return (parent) -> {
|
||||||
|
if (!ConfigUtil.isYaclLoaded())
|
||||||
|
return parent;
|
||||||
|
return new ConfigHandler().showGui(parent);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package xyz.devcomp.elytralock.mixin;
|
||||||
|
|
||||||
|
import xyz.devcomp.elytralock.ElytraLock;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.mutable.MutableObject;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.network.ClientPlayerInteractionManager;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
@Mixin(ClientPlayerInteractionManager.class)
|
||||||
|
public class ClientPlayerInteractionManagerMixin {
|
||||||
|
@Inject(method = "interactItem(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/util/Hand;)Lnet/minecraft/util/ActionResult;", at = @At(value = "INVOKE", target = "net/minecraft/client/network/ClientPlayerInteractionManager.sendSequencedPacket (Lnet/minecraft/client/world/ClientWorld;Lnet/minecraft/client/network/SequencedPacketCreator;)V"), cancellable = true)
|
||||||
|
private void skipElytra(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> info, @Local MutableObject<ActionResult> mutableObject) {
|
||||||
|
ItemStack itemStack = player.getStackInHand(hand);
|
||||||
|
if (itemStack.isOf(Items.ELYTRA) && ElytraLock.isLocked()) {
|
||||||
|
ElytraLock.LOGGER.info("Skipping sending PlayerInteractItemC2SPacket for locked elytra");
|
||||||
|
ElytraLock.client.inGameHud.getChatHud().addMessage(Text.translatable("elytralock.chat.lockedMessage"));
|
||||||
|
|
||||||
|
mutableObject.setValue(ActionResult.FAIL);
|
||||||
|
info.setReturnValue((ActionResult) mutableObject.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package xyz.devcomp.elytralock.mixin;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import xyz.devcomp.elytralock.ElytraLock;
|
||||||
|
import xyz.devcomp.elytralock.util.RunOnceOnToggle;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
|
||||||
|
// TODO: In the future, make fall flying prevention and elytra lock separate
|
||||||
|
// Fall flying prevention should be subset of elytra locking which should be
|
||||||
|
// individually toggleable
|
||||||
|
|
||||||
|
@Mixin(PlayerEntity.class)
|
||||||
|
public class PlayerEntityMixin {
|
||||||
|
private static RunOnceOnToggle<String> logOnce = new RunOnceOnToggle<String>(
|
||||||
|
new Consumer<String>() {
|
||||||
|
public void accept(String msg) {
|
||||||
|
ElytraLock.LOGGER.info(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
@Inject(method = "checkFallFlying()Z", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void preventFallFlying(CallbackInfoReturnable<Boolean> info) {
|
||||||
|
if (logOnce.run("Elytra is locked, so preventing fall flying"))
|
||||||
|
info.setReturnValue(false);
|
||||||
|
}
|
||||||
|
}
|
28
remappedSrc/xyz/devcomp/elytralock/util/RunOnceOnToggle.java
Normal file
28
remappedSrc/xyz/devcomp/elytralock/util/RunOnceOnToggle.java
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package xyz.devcomp.elytralock.util;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import xyz.devcomp.elytralock.ElytraLock;
|
||||||
|
|
||||||
|
public class RunOnceOnToggle<T> {
|
||||||
|
private static boolean hasRun = false;
|
||||||
|
private Consumer<T> toRun;
|
||||||
|
|
||||||
|
public RunOnceOnToggle(Consumer<T> toRun) {
|
||||||
|
this.toRun = toRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean run(T param) {
|
||||||
|
boolean isLocked = ElytraLock.isLocked();
|
||||||
|
if (isLocked) {
|
||||||
|
if (!hasRun) {
|
||||||
|
toRun.accept(param);
|
||||||
|
hasRun = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasRun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isLocked;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue