Added ability to set the max health of a disguise using attributes

This commit is contained in:
libraryaddict
2014-05-23 14:52:21 +12:00
parent 0c305a8151
commit 26ccaabe83
7 changed files with 89 additions and 9 deletions

View File

@@ -17,6 +17,7 @@ public class DisguiseConfig {
private static boolean keepDisguiseEntityDespawn;
private static boolean keepDisguisePlayerDeath;
private static boolean keepDisguisePlayerLogout;
private static boolean maxHealthIsDisguisedEntity;
private static boolean miscDisguisesForLivingEnabled;
private static boolean modifyBoundingBox;
private static boolean movementEnabled;
@@ -87,6 +88,10 @@ public class DisguiseConfig {
return keepDisguisePlayerLogout;
}
public static boolean isMaxHealthDeterminedByDisguisedEntity() {
return maxHealthIsDisguisedEntity;
}
public static boolean isMetadataPacketsEnabled() {
return sendsEntityMetadata;
}
@@ -240,6 +245,10 @@ public class DisguiseConfig {
keepDisguisePlayerLogout = keepDisguise;
}
public static void setMaxHealthDeterminedByDisguisedEntity(boolean isDetermined) {
maxHealthIsDisguisedEntity = isDetermined;
}
public static void setMetadataPacketsEnabled(boolean enabled) {
sendsEntityMetadata = enabled;
}

View File

@@ -27,6 +27,7 @@ import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Damageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Zombie;
@@ -107,6 +108,7 @@ public class LibsDisguises extends JavaPlugin {
DisguiseConfig.setEntityStatusPacketsEnabled(getConfig().getBoolean("PacketsEnabled.EntityStatus"));
DisguiseConfig.setCollectPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Collect"));
DisguiseConfig.setMetadataPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Metadata"));
DisguiseConfig.setMaxHealthDeterminedByDisguisedEntity(getConfig().getBoolean("MaxHealthDeterminedByEntity"));
try {
// 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.
@@ -234,7 +236,8 @@ public class LibsDisguises extends JavaPlugin {
break;
}
}
DisguiseValues disguiseValues = new DisguiseValues(disguiseType, nmsEntity.getClass(), entitySize);
DisguiseValues disguiseValues = new DisguiseValues(disguiseType, nmsEntity.getClass(), entitySize,
bukkitEntity instanceof Damageable ? ((Damageable) bukkitEntity).getMaxHealth() : 0);
for (WrappedWatchableObject watch : WrappedDataWatcher.getEntityWatcher(bukkitEntity).getWatchableObjects()) {
disguiseValues.setMetaValue(watch.getIndex(), watch.getValue());
// Uncomment when I need to find the new datawatcher values for a class..

View File

@@ -31,6 +31,8 @@ public class LivingWatcher extends FlagWatcher {
ex.printStackTrace();
}
}
private double maxHealth;
private boolean maxHealthSet;
private HashSet<Integer> potionEffects = new HashSet<Integer>();
public LivingWatcher(Disguise disguise) {
@@ -48,6 +50,8 @@ public class LivingWatcher extends FlagWatcher {
public LivingWatcher clone(Disguise disguise) {
LivingWatcher clone = (LivingWatcher) super.clone(disguise);
clone.potionEffects = (HashSet<Integer>) potionEffects.clone();
clone.maxHealth = maxHealth;
clone.maxHealthSet = maxHealthSet;
return clone;
}
@@ -59,6 +63,10 @@ public class LivingWatcher extends FlagWatcher {
return (Float) getValue(6, 0F);
}
public double getMaxHealth() {
return maxHealth;
}
public boolean getPotionParticlesRemoved() {
return (Byte) getValue(8, (byte) 0) == 1;
}
@@ -105,6 +113,10 @@ public class LivingWatcher extends FlagWatcher {
return (Byte) getValue(11, (byte) 0) == 1;
}
public boolean isMaxHealthSet() {
return maxHealthSet;
}
public void removePotionEffect(PotionEffectType type) {
if (potionEffects.contains(type.getId())) {
potionEffects.remove(type.getId());
@@ -139,4 +151,10 @@ public class LivingWatcher extends FlagWatcher {
sendData(6);
}
public void setMaxHealth(double newHealth) {
this.maxHealth = newHealth;
maxHealthSet = true;
// TODO Send packet
}
}

View File

@@ -47,13 +47,15 @@ public class DisguiseValues {
private FakeBoundingBox babyBox;
private float[] entitySize;
private int enumEntitySize;
private double maxHealth;
private HashMap<Integer, Object> metaValues = new HashMap<Integer, Object>();
private Class nmsEntityClass;
public DisguiseValues(DisguiseType type, Class classType, int entitySize) {
public DisguiseValues(DisguiseType type, Class classType, int entitySize, double maxHealth) {
values.put(type, this);
enumEntitySize = entitySize;
nmsEntityClass = classType;
this.maxHealth = maxHealth;
}
public FakeBoundingBox getAdultBox() {
@@ -112,6 +114,10 @@ public class DisguiseValues {
return (int) Math.floor(paramDouble * 32.0D);
}
public double getMaxHealth() {
return maxHealth;
}
public HashMap<Integer, Object> getMetaValues() {
return metaValues;
}

View File

@@ -15,6 +15,7 @@ import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
import me.libraryaddict.disguise.disguisetypes.MobDisguise;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher;
import me.libraryaddict.disguise.utilities.DisguiseSound.SoundType;
import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion;
@@ -43,6 +44,8 @@ import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.wrappers.WrappedAttribute;
import com.comphenix.protocol.wrappers.WrappedAttribute.Builder;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
@@ -1173,10 +1176,39 @@ public class PacketsManager {
if (disguise != null) {
packets = new PacketContainer[] { sentPacket };
// If packet is PacketType.Play.Server.UPDATE_ATTRIBUTES
// This packet sends attributes
if (sentPacket.getType() == PacketType.Play.Server.UPDATE_ATTRIBUTES) {
packets = new PacketContainer[0];
if (disguise.isMiscDisguise()) {
packets = new PacketContainer[0];
} else {
List<WrappedAttribute> attributes = new ArrayList<WrappedAttribute>();
for (WrappedAttribute attribute : sentPacket.getAttributeCollectionModifier().read(0)) {
if (attribute.getAttributeKey().equals("generic.maxHealth")) {
packets[0] = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES);
Builder builder;
if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) {
builder = WrappedAttribute.newBuilder();
builder.attributeKey("generic.maxHealth");
builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth());
} else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity()) {
builder = WrappedAttribute.newBuilder(attribute);
} else {
builder = WrappedAttribute.newBuilder();
builder.attributeKey("generic.maxHealth");
builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth());
}
builder.packet(packets[0]);
attributes.add(builder.build());
break;
}
}
if (!attributes.isEmpty()) {
packets[0].getIntegers().write(0, entity.getEntityId());
packets[0].getAttributeCollectionModifier().write(0, attributes);
} else {
packets = new PacketContainer[0];
}
}
}
else if (sentPacket.getType() == PacketType.Play.Server.ATTACH_ENTITY) {