diff --git a/README.md b/README.md
index 755a735..efbe25f 100644
--- a/README.md
+++ b/README.md
@@ -59,7 +59,9 @@ This makes riding horses around path blocks way less frustrating.
Allow swimming while Mounted
Normally Horses will sink in water when you are riding them.\
-This makes you float on the surface as if they weren't mounted
+This makes you float on the surface as if they weren't mounted.\
+The default config turns this ability off for skeleton and zombie horses, and camels.\
+Have you ever seen a camel swim? I think not!
@@ -87,10 +89,12 @@ This prevents them from doing that.
![image](https://i.imgur.com/QTk8w33.gif)
- Sprint + Inventory to open survival inventory
+ Hotkey to open survival inventory
![image](https://i.imgur.com/8oOswAR.png)
-
-*Horse Buff pulls from your Minecraft keybinds, so if you change your inventory/sprint key, that will change what you need to press to access your survival inventory
+* Pre 1.20.2
+ * Horse Buff pulls from your Minecraft keybinds, so if you change your inventory/sprint key, that will change what you need to press to access your survival inventory
+* Post 1.20.2
+ * A keybind for opening your inventory while on a horse has been added. ALT + Inv (ALT + E) is now the default, but you can change it to whatever you like
diff --git a/build.gradle b/build.gradle
index 3c17055..a9a5c9a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,5 @@
plugins {
- id 'fabric-loom' version '0.11-SNAPSHOT'
+ id 'fabric-loom' version '1.4-SNAPSHOT'
id 'maven-publish'
}
@@ -38,11 +38,12 @@ dependencies {
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// Fabric API
- //modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
+ modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modIncludeImplementation(fabricApi.module("fabric-api-base", project.fabric_version))
modIncludeImplementation(fabricApi.module("fabric-rendering-data-attachment-v1", project.fabric_version))
modIncludeImplementation(fabricApi.module("fabric-lifecycle-events-v1", project.fabric_version))
modIncludeImplementation(fabricApi.module("fabric-registry-sync-v0", project.fabric_version))
+ modIncludeImplementation(fabricApi.module("fabric-key-binding-api-v1", project.fabric_version))
// Cloth Config
modIncludeImplementation("me.shedaniel.cloth:cloth-config-fabric:${project.cloth_config_version}"){
diff --git a/gradle.properties b/gradle.properties
index 7f17c33..01c2b4a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -4,9 +4,9 @@ org.gradle.jvmargs=-Xmx1G
# Fabric Properties
# check these on https://fabricmc.net/develop/
-minecraft_version=1.20
-yarn_mappings=1.20+build.1
-loader_version=0.14.21
+minecraft_version=1.20.2
+yarn_mappings=1.20.2+build.4
+loader_version=0.15.0
# Mod Properties
mod_version = 2.1.3
@@ -14,7 +14,7 @@ maven_group = com.HorseBuff
archives_base_name = HorseBuff
# Dependencies
-fabric_version=0.83.0+1.20
-cloth_config_version=11.0.99
-mod_menu_version=7.0.1
+fabric_version=0.91.1+1.20.2
+cloth_config_version=12.0.111
+mod_menu_version=8.0.0
mixinextras_version=0.2.0
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index ffed3a2..a595206 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/src/main/java/net/F53/HorseBuff/ClientInit.java b/src/main/java/net/F53/HorseBuff/ClientInit.java
new file mode 100644
index 0000000..1cf37af
--- /dev/null
+++ b/src/main/java/net/F53/HorseBuff/ClientInit.java
@@ -0,0 +1,20 @@
+package net.F53.HorseBuff;
+
+import net.fabricmc.api.ClientModInitializer;
+import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
+import net.minecraft.client.option.KeyBinding;
+import net.minecraft.client.util.InputUtil;
+import org.lwjgl.glfw.GLFW;
+
+public class ClientInit implements ClientModInitializer {
+
+ public static KeyBinding horsePlayerInventory = KeyBindingHelper.registerKeyBinding(new KeyBinding(
+ "text.HorseBuff.keybinding.horsePlayerInventory",
+ InputUtil.Type.KEYSYM,
+ GLFW.GLFW_KEY_LEFT_ALT,
+ "text.HorseBuff.keybinding.category"
+ ));
+
+ @Override
+ public void onInitializeClient() {}
+}
diff --git a/src/main/java/net/F53/HorseBuff/config/ModConfig.java b/src/main/java/net/F53/HorseBuff/config/ModConfig.java
index 79127f0..4016336 100644
--- a/src/main/java/net/F53/HorseBuff/config/ModConfig.java
+++ b/src/main/java/net/F53/HorseBuff/config/ModConfig.java
@@ -35,7 +35,15 @@ public class ModConfig implements ConfigData{
@ConfigEntry.Category("Client")
@ConfigEntry.Gui.Tooltip
- public boolean swim = true;
+ public boolean swimHorse = true;
+
+ @ConfigEntry.Category("Client")
+ @ConfigEntry.Gui.Tooltip
+ public boolean swimCamel = false;
+
+ @ConfigEntry.Category("Client")
+ @ConfigEntry.Gui.Tooltip
+ public boolean swimDead = false;
@ConfigEntry.Category("Client")
@ConfigEntry.Gui.Tooltip
diff --git a/src/main/java/net/F53/HorseBuff/mixin/Client/InventoryAccessor.java b/src/main/java/net/F53/HorseBuff/mixin/Client/InventoryAccessor.java
index b5062be..02e5340 100644
--- a/src/main/java/net/F53/HorseBuff/mixin/Client/InventoryAccessor.java
+++ b/src/main/java/net/F53/HorseBuff/mixin/Client/InventoryAccessor.java
@@ -11,6 +11,7 @@
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
+import net.F53.HorseBuff.ClientInit;
@Mixin(value = MinecraftClient.class, priority = 960)
public abstract class InventoryAccessor {
@@ -23,7 +24,7 @@ public abstract class InventoryAccessor {
@Redirect(method= "handleInputEvents()V", at = @At(value = "INVOKE", target = "net/minecraft/client/network/ClientPlayerEntity.openRidingInventory ()V"))
void playerInventoryAccess(ClientPlayerEntity instance){
assert this.player != null;
- if (MinecraftClient.getInstance().options.sprintKey.isPressed()) {
+ if (ClientInit.horsePlayerInventory.isPressed()) {
tutorialManager.onInventoryOpened();
setScreen(new InventoryScreen(this.player));
}
diff --git a/src/main/java/net/F53/HorseBuff/mixin/Client/Swim.java b/src/main/java/net/F53/HorseBuff/mixin/Client/Swim.java
new file mode 100644
index 0000000..2bdf5fb
--- /dev/null
+++ b/src/main/java/net/F53/HorseBuff/mixin/Client/Swim.java
@@ -0,0 +1,49 @@
+package net.F53.HorseBuff.mixin.Client;
+
+import net.F53.HorseBuff.config.ModConfig;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.mob.SkeletonHorseEntity;
+import net.minecraft.entity.mob.ZombieHorseEntity;
+import net.minecraft.entity.passive.*;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.registry.tag.FluidTags;
+import net.minecraft.util.math.Vec3d;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(value = LivingEntity.class)
+public class Swim {
+ @Inject(method = "travelControlled", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;travel(Lnet/minecraft/util/math/Vec3d;)V", shift = At.Shift.BEFORE))
+ private void fakeSwim(PlayerEntity controllingPlayer, Vec3d movementInput, CallbackInfo ci) {
+ if (!((Object)this instanceof AbstractHorseEntity)) {return;}
+ AbstractHorseEntity horseInstance = (AbstractHorseEntity) (Object) this;
+ if (!shouldSwim(horseInstance)) {return;}
+
+ if (horseInstance.getFluidHeight(FluidTags.WATER) > horseInstance.getSwimHeight()) {
+ horseInstance.addVelocity(0, 0.08, 0);
+ }
+ }
+
+ @Unique
+ private boolean shouldSwim(AbstractHorseEntity horseInstance) {
+ if (horseInstance instanceof HorseEntity ||
+ horseInstance instanceof DonkeyEntity ||
+ horseInstance instanceof MuleEntity) {
+ return ModConfig.getInstance().swimHorse;
+ }
+
+ if (horseInstance instanceof SkeletonHorseEntity ||
+ horseInstance instanceof ZombieHorseEntity) {
+ return ModConfig.getInstance().swimDead;
+ }
+
+ if (horseInstance instanceof CamelEntity) {
+ return ModConfig.getInstance().swimCamel;
+ }
+
+ return false; // you should never be able to reach this, but if you do it defaults to vanilla behavior
+ }
+}
diff --git a/src/main/java/net/F53/HorseBuff/mixin/Server/Swim.java b/src/main/java/net/F53/HorseBuff/mixin/Server/Swim.java
deleted file mode 100644
index faee91e..0000000
--- a/src/main/java/net/F53/HorseBuff/mixin/Server/Swim.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package net.F53.HorseBuff.mixin.Server;
-
-import net.F53.HorseBuff.config.ModConfig;
-import net.minecraft.entity.LivingEntity;
-import net.minecraft.entity.passive.AbstractHorseEntity;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.registry.tag.FluidTags;
-import net.minecraft.util.math.Vec3d;
-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.CallbackInfo;
-
-@Mixin(value = LivingEntity.class)
-public class Swim {
- @Inject(method = "travelControlled", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;travel(Lnet/minecraft/util/math/Vec3d;)V", shift = At.Shift.BEFORE))
- private void fakeSwim(PlayerEntity controllingPlayer, Vec3d movementInput, CallbackInfo ci) {
- if (ModConfig.getInstance().swim && ((LivingEntity)(Object)this instanceof AbstractHorseEntity)) {
- AbstractHorseEntity instance = ((AbstractHorseEntity)(Object)this);
- if (instance.getFluidHeight(FluidTags.WATER) > instance.getSwimHeight()) {
- instance.addVelocity(0, 0.08, 0);
- }
- }
- }
-}
diff --git a/src/main/resources/assets/horsebuff/lang/en_us.json b/src/main/resources/assets/horsebuff/lang/en_us.json
index 7f07f41..32a7eca 100644
--- a/src/main/resources/assets/horsebuff/lang/en_us.json
+++ b/src/main/resources/assets/horsebuff/lang/en_us.json
@@ -27,8 +27,14 @@
"text.autoconfig.HorseBuff.option.noBuck": "Disable Random Bucking",
"text.autoconfig.HorseBuff.option.noBuck.@Tooltip": "Yes - Prevents horses from randomly bucking while mounted, no more random stops!\nNo - vanilla behavior",
- "text.autoconfig.HorseBuff.option.swim": "Horse Swimming",
- "text.autoconfig.HorseBuff.option.swim.@Tooltip": "Yes - Lets horses swim when you are riding them.\nNo - Horses sink when you ride them in water (vanilla behavior)",
+ "text.autoconfig.HorseBuff.option.swimHorse": "Horse, Mules, and Donkeys Swim",
+ "text.autoconfig.HorseBuff.option.swimHorse.@Tooltip": "Yes - Lets horses, mules, and donkeys swim when you are riding them.\nNo - Horses, mules, and donkeys sink when you ride them in water (vanilla behavior)",
+
+ "text.autoconfig.HorseBuff.option.swimCamel": "Camels Swim",
+ "text.autoconfig.HorseBuff.option.swimCamel.@Tooltip": "Yes - Lets camels swim when you are riding them.\nNo - Camels sink when you ride them in water (vanilla behavior)",
+
+ "text.autoconfig.HorseBuff.option.swimDead": "Undead Horses Swim",
+ "text.autoconfig.HorseBuff.option.swimDead.@Tooltip": "Yes - Lets Skeleton and Zombie horses swim when you are riding them.\nNo - Skeleton and Zombie horses sink when you ride them in water (vanilla behavior)",
"text.autoconfig.HorseBuff.option.pitchFade": "Horse Fade",
"text.autoconfig.HorseBuff.option.pitchFade.@Tooltip": "When mounted, the horse gets more transparent the further you look down",
@@ -48,5 +54,9 @@
"text.autoconfig.HorseBuff.option.horseHeadAngleOffset.@Tooltip": "When mounted, horse heads are angled an extra N degrees down\n 0 is disabled\n 30 is good for visibility and style\n 45 is good for breaking necks",
"text.autoconfig.HorseBuff.option.jeb_Horses": "jeb_ Horses",
- "text.autoconfig.HorseBuff.option.jeb_Horses.@Tooltip": "Like sheep, horses will become RGB when named \"jeb\""
+ "text.autoconfig.HorseBuff.option.jeb_Horses.@Tooltip": "Like sheep, horses will become RGB when named \"jeb\"",
+
+
+ "text.HorseBuff.keybinding.category": "Horse Buff",
+ "text.HorseBuff.keybinding.horsePlayerInventory": "Open Inventory on Horse"
}
\ No newline at end of file
diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json
index 21819a1..ffdaf9d 100644
--- a/src/main/resources/fabric.mod.json
+++ b/src/main/resources/fabric.mod.json
@@ -21,6 +21,7 @@
"environment": "*",
"entrypoints": {
"main": [ "net.F53.HorseBuff.HorseBuffInit" ],
+ "client": [ "net.F53.HorseBuff.ClientInit" ],
"modmenu": [ "net.F53.HorseBuff.config.ModMenuIntegration" ]
},
"mixins": [
@@ -28,8 +29,8 @@
],
"depends": {
- "fabricloader": ">=0.14.6",
- "minecraft": ">=1.20 <1.20.2-",
+ "fabricloader": ">=0.14.23",
+ "minecraft": ">=1.20.2",
"java": ">=17"
}
}
diff --git a/src/main/resources/horsebuff.mixins.json b/src/main/resources/horsebuff.mixins.json
index 2d7d8b4..05dc5a5 100644
--- a/src/main/resources/horsebuff.mixins.json
+++ b/src/main/resources/horsebuff.mixins.json
@@ -12,14 +12,14 @@
"Server.MovementCheck",
"Server.NoBuck",
"Server.NoWander",
- "Server.StepHeight",
- "Server.Swim"
+ "Server.StepHeight"
],
"client": [
"Client.HeadPitchOffset",
"Client.HorseRenderer",
"Client.InventoryAccessor",
"Client.JebHorseTintable",
+ "Client.Swim",
"Client.TransparentArmor",
"Client.TransparentLlamaDecor",
"Client.TransparentMarkings"