Calculate attribute modifiers and fix sprinting/sneaking

This commit is contained in:
AJ Ferguson 2019-10-17 23:54:20 -08:00
parent a45fdc508d
commit 2bab0d1d19
5 changed files with 61 additions and 28 deletions

View file

@ -71,6 +71,7 @@ public class Entity {
protected Set<Long> passengers = new HashSet<>(); protected Set<Long> passengers = new HashSet<>();
protected Map<AttributeType, Attribute> attributes = new HashMap<>(); protected Map<AttributeType, Attribute> attributes = new HashMap<>();
protected EntityDataDictionary metadata = new EntityDataDictionary();
public Entity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { public Entity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
this.entityId = entityId; this.entityId = entityId;
@ -83,6 +84,19 @@ public class Entity {
this.valid = false; this.valid = false;
this.movePending = false; this.movePending = false;
this.dimension = 0; this.dimension = 0;
metadata.put(EntityData.SCALE, 1f);
metadata.put(EntityData.MAX_AIR, (short) 400);
metadata.put(EntityData.AIR, (short) 0);
metadata.put(EntityData.LEAD_HOLDER_EID, -1L);
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, entityType.getHeight());
metadata.put(EntityData.BOUNDING_BOX_WIDTH, entityType.getWidth());
EntityFlags flags = new EntityFlags();
flags.setFlag(EntityFlag.HAS_GRAVITY, true);
flags.setFlag(EntityFlag.HAS_COLLISION, true);
flags.setFlag(EntityFlag.CAN_SHOW_NAME, true);
flags.setFlag(EntityFlag.CAN_CLIMB, true);
metadata.putFlags(flags);
} }
public void spawnEntity(GeyserSession session) { public void spawnEntity(GeyserSession session) {
@ -94,7 +108,7 @@ public class Entity {
addEntityPacket.setMotion(motion); addEntityPacket.setMotion(motion);
addEntityPacket.setRotation(getBedrockRotation()); addEntityPacket.setRotation(getBedrockRotation());
addEntityPacket.setEntityType(entityType.getType()); addEntityPacket.setEntityType(entityType.getType());
addEntityPacket.getMetadata().putAll(getMetadata()); addEntityPacket.getMetadata().putAll(metadata);
valid = true; valid = true;
session.getUpstream().sendPacket(addEntityPacket); session.getUpstream().sendPacket(addEntityPacket);
@ -137,24 +151,6 @@ public class Entity {
this.movePending = true; this.movePending = true;
} }
public EntityDataDictionary getMetadata() {
EntityFlags flags = new EntityFlags();
flags.setFlag(EntityFlag.HAS_GRAVITY, true);
flags.setFlag(EntityFlag.HAS_COLLISION, true);
flags.setFlag(EntityFlag.CAN_SHOW_NAME, true);
flags.setFlag(EntityFlag.CAN_CLIMB, true);
EntityDataDictionary dictionary = new EntityDataDictionary();
dictionary.put(EntityData.SCALE, 1f);
dictionary.put(EntityData.MAX_AIR, (short) 400);
dictionary.put(EntityData.AIR, (short) 0);
dictionary.put(EntityData.LEAD_HOLDER_EID, -1L);
dictionary.put(EntityData.BOUNDING_BOX_HEIGHT, entityType.getHeight());
dictionary.put(EntityData.BOUNDING_BOX_WIDTH, entityType.getWidth());
dictionary.putFlags(flags);
return dictionary;
}
public void updateBedrockAttributes(GeyserSession session) { public void updateBedrockAttributes(GeyserSession session) {
List<com.nukkitx.protocol.bedrock.data.Attribute> attributes = new ArrayList<>(); List<com.nukkitx.protocol.bedrock.data.Attribute> attributes = new ArrayList<>();
for (Map.Entry<AttributeType, Attribute> entry : this.attributes.entrySet()) { for (Map.Entry<AttributeType, Attribute> entry : this.attributes.entrySet()) {
@ -171,7 +167,7 @@ public class Entity {
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
entityDataPacket.setRuntimeEntityId(geyserId); entityDataPacket.setRuntimeEntityId(geyserId);
entityDataPacket.getMetadata().putAll(getMetadata()); entityDataPacket.getMetadata().putAll(metadata);
session.getUpstream().sendPacket(entityDataPacket); session.getUpstream().sendPacket(entityDataPacket);
} }

View file

@ -43,7 +43,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
@Override @Override
public void translate(PlayerActionPacket packet, GeyserSession session) { public void translate(PlayerActionPacket packet, GeyserSession session) {
Entity entity = session.getEntityCache().getEntityByGeyserId(packet.getRuntimeEntityId()); Entity entity = session.getPlayerEntity();
if (entity == null) if (entity == null)
return; return;

View file

@ -25,7 +25,10 @@
package org.geysermc.connector.network.translators.java.entity; package org.geysermc.connector.network.translators.java.entity;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityMetadataPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityMetadataPacket;
import com.nukkitx.protocol.bedrock.data.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket; import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
@ -42,6 +45,15 @@ public class JavaEntityMetadataTranslator extends PacketTranslator<ServerEntityM
if (entity == null) return; if (entity == null) return;
if (entity.isValid()) { if (entity.isValid()) {
//temp sprint/sneak fix
for (EntityMetadata metadata : packet.getMetadata()) {
if (metadata.getId() == 0 && metadata.getType() == MetadataType.BYTE) {
byte xd = (byte)metadata.getValue();
entity.getMetadata().getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08);
entity.getMetadata().getFlags().setFlag(EntityFlag.SNEAKING, (xd & 0x02) == 0x02);
}
}
// TODO: Make this actually useful lol // TODO: Make this actually useful lol
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
entityDataPacket.setRuntimeEntityId(entity.getGeyserId()); entityDataPacket.setRuntimeEntityId(entity.getGeyserId());

View file

@ -31,6 +31,7 @@ import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.attribute.AttributeType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.utils.AttributeUtils;
public class JavaEntityPropertiesTranslator extends PacketTranslator<ServerEntityPropertiesPacket> { public class JavaEntityPropertiesTranslator extends PacketTranslator<ServerEntityPropertiesPacket> {
@ -45,23 +46,23 @@ public class JavaEntityPropertiesTranslator extends PacketTranslator<ServerEntit
for (Attribute attribute : packet.getAttributes()) { for (Attribute attribute : packet.getAttributes()) {
switch (attribute.getType()) { switch (attribute.getType()) {
case GENERIC_MAX_HEALTH: case GENERIC_MAX_HEALTH:
entity.getAttributes().put(AttributeType.MAX_HEALTH, AttributeType.MAX_HEALTH.getAttribute((float) attribute.getValue())); entity.getAttributes().put(AttributeType.MAX_HEALTH, AttributeType.MAX_HEALTH.getAttribute((float) AttributeUtils.calculateValue(attribute)));
break; break;
case GENERIC_ATTACK_DAMAGE: case GENERIC_ATTACK_DAMAGE:
entity.getAttributes().put(AttributeType.ATTACK_DAMAGE, AttributeType.ATTACK_DAMAGE.getAttribute((float) attribute.getValue())); entity.getAttributes().put(AttributeType.ATTACK_DAMAGE, AttributeType.ATTACK_DAMAGE.getAttribute((float) AttributeUtils.calculateValue(attribute)));
break; break;
case GENERIC_FLYING_SPEED: case GENERIC_FLYING_SPEED:
entity.getAttributes().put(AttributeType.FLYING_SPEED, AttributeType.FLYING_SPEED.getAttribute((float) attribute.getValue())); entity.getAttributes().put(AttributeType.FLYING_SPEED, AttributeType.FLYING_SPEED.getAttribute((float) AttributeUtils.calculateValue(attribute)));
entity.getAttributes().put(AttributeType.MOVEMENT_SPEED, AttributeType.MOVEMENT_SPEED.getAttribute((float) attribute.getValue())); entity.getAttributes().put(AttributeType.MOVEMENT_SPEED, AttributeType.MOVEMENT_SPEED.getAttribute((float) AttributeUtils.calculateValue(attribute)));
break; break;
case GENERIC_MOVEMENT_SPEED: case GENERIC_MOVEMENT_SPEED:
entity.getAttributes().put(AttributeType.MOVEMENT_SPEED, AttributeType.MOVEMENT_SPEED.getAttribute((float) attribute.getValue())); entity.getAttributes().put(AttributeType.MOVEMENT_SPEED, AttributeType.MOVEMENT_SPEED.getAttribute((float) AttributeUtils.calculateValue(attribute)));
break; break;
case GENERIC_FOLLOW_RANGE: case GENERIC_FOLLOW_RANGE:
entity.getAttributes().put(AttributeType.FOLLOW_RANGE, AttributeType.FOLLOW_RANGE.getAttribute((float) attribute.getValue())); entity.getAttributes().put(AttributeType.FOLLOW_RANGE, AttributeType.FOLLOW_RANGE.getAttribute((float) AttributeUtils.calculateValue(attribute)));
break; break;
case GENERIC_KNOCKBACK_RESISTANCE: case GENERIC_KNOCKBACK_RESISTANCE:
entity.getAttributes().put(AttributeType.KNOCKBACK_RESISTANCE, AttributeType.KNOCKBACK_RESISTANCE.getAttribute((float) attribute.getValue())); entity.getAttributes().put(AttributeType.KNOCKBACK_RESISTANCE, AttributeType.KNOCKBACK_RESISTANCE.getAttribute((float) AttributeUtils.calculateValue(attribute)));
break; break;
} }
} }

View file

@ -1,5 +1,7 @@
package org.geysermc.connector.utils; package org.geysermc.connector.utils;
import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeModifier;
import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation;
import org.geysermc.connector.entity.attribute.Attribute; import org.geysermc.connector.entity.attribute.Attribute;
import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.attribute.AttributeType;
@ -42,4 +44,26 @@ public class AttributeUtils {
return new com.nukkitx.protocol.bedrock.data.Attribute(type.getBedrockIdentifier(), attribute.getMinimum(), attribute.getMaximum(), attribute.getValue(), attribute.getDefaultValue()); return new com.nukkitx.protocol.bedrock.data.Attribute(type.getBedrockIdentifier(), attribute.getMinimum(), attribute.getMaximum(), attribute.getValue(), attribute.getDefaultValue());
} }
//https://minecraft.gamepedia.com/Attribute#Modifiers
public static double calculateValue(com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute attribute) {
double base = attribute.getValue();
for (AttributeModifier modifier : attribute.getModifiers()) {
if (modifier.getOperation() == ModifierOperation.ADD) {
base += modifier.getAmount();
}
}
double value = base;
for (AttributeModifier modifier : attribute.getModifiers()) {
if (modifier.getOperation() == ModifierOperation.ADD_MULTIPLIED) {
value += base * modifier.getAmount();
}
}
for (AttributeModifier modifier : attribute.getModifiers()) {
if (modifier.getOperation() == ModifierOperation.MULTIPLY) {
value *= 1.0D + modifier.getAmount();
}
}
return value;
}
} }