forked from GeyserMC/Geyser
Merge pull request #65 from AJ-Ferguson/master
Calculate attribute modifiers and fix sprinting/sneaking
This commit is contained in:
commit
46107df0f8
5 changed files with 61 additions and 28 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue