Added ability to set the max health of a disguise using attributes
This commit is contained in:
parent
0c305a8151
commit
26ccaabe83
@ -65,6 +65,12 @@ KeepDisguises:
|
||||
PlayerDeath: 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 means you can not have a living entity disguise as a non-living entity.
|
||||
# This disables the Attributes packet, Non-living entities can still disguise as other non-living
|
||||
@ -91,6 +97,7 @@ PacketsEnabled:
|
||||
# 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.
|
||||
# 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
|
||||
# Movement packets are the biggest cpu hit. These are majorly used to ensure that the disguises facing direction isn't bugged up
|
||||
Movement: true
|
||||
|
15
pom.xml
15
pom.xml
@ -75,16 +75,21 @@
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>craftbukkit</artifactId>
|
||||
<version>1.7.8-R0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</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>
|
||||
|
||||
<distributionManagement>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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..
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user