Fix max health not working properly, implement proper cracked support for iron golem. Fixes #549

This commit is contained in:
libraryaddict 2021-04-24 13:40:02 +12:00
parent ee2224e68f
commit 5b59ad98d5
7 changed files with 114 additions and 48 deletions

View File

@ -282,6 +282,10 @@ public class FlagWatcher {
} }
value = entityValues.get(id); value = entityValues.get(id);
if (id == MetaIndex.LIVING_HEALTH.getIndex() && (float) watch.getRawValue() <= 0) {
value = watch.getRawValue();
}
} else if (backupEntityValues.containsKey(id)) { } else if (backupEntityValues.containsKey(id)) {
if (backupEntityValues.get(id) == null) { if (backupEntityValues.get(id) == null) {
continue; continue;

View File

@ -0,0 +1,11 @@
package me.libraryaddict.disguise.disguisetypes;
/**
* Created by libraryaddict on 24/04/2021.
*/
public enum GolemCrack {
HEALTH_100,
HEALTH_75,
HEALTH_50,
HEALTH_25
}

View File

@ -1,9 +1,57 @@
package me.libraryaddict.disguise.disguisetypes.watchers; package me.libraryaddict.disguise.disguisetypes.watchers;
import lombok.Getter;
import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.GolemCrack;
import me.libraryaddict.disguise.utilities.reflection.NmsAddedIn;
import me.libraryaddict.disguise.utilities.reflection.NmsVersion;
public class IronGolemWatcher extends InsentientWatcher { public class IronGolemWatcher extends InsentientWatcher {
private GolemCrack cracks;
public IronGolemWatcher(Disguise disguise) { public IronGolemWatcher(Disguise disguise) {
super(disguise); super(disguise);
} }
@NmsAddedIn(NmsVersion.v1_16)
public GolemCrack getCracks() {
return cracks;
}
@NmsAddedIn(NmsVersion.v1_16)
public void setCracks(GolemCrack cracks) {
if (cracks == getCracks() || cracks == null) {
return;
}
this.cracks = cracks;
switch (cracks) {
case HEALTH_25:
setHealth(24);
break;
case HEALTH_50:
setHealth(49);
break;
case HEALTH_75:
setHealth(74);
break;
case HEALTH_100:
setHealth(100);
break;
}
if (!isMaxHealthSet() || getMaxHealth() != 100) {
setMaxHealth(100);
}
}
@Override
public IronGolemWatcher clone(Disguise disguise) {
IronGolemWatcher watcher = (IronGolemWatcher) super.clone(disguise);
watcher.setCracks(getCracks());
return watcher;
}
} }

View File

@ -11,6 +11,7 @@ import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.FlagWatcher; import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
import me.libraryaddict.disguise.disguisetypes.MetaIndex; import me.libraryaddict.disguise.disguisetypes.MetaIndex;
import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.parser.RandomDefaultValue;
import me.libraryaddict.disguise.utilities.reflection.NmsAddedIn; import me.libraryaddict.disguise.utilities.reflection.NmsAddedIn;
import me.libraryaddict.disguise.utilities.reflection.NmsVersion; import me.libraryaddict.disguise.utilities.reflection.NmsVersion;
import org.bukkit.Color; import org.bukkit.Color;
@ -129,7 +130,7 @@ public class LivingWatcher extends FlagWatcher {
Builder builder; Builder builder;
builder = WrappedAttribute.newBuilder(); builder = WrappedAttribute.newBuilder();
builder.attributeKey("generic.maxHealth"); builder.attributeKey(NmsVersion.v1_16.isSupported() ? "generic.max_health" : "generic.maxHealth");
builder.baseValue(getMaxHealth()); builder.baseValue(getMaxHealth());
builder.packet(packet); builder.packet(packet);
@ -142,9 +143,14 @@ public class LivingWatcher extends FlagWatcher {
for (Player player : DisguiseUtilities.getPerverts(getDisguise())) { for (Player player : DisguiseUtilities.getPerverts(getDisguise())) {
try { try {
if (player == getDisguise().getEntity()) {
PacketContainer p = packet.shallowClone();
p.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
ProtocolLibrary.getProtocolManager().sendServerPacket(player, p, false);
} else {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
} }
catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@ -23,16 +23,14 @@ import java.util.List;
* Created by libraryaddict on 3/01/2019. * Created by libraryaddict on 3/01/2019.
*/ */
public class PacketHandlerAttributes implements IPacketHandler { public class PacketHandlerAttributes implements IPacketHandler {
private boolean skipAttributes = !NmsVersion.v1_14.isSupported() && private boolean skipAttributes = !NmsVersion.v1_14.isSupported() && ProtocolLibrary.getPlugin().getDescription().getVersion().equals("4.5.0");
ProtocolLibrary.getPlugin().getDescription().getVersion().equals("4.5.0");
public PacketHandlerAttributes() { public PacketHandlerAttributes() {
if (!skipAttributes) { if (!skipAttributes) {
return; return;
} }
DisguiseUtilities.getLogger() DisguiseUtilities.getLogger().info("You are running ProtocolLib 4.5.0, attributes will not be handled; Update if you can.");
.info("You are running ProtocolLib 4.5.0, attributes will not be handled; Update if you can.");
} }
@Override @Override
@ -41,8 +39,7 @@ public class PacketHandlerAttributes implements IPacketHandler {
} }
@Override @Override
public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, Entity entity) {
Entity entity) {
packets.clear(); packets.clear();
// Skip due to a bug in ProtocolLib // Skip due to a bug in ProtocolLib
@ -58,27 +55,25 @@ public class PacketHandlerAttributes implements IPacketHandler {
PacketContainer updateAttributes = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES); PacketContainer updateAttributes = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES);
for (WrappedAttribute attribute : sentPacket.getAttributeCollectionModifier().read(0)) { for (WrappedAttribute attribute : sentPacket.getAttributeCollectionModifier().read(0)) {
if (attribute.getAttributeKey().equals("generic.maxHealth")) { if (attribute.getAttributeKey().equals(NmsVersion.v1_16.isSupported() ? "generic.max_health" : "generic.maxHealth")) {
WrappedAttribute.Builder builder; WrappedAttribute.Builder builder;
if (disguise.getWatcher() instanceof LivingWatcher && if (disguise.getWatcher() instanceof LivingWatcher && ((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) {
((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) {
builder = WrappedAttribute.newBuilder(); builder = WrappedAttribute.newBuilder();
builder.attributeKey("generic.maxHealth"); builder.attributeKey(attribute.getAttributeKey());
builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth()); builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth());
} else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity()) { } else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity()) {
builder = WrappedAttribute.newBuilder(attribute); builder = WrappedAttribute.newBuilder(attribute);
} else { } else {
builder = WrappedAttribute.newBuilder(); builder = WrappedAttribute.newBuilder();
builder.attributeKey("generic.maxHealth"); builder.attributeKey(attribute.getAttributeKey());
builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth()); builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth());
} }
builder.packet(updateAttributes); builder.packet(updateAttributes);
attributes.add(builder.build()); attributes.add(builder.build());
} else if (attribute.getAttributeKey().equals("generic.movementSpeed") && } else if (attribute.getAttributeKey().equals(NmsVersion.v1_16.isSupported() ? "generic.movement_speed" : "generic.movementSpeed") && disguise.getWatcher() instanceof AbstractHorseWatcher) {
disguise.getWatcher() instanceof AbstractHorseWatcher) {
WrappedAttribute.Builder builder = WrappedAttribute.newBuilder(attribute); WrappedAttribute.Builder builder = WrappedAttribute.newBuilder(attribute);
builder.packet(updateAttributes); builder.packet(updateAttributes);

View File

@ -71,33 +71,6 @@ public class PacketHandlerSpawn implements IPacketHandler {
Disguise disguise = packets.getDisguise(); Disguise disguise = packets.getDisguise();
boolean sendArmor = true; boolean sendArmor = true;
if (DisguiseConfig.isMiscDisguisesForLivingEnabled()) {
if (disguise.getWatcher() instanceof LivingWatcher) {
ArrayList<WrappedAttribute> attributes = new ArrayList<>();
WrappedAttribute.Builder builder = WrappedAttribute.newBuilder().attributeKey("generic.maxHealth");
if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) {
builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth());
} else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity() && disguisedEntity instanceof Damageable) {
builder.baseValue(((Damageable) disguisedEntity).getMaxHealth());
} else {
builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth());
}
PacketContainer packet = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES);
builder.packet(packet);
attributes.add(builder.build());
packet.getIntegers().write(0, disguisedEntity.getEntityId());
packet.getAttributeCollectionModifier().write(0, attributes);
packets.addPacket(packet);
}
}
Location loc = disguisedEntity.getLocation().clone().add(0, DisguiseUtilities.getYModifier(disguise) + disguise.getWatcher().getYModifier(), 0); Location loc = disguisedEntity.getLocation().clone().add(0, DisguiseUtilities.getYModifier(disguise) + disguise.getWatcher().getYModifier(), 0);
Float pitchLock = DisguiseConfig.isMovementPacketsEnabled() ? disguise.getWatcher().getPitchLock() : null; Float pitchLock = DisguiseConfig.isMovementPacketsEnabled() ? disguise.getWatcher().getPitchLock() : null;
@ -356,8 +329,7 @@ public class PacketHandlerSpawn implements IPacketHandler {
entityType = ReflectionManager.getEntityType(disguise.getType().getEntityType()); entityType = ReflectionManager.getEntityType(disguise.getType().getEntityType());
} }
Object[] params = Object[] params = new Object[]{disguisedEntity.getEntityId(), disguise.getUUID(), x, y, z, loc.getPitch(), loc.getYaw(), entityType, data,
new Object[]{disguisedEntity.getEntityId(), disguise.getUUID(), x, y, z, loc.getPitch(), loc.getYaw(), entityType, data,
ReflectionManager.getVec3D(disguisedEntity.getVelocity())}; ReflectionManager.getVec3D(disguisedEntity.getVelocity())};
spawnEntity = ProtocolLibrary.getProtocolManager().createPacketConstructor(PacketType.Play.Server.SPAWN_ENTITY, params).createPacket(params); spawnEntity = ProtocolLibrary.getProtocolManager().createPacketConstructor(PacketType.Play.Server.SPAWN_ENTITY, params).createPacket(params);
@ -430,6 +402,34 @@ public class PacketHandlerSpawn implements IPacketHandler {
packets.addPacket(newPacket); packets.addPacket(newPacket);
} }
if (DisguiseConfig.isMiscDisguisesForLivingEnabled()) {
if (disguise.getWatcher() instanceof LivingWatcher) {
ArrayList<WrappedAttribute> attributes = new ArrayList<>();
WrappedAttribute.Builder builder =
WrappedAttribute.newBuilder().attributeKey(NmsVersion.v1_16.isSupported() ? "generic.max_health" : "generic.maxHealth");
if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) {
builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth());
} else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity() && disguisedEntity instanceof Damageable) {
builder.baseValue(((Damageable) disguisedEntity).getMaxHealth());
} else {
builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth());
}
PacketContainer packet = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES);
builder.packet(packet);
attributes.add(builder.build());
packet.getIntegers().write(0, disguisedEntity.getEntityId());
packet.getAttributeCollectionModifier().write(0, attributes);
packets.addPacket(packet);
}
}
if (!disguise.isPlayerDisguise() || normalPlayerDisguise) { if (!disguise.isPlayerDisguise() || normalPlayerDisguise) {
DisguiseUtilities.getNamePackets(disguise, new String[0]).forEach(packets::addPacket); DisguiseUtilities.getNamePackets(disguise, new String[0]).forEach(packets::addPacket);
} }

View File

@ -5,6 +5,7 @@ import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedParticle; import com.comphenix.protocol.wrappers.WrappedParticle;
import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.disguisetypes.EntityPose; import me.libraryaddict.disguise.disguisetypes.EntityPose;
import me.libraryaddict.disguise.disguisetypes.GolemCrack;
import me.libraryaddict.disguise.disguisetypes.RabbitType; import me.libraryaddict.disguise.disguisetypes.RabbitType;
import me.libraryaddict.disguise.utilities.params.types.ParamInfoEnum; import me.libraryaddict.disguise.utilities.params.types.ParamInfoEnum;
import me.libraryaddict.disguise.utilities.params.types.base.*; import me.libraryaddict.disguise.utilities.params.types.base.*;
@ -129,6 +130,7 @@ public class ParamInfoTypes {
"etc. 30m20secs = 30 minutes, 20 seconds")); "etc. 30m20secs = 30 minutes, 20 seconds"));
paramInfos.add(new ParamInfoEnum(ChatColor.class, "ChatColor", "A chat color")); paramInfos.add(new ParamInfoEnum(ChatColor.class, "ChatColor", "A chat color"));
paramInfos.add(new ParamInfoEnum(GolemCrack.class, "Golem Cracked", "The stage a golem has been cracked"));
// Register base types // Register base types
Map<String, Object> booleanMap = new HashMap<>(); Map<String, Object> booleanMap = new HashMap<>();