Actually set the bounding box

This commit is contained in:
libraryaddict 2013-12-22 13:03:47 +13:00
parent 686b25d59b
commit f6d0994079
7 changed files with 160 additions and 86 deletions

View File

@ -41,3 +41,7 @@ ShowNamesAboveDisguises: false
# This supports the above option. # This supports the above option.
# If this is true, then the name shown above the head appears regardless of if you are looking at the disguise directly or not. # If this is true, then the name shown above the head appears regardless of if you are looking at the disguise directly or not.
NameAboveHeadAlwaysVisible: true NameAboveHeadAlwaysVisible: true
# This modifys the bounding box, This is stuff like can a arrow hit them.
# If you turn this to true, arrows will act like they hit the disguise in the right place!
# So someone disguised as a enderdragon will easily get shot down by arrows!
ModifyBoundingBox: true

View File

@ -22,6 +22,7 @@ public class DisguiseAPI {
private static boolean hidingArmor; private static boolean hidingArmor;
private static boolean hidingHeldItem; private static boolean hidingHeldItem;
private static boolean isEntityAnimationsAdded; private static boolean isEntityAnimationsAdded;
private static boolean modifyBoundingBox;
private static boolean removeUnseenDisguises; private static boolean removeUnseenDisguises;
private static boolean sendVelocity; private static boolean sendVelocity;
private static boolean showNameAboveHead; private static boolean showNameAboveHead;
@ -191,6 +192,10 @@ public class DisguiseAPI {
return hidingHeldItem; return hidingHeldItem;
} }
public static boolean isModifyBoundingBox() {
return modifyBoundingBox;
}
public static boolean isNameAboveHeadAlwaysVisible() { public static boolean isNameAboveHeadAlwaysVisible() {
return showNameAboveHeadAlwaysVisible; return showNameAboveHeadAlwaysVisible;
} }
@ -261,6 +266,10 @@ public class DisguiseAPI {
} }
} }
public static void setModifyBoundingBox(boolean modifyBounding) {
modifyBoundingBox = modifyBounding;
}
public static void setNameAboveHeadAlwaysVisible(boolean alwaysVisible) { public static void setNameAboveHeadAlwaysVisible(boolean alwaysVisible) {
showNameAboveHeadAlwaysVisible = alwaysVisible; showNameAboveHeadAlwaysVisible = alwaysVisible;
} }

View File

@ -67,6 +67,7 @@ public class LibsDisguises extends JavaPlugin {
DisguiseAPI.setAddEntityAnimations(getConfig().getBoolean("AddEntityAnimations")); DisguiseAPI.setAddEntityAnimations(getConfig().getBoolean("AddEntityAnimations"));
DisguiseAPI.setNameOfPlayerShownAboveDisguise(getConfig().getBoolean("ShowNamesAboveDisguises")); DisguiseAPI.setNameOfPlayerShownAboveDisguise(getConfig().getBoolean("ShowNamesAboveDisguises"));
DisguiseAPI.setNameAboveHeadAlwaysVisible(getConfig().getBoolean("NameAboveHeadAlwaysVisible")); DisguiseAPI.setNameAboveHeadAlwaysVisible(getConfig().getBoolean("NameAboveHeadAlwaysVisible"));
DisguiseAPI.setModifyBoundingBox(getConfig().getBoolean("ModifyBoundingBox"));
try { try {
// Here I use reflection to set the plugin for Disguise.. // Here I use reflection to set the plugin for Disguise..
// Kind of stupid but I don't want open API calls for a commonly used object. // Kind of stupid but I don't want open API calls for a commonly used object.

View File

@ -7,6 +7,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType;
import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.HorseWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.HorseWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher;
@ -35,6 +36,7 @@ public abstract class Disguise {
private boolean hearSelfDisguise = DisguiseAPI.isSelfDisguisesSoundsReplaced(); private boolean hearSelfDisguise = DisguiseAPI.isSelfDisguisesSoundsReplaced();
private boolean hideArmorFromSelf = DisguiseAPI.isHidingArmorFromSelf(); private boolean hideArmorFromSelf = DisguiseAPI.isHidingArmorFromSelf();
private boolean hideHeldItemFromSelf = DisguiseAPI.isHidingHeldItemFromSelf(); private boolean hideHeldItemFromSelf = DisguiseAPI.isHidingHeldItemFromSelf();
private boolean modifyBoundingBox = DisguiseAPI.isModifyBoundingBox();
private boolean replaceSounds = DisguiseAPI.isSoundEnabled(); private boolean replaceSounds = DisguiseAPI.isSoundEnabled();
private BukkitRunnable velocityRunnable; private BukkitRunnable velocityRunnable;
private boolean velocitySent = DisguiseAPI.isVelocitySent(); private boolean velocitySent = DisguiseAPI.isVelocitySent();
@ -56,8 +58,10 @@ public abstract class Disguise {
if (getWatcher() != null) if (getWatcher() != null)
return; return;
if (newType.getEntityType() == null) { if (newType.getEntityType() == null) {
throw new RuntimeException("DisguiseType " + newType throw new RuntimeException(
+ " was used in a futile attempt to construct a disguise, but this version of craftbukkit does not have that entity"); "DisguiseType "
+ newType
+ " was used in a futile attempt to construct a disguise, but this version of craftbukkit does not have that entity");
} }
// Set the disguise type // Set the disguise type
disguiseType = newType; disguiseType = newType;
@ -179,7 +183,7 @@ public abstract class Disguise {
final boolean sendMovementPacket = movement; final boolean sendMovementPacket = movement;
final double vectorY = fallSpeed; final double vectorY = fallSpeed;
final boolean alwaysSendVelocity = alwaysSend; final boolean alwaysSendVelocity = alwaysSend;
final TargetedDisguise disguise=(TargetedDisguise) this; final TargetedDisguise disguise = (TargetedDisguise) this;
// A scheduler to clean up any unused disguises. // A scheduler to clean up any unused disguises.
velocityRunnable = new BukkitRunnable() { velocityRunnable = new BukkitRunnable() {
private int i = 0; private int i = 0;
@ -344,6 +348,10 @@ public abstract class Disguise {
return false; return false;
} }
public boolean isModifyBoundingBox() {
return modifyBoundingBox;
}
public boolean isPlayerDisguise() { public boolean isPlayerDisguise() {
return false; return false;
} }
@ -439,6 +447,19 @@ public abstract class Disguise {
} }
} }
public void setModifyBoundingBox(boolean modifyBox) {
if (((TargetedDisguise) this).getDisguiseTarget() != TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) {
throw new RuntimeException(
"Cannot modify the bounding box of a disguise which is not TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS");
}
if (isModifyBoundingBox() != modifyBox) {
this.modifyBoundingBox = modifyBox;
if (DisguiseUtilities.isDisguiseInUse(this)) {
DisguiseUtilities.doBoundingBox((TargetedDisguise) this);
}
}
}
public void setReplaceSounds(boolean areSoundsReplaced) { public void setReplaceSounds(boolean areSoundsReplaced) {
replaceSounds = areSoundsReplaced; replaceSounds = areSoundsReplaced;
} }

View File

@ -11,14 +11,19 @@ import java.util.List;
import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; import me.libraryaddict.disguise.disguisetypes.TargetedDisguise;
import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher;
import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType; import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
@ -38,13 +43,14 @@ public class DisguiseUtilities {
private static HashMap<Integer, HashSet<TargetedDisguise>> targetedDisguises = new HashMap<Integer, HashSet<TargetedDisguise>>(); private static HashMap<Integer, HashSet<TargetedDisguise>> targetedDisguises = new HashMap<Integer, HashSet<TargetedDisguise>>();
public static void addDisguise(int entityId, TargetedDisguise disguise) { public static void addDisguise(int entityId, TargetedDisguise disguise) {
// TODO Make sure that the disguised entity doesn't have the player looking at other girls
// ^ Done?
if (!getDisguises().containsKey(entityId)) { if (!getDisguises().containsKey(entityId)) {
getDisguises().put(entityId, new HashSet<TargetedDisguise>()); getDisguises().put(entityId, new HashSet<TargetedDisguise>());
} }
getDisguises().get(entityId).add(disguise); getDisguises().get(entityId).add(disguise);
checkConflicts(disguise, null); checkConflicts(disguise, null);
if (disguise.getDisguiseTarget() == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS && disguise.isModifyBoundingBox()) {
doBoundingBox(disguise);
}
} }
/** /**
@ -126,6 +132,36 @@ public class DisguiseUtilities {
} }
} }
public static void doBoundingBox(TargetedDisguise disguise) {
// TODO Slimes
Entity entity = disguise.getEntity();
if (entity != null) {
if (isDisguiseInUse(disguise)) {
DisguiseValues values = DisguiseValues.getDisguiseValues(disguise.getType());
FakeBoundingBox fakeBox = values.getAdultBox();
if (values.getBabyBox() != null) {
if (disguise.getWatcher() instanceof AgeableWatcher
&& (((AgeableWatcher) disguise.getWatcher()).isBaby())
|| (disguise.getWatcher() instanceof ZombieWatcher && ((ZombieWatcher) disguise.getWatcher())
.isBaby())) {
fakeBox = values.getBabyBox();
}
}
ReflectionManager.setBoundingBox(entity, fakeBox.getX(), fakeBox.getY(), fakeBox.getZ());
} else {
DisguiseValues values = DisguiseValues.getDisguiseValues(DisguiseType.getType(entity.getType()));
FakeBoundingBox fakeBox = values.getAdultBox();
if (values.getBabyBox() != null) {
if (entity instanceof Ageable && !(((Ageable) entity).isAdult())
|| (entity instanceof Zombie && ((Zombie) entity).isBaby())) {
fakeBox = values.getBabyBox();
}
}
ReflectionManager.setBoundingBox(disguise.getEntity(), fakeBox.getX(), fakeBox.getY(), fakeBox.getZ());
}
}
}
@Deprecated @Deprecated
public static TargetedDisguise getDisguise(int entityId) { public static TargetedDisguise getDisguise(int entityId) {
TargetedDisguise toReturn = null; TargetedDisguise toReturn = null;
@ -275,6 +311,9 @@ public class DisguiseUtilities {
if (getDisguises().get(entityId).isEmpty()) { if (getDisguises().get(entityId).isEmpty()) {
getDisguises().remove(entityId); getDisguises().remove(entityId);
} }
if (disguise.getDisguiseTarget() == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS && disguise.isModifyBoundingBox()) {
doBoundingBox(disguise);
}
return true; return true;
} }
return false; return false;

View File

@ -43,11 +43,11 @@ public class DisguiseValues {
return getDisguiseValues(type).getNmsEntityClass(); return getDisguiseValues(type).getNmsEntityClass();
} }
private FakeBoundingBox adultBox;
private FakeBoundingBox babyBox;
private int enumEntitySize; private int enumEntitySize;
private HashMap<Integer, Object> metaValues = new HashMap<Integer, Object>(); private HashMap<Integer, Object> metaValues = new HashMap<Integer, Object>();
private Class nmsEntityClass; private Class nmsEntityClass;
private FakeBoundingBox adultBox;
private FakeBoundingBox babyBox;
public DisguiseValues(DisguiseType type, Class classType, int entitySize) { public DisguiseValues(DisguiseType type, Class classType, int entitySize) {
values.put(type, this); values.put(type, this);
@ -55,22 +55,14 @@ public class DisguiseValues {
nmsEntityClass = classType; nmsEntityClass = classType;
} }
public FakeBoundingBox getBabyBox() {
return babyBox;
}
public void setAdultBox(FakeBoundingBox newBox) {
adultBox = newBox;
}
public void setBabyBox(FakeBoundingBox newBox) {
babyBox = newBox;
}
public FakeBoundingBox getAdultBox() { public FakeBoundingBox getAdultBox() {
return adultBox; return adultBox;
} }
public FakeBoundingBox getBabyBox() {
return babyBox;
}
public int getEntitySize(double paramDouble) { public int getEntitySize(double paramDouble) {
double d = paramDouble - (((int) Math.floor(paramDouble)) + 0.5D); double d = paramDouble - (((int) Math.floor(paramDouble)) + 0.5D);
@ -123,6 +115,14 @@ public class DisguiseValues {
return nmsEntityClass; return nmsEntityClass;
} }
public void setAdultBox(FakeBoundingBox newBox) {
adultBox = newBox;
}
public void setBabyBox(FakeBoundingBox newBox) {
babyBox = newBox;
}
public void setMetaValue(int no, Object value) { public void setMetaValue(int no, Object value) {
metaValues.put(no, value); metaValues.put(no, value);
} }

View File

@ -55,6 +55,35 @@ public class ReflectionManager {
} }
} }
public static Object createEntityInstance(String entityName) {
try {
Class entityClass = getNmsClass("Entity" + entityName);
Object entityObject;
Object world = getWorld(Bukkit.getWorlds().get(0));
if (entityName.equals("Player")) {
Object minecraftServer = getNmsClass("MinecraftServer").getMethod("getServer").invoke(null);
Object playerinteractmanager = getNmsClass("PlayerInteractManager").getConstructor(getNmsClass("World"))
.newInstance(world);
if (isAfter17()) {
Object gameProfile = getGameProfile("LibsDisguises");
entityObject = entityClass.getConstructor(getNmsClass("MinecraftServer"), getNmsClass("WorldServer"),
gameProfile.getClass(), playerinteractmanager.getClass()).newInstance(minecraftServer, world,
gameProfile, playerinteractmanager);
} else {
entityObject = entityClass.getConstructor(getNmsClass("MinecraftServer"), getNmsClass("World"), String.class,
playerinteractmanager.getClass()).newInstance(minecraftServer, world, "LibsDisguises",
playerinteractmanager);
}
} else {
entityObject = entityClass.getConstructor(getNmsClass("World")).newInstance(world);
}
return entityObject;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static FakeBoundingBox getBoundingBox(Entity entity) { public static FakeBoundingBox getBoundingBox(Entity entity) {
try { try {
Object boundingBox = getNmsClass("Entity").getField("boundingBox").get(getNmsEntity(entity)); Object boundingBox = getNmsClass("Entity").getField("boundingBox").get(getNmsEntity(entity));
@ -94,72 +123,6 @@ public class ReflectionManager {
return null; return null;
} }
public static void setBoundingBox(Entity entity, double newX, double newY, double newZ) {
try {
Object boundingBox = getNmsClass("Entity").getField("boundingBox").get(getNmsEntity(entity));
double x = 0, y = 0, z = 0;
int stage = 0;
for (Field field : boundingBox.getClass().getFields()) {
if (field.getType().getSimpleName().equals("Double")) {
stage++;
switch (stage) {
case 1:
x = field.getDouble(boundingBox);
break;
case 2:
y = field.getDouble(boundingBox);
break;
case 3:
z = field.getDouble(boundingBox);
break;
case 4:
field.setDouble(boundingBox, x);
break;
case 5:
field.setDouble(boundingBox, y);
break;
case 6:
field.setDouble(boundingBox, z);
break;
default:
throw new Exception("Error while setting the bounding box, more doubles than I thought??");
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static Object createEntityInstance(String entityName) {
try {
Class entityClass = getNmsClass("Entity" + entityName);
Object entityObject;
Object world = getWorld(Bukkit.getWorlds().get(0));
if (entityName.equals("Player")) {
Object minecraftServer = getNmsClass("MinecraftServer").getMethod("getServer").invoke(null);
Object playerinteractmanager = getNmsClass("PlayerInteractManager").getConstructor(getNmsClass("World"))
.newInstance(world);
if (isAfter17()) {
Object gameProfile = getGameProfile("LibsDisguises");
entityObject = entityClass.getConstructor(getNmsClass("MinecraftServer"), getNmsClass("WorldServer"),
gameProfile.getClass(), playerinteractmanager.getClass()).newInstance(minecraftServer, world,
gameProfile, playerinteractmanager);
} else {
entityObject = entityClass.getConstructor(getNmsClass("MinecraftServer"), getNmsClass("World"), String.class,
playerinteractmanager.getClass()).newInstance(minecraftServer, world, "LibsDisguises",
playerinteractmanager);
}
} else {
entityObject = entityClass.getConstructor(getNmsClass("World")).newInstance(world);
}
return entityObject;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Entity getBukkitEntity(Object nmsEntity) { public static Entity getBukkitEntity(Object nmsEntity) {
try { try {
Entity bukkitEntity = (Entity) ReflectionManager.getNmsClass("Entity").getMethod("getBukkitEntity").invoke(nmsEntity); Entity bukkitEntity = (Entity) ReflectionManager.getNmsClass("Entity").getMethod("getBukkitEntity").invoke(nmsEntity);
@ -272,4 +235,41 @@ public class ReflectionManager {
return after17; return after17;
} }
public static void setBoundingBox(Entity entity, double newX, double newY, double newZ) {
try {
Object boundingBox = getNmsClass("Entity").getField("boundingBox").get(getNmsEntity(entity));
double x = 0, y = 0, z = 0;
int stage = 0;
for (Field field : boundingBox.getClass().getFields()) {
if (field.getType().getSimpleName().equals("Double")) {
stage++;
switch (stage) {
case 1:
x = field.getDouble(boundingBox);
break;
case 2:
y = field.getDouble(boundingBox);
break;
case 3:
z = field.getDouble(boundingBox);
break;
case 4:
field.setDouble(boundingBox, x);
break;
case 5:
field.setDouble(boundingBox, y);
break;
case 6:
field.setDouble(boundingBox, z);
break;
default:
throw new Exception("Error while setting the bounding box, more doubles than I thought??");
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
} }