diff --git a/src/main/java/dev/o7moon/openboatutils/ClientboundPackets.java b/src/main/java/dev/o7moon/openboatutils/ClientboundPackets.java index d39bbe0..f5d3058 100644 --- a/src/main/java/dev/o7moon/openboatutils/ClientboundPackets.java +++ b/src/main/java/dev/o7moon/openboatutils/ClientboundPackets.java @@ -30,7 +30,8 @@ public enum ClientboundPackets { REMOVE_BLOCKS_SLIPPERINESS, CLEAR_SLIPPERINESS, MODE_SERIES, - EXCLUSIVE_MODE_SERIES; + EXCLUSIVE_MODE_SERIES, + SET_PER_BLOCK; public static void registerHandlers(){ ClientPlayNetworking.registerGlobalReceiver(OpenBoatUtils.settingsChannel, (client, handler, buf, responseSender) -> { @@ -149,6 +150,13 @@ public static void registerHandlers(){ Modes.setMode(Modes.values()[mode]); } return; + case 26: + short setting = buf.readShort(); + float value = buf.readFloat(); + blocks = buf.readString(); + blocksArray = blocks.split(","); + OpenBoatUtils.setBlocksSetting(OpenBoatUtils.PerBlockSettingType.values()[setting], Arrays.asList(blocksArray), value); + return; } } catch (Exception E) { OpenBoatUtils.LOG.error("Error when handling clientbound openboatutils packet: "); diff --git a/src/main/java/dev/o7moon/openboatutils/Modes.java b/src/main/java/dev/o7moon/openboatutils/Modes.java index a756b93..c0f84ef 100644 --- a/src/main/java/dev/o7moon/openboatutils/Modes.java +++ b/src/main/java/dev/o7moon/openboatutils/Modes.java @@ -1,5 +1,7 @@ package dev.o7moon.openboatutils; +import java.util.ArrayList; + public enum Modes { BROKEN_SLIME_RALLY,//0 BROKEN_SLIME_RALLY_BLUE,//1 @@ -16,7 +18,12 @@ public enum Modes { BA_BLUE_NOFD,//12 PARKOUR_BLUE,//13 BA,//14 - BA_BLUE;//15 + BA_BLUE,//15 + JUMP_BLOCKS,//16 + BOOSTER_BLOCKS,//17 + DEFAULT_ICE,//18 + DEFAULT_BLUE_ICE,//19 + ; public static void setMode(Modes mode) { switch (mode){ @@ -132,6 +139,22 @@ public static void setMode(Modes mode) { OpenBoatUtils.setWaterElevation(true); OpenBoatUtils.breakSlimePlease(); return; + case JUMP_BLOCKS: + OpenBoatUtils.setBlockSetting(OpenBoatUtils.PerBlockSettingType.jumpForce, "minecraft:orange_concrete", 0.36f);// ~1 block + OpenBoatUtils.setBlockSetting(OpenBoatUtils.PerBlockSettingType.jumpForce, "minecraft:black_concrete", 0.0f);// no jump + OpenBoatUtils.setBlockSetting(OpenBoatUtils.PerBlockSettingType.jumpForce, "minecraft:green_concrete", 0.5f);// ~2-3 block + OpenBoatUtils.setBlockSetting(OpenBoatUtils.PerBlockSettingType.jumpForce, "minecraft:yellow_concrete", 0.18f);// ~0.5 blocks + return; + case BOOSTER_BLOCKS: + OpenBoatUtils.setBlockSetting(OpenBoatUtils.PerBlockSettingType.forwardsAccel, "minecraft:magenta_glazed_terracotta", 0.08f);// double accel + OpenBoatUtils.setBlockSetting(OpenBoatUtils.PerBlockSettingType.yawAccel, "minecraft:light_gray_glazed_terracotta", 0.08f);// double yaw accel + return; + case DEFAULT_ICE: + OpenBoatUtils.setAllBlocksSlipperiness(0.98f); + return; + case DEFAULT_BLUE_ICE: + OpenBoatUtils.setAllBlocksSlipperiness(0.985f); + return; } } } diff --git a/src/main/java/dev/o7moon/openboatutils/OpenBoatUtils.java b/src/main/java/dev/o7moon/openboatutils/OpenBoatUtils.java index 2256f6f..54af83e 100644 --- a/src/main/java/dev/o7moon/openboatutils/OpenBoatUtils.java +++ b/src/main/java/dev/o7moon/openboatutils/OpenBoatUtils.java @@ -10,15 +10,26 @@ import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.LilyPadBlock; +import net.minecraft.entity.vehicle.BoatEntity; import net.minecraft.network.PacketByteBuf; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.Identifier; +import net.minecraft.util.function.BooleanBiFunction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static net.minecraft.server.command.CommandManager.*; + +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -68,6 +79,16 @@ public void onInitialize() { put("minecraft:frosted_ice",0.98f); }};*/ + enum PerBlockSettingType { + jumpForce, + forwardsAccel, + backwardsAccel, + yawAccel, + turnForwardsAccel, + } + + public static HashMap> perBlockSettings; + public static HashMap getVanillaSlipperinessMap() { if (vanillaSlipperinessMap == null) { vanillaSlipperinessMap = new HashMap<>(); @@ -80,6 +101,56 @@ public static HashMap getVanillaSlipperinessMap() { return vanillaSlipperinessMap; } + public static boolean settingHasPerBlock(PerBlockSettingType setting) { + return perBlockSettings != null && perBlockSettings.containsKey(setting.ordinal()); + } + + public static float getNearbySetting(BoatEntity instance, PerBlockSettingType setting) { + Box box = instance.getBoundingBox(); + Box box2 = new Box(box.minX, box.minY - 0.001, box.minZ, box.maxX, box.minY, box.maxZ); + int i = MathHelper.floor(box2.minX) - 1; + int j = MathHelper.ceil(box2.maxX) + 1; + int k = MathHelper.floor(box2.minY) - 1; + int l = MathHelper.ceil(box2.maxY) + 1; + int m = MathHelper.floor(box2.minZ) - 1; + int n = MathHelper.ceil(box2.maxZ) + 1; + VoxelShape voxelShape = VoxelShapes.cuboid(box2); + float f = 0.0f; + int o = 0; + BlockPos.Mutable mutable = new BlockPos.Mutable(); + for (int p = i; p < j; ++p) { + for (int q = m; q < n; ++q) { + int r = (p == i || p == j - 1 ? 1 : 0) + (q == m || q == n - 1 ? 1 : 0); + if (r == 2) continue; + for (int s = k; s < l; ++s) { + if (r > 0 && (s == k || s == l - 1)) continue; + mutable.set(p, s, q); + BlockState blockState = instance.getWorld().getBlockState(mutable); + if (blockState.getBlock() instanceof LilyPadBlock || !VoxelShapes.matchesAnywhere(blockState.getCollisionShape(instance.getWorld(), mutable).offset(p, s, q), voxelShape, BooleanBiFunction.AND)) continue; + f += getPerBlockForBlock(setting, Registries.BLOCK.getId(blockState.getBlock()).toString()); + ++o; + } + } + } + if (o == 0) return getPerBlockForBlock(setting, "minecraft:air"); + return f / (float)o; + } + + public static float getPerBlockForBlock(PerBlockSettingType setting, String blockid){ + return settingHasPerBlock(setting) && perBlockSettings.get(setting.ordinal()).containsKey(blockid) ? perBlockSettings.get(setting.ordinal()).get(blockid): defaultPerBlock(setting); + } + + public static float defaultPerBlock(PerBlockSettingType setting) { + switch (setting) { + case yawAccel -> {return yawAcceleration;} + case jumpForce -> {return jumpForce;} + case forwardsAccel -> {return forwardsAcceleration;} + case backwardsAccel -> {return backwardsAcceleration;} + case turnForwardsAccel -> {return turningForwardsAcceleration;} + }; + return 0;// unreachable but java compiler hates me (personally) + } + public static HashMap getSlipperinessMap() { if (slipperinessMap == null) { slipperinessMap = new HashMap<>(getVanillaSlipperinessMap()); @@ -113,7 +184,7 @@ public static void resetSettings(){ put("minecraft:blue_ice",0.989f); put("minecraft:frosted_ice",0.98f); }};*/ - + perBlockSettings = new HashMap(); } public static void setStepSize(float stepsize){ @@ -248,4 +319,43 @@ public static void clearSlipperinessMap() { enabled = true; slipperinessMap = new HashMap<>(); } + + public static float GetJumpForce(BoatEntity boat) { + if (!settingHasPerBlock(PerBlockSettingType.jumpForce)) return jumpForce; + else return getNearbySetting(boat, PerBlockSettingType.jumpForce); + } + + public static float GetYawAccel(BoatEntity boat) { + if (!settingHasPerBlock(PerBlockSettingType.yawAccel)) return yawAcceleration; + else return getNearbySetting(boat, PerBlockSettingType.yawAccel); + } + + public static float GetForwardAccel(BoatEntity boat) { + if (!settingHasPerBlock(PerBlockSettingType.forwardsAccel)) return forwardsAcceleration; + else return getNearbySetting(boat, PerBlockSettingType.forwardsAccel); + } + + public static float GetBackwardAccel(BoatEntity boat) { + if (!settingHasPerBlock(PerBlockSettingType.backwardsAccel)) return backwardsAcceleration; + else return getNearbySetting(boat, PerBlockSettingType.backwardsAccel); + } + + public static float GetTurnForwardAccel(BoatEntity boat) { + if (!settingHasPerBlock(PerBlockSettingType.turnForwardsAccel)) return turningForwardsAcceleration; + else return getNearbySetting(boat, PerBlockSettingType.turnForwardsAccel); + } + + public static void setBlocksSetting(PerBlockSettingType setting, List blocks, float value) { + enabled = true; + if (!settingHasPerBlock(setting)) perBlockSettings.put(setting.ordinal(), new HashMap()); + HashMap map = perBlockSettings.get(setting.ordinal()); + for (String block : blocks) { + map.put(block, value); + } + } + public static void setBlockSetting(PerBlockSettingType setting, String block, float value) { + ArrayList blocks = new ArrayList<>(); + blocks.add(block); + setBlocksSetting(setting, blocks, value); + } } diff --git a/src/main/java/dev/o7moon/openboatutils/SingleplayerCommands.java b/src/main/java/dev/o7moon/openboatutils/SingleplayerCommands.java index 9a74244..b53babe 100644 --- a/src/main/java/dev/o7moon/openboatutils/SingleplayerCommands.java +++ b/src/main/java/dev/o7moon/openboatutils/SingleplayerCommands.java @@ -384,6 +384,33 @@ public static void registerCommands(){ return 1; })) ); + + dispatcher.register( + literal("setblocksetting").then(argument("setting", StringArgumentType.string()).then(argument("value", FloatArgumentType.floatArg()).then(argument("blocks", StringArgumentType.greedyString()).executes(ctx -> { + ServerPlayerEntity player = ctx.getSource().getPlayer(); + if (player == null) return 0; + OpenBoatUtils.PerBlockSettingType setting; + try { + setting = OpenBoatUtils.PerBlockSettingType.valueOf(StringArgumentType.getString(ctx, "setting")); + } catch (Exception e) { + String valid_settings = ""; + for (OpenBoatUtils.PerBlockSettingType s : OpenBoatUtils.PerBlockSettingType.values()) { + valid_settings += s.toString() + " "; + } + ctx.getSource().sendMessage(Text.literal("Invalid setting! Valid settings are: "+valid_settings)); + return 0; + } + float value = FloatArgumentType.getFloat(ctx, "value"); + String blocks = StringArgumentType.getString(ctx, "blocks"); + PacketByteBuf packet = PacketByteBufs.create(); + packet.writeShort(ClientboundPackets.SET_PER_BLOCK.ordinal()); + packet.writeShort(setting.ordinal()); + packet.writeFloat(value); + packet.writeString(blocks); + ServerPlayNetworking.send(player, OpenBoatUtils.settingsChannel, packet); + return 1; + })))) + ); }); } } diff --git a/src/main/java/dev/o7moon/openboatutils/mixin/BoatMixin.java b/src/main/java/dev/o7moon/openboatutils/mixin/BoatMixin.java index 697f41c..fbe4f5a 100644 --- a/src/main/java/dev/o7moon/openboatutils/mixin/BoatMixin.java +++ b/src/main/java/dev/o7moon/openboatutils/mixin/BoatMixin.java @@ -55,9 +55,11 @@ void oncePerTick(BoatEntity instance, BoatEntity.Location loc, MinecraftClient m OpenBoatUtils.coyoteTimer--; } - if (OpenBoatUtils.coyoteTimer >= 0 && OpenBoatUtils.jumpForce > 0f && minecraft.options.jumpKey.isPressed()) { + float jumpForce = OpenBoatUtils.GetJumpForce((BoatEntity)(Object)this); + + if (OpenBoatUtils.coyoteTimer >= 0 && jumpForce > 0f && minecraft.options.jumpKey.isPressed()) { Vec3d velocity = instance.getVelocity(); - instance.setVelocity(velocity.x, OpenBoatUtils.jumpForce, velocity.z); + instance.setVelocity(velocity.x, jumpForce, velocity.z); OpenBoatUtils.coyoteTimer = -1;// cant jump again until grounded } } @@ -143,26 +145,26 @@ private void redirectYawVelocityIncrement(BoatEntity boat, float yawVelocity) { float original_delta = yawVelocity - this.yawVelocity; // sign isn't needed here because the vanilla acceleration is exactly 1, // but I suppose this helps if mojang ever decides to change that value for some reason - this.yawVelocity += MathHelper.sign(original_delta) * OpenBoatUtils.yawAcceleration; + this.yawVelocity += MathHelper.sign(original_delta) * OpenBoatUtils.GetYawAccel((BoatEntity)(Object)this); } // a whole lotta modifyconstants because mojang put the acceleration values in literals @ModifyConstant(method = "updatePaddles", constant = @Constant(floatValue = 0.04f, ordinal = 0)) private float forwardsAccel(float original) { if (!OpenBoatUtils.enabled) return original; - return OpenBoatUtils.forwardsAcceleration; + return OpenBoatUtils.GetForwardAccel((BoatEntity)(Object)this); } @ModifyConstant(method = "updatePaddles", constant = @Constant(floatValue = 0.005f, ordinal = 0)) private float turnAccel(float original) { if (!OpenBoatUtils.enabled) return original; - return OpenBoatUtils.turningForwardsAcceleration; + return OpenBoatUtils.GetTurnForwardAccel((BoatEntity)(Object)this); } @ModifyConstant(method = "updatePaddles", constant = @Constant(floatValue = 0.005f, ordinal = 1)) private float backwardsAccel(float original) { if (!OpenBoatUtils.enabled) return original; - return OpenBoatUtils.backwardsAcceleration; + return OpenBoatUtils.GetBackwardAccel((BoatEntity)(Object)this); } @Redirect(method = "updatePaddles", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/vehicle/BoatEntity;pressingForward:Z", opcode = Opcodes.GETFIELD, ordinal = 0))