Skip to content

Commit

Permalink
Merge branch 'dev-goodroach-enablebleedfix' of https://github.com/goo…
Browse files Browse the repository at this point in the history
…droach/Movecraft-Combat into dev-goodroach-bleedfix
  • Loading branch information
goodroach committed Oct 23, 2023
2 parents ba9617b + 526503f commit dd11010
Show file tree
Hide file tree
Showing 11 changed files with 357 additions and 149 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>java.net.countercraft.movecraft.combat</groupId>
<artifactId>Movecraft-Combat</artifactId>
<version>2.0.0_beta-2</version>
<version>2.0.0_beta-3</version>
<packaging>jar</packaging>

<name>Movecraft-Combat</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang.reflect.FieldUtils;
import org.bukkit.Bukkit;
import org.bukkit.Material;
Expand All @@ -18,6 +19,7 @@

public class BlastResistanceOverride {
public static Map<Material, Float> BlastResistanceOverride = null;
private static BlastResistanceNMS nmsInterface;

public static void load(@NotNull FileConfiguration config) {
if (!config.contains("BlastResistanceOverride"))
Expand All @@ -44,23 +46,21 @@ public static void load(@NotNull FileConfiguration config) {
BlastResistanceOverride.put(m, value);
}
}

String packageName = Bukkit.getServer().getClass().getPackage().getName();
String version = packageName.substring(packageName.lastIndexOf('.') + 1);
int major_version = Integer.parseInt(version.split("_")[1]);
if (major_version < 17) {
nmsInterface = new BlastResistanceNMS_V1(); // Tested on 1.14.4 and 1.16.5
} else if (major_version == 20) {
nmsInterface = new BlastResistanceNMS_v1_20(); // Tested on 1.20.1
} else {
nmsInterface = new BlastResistanceNMS_V2(); // Tested on 1.19.4 and 1.18.2
}
}

public static boolean setBlastResistance(Material m, float resistance) {
try {
String packageName = Bukkit.getServer().getClass().getPackage().getName();
String version = packageName.substring(packageName.lastIndexOf('.') + 1);
Class<?> clazz = Class.forName("org.bukkit.craftbukkit." + version + ".util.CraftMagicNumbers");
Method method = clazz.getMethod("getBlock", Material.class);
Object block = method.invoke(null, m);
Field field = FieldUtils.getField(block.getClass(), "durability", true);
FieldUtils.writeField(field, block, resistance);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
| SecurityException | ClassNotFoundException e) {
e.printStackTrace();
return false;
}
return true;
return nmsInterface.setBlastResistance(m, resistance);
}

public static boolean revertToVanilla(Material m) {
Expand All @@ -69,13 +69,85 @@ public static boolean revertToVanilla(Material m) {

public static void enable() {
for (var entry : BlastResistanceOverride.entrySet()) {
setBlastResistance(entry.getKey(), entry.getValue());
if (!setBlastResistance(entry.getKey(), entry.getValue()))
MovecraftCombat.getInstance().getLogger()
.warning("Unable to set " + entry.getKey().name() + ": " + entry.getValue());
}
}

public static void disable() {
for (Material m : BlastResistanceOverride.keySet()) {
revertToVanilla(m);
if (!revertToVanilla(m))
MovecraftCombat.getInstance().getLogger().warning("Unable to reset " + m.name());
}
}

private static class BlastResistanceNMS {
public boolean setBlastResistance(Material m, float resistance) {
throw new NotImplementedException();
}

protected static Class<?> getCraftMagicNumbersClass() throws ClassNotFoundException {
String packageName = Bukkit.getServer().getClass().getPackage().getName();
String version = packageName.substring(packageName.lastIndexOf('.') + 1);
return Class.forName("org.bukkit.craftbukkit." + version + ".util.CraftMagicNumbers");
}

protected static Object getBlockClass(Class<?> magicNumbers, Material m)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Method method = magicNumbers.getMethod("getBlock", Material.class);
return method.invoke(null, m);
}

protected static void writeField(Object block, String fieldName, float resistance)
throws IllegalAccessException {
Field field = FieldUtils.getField(block.getClass(), fieldName, true);
FieldUtils.writeField(field, block, resistance);
}
}

private static class BlastResistanceNMS_V1 extends BlastResistanceNMS {
public boolean setBlastResistance(Material m, float resistance) {
try {
Object block = getBlockClass(getCraftMagicNumbersClass(), m);
writeField(block, "durability", resistance);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException
| SecurityException | ClassNotFoundException e) {
e.printStackTrace();
return false;
}
return true;
}
}

private static class BlastResistanceNMS_V2 extends BlastResistanceNMS {
public boolean setBlastResistance(Material m, float resistance) {
try {
Object block = getBlockClass(getCraftMagicNumbersClass(), m);
writeField(block, "aH", resistance); // obfuscated explosionResistance
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException
| SecurityException | ClassNotFoundException e) {
e.printStackTrace();
return false;
}
return true;
}
}

private static class BlastResistanceNMS_v1_20 extends BlastResistanceNMS {
public boolean setBlastResistance(Material m, float resistance) {
try {
Object block = getBlockClass(getCraftMagicNumbersClass(), m);
writeField(block, "aF", resistance); // obfuscated explosionResistance
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException
| SecurityException | ClassNotFoundException e) {
e.printStackTrace();
return false;
}
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;

import java.util.HashSet;
import java.util.Set;

import static net.countercraft.movecraft.util.ChatUtils.ERROR_PREFIX;

public class AADirectors extends Directors implements Listener {
public static final NamespacedKey ALLOW_AA_DIRECTOR_SIGN = new NamespacedKey("movecraft-combat", "allow_aa_director_sign");
private static final String HEADER = "AA Director";
public static int AADirectorDistance = 50;
public static int AADirectorNodeDistance = 3;
public static int AADirectorRange = 120;
private long lastCheck = 0;

Expand All @@ -46,6 +50,7 @@ public static void register() {

public static void load(@NotNull FileConfiguration config) {
AADirectorDistance = config.getInt("AADirectorDistance", 50);
AADirectorNodeDistance = config.getInt("AADirectorNodeDistance", 3);
AADirectorRange = config.getInt("AADirectorRange", 120);
}

Expand Down Expand Up @@ -75,28 +80,45 @@ private void processFireball(@NotNull SmallFireball fireball) {
if (!(c instanceof PlayerCraft) || !hasDirector((PlayerCraft) c))
return;

Player p = getDirector((PlayerCraft) c);
HashSet<DirectorData> craftDirectors = getCraftDirectors((PlayerCraft) c);
Player player;
Player dominantPlayer = null;

MovecraftLocation midPoint = c.getHitBox().getMidPoint();
int distX = Math.abs(midPoint.getX() - fireball.getLocation().getBlockX());
int distY = Math.abs(midPoint.getY() - fireball.getLocation().getBlockY());
int distZ = Math.abs(midPoint.getZ() - fireball.getLocation().getBlockZ());
if (distX > AADirectorDistance || distY > AADirectorDistance || distZ > AADirectorDistance)
return;
for (DirectorData data : craftDirectors) {
if (data.getSelectedNodes().isEmpty() || data.getSignLocations().isEmpty()) {
dominantPlayer = data.getPlayer();
}
}
if (dominantPlayer != null) {
player = dominantPlayer;
} else {
player = getClosestDirectorFromProjectile(
craftDirectors,
fireball.getLocation().toVector(),
AADirectorNodeDistance
);
}

fireball.setShooter(p);
if (player == null || player.getInventory().getItemInMainHand().getType() != Directors.DirectorTool)
return;

if (p == null || p.getInventory().getItemInMainHand().getType() != Directors.DirectorTool)
MovecraftLocation midpoint = c.getHitBox().getMidPoint();
int distX = Math.abs(midpoint.getX() - fireball.getLocation().getBlockX());
int distY = Math.abs(midpoint.getY() - fireball.getLocation().getBlockY());
int distZ = Math.abs(midpoint.getZ() - fireball.getLocation().getBlockZ());
if (distX*distX + distY*distY + distZ*distZ >= AADirectorDistance*AADirectorDistance)
return;

fireball.setShooter(player);

Vector fireballVector = fireball.getVelocity();
double speed = fireballVector.length(); // store the speed to add it back in later, since all the values we will be using are "normalized", IE: have a speed of 1
fireballVector = fireballVector.normalize(); // you normalize it for comparison with the new direction to see if we are trying to steer too far

Block targetBlock = DirectorUtils.getDirectorBlock(p, AADirectorRange);
Block targetBlock = DirectorUtils.getDirectorBlock(player, AADirectorRange);
Vector targetVector;
if (targetBlock == null || targetBlock.getType().equals(Material.AIR)) // the player is looking at nothing, shoot in that general direction
targetVector = p.getLocation().getDirection();
targetVector = player.getLocation().getDirection();
else { // shoot directly at the block the player is looking at (IE: with convergence)
targetVector = targetBlock.getLocation().toVector().subtract(fireball.getLocation().toVector());
targetVector = targetVector.normalize();
Expand Down Expand Up @@ -177,8 +199,15 @@ public void onSignClick(@NotNull PlayerInteractEvent e) {
return;
}

Set<String> selectedLines = processSign(sign);
if (isNodesShared(selectedLines, foundCraft, p)) {
p.sendMessage(ERROR_PREFIX + " " + I18nSupport.getInternationalisedString("AADirector - Must Not Share Nodes"));
return;
}

clearDirector(p);
addDirector(foundCraft, p);
addDirector(p, foundCraft, selectedLines);

p.sendMessage(I18nSupport.getInternationalisedString("AADirector - Directing"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
import net.countercraft.movecraft.util.MathUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.block.data.type.TNT;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
Expand All @@ -33,7 +35,9 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import static net.countercraft.movecraft.util.ChatUtils.ERROR_PREFIX;
Expand All @@ -42,11 +46,11 @@ public class CannonDirectors extends Directors implements Listener {
public static final NamespacedKey ALLOW_CANNON_DIRECTOR_SIGN = new NamespacedKey("movecraft-combat", "allow_cannon_director_sign");
private static final String HEADER = "Cannon Director";
public static int CannonDirectorDistance = 100;
public static int CannonDirectorNodeDistance = 3;
public static int CannonDirectorRange = 120;
private final Object2DoubleOpenHashMap<TNTPrimed> tracking = new Object2DoubleOpenHashMap<>();
private long lastCheck = 0;


public CannonDirectors() {
super();
}
Expand All @@ -57,6 +61,7 @@ public static void register() {

public static void load(@NotNull FileConfiguration config) {
CannonDirectorDistance = config.getInt("CannonDirectorDistance", 100);
CannonDirectorNodeDistance = config.getInt("CannonDirectorNodeDistance", 3);
CannonDirectorRange = config.getInt("CannonDirectorRange", 120);
}

Expand Down Expand Up @@ -98,16 +103,33 @@ private void processTNT(@NotNull TNTPrimed tnt) {
if (!(c instanceof PlayerCraft))
return;

MovecraftLocation midpoint = c.getHitBox().getMidPoint();
int distX = Math.abs(midpoint.getX() - tnt.getLocation().getBlockX());
int distY = Math.abs(midpoint.getY() - tnt.getLocation().getBlockY());
int distZ = Math.abs(midpoint.getZ() - tnt.getLocation().getBlockZ());
if (!hasDirector((PlayerCraft) c) || distX >= CannonDirectorDistance
|| distY >= CannonDirectorDistance || distZ >= CannonDirectorDistance)
// Automatically calibrate the TNT location based on its velocity to make it closer to the firing point.
Location correctedLocation = tnt.getLocation().clone().add(tnt.getVelocity().clone().multiply(-1.2));
Vector correctedPosition = correctedLocation.toVector();

HashSet<DirectorData> craftDirectors = getCraftDirectors((PlayerCraft) c);
Player player = null;
for (DirectorData data : craftDirectors) {
if (data.getSelectedNodes().isEmpty()) {
player = data.getPlayer();
}
}
if (player == null) {
player = getClosestDirectorFromProjectile(
craftDirectors,
correctedPosition,
CannonDirectorNodeDistance
);
}

if (player == null || player.getInventory().getItemInMainHand().getType() != Directors.DirectorTool)
return;

Player p = getDirector((PlayerCraft) c);
if (p == null || p.getInventory().getItemInMainHand().getType() != Directors.DirectorTool)
MovecraftLocation midpoint = c.getHitBox().getMidPoint();
int distX = Math.abs(midpoint.getX() - correctedPosition.getBlockX());
int distY = Math.abs(midpoint.getY() - correctedPosition.getBlockY());
int distZ = Math.abs(midpoint.getZ() - correctedPosition.getBlockZ());
if (distX*distX + distY*distY + distZ*distZ >= CannonDirectorDistance*CannonDirectorDistance)
return;

// Store the speed to add it back in later, since all the values we will be using are "normalized", IE: have a speed of 1
Expand All @@ -117,10 +139,10 @@ private void processTNT(@NotNull TNTPrimed tnt) {
double horizontalSpeed = tntVector.length();
tntVector = tntVector.normalize(); // you normalize it for comparison with the new direction to see if we are trying to steer too far

Block targetBlock = DirectorUtils.getDirectorBlock(p, CannonDirectorRange);
Block targetBlock = DirectorUtils.getDirectorBlock(player, CannonDirectorRange);
Vector targetVector;
if (targetBlock == null || targetBlock.getType().equals(Material.AIR)) // the player is looking at nothing, shoot in that general direction
targetVector = p.getLocation().getDirection();
targetVector = player.getLocation().getDirection();
else // shoot directly at the block the player is looking at (IE: with convergence)
targetVector = targetBlock.getLocation().toVector().subtract(tnt.getLocation().toVector());

Expand Down Expand Up @@ -207,8 +229,15 @@ public final void onSignClick(@NotNull PlayerInteractEvent e) {
return;
}

Set<String> selectedLines = processSign(sign);
if (isNodesShared(selectedLines, foundCraft, p)) {
p.sendMessage(ERROR_PREFIX + " " + I18nSupport.getInternationalisedString("CannonDirector - Must Not Share Nodes"));
return;
}

clearDirector(p);
addDirector(foundCraft, p);
addDirector(p, foundCraft, selectedLines);

p.sendMessage(I18nSupport.getInternationalisedString("CannonDirector - Directing"));
}

Expand Down
Loading

0 comments on commit dd11010

Please sign in to comment.