Merge pull request #345 from CivMC/anti-derailment

A partial fix for minecart derailment
This commit is contained in:
RedDevel2
2024-03-05 19:10:43 +01:00
committed by GitHub
2 changed files with 101 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
package com.programmerdan.minecraft.simpleadminhacks.hacks.basic;
import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent;
import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks;
import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHack;
import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHackConfig;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftMinecart;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.vehicle.VehicleMoveEvent;
import org.bukkit.util.Vector;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Prevents minecarts from derailing by forcibly slowing them down to 8m/s when they would otherwise derail
*/
public class AntiDerailment extends BasicHack {
private Map<Minecart, Vector> previousTickMinecartVelocity;
public AntiDerailment(SimpleAdminHacks plugin, BasicHackConfig config) {
super(plugin, config);
}
@Override
public void onEnable() {
super.onEnable();
previousTickMinecartVelocity = new HashMap<>();
}
@Override
public void onDisable() {
super.onDisable();
previousTickMinecartVelocity.clear();
}
@EventHandler
public void on(EntityRemoveFromWorldEvent e) {
if (e.getEntity() instanceof Minecart minecart) {
previousTickMinecartVelocity.remove(minecart);
}
}
@EventHandler
public void onDerailment(VehicleMoveEvent e) {
// This method is EXTREMELY fucked but basically if it detects a super fast minecart is going to derail, it will
// undo one tick of movement and redo it at 8m/s (the default minecart speed)
// To do this it also needs to store the velocity from the previous tick to recreate the movement properly
if (!(e.getVehicle() instanceof Minecart minecart)) {
return;
}
List<Entity> passengers = minecart.getPassengers();
if (passengers.size() != 1 || !(passengers.get(0) instanceof Player)) {
previousTickMinecartVelocity.put(minecart, minecart.getVelocity());
return;
}
if (minecart.getMaxSpeed() == 0.4D || !previousTickMinecartVelocity.containsKey(minecart)) {
previousTickMinecartVelocity.put(minecart, minecart.getVelocity());
return;
}
Block fromBlock = e.getFrom().getBlock();
if (!Tag.RAILS.isTagged(fromBlock.getType())) {
previousTickMinecartVelocity.put(minecart, minecart.getVelocity());
return;
}
Block block = e.getTo().getBlock();
if (Tag.RAILS.isTagged(block.getType())) {
previousTickMinecartVelocity.put(minecart, minecart.getVelocity());
if (e.getTo().getY() < e.getFrom().getY()) {
return;
}
return;
}
AbstractMinecart handle = ((CraftMinecart) minecart).getHandle();
handle.setPos(e.getFrom().getX(), e.getFrom().getY(), e.getFrom().getZ());
minecart.setVelocity(previousTickMinecartVelocity.get(minecart));
double maxSpeed = minecart.getMaxSpeed();
minecart.setMaxSpeed(0.4D); // 8m/s, default minecart speed
handle.tick();
minecart.setMaxSpeed(maxSpeed);
previousTickMinecartVelocity.put(minecart, minecart.getVelocity());
}
}

View File

@@ -545,3 +545,5 @@ hacks:
enabled: true
minSpeed: 0.1125
maxSpeed: 0.438827582278 # 18.5m/s
AntiDerailment:
enabled: true