Fix attributes not being fully sent for the first player login

This commit is contained in:
themode 2021-01-06 21:09:27 +01:00
parent 459e65da72
commit 84fd568c0c
4 changed files with 24 additions and 12 deletions

View File

@ -13,6 +13,10 @@ public class Attribute {
private static final Map<String, Attribute> ATTRIBUTES = new HashMap<>();
static {
Attributes.init();
}
private final String key;
private final float defaultValue;
private final float maxValue;

View File

@ -24,6 +24,7 @@ public class AttributeInstance {
this.attribute = attribute;
this.propertyChangeListener = listener;
this.baseValue = attribute.getDefaultValue();
refreshCachedValue();
}
/**
@ -90,6 +91,7 @@ public class AttributeInstance {
*
* @return the modifiers.
*/
@NotNull
public Collection<AttributeModifier> getModifiers() {
return modifiers.values();
}
@ -107,18 +109,19 @@ public class AttributeInstance {
* Recalculate the value of this attribute instance using the modifiers.
*/
protected void refreshCachedValue() {
final Collection<AttributeModifier> modifiers = getModifiers();
float base = getBaseValue();
for (var modifier : modifiers.values().stream().filter(mod -> mod.getOperation() == AttributeOperation.ADDITION).toArray(AttributeModifier[]::new)) {
for (var modifier : modifiers.stream().filter(mod -> mod.getOperation() == AttributeOperation.ADDITION).toArray(AttributeModifier[]::new)) {
base += modifier.getAmount();
}
float result = base;
for (var modifier : modifiers.values().stream().filter(mod -> mod.getOperation() == AttributeOperation.MULTIPLY_BASE).toArray(AttributeModifier[]::new)) {
for (var modifier : modifiers.stream().filter(mod -> mod.getOperation() == AttributeOperation.MULTIPLY_BASE).toArray(AttributeModifier[]::new)) {
result += (base * modifier.getAmount());
}
for (var modifier : modifiers.values().stream().filter(mod -> mod.getOperation() == AttributeOperation.MULTIPLY_TOTAL).toArray(AttributeModifier[]::new)) {
for (var modifier : modifiers.stream().filter(mod -> mod.getOperation() == AttributeOperation.MULTIPLY_TOTAL).toArray(AttributeModifier[]::new)) {
result *= (1.0f + modifier.getAmount());
}

View File

@ -4,6 +4,7 @@ package net.minestom.server.attribute;
* The Minecraft, vanilla, standards attributes.
*/
public final class Attributes {
public static final Attribute MAX_HEALTH = (new Attribute("generic.max_health", true, 20, 1024)).register();
public static final Attribute FOLLOW_RANGE = (new Attribute("generic.follow_range", true, 32, 2048)).register();
public static final Attribute KNOCKBACK_RESISTANCE = (new Attribute("generic.knockback_resistance", true, 0, 1)).register();
@ -21,4 +22,8 @@ public final class Attributes {
private Attributes() throws IllegalAccessException {
throw new IllegalAccessException("Cannot instantiate a static class");
}
protected static void init() {
// Empty, here to register all the vanilla attributes
}
}

View File

@ -31,11 +31,7 @@ import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
@ -507,12 +503,15 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
*/
@NotNull
protected EntityPropertiesPacket getPropertiesPacket() {
// Get all the attributes which should be sent to the client
final AttributeInstance[] instances = attributeModifiers.values().stream()
.filter(i -> i.getAttribute().isShared())
.toArray(AttributeInstance[]::new);
EntityPropertiesPacket propertiesPacket = new EntityPropertiesPacket();
propertiesPacket.entityId = getEntityId();
AttributeInstance[] instances = attributeModifiers.values().stream()
.filter(i -> i.getAttribute().isShared())
.toArray(AttributeInstance[]::new);
EntityPropertiesPacket.Property[] properties = new EntityPropertiesPacket.Property[instances.length];
for (int i = 0; i < properties.length; ++i) {
EntityPropertiesPacket.Property property = new EntityPropertiesPacket.Property();
@ -535,7 +534,8 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
*/
private void setupAttributes() {
for (Attribute attribute : Attribute.values()) {
attributeModifiers.put(attribute.getKey(), new AttributeInstance(attribute, this::onAttributeChanged));
final AttributeInstance attributeInstance = new AttributeInstance(attribute, this::onAttributeChanged);
this.attributeModifiers.put(attribute.getKey(), attributeInstance);
}
}