Added ability to set the max health of a disguise using attributes
This commit is contained in:
parent
0c305a8151
commit
26ccaabe83
@ -64,6 +64,12 @@ KeepDisguises:
|
|||||||
EntityDespawn: false
|
EntityDespawn: false
|
||||||
PlayerDeath: false
|
PlayerDeath: false
|
||||||
PlayerLogout: false
|
PlayerLogout: false
|
||||||
|
|
||||||
|
# This controls if a entitys max health is determined by the entity, or by the disguise.
|
||||||
|
# Wither is 200, a player is 20. With this enabled, a player disguised as a wither will have the boss bar health accurate to the players health.
|
||||||
|
# Else it will be 1/20 of the boss bar when he is full health.
|
||||||
|
# Setting this in LivingWatcher overrides both values.
|
||||||
|
MaxHealthDeterminedByEntity: true
|
||||||
|
|
||||||
# This here is a option to turn off misc disguises.
|
# This here is a option to turn off misc disguises.
|
||||||
# This means you can not have a living entity disguise as a non-living entity.
|
# This means you can not have a living entity disguise as a non-living entity.
|
||||||
@ -91,6 +97,7 @@ PacketsEnabled:
|
|||||||
# This is good if performance is extremely in need.
|
# This is good if performance is extremely in need.
|
||||||
# This is bad to disable unless you are ONLY going to use the disguises for decorations.
|
# This is bad to disable unless you are ONLY going to use the disguises for decorations.
|
||||||
# To be honest. This is basically "Disable entity animations". That option is called 'AddEntityAnimations' in the config but unlike that, this is always in effect.
|
# To be honest. This is basically "Disable entity animations". That option is called 'AddEntityAnimations' in the config but unlike that, this is always in effect.
|
||||||
|
# Animations set by use of the api or through the disguise command are still in effect.
|
||||||
Metadata: true
|
Metadata: true
|
||||||
# Movement packets are the biggest cpu hit. These are majorly used to ensure that the disguises facing direction isn't bugged up
|
# Movement packets are the biggest cpu hit. These are majorly used to ensure that the disguises facing direction isn't bugged up
|
||||||
Movement: true
|
Movement: true
|
||||||
|
15
pom.xml
15
pom.xml
@ -75,16 +75,21 @@
|
|||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>org.bukkit</groupId>
|
|
||||||
<artifactId>craftbukkit</artifactId>
|
|
||||||
<version>1.7.8-R0.1-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.comphenix.protocol</groupId>
|
<groupId>com.comphenix.protocol</groupId>
|
||||||
<artifactId>ProtocolLib</artifactId>
|
<artifactId>ProtocolLib</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>3.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot-api</artifactId>
|
||||||
|
<version>1.7.8-R0.1-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot</artifactId>
|
||||||
|
<version>1.7.8-R0.1-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
|
@ -17,6 +17,7 @@ public class DisguiseConfig {
|
|||||||
private static boolean keepDisguiseEntityDespawn;
|
private static boolean keepDisguiseEntityDespawn;
|
||||||
private static boolean keepDisguisePlayerDeath;
|
private static boolean keepDisguisePlayerDeath;
|
||||||
private static boolean keepDisguisePlayerLogout;
|
private static boolean keepDisguisePlayerLogout;
|
||||||
|
private static boolean maxHealthIsDisguisedEntity;
|
||||||
private static boolean miscDisguisesForLivingEnabled;
|
private static boolean miscDisguisesForLivingEnabled;
|
||||||
private static boolean modifyBoundingBox;
|
private static boolean modifyBoundingBox;
|
||||||
private static boolean movementEnabled;
|
private static boolean movementEnabled;
|
||||||
@ -87,6 +88,10 @@ public class DisguiseConfig {
|
|||||||
return keepDisguisePlayerLogout;
|
return keepDisguisePlayerLogout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isMaxHealthDeterminedByDisguisedEntity() {
|
||||||
|
return maxHealthIsDisguisedEntity;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isMetadataPacketsEnabled() {
|
public static boolean isMetadataPacketsEnabled() {
|
||||||
return sendsEntityMetadata;
|
return sendsEntityMetadata;
|
||||||
}
|
}
|
||||||
@ -240,6 +245,10 @@ public class DisguiseConfig {
|
|||||||
keepDisguisePlayerLogout = keepDisguise;
|
keepDisguisePlayerLogout = keepDisguise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setMaxHealthDeterminedByDisguisedEntity(boolean isDetermined) {
|
||||||
|
maxHealthIsDisguisedEntity = isDetermined;
|
||||||
|
}
|
||||||
|
|
||||||
public static void setMetadataPacketsEnabled(boolean enabled) {
|
public static void setMetadataPacketsEnabled(boolean enabled) {
|
||||||
sendsEntityMetadata = enabled;
|
sendsEntityMetadata = enabled;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import org.bukkit.configuration.ConfigurationSection;
|
|||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.entity.Ageable;
|
import org.bukkit.entity.Ageable;
|
||||||
|
import org.bukkit.entity.Damageable;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.Zombie;
|
import org.bukkit.entity.Zombie;
|
||||||
@ -107,6 +108,7 @@ public class LibsDisguises extends JavaPlugin {
|
|||||||
DisguiseConfig.setEntityStatusPacketsEnabled(getConfig().getBoolean("PacketsEnabled.EntityStatus"));
|
DisguiseConfig.setEntityStatusPacketsEnabled(getConfig().getBoolean("PacketsEnabled.EntityStatus"));
|
||||||
DisguiseConfig.setCollectPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Collect"));
|
DisguiseConfig.setCollectPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Collect"));
|
||||||
DisguiseConfig.setMetadataPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Metadata"));
|
DisguiseConfig.setMetadataPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Metadata"));
|
||||||
|
DisguiseConfig.setMaxHealthDeterminedByDisguisedEntity(getConfig().getBoolean("MaxHealthDeterminedByEntity"));
|
||||||
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.
|
||||||
@ -234,7 +236,8 @@ public class LibsDisguises extends JavaPlugin {
|
|||||||
break;
|
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()) {
|
for (WrappedWatchableObject watch : WrappedDataWatcher.getEntityWatcher(bukkitEntity).getWatchableObjects()) {
|
||||||
disguiseValues.setMetaValue(watch.getIndex(), watch.getValue());
|
disguiseValues.setMetaValue(watch.getIndex(), watch.getValue());
|
||||||
// Uncomment when I need to find the new datawatcher values for a class..
|
// Uncomment when I need to find the new datawatcher values for a class..
|
||||||
|
@ -31,6 +31,8 @@ public class LivingWatcher extends FlagWatcher {
|
|||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private double maxHealth;
|
||||||
|
private boolean maxHealthSet;
|
||||||
private HashSet<Integer> potionEffects = new HashSet<Integer>();
|
private HashSet<Integer> potionEffects = new HashSet<Integer>();
|
||||||
|
|
||||||
public LivingWatcher(Disguise disguise) {
|
public LivingWatcher(Disguise disguise) {
|
||||||
@ -48,6 +50,8 @@ public class LivingWatcher extends FlagWatcher {
|
|||||||
public LivingWatcher clone(Disguise disguise) {
|
public LivingWatcher clone(Disguise disguise) {
|
||||||
LivingWatcher clone = (LivingWatcher) super.clone(disguise);
|
LivingWatcher clone = (LivingWatcher) super.clone(disguise);
|
||||||
clone.potionEffects = (HashSet<Integer>) potionEffects.clone();
|
clone.potionEffects = (HashSet<Integer>) potionEffects.clone();
|
||||||
|
clone.maxHealth = maxHealth;
|
||||||
|
clone.maxHealthSet = maxHealthSet;
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +63,10 @@ public class LivingWatcher extends FlagWatcher {
|
|||||||
return (Float) getValue(6, 0F);
|
return (Float) getValue(6, 0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getMaxHealth() {
|
||||||
|
return maxHealth;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean getPotionParticlesRemoved() {
|
public boolean getPotionParticlesRemoved() {
|
||||||
return (Byte) getValue(8, (byte) 0) == 1;
|
return (Byte) getValue(8, (byte) 0) == 1;
|
||||||
}
|
}
|
||||||
@ -105,6 +113,10 @@ public class LivingWatcher extends FlagWatcher {
|
|||||||
return (Byte) getValue(11, (byte) 0) == 1;
|
return (Byte) getValue(11, (byte) 0) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isMaxHealthSet() {
|
||||||
|
return maxHealthSet;
|
||||||
|
}
|
||||||
|
|
||||||
public void removePotionEffect(PotionEffectType type) {
|
public void removePotionEffect(PotionEffectType type) {
|
||||||
if (potionEffects.contains(type.getId())) {
|
if (potionEffects.contains(type.getId())) {
|
||||||
potionEffects.remove(type.getId());
|
potionEffects.remove(type.getId());
|
||||||
@ -139,4 +151,10 @@ public class LivingWatcher extends FlagWatcher {
|
|||||||
sendData(6);
|
sendData(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMaxHealth(double newHealth) {
|
||||||
|
this.maxHealth = newHealth;
|
||||||
|
maxHealthSet = true;
|
||||||
|
// TODO Send packet
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -47,13 +47,15 @@ public class DisguiseValues {
|
|||||||
private FakeBoundingBox babyBox;
|
private FakeBoundingBox babyBox;
|
||||||
private float[] entitySize;
|
private float[] entitySize;
|
||||||
private int enumEntitySize;
|
private int enumEntitySize;
|
||||||
|
private double maxHealth;
|
||||||
private HashMap<Integer, Object> metaValues = new HashMap<Integer, Object>();
|
private HashMap<Integer, Object> metaValues = new HashMap<Integer, Object>();
|
||||||
private Class nmsEntityClass;
|
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);
|
values.put(type, this);
|
||||||
enumEntitySize = entitySize;
|
enumEntitySize = entitySize;
|
||||||
nmsEntityClass = classType;
|
nmsEntityClass = classType;
|
||||||
|
this.maxHealth = maxHealth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FakeBoundingBox getAdultBox() {
|
public FakeBoundingBox getAdultBox() {
|
||||||
@ -112,6 +114,10 @@ public class DisguiseValues {
|
|||||||
return (int) Math.floor(paramDouble * 32.0D);
|
return (int) Math.floor(paramDouble * 32.0D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getMaxHealth() {
|
||||||
|
return maxHealth;
|
||||||
|
}
|
||||||
|
|
||||||
public HashMap<Integer, Object> getMetaValues() {
|
public HashMap<Integer, Object> getMetaValues() {
|
||||||
return metaValues;
|
return metaValues;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
|
|||||||
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
|
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
|
||||||
import me.libraryaddict.disguise.disguisetypes.MobDisguise;
|
import me.libraryaddict.disguise.disguisetypes.MobDisguise;
|
||||||
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
|
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
|
||||||
|
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
|
||||||
import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher;
|
import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher;
|
||||||
import me.libraryaddict.disguise.utilities.DisguiseSound.SoundType;
|
import me.libraryaddict.disguise.utilities.DisguiseSound.SoundType;
|
||||||
import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion;
|
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.PacketEvent;
|
||||||
import com.comphenix.protocol.events.PacketListener;
|
import com.comphenix.protocol.events.PacketListener;
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
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.WrappedDataWatcher;
|
||||||
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
||||||
|
|
||||||
@ -1173,10 +1176,39 @@ public class PacketsManager {
|
|||||||
if (disguise != null) {
|
if (disguise != null) {
|
||||||
packets = new PacketContainer[] { sentPacket };
|
packets = new PacketContainer[] { sentPacket };
|
||||||
|
|
||||||
// If packet is PacketType.Play.Server.UPDATE_ATTRIBUTES
|
|
||||||
// This packet sends attributes
|
// This packet sends attributes
|
||||||
if (sentPacket.getType() == PacketType.Play.Server.UPDATE_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) {
|
else if (sentPacket.getType() == PacketType.Play.Server.ATTACH_ENTITY) {
|
||||||
|
Loading…
Reference in New Issue
Block a user