From 3fd3020cc2612e7d13d852d59cab8000a418aaf4 Mon Sep 17 00:00:00 2001 From: okx-code Date: Wed, 13 Dec 2023 00:16:01 +0000 Subject: [PATCH 1/8] Add BetterRails, FasterHorses, RailDeoxidise, and miscellaneous things - BetterRails lets you change rail speed based on the block below. - FasterHorses increases the maximum speed of horses - CopperRail lets you deoxidise a block below a rail by right-clicking on the rail, and oxidises copper when a minecart goes over it - Fixed StriderBreeding randomness calculations - Order /sah list alphabetically - Actually disable hacks that should be disabled --- .../configs/BetterRailsConfig.java | 44 ++++++ .../framework/HackManager.java | 4 +- .../framework/commands/CommandRegistrar.java | 7 +- .../framework/commands/HacksCommand.java | 16 +- .../simpleadminhacks/hacks/BetterRails.java | 106 ++++++++++++++ .../simpleadminhacks/hacks/HorseStats.java | 18 ++- .../hacks/basic/CopperRail.java | 138 ++++++++++++++++++ .../hacks/basic/FasterHorses.java | 63 ++++++++ .../hacks/basic/StriderBreeding.java | 22 ++- paper/src/main/resources/config.yml | 21 +++ 10 files changed, 411 insertions(+), 28 deletions(-) create mode 100644 paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/BetterRailsConfig.java create mode 100644 paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/BetterRails.java create mode 100644 paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java create mode 100644 paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/FasterHorses.java diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/BetterRailsConfig.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/BetterRailsConfig.java new file mode 100644 index 00000000..8cefb94e --- /dev/null +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/BetterRailsConfig.java @@ -0,0 +1,44 @@ +package com.programmerdan.minecraft.simpleadminhacks.configs; + +import com.google.common.collect.Maps; +import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; +import com.programmerdan.minecraft.simpleadminhacks.framework.SimpleHackConfig; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import vg.civcraft.mc.civmodcore.utilities.CivLogger; + +import java.util.*; + +public final class BetterRailsConfig extends SimpleHackConfig { + + private final CivLogger logger; + + private Map speeds; + private double baseSpeed = 8; + + public BetterRailsConfig(SimpleAdminHacks plugin, ConfigurationSection base) { + super(plugin, base, false); + this.logger = CivLogger.getLogger(getClass()); + wireup(base); + } + + @Override + protected void wireup(ConfigurationSection config) { + this.baseSpeed = config.getDouble("base"); + + ConfigurationSection materials = config.getConfigurationSection("materials"); + Set keys = materials.getKeys(false); + this.speeds = Maps.newHashMapWithExpectedSize(keys.size()); + for (String key : keys) { + this.speeds.put(Material.valueOf(key), materials.getDouble(key)); + } + } + + public Double getMaxSpeedMetresPerSecond(Material material) { + return speeds.get(material); + } + + public double getBaseSpeed() { + return baseSpeed; + } +} diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/framework/HackManager.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/framework/HackManager.java index 4f1a9a8c..00da9c46 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/framework/HackManager.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/framework/HackManager.java @@ -130,7 +130,9 @@ public SimpleHack loadHack(final Class> hackClass, final Config public void enableAllHacks() { for (final SimpleHack hack : hacks) { - enableHack(hack); + if (hack.shouldEnable()) { + enableHack(hack); + } } } diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/framework/commands/CommandRegistrar.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/framework/commands/CommandRegistrar.java index b60afafb..7b00ad75 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/framework/commands/CommandRegistrar.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/framework/commands/CommandRegistrar.java @@ -5,8 +5,9 @@ import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; import com.programmerdan.minecraft.simpleadminhacks.framework.SimpleHack; import com.programmerdan.minecraft.simpleadminhacks.framework.SimpleHackConfig; -import java.util.ArrayList; -import java.util.List; +import java.util.Set; +import java.util.TreeSet; + import vg.civcraft.mc.civmodcore.commands.CommandManager; public class CommandRegistrar extends CommandManager { @@ -31,7 +32,7 @@ public void registerCommands() { public void registerCompletions(final CommandCompletions completions) { super.registerCompletions(completions); completions.registerAsyncCompletion("hacks", (context) -> { - final List names = new ArrayList<>(); + final Set names = new TreeSet<>(); for (final SimpleHack hack : this.plugin.getHackManager().getHacks()) { names.add(hack.getName()); } diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/framework/commands/HacksCommand.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/framework/commands/HacksCommand.java index 14c160a1..de415ffd 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/framework/commands/HacksCommand.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/framework/commands/HacksCommand.java @@ -13,7 +13,9 @@ import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; import com.programmerdan.minecraft.simpleadminhacks.framework.SimpleHack; import com.programmerdan.minecraft.simpleadminhacks.framework.SimpleHackConfig; -import java.util.List; + +import java.util.*; + import net.md_5.bungee.api.ChatColor; import org.bukkit.command.CommandSender; @@ -34,11 +36,13 @@ public void viewHacksCommand(final CommandSender sender) { if (hacks.isEmpty()) { sender.sendMessage(" No hacks registered."); } - else { - for (final SimpleHack hack : hacks) { - sender.sendMessage(" • " + ChatColor.YELLOW + hack.getName() + ": " + ChatColor.AQUA + - (hack.isEnabled() ? "enabled" : "disabled")); - } + final Map> names = new TreeMap<>(); + for (SimpleHack hack : hacks) { + names.put(hack.getName(), hack); + } + for (final SimpleHack hack : names.values()) { + sender.sendMessage(" • " + ChatColor.YELLOW + hack.getName() + ": " + ChatColor.AQUA + + (hack.isEnabled() ? "enabled" : "disabled")); } } diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/BetterRails.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/BetterRails.java new file mode 100644 index 00000000..47722e30 --- /dev/null +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/BetterRails.java @@ -0,0 +1,106 @@ +package com.programmerdan.minecraft.simpleadminhacks.hacks; + + +import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; +import com.programmerdan.minecraft.simpleadminhacks.configs.BetterRailsConfig; +import com.programmerdan.minecraft.simpleadminhacks.framework.SimpleHack; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Minecart; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.vehicle.VehicleEnterEvent; +import org.bukkit.event.vehicle.VehicleExitEvent; +import org.bukkit.event.vehicle.VehicleMoveEvent; + +public final class BetterRails extends SimpleHack implements Listener { + + // A minecart goes at 8m/s but its internal speed is 0.4, this adjusts for that + private static final double METRES_PER_SECOND_TO_SPEED = 0.05; + private static final double VANILLA_SPEED = 0.4; + + public BetterRails(SimpleAdminHacks plugin, final BetterRailsConfig config) { + super(plugin, config); + } + + public static BetterRailsConfig generate(SimpleAdminHacks plugin, ConfigurationSection config) { + return new BetterRailsConfig(plugin, config); + } + + @Override + public void onEnable() { + plugin().registerListener(this); + } + + @Override + public void onDisable() { + HandlerList.unregisterAll(this); + } + + @EventHandler + public void on(VehicleMoveEvent event) { + if (!(event.getVehicle() instanceof Minecart minecart)) { + return; + } + + Location to = event.getTo(); + Location from = event.getFrom(); + if (to.getBlockX() == from.getBlockX() && to.getBlockY() == from.getBlockY() && to.getBlockZ() == from.getBlockZ()) { + return; + } + + for (Entity entity : minecart.getPassengers()) { + if (entity instanceof Player) { + adjustSpeed(minecart); + return; + } + } + } + + @EventHandler + public void on(VehicleEnterEvent event) { + if (!(event.getVehicle() instanceof Minecart minecart)) { + return; + } + + if (event.getEntered() instanceof Player) { + adjustSpeed(minecart); + } + } + + @EventHandler + public void on(VehicleExitEvent event) { + if (!(event.getVehicle() instanceof Minecart minecart)) { + return; + } + + // Empty minecarts should return to their vanilla speed + minecart.setMaxSpeed(VANILLA_SPEED); + } + + + private void adjustSpeed(Minecart minecart) { + Material belowRail = minecart.getLocation().subtract(0, 1, 0).getBlock().getType(); + Material belowRail2 = minecart.getLocation().subtract(0, 2, 0).getBlock().getType(); + + Double belowRailSpeed = config.getMaxSpeedMetresPerSecond(belowRail); + Double belowRail2Speed = config.getMaxSpeedMetresPerSecond(belowRail2); + + double speedMetresPerSecond; + if (belowRailSpeed != null && belowRail2Speed != null) { + speedMetresPerSecond = Math.max(belowRailSpeed, belowRail2Speed); + } else if (belowRailSpeed != null) { + speedMetresPerSecond = belowRailSpeed; + } else if (belowRail2Speed != null) { + speedMetresPerSecond = belowRail2Speed; + } else { + speedMetresPerSecond = config.getBaseSpeed(); + } + + minecart.setMaxSpeed(speedMetresPerSecond * METRES_PER_SECOND_TO_SPEED); + } +} diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/HorseStats.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/HorseStats.java index 9302f8ef..0ea10f83 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/HorseStats.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/HorseStats.java @@ -17,6 +17,7 @@ import org.bukkit.inventory.ItemStack; public class HorseStats extends SimpleHack implements Listener { + private static final double INTERNAL_TO_METRES_PER_SECOND = 42.15778758471; public HorseStats(SimpleAdminHacks plugin, HorseStatsConfig config) { super(plugin, config); @@ -36,24 +37,31 @@ public void onHorseStatCheck(PlayerInteractEntityEvent event) { AbstractHorse horse = (AbstractHorse)entity; AttributeInstance attrHealth = horse.getAttribute(Attribute.GENERIC_MAX_HEALTH); AttributeInstance attrSpeed = horse.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED); - event.getPlayer().sendMessage(String.format("%sHealth = %f, Speed = %f, Jump height = %f", + event.getPlayer().sendMessage(String.format("%sHealth = %f, Speed = %fm/s, Jump height = %f blocks", ChatColor.YELLOW, attrHealth.getBaseValue(), - attrSpeed.getBaseValue(), - horse.getJumpStrength())); + attrSpeed.getBaseValue() * INTERNAL_TO_METRES_PER_SECOND, + jumpHeightInBlocks(horse.getJumpStrength()))); + event.setCancelled(true); } else if (entity instanceof Strider) { Strider strider = (Strider) entity; AttributeInstance attrHealth = strider.getAttribute(Attribute.GENERIC_MAX_HEALTH); AttributeInstance attrSpeed = strider.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED); - event.getPlayer().sendMessage(String.format("%sHealth = %f, Speed = %f", + event.getPlayer().sendMessage(String.format("%sHealth = %f, Speed = %fm/s", ChatColor.YELLOW, attrHealth.getBaseValue(), - attrSpeed.getBaseValue())); + attrSpeed.getBaseValue() * INTERNAL_TO_METRES_PER_SECOND)); + event.setCancelled(true); } else { return; } } + private double jumpHeightInBlocks(double x) { + // This is a curve-fitted formula, so not 100% accurate + return -0.1817584952 * x * x * x + 3.689713992 * x * x + 2.128599134 * x - 0.343930367; + } + @Override public void registerListeners() { if (config.isEnabled()) { diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java new file mode 100644 index 00000000..ea8fa359 --- /dev/null +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java @@ -0,0 +1,138 @@ +package com.programmerdan.minecraft.simpleadminhacks.hacks.basic; + +import com.destroystokyo.paper.MaterialTags; +import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; +import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHack; +import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHackConfig; +import com.programmerdan.minecraft.simpleadminhacks.framework.autoload.AutoLoad; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.level.block.WeatheringCopper; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.SoundCategory; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_18_R2.block.CraftBlock; +import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_18_R2.event.CraftEventFactory; +import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Minecart; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.vehicle.VehicleMoveEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; + +import java.util.Optional; + +public class CopperRail extends BasicHack { + + // ServerLevel has a private version of this so we will make one ourselves + private final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(); + + @AutoLoad + private boolean deoxidise; + + @AutoLoad + private double damage; + + public CopperRail(SimpleAdminHacks plugin, BasicHackConfig config) { + super(plugin, config); + } + + @EventHandler + public void on(VehicleMoveEvent event) { + if (this.damage <= 0 || !(event.getVehicle() instanceof Minecart minecart)) { + return; + } + + boolean hasPlayer = false; + for (Entity entity : minecart.getPassengers()) { + if (entity instanceof Player) { + hasPlayer = true; + break; + } + } + + if (!hasPlayer) { + return; + } + + Location to = event.getTo(); + Location from = event.getFrom(); + if (to.getBlockX() == from.getBlockX() && to.getBlockY() == from.getBlockY() && to.getBlockZ() == from.getBlockZ()) { + return; + } + + Block copperBlock = minecart.getLocation().getBlock().getRelative(BlockFace.DOWN); + Optional next = WeatheringCopper.getNext(((CraftBlock) copperBlock).getNMS().getBlock()); + if (next.isEmpty()) { + copperBlock = copperBlock.getRelative(BlockFace.DOWN); + } + + next = WeatheringCopper.getNext(((CraftBlock) copperBlock).getNMS().getBlock()); + if (next.isEmpty()) { + return; + } + + CraftBlock craftBlock = (CraftBlock) copperBlock; + BlockState state = craftBlock.getNMS(); + ServerLevel level = ((CraftWorld) copperBlock.getWorld()).getHandle(); + // We damage the copper directly instead of using random ticking, as random ticking is easy to cheese + // by placing waxed copper next to the rail, entirely preventing the rest of the rail from oxidising. + WeatheringCopper copper = (WeatheringCopper) state.getBlock(); + float chanceModifier = copper.getChanceModifier(); + if (this.damage * chanceModifier > this.randomTickRandom.nextFloat()) { + copper.getNext(state).ifPresent((iblockdata2) -> { + CraftEventFactory.handleBlockFormEvent(level, craftBlock.getPosition(), iblockdata2); + }); + } + } + + @EventHandler + public void on(PlayerInteractEvent event) { + if (!this.deoxidise) { + return; + } + + ItemStack item = event.getItem(); + if (item == null || !MaterialTags.AXES.isTagged(item)) { + return; + } + + Block block = event.getClickedBlock(); + if (block == null || !MaterialTags.RAILS.isTagged(block)) { + return; + } + + Block copperBlock = block.getRelative(BlockFace.DOWN); + Optional previous = WeatheringCopper.getPrevious(((CraftBlock) copperBlock).getNMS()); + if (previous.isEmpty()) { + copperBlock = copperBlock.getRelative(BlockFace.DOWN); + } + + previous = WeatheringCopper.getPrevious(((CraftBlock) copperBlock).getNMS()); + if (previous.isEmpty()) { + return; + } + + copperBlock.setType(previous.get().getBukkitMaterial()); + + block.getWorld().playSound(block.getLocation(), Sound.ITEM_AXE_SCRAPE, SoundCategory.BLOCKS, 1, 1); + block.getWorld().playEffect(block.getLocation(), Effect.OXIDISED_COPPER_SCRAPE, 0); + + CraftPlayer player = (CraftPlayer) event.getPlayer(); + // TODO: In 1.19 or above, this can be replaced with ItemStack#damage thanks to Paper + ((CraftItemStack) item).handle.hurtAndBreak(1, player.getHandle(), p -> { + p.broadcastBreakEvent(event.getHand() == EquipmentSlot.HAND ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND); + }); + + event.setCancelled(true); + } +} diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/FasterHorses.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/FasterHorses.java new file mode 100644 index 00000000..281f5fa2 --- /dev/null +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/FasterHorses.java @@ -0,0 +1,63 @@ +package com.programmerdan.minecraft.simpleadminhacks.hacks.basic; + +import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; +import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHack; +import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHackConfig; +import com.programmerdan.minecraft.simpleadminhacks.framework.autoload.AutoLoad; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeInstance; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityBreedEvent; + +import java.util.logging.Level; + +public class FasterHorses extends BasicHack { + @AutoLoad + private double minSpeed; + @AutoLoad + private double maxSpeed; + + public FasterHorses(SimpleAdminHacks plugin, BasicHackConfig config) { + super(plugin, config); + } + + @EventHandler(priority = EventPriority.HIGH) + public void on(EntityBreedEvent event) { + if (event.getEntity().getType() != EntityType.HORSE) { + return; + } + double dadSpeed = event.getFather().getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).getBaseValue(); + double mumSpeed = event.getMother().getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).getBaseValue(); + double irwinHallDist = (Math.random() * 0.3 + Math.random() * 0.3 + Math.random() * 0.3) * ((this.maxSpeed - this.minSpeed) / 0.9) + this.minSpeed; + double newSpeed = (dadSpeed + mumSpeed + irwinHallDist) / 3; + if (newSpeed < minSpeed) { + newSpeed = minSpeed; + } else if (newSpeed > maxSpeed) { + newSpeed = maxSpeed; + } + event.getEntity().getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(newSpeed); + + plugin.getLogger().log(Level.INFO, "Horse breed to have speed: " + newSpeed); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void on(CreatureSpawnEvent event) { + if (event.getEntity().getType() != EntityType.HORSE) { + return; + } + if (event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.BREEDING) { + return; + } + + AttributeInstance moveSpeed = event.getEntity().getAttribute(Attribute.GENERIC_MOVEMENT_SPEED); + if (moveSpeed == null) { + return; + } + double irwinHallDist = (Math.random() * 0.3 + Math.random() * 0.3 + Math.random() * 0.3) * ((this.maxSpeed - this.minSpeed) / 0.9) + this.minSpeed; + moveSpeed.setBaseValue(irwinHallDist); + plugin.getLogger().log(Level.INFO, "Setting Horse Speed to: " + irwinHallDist); + } +} diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/StriderBreeding.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/StriderBreeding.java index 102c5b26..8e1dde29 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/StriderBreeding.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/StriderBreeding.java @@ -36,11 +36,8 @@ public void onStriderBreed(EntityBreedEvent event) { } double dadSpeed = event.getFather().getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).getBaseValue(); double mumSpeed = event.getMother().getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).getBaseValue(); - double randomSpeed = Math.random() * (this.maxSpeed - this.minSpeed) + this.minSpeed; - //the 0.44.... number, I was given this number by Okx#5481, apparently it is the horse speed generation number - //Also worth noting he told me it is not exactly a bell curve even if I did name it bellCurve - double bellCurve = (0.44999998807907104 + randomSpeed * 0.3 + randomSpeed * 0.3 + randomSpeed * 0.3) * 0.25; - double newStriderSpeed = (dadSpeed + mumSpeed + bellCurve) / 3; + double irwinHallDist = (0.45 + Math.random() * 0.3 + Math.random() * 0.3 + Math.random() * 0.3) * 0.25; + double newStriderSpeed = (dadSpeed + mumSpeed + irwinHallDist) / 3; if (newStriderSpeed < minSpeed) { newStriderSpeed = minSpeed; } else if (newStriderSpeed > maxSpeed) { @@ -80,15 +77,14 @@ public void rollSpeedStat(LivingEntity strider, double minSpeed, double maxSpeed if (moveSpeed == null) { return; } - double random = Math.random() * (maxSpeed - minSpeed) + minSpeed; - double bellCurve = (0.44999998807907104 + random * 0.3 + random * 0.3 + random * 0.3) * 0.25; - if (bellCurve < minSpeed) { - bellCurve = minSpeed; - } else if (bellCurve > maxSpeed) { - bellCurve = maxSpeed; + double irwinHallDist = (0.45 + Math.random() * 0.3 + Math.random() * 0.3 + Math.random() * 0.3) * 0.25; + if (irwinHallDist < minSpeed) { + irwinHallDist = minSpeed; + } else if (irwinHallDist > maxSpeed) { + irwinHallDist = maxSpeed; } - moveSpeed.setBaseValue(bellCurve); - plugin.getLogger().log(Level.INFO, "Setting Strider Speed to: " + bellCurve); + moveSpeed.setBaseValue(irwinHallDist); + plugin.getLogger().log(Level.INFO, "Setting Strider Speed to: " + irwinHallDist); } public void rollHealthStat(LivingEntity strider, int minHealth, int maxHealth) { diff --git a/paper/src/main/resources/config.yml b/paper/src/main/resources/config.yml index 55a65dec..0c585c13 100644 --- a/paper/src/main/resources/config.yml +++ b/paper/src/main/resources/config.yml @@ -513,3 +513,24 @@ hacks: ToggleLamp: enabled: false cooldownTime: 100 + BetterRails: + enabled: true + # All in metres per second + # Minecraft will prevent you going faster than 30m/s + base: 12 + materials: + COBBLESTONE: 8 + COPPER_BLOCK: 30 + EXPOSED_COPPER: 24 + WEATHERED_COPPER: 19 + OXIDIZED_COPPER: 15 + CopperRail: + enabled: true + deoxidise: true + # Chance to oxidise copper one level. + # Unoxidised copper will oxidise at 75% of this level. + damage: 0.1 + FasterHorses: + enabled: true + minSpeed: 0.1125 + maxSpeed: 0.438827582278 # 18.5m/s From edc7e08272744870c2cc398fc00715b5adeae854 Mon Sep 17 00:00:00 2001 From: okx-code Date: Wed, 13 Dec 2023 00:18:16 +0000 Subject: [PATCH 2/8] update damage --- paper/src/main/resources/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper/src/main/resources/config.yml b/paper/src/main/resources/config.yml index 0c585c13..2b9175e3 100644 --- a/paper/src/main/resources/config.yml +++ b/paper/src/main/resources/config.yml @@ -529,7 +529,7 @@ hacks: deoxidise: true # Chance to oxidise copper one level. # Unoxidised copper will oxidise at 75% of this level. - damage: 0.1 + damage: 0.03 FasterHorses: enabled: true minSpeed: 0.1125 From 358a2aeb5475968d008531bca14e50a243e202d1 Mon Sep 17 00:00:00 2001 From: okx-code Date: Wed, 13 Dec 2023 00:22:29 +0000 Subject: [PATCH 3/8] ignore cancelled (better citadel interaction) --- .../minecraft/simpleadminhacks/hacks/basic/CopperRail.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java index ea8fa359..9735e10d 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java @@ -95,7 +95,7 @@ public void on(VehicleMoveEvent event) { } } - @EventHandler + @EventHandler(ignoreCancelled = true) public void on(PlayerInteractEvent event) { if (!this.deoxidise) { return; From 04f28a3d39561be02ca9d6b743e1be29a5a2c820 Mon Sep 17 00:00:00 2001 From: okx-code Date: Wed, 13 Dec 2023 01:12:58 +0000 Subject: [PATCH 4/8] add faster speeds if exposed to the sky --- .../configs/BetterRailsConfig.java | 20 +++++++++++++ .../simpleadminhacks/hacks/BetterRails.java | 28 +++++++++++-------- paper/src/main/resources/config.yml | 15 +++++++--- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/BetterRailsConfig.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/BetterRailsConfig.java index 8cefb94e..697114c4 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/BetterRailsConfig.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/BetterRailsConfig.java @@ -16,6 +16,9 @@ public final class BetterRailsConfig extends SimpleHackConfig { private Map speeds; private double baseSpeed = 8; + private Map skySpeeds; + private double skySpeed = 8; + public BetterRailsConfig(SimpleAdminHacks plugin, ConfigurationSection base) { super(plugin, base, false); this.logger = CivLogger.getLogger(getClass()); @@ -32,13 +35,30 @@ protected void wireup(ConfigurationSection config) { for (String key : keys) { this.speeds.put(Material.valueOf(key), materials.getDouble(key)); } + + this.skySpeed = config.getDouble("skyBase"); + + ConfigurationSection skyMaterials = config.getConfigurationSection("skyMaterials"); + Set skyKeys = skyMaterials.getKeys(false); + this.skySpeeds = Maps.newHashMapWithExpectedSize(skyKeys.size()); + for (String key : skyKeys) { + this.skySpeeds.put(Material.valueOf(key), skyMaterials.getDouble(key)); + } } public Double getMaxSpeedMetresPerSecond(Material material) { return speeds.get(material); } + public Double getSkySpeedMetresPerSecond(Material material) { + return skySpeeds.get(material); + } + public double getBaseSpeed() { return baseSpeed; } + + public double getSkySpeed() { + return skySpeed; + } } diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/BetterRails.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/BetterRails.java index 47722e30..7ba157e9 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/BetterRails.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/BetterRails.java @@ -4,6 +4,7 @@ import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; import com.programmerdan.minecraft.simpleadminhacks.configs.BetterRailsConfig; import com.programmerdan.minecraft.simpleadminhacks.framework.SimpleHack; +import org.bukkit.HeightMap; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -87,20 +88,25 @@ private void adjustSpeed(Minecart minecart) { Material belowRail = minecart.getLocation().subtract(0, 1, 0).getBlock().getType(); Material belowRail2 = minecart.getLocation().subtract(0, 2, 0).getBlock().getType(); - Double belowRailSpeed = config.getMaxSpeedMetresPerSecond(belowRail); - Double belowRail2Speed = config.getMaxSpeedMetresPerSecond(belowRail2); + double speedMetresPerSecond = maxOrGet(config.getMaxSpeedMetresPerSecond(belowRail), config.getMaxSpeedMetresPerSecond(belowRail2), config.getBaseSpeed()); - double speedMetresPerSecond; - if (belowRailSpeed != null && belowRail2Speed != null) { - speedMetresPerSecond = Math.max(belowRailSpeed, belowRail2Speed); - } else if (belowRailSpeed != null) { - speedMetresPerSecond = belowRailSpeed; - } else if (belowRail2Speed != null) { - speedMetresPerSecond = belowRail2Speed; - } else { - speedMetresPerSecond = config.getBaseSpeed(); + if (minecart.getLocation().getBlockY() == minecart.getWorld().getHighestBlockYAt(minecart.getLocation(), HeightMap.WORLD_SURFACE)) { + speedMetresPerSecond += maxOrGet(config.getSkySpeedMetresPerSecond(belowRail), config.getSkySpeedMetresPerSecond(belowRail2), config.getSkySpeed()); } + minecart.setMaxSpeed(speedMetresPerSecond * METRES_PER_SECOND_TO_SPEED); } + + private double maxOrGet(Double left, Double right, double defaultAmount) { + if (left != null && right != null) { + return Math.max(left, right); + } else if (left != null) { + return left; + } else if (right != null) { + return right; + } else { + return defaultAmount; + } + } } diff --git a/paper/src/main/resources/config.yml b/paper/src/main/resources/config.yml index 2b9175e3..4858936d 100644 --- a/paper/src/main/resources/config.yml +++ b/paper/src/main/resources/config.yml @@ -520,10 +520,17 @@ hacks: base: 12 materials: COBBLESTONE: 8 - COPPER_BLOCK: 30 - EXPOSED_COPPER: 24 - WEATHERED_COPPER: 19 - OXIDIZED_COPPER: 15 + COPPER_BLOCK: 29 + EXPOSED_COPPER: 23 + WEATHERED_COPPER: 18 + OXIDIZED_COPPER: 14 + skyBase: 1 + skyMaterials: + COBBLESTONE: 0 + COPPER_BLOCK: 1 + EXPOSED_COPPER: 1 + WEATHERED_COPPER: 1 + OXIDIZED_COPPER: 1 CopperRail: enabled: true deoxidise: true From af9e2cfb44b9b4b02df76fdf6876a912cca971e7 Mon Sep 17 00:00:00 2001 From: okx-code Date: Wed, 13 Dec 2023 01:13:46 +0000 Subject: [PATCH 5/8] fix default --- .../minecraft/simpleadminhacks/configs/BetterRailsConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/BetterRailsConfig.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/BetterRailsConfig.java index 697114c4..77097ea6 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/BetterRailsConfig.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/BetterRailsConfig.java @@ -17,7 +17,7 @@ public final class BetterRailsConfig extends SimpleHackConfig { private double baseSpeed = 8; private Map skySpeeds; - private double skySpeed = 8; + private double skySpeed = 0; public BetterRailsConfig(SimpleAdminHacks plugin, ConfigurationSection base) { super(plugin, base, false); From 863cae02d351c3e6a33ff5ffe4318277b371c0da Mon Sep 17 00:00:00 2001 From: okx-code Date: Thu, 21 Dec 2023 04:31:58 +0000 Subject: [PATCH 6/8] rails shouldn't oxidise naturally --- .../hacks/basic/CopperRail.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java index 9735e10d..979ef826 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java @@ -24,6 +24,7 @@ import org.bukkit.entity.Minecart; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockFormEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.vehicle.VehicleMoveEvent; import org.bukkit.inventory.EquipmentSlot; @@ -135,4 +136,27 @@ public void on(PlayerInteractEvent event) { event.setCancelled(true); } + + // It's not really fair for copper blocks that are below rails to naturally oxidise, + // as it is easy to cheese by placing a waxed copper block every 9 blocks + @EventHandler + public void on(BlockFormEvent event) { + Block block = event.getBlock(); + + Optional next = WeatheringCopper.getNext(((CraftBlock) block).getNMS().getBlock()); + if (next.isEmpty()) { + return; + } + + Block railAbove = block.getRelative(BlockFace.UP); + if (!MaterialTags.RAILS.isTagged(railAbove)) { + railAbove = railAbove.getRelative(BlockFace.UP); + } + + if (!MaterialTags.RAILS.isTagged(railAbove)) { + return; + } + + event.setCancelled(true); + } } From 13a22b6f1447e2b7ecc0a8482283dd8b9f602ac0 Mon Sep 17 00:00:00 2001 From: okx-code Date: Wed, 10 Jan 2024 23:49:40 +0000 Subject: [PATCH 7/8] Fix copper oxidising not as much as it should --- .../hacks/basic/CopperRail.java | 69 +++++++++++++------ 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java index 979ef826..1195f533 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/CopperRail.java @@ -30,6 +30,8 @@ import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; public class CopperRail extends BasicHack { @@ -43,6 +45,8 @@ public class CopperRail extends BasicHack { @AutoLoad private double damage; + private boolean formingBlock = false; + public CopperRail(SimpleAdminHacks plugin, BasicHackConfig config) { super(plugin, config); } @@ -71,28 +75,49 @@ public void on(VehicleMoveEvent event) { return; } - Block copperBlock = minecart.getLocation().getBlock().getRelative(BlockFace.DOWN); - Optional next = WeatheringCopper.getNext(((CraftBlock) copperBlock).getNMS().getBlock()); - if (next.isEmpty()) { - copperBlock = copperBlock.getRelative(BlockFace.DOWN); - } - - next = WeatheringCopper.getNext(((CraftBlock) copperBlock).getNMS().getBlock()); - if (next.isEmpty()) { - return; + int signX = from.getBlockX() > to.getBlockX() ? 1 : -1; + int signZ = from.getBlockZ() > to.getBlockZ() ? 1 : -1; + boolean firstBlock = true; + + List copperBlocks = new ArrayList<>(4); + for (int x = to.getBlockX(); x != to.getBlockX() + (from.getBlockX() - to.getBlockX()) + signX; x += signX) { + for (int z = to.getBlockZ(); z != to.getBlockZ() + (from.getBlockZ() - to.getBlockZ()) + signZ; z += signZ) { + if (firstBlock) { + firstBlock = false; + continue; + } + Location location = new Location(minecart.getWorld(), x, from.getY(), z); + Block topCopperBlock = location.getBlock().getRelative(BlockFace.DOWN); + Optional next = WeatheringCopper.getNext(((CraftBlock) topCopperBlock).getNMS().getBlock()); + if (next.isPresent()) { + copperBlocks.add(topCopperBlock); + } + Block belowCopperBlock = topCopperBlock.getRelative(BlockFace.DOWN); + next = WeatheringCopper.getNext(((CraftBlock) belowCopperBlock).getNMS().getBlock()); + if (next.isPresent()) { + copperBlocks.add(belowCopperBlock); + } + } } - CraftBlock craftBlock = (CraftBlock) copperBlock; - BlockState state = craftBlock.getNMS(); - ServerLevel level = ((CraftWorld) copperBlock.getWorld()).getHandle(); - // We damage the copper directly instead of using random ticking, as random ticking is easy to cheese - // by placing waxed copper next to the rail, entirely preventing the rest of the rail from oxidising. - WeatheringCopper copper = (WeatheringCopper) state.getBlock(); - float chanceModifier = copper.getChanceModifier(); - if (this.damage * chanceModifier > this.randomTickRandom.nextFloat()) { - copper.getNext(state).ifPresent((iblockdata2) -> { - CraftEventFactory.handleBlockFormEvent(level, craftBlock.getPosition(), iblockdata2); - }); + for (Block copperBlock : copperBlocks) { + CraftBlock craftBlock = (CraftBlock) copperBlock; + BlockState state = craftBlock.getNMS(); + ServerLevel level = ((CraftWorld) copperBlock.getWorld()).getHandle(); + // We damage the copper directly instead of using random ticking, as random ticking is easy to cheese + // by placing waxed copper next to the rail, entirely preventing the rest of the rail from oxidising. + WeatheringCopper copper = (WeatheringCopper) state.getBlock(); + float chanceModifier = copper.getChanceModifier(); + if (this.damage * chanceModifier > this.randomTickRandom.nextFloat()) { + copper.getNext(state).ifPresent((iblockdata2) -> { + try { + formingBlock = true; + CraftEventFactory.handleBlockFormEvent(level, craftBlock.getPosition(), iblockdata2); + } finally { + formingBlock = false; + } + }); + } } } @@ -141,6 +166,10 @@ public void on(PlayerInteractEvent event) { // as it is easy to cheese by placing a waxed copper block every 9 blocks @EventHandler public void on(BlockFormEvent event) { + if (formingBlock) { + return; + } + Block block = event.getBlock(); Optional next = WeatheringCopper.getNext(((CraftBlock) block).getNMS().getBlock()); From e2f0e609e9a0ca1e780b7995c79e250ba82758f6 Mon Sep 17 00:00:00 2001 From: okx-code Date: Mon, 15 Jan 2024 17:52:33 +0000 Subject: [PATCH 8/8] this breaks the nice geometric series this was also supposed to be decremented when the 1m/s sky buff was added --- paper/src/main/resources/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper/src/main/resources/config.yml b/paper/src/main/resources/config.yml index 4858936d..eef5f514 100644 --- a/paper/src/main/resources/config.yml +++ b/paper/src/main/resources/config.yml @@ -517,7 +517,7 @@ hacks: enabled: true # All in metres per second # Minecraft will prevent you going faster than 30m/s - base: 12 + base: 11 materials: COBBLESTONE: 8 COPPER_BLOCK: 29