Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2025-01-12 08:01:06 +01:00
Entity refactory aaaaaaAAAAAAA
Dieser Commit ist enthalten in:
Ursprung
951b616f98
Commit
11997ed82b
@ -44,6 +44,7 @@ import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
|||||||
import org.geysermc.connector.command.CommandManager;
|
import org.geysermc.connector.command.CommandManager;
|
||||||
import org.geysermc.connector.common.AuthType;
|
import org.geysermc.connector.common.AuthType;
|
||||||
import org.geysermc.connector.configuration.GeyserConfiguration;
|
import org.geysermc.connector.configuration.GeyserConfiguration;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinitions;
|
||||||
import org.geysermc.connector.metrics.Metrics;
|
import org.geysermc.connector.metrics.Metrics;
|
||||||
import org.geysermc.connector.network.ConnectorServerEventHandler;
|
import org.geysermc.connector.network.ConnectorServerEventHandler;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
@ -153,6 +154,7 @@ public class GeyserConnector {
|
|||||||
BlockRegistries.init();
|
BlockRegistries.init();
|
||||||
Registries.init();
|
Registries.init();
|
||||||
|
|
||||||
|
EntityDefinitions.init();
|
||||||
ItemTranslator.init();
|
ItemTranslator.init();
|
||||||
MessageTranslator.init();
|
MessageTranslator.init();
|
||||||
LocaleUtils.init();
|
LocaleUtils.init();
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.command.defaults;
|
package org.geysermc.connector.command.defaults;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
|
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
|
||||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockFace;
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.CommandSender;
|
import org.geysermc.connector.command.CommandSender;
|
||||||
@ -47,7 +47,7 @@ public class OffhandCommand extends GeyserCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ServerboundPlayerActionPacket releaseItemPacket = new ServerboundPlayerActionPacket(PlayerAction.SWAP_HANDS, BlockUtils.POSITION_ZERO,
|
ServerboundPlayerActionPacket releaseItemPacket = new ServerboundPlayerActionPacket(PlayerAction.SWAP_HANDS, BlockUtils.POSITION_ZERO,
|
||||||
BlockFace.DOWN);
|
Direction.DOWN);
|
||||||
session.sendDownstreamPacket(releaseItemPacket);
|
session.sendDownstreamPacket(releaseItemPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,37 +26,43 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class AbstractArrowEntity extends Entity {
|
public class AbstractArrowEntity extends Entity {
|
||||||
|
|
||||||
public AbstractArrowEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public AbstractArrowEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
// Set the correct texture if using the resource pack
|
// Set the correct texture if using the resource pack
|
||||||
metadata.getFlags().setFlag(EntityFlag.BRIBED, entityType == EntityType.SPECTRAL_ARROW);
|
dirtyMetadata.getFlags().setFlag(EntityFlag.BRIBED, definition.entityType() == EntityType.SPECTRAL_ARROW);
|
||||||
|
|
||||||
setMotion(motion);
|
setMotion(motion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setArrowFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
byte data = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 8) {
|
|
||||||
byte data = (byte) entityMetadata.getValue();
|
|
||||||
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.CRITICAL, (data & 0x01) == 0x01);
|
setFlag(EntityFlag.CRITICAL, (data & 0x01) == 0x01);
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRotation(Vector3f rotation) {
|
|
||||||
// Ignore the rotation sent by the Java server since the
|
// Ignore the rotation sent by the Java server since the
|
||||||
// Java client calculates the rotation from the motion
|
// Java client calculates the rotation from the motion
|
||||||
|
@Override
|
||||||
|
public void setYaw(float yaw) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPitch(float pitch) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeadYaw(float headYaw) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -64,8 +70,8 @@ public class AbstractArrowEntity extends Entity {
|
|||||||
super.setMotion(motion);
|
super.setMotion(motion);
|
||||||
|
|
||||||
double horizontalSpeed = Math.sqrt(motion.getX() * motion.getX() + motion.getZ() * motion.getZ());
|
double horizontalSpeed = Math.sqrt(motion.getX() * motion.getX() + motion.getZ() * motion.getZ());
|
||||||
float yaw = (float) Math.toDegrees(Math.atan2(motion.getX(), motion.getZ()));
|
this.yaw = (float) Math.toDegrees(Math.atan2(motion.getX(), motion.getZ()));
|
||||||
float pitch = (float) Math.toDegrees(Math.atan2(motion.getY(), horizontalSpeed));
|
this.pitch = (float) Math.toDegrees(Math.atan2(motion.getY(), horizontalSpeed));
|
||||||
rotation = Vector3f.from(yaw, pitch, yaw);
|
this.headYaw = yaw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,44 +26,47 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||||
import com.github.steveice10.mc.protocol.data.game.level.particle.Particle;
|
import com.github.steveice10.mc.protocol.data.game.level.particle.Particle;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.utils.EffectUtils;
|
import org.geysermc.connector.utils.EffectUtils;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class AreaEffectCloudEntity extends Entity {
|
public class AreaEffectCloudEntity extends Entity {
|
||||||
|
|
||||||
public AreaEffectCloudEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public AreaEffectCloudEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
// Without this the cloud doesn't appear,
|
|
||||||
metadata.put(EntityData.AREA_EFFECT_CLOUD_DURATION, 600);
|
|
||||||
|
|
||||||
// This disabled client side shrink of the cloud
|
|
||||||
metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, 0.0f);
|
|
||||||
metadata.put(EntityData.AREA_EFFECT_CLOUD_CHANGE_RATE, -0.005f);
|
|
||||||
metadata.put(EntityData.AREA_EFFECT_CLOUD_CHANGE_ON_PICKUP, -0.5f);
|
|
||||||
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
protected void initializeMetadata() {
|
||||||
if (entityMetadata.getId() == 8) {
|
super.initializeMetadata();
|
||||||
metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, entityMetadata.getValue());
|
// Without this the cloud doesn't appear,
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, 2.0f * (float) entityMetadata.getValue());
|
dirtyMetadata.put(EntityData.AREA_EFFECT_CLOUD_DURATION, 600);
|
||||||
} else if (entityMetadata.getId() == 9) {
|
|
||||||
metadata.put(EntityData.EFFECT_COLOR, entityMetadata.getValue());
|
// This disabled client side shrink of the cloud
|
||||||
} else if (entityMetadata.getId() == 11) {
|
dirtyMetadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, 0.0f);
|
||||||
Particle particle = (Particle) entityMetadata.getValue();
|
dirtyMetadata.put(EntityData.AREA_EFFECT_CLOUD_CHANGE_RATE, -0.005f);
|
||||||
|
dirtyMetadata.put(EntityData.AREA_EFFECT_CLOUD_CHANGE_ON_PICKUP, -0.5f);
|
||||||
|
|
||||||
|
setFlag(EntityFlag.FIRE_IMMUNE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRadius(EntityMetadata<Float> entityMetadata) {
|
||||||
|
float value = ((FloatEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
dirtyMetadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, value);
|
||||||
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, 2.0f * value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParticle(EntityMetadata<Particle> entityMetadata) {
|
||||||
|
Particle particle = entityMetadata.getValue();
|
||||||
int particleId = EffectUtils.getParticleId(session, particle.getType());
|
int particleId = EffectUtils.getParticleId(session, particle.getType());
|
||||||
if (particleId != -1) {
|
if (particleId != -1) {
|
||||||
metadata.put(EntityData.AREA_EFFECT_CLOUD_PARTICLE_ID, particleId);
|
dirtyMetadata.put(EntityData.AREA_EFFECT_CLOUD_PARTICLE_ID, particleId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -26,13 +26,16 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.AnimatePacket;
|
import com.nukkitx.protocol.bedrock.packet.AnimatePacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import lombok.Getter;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class BoatEntity extends Entity {
|
public class BoatEntity extends Entity {
|
||||||
@ -52,28 +55,36 @@ public class BoatEntity extends Entity {
|
|||||||
private boolean isPaddlingRight;
|
private boolean isPaddlingRight;
|
||||||
private float paddleTimeRight;
|
private float paddleTimeRight;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saved for using the "pick" functionality on a boat.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private int variant;
|
||||||
|
|
||||||
// Looks too fast and too choppy with 0.1f, which is how I believe the Microsoftian client handles it
|
// Looks too fast and too choppy with 0.1f, which is how I believe the Microsoftian client handles it
|
||||||
private final float ROWING_SPEED = 0.05f;
|
private final float ROWING_SPEED = 0.05f;
|
||||||
|
|
||||||
public BoatEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public BoatEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position.add(0d, entityType.getOffset(), 0d), motion, rotation.add(90, 0, 90));
|
// Initial rotation is incorrect
|
||||||
|
super(session, entityId, geyserId, uuid, definition, position.add(0d, definition.offset(), 0d), motion, yaw + 90, 0, yaw + 90);
|
||||||
|
|
||||||
// Required to be able to move on land 1.16.200+ or apply gravity not in the water 1.16.100+
|
// Required to be able to move on land 1.16.200+ or apply gravity not in the water 1.16.100+
|
||||||
metadata.put(EntityData.IS_BUOYANT, (byte) 1);
|
dirtyMetadata.put(EntityData.IS_BUOYANT, (byte) 1);
|
||||||
metadata.put(EntityData.BUOYANCY_DATA, BUOYANCY_DATA);
|
dirtyMetadata.put(EntityData.BUOYANCY_DATA, BUOYANCY_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
|
||||||
// We don't include the rotation (y) as it causes the boat to appear sideways
|
// We don't include the rotation (y) as it causes the boat to appear sideways
|
||||||
setPosition(position.add(0d, this.entityType.getOffset(), 0d));
|
setPosition(position.add(0d, this.definition.offset(), 0d));
|
||||||
setRotation(Vector3f.from(rotation.getX() + 90, 0, rotation.getX() + 90));
|
this.yaw = yaw + 90;
|
||||||
|
this.headYaw = yaw + 90;
|
||||||
setOnGround(isOnGround);
|
setOnGround(isOnGround);
|
||||||
|
|
||||||
MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
|
MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
|
||||||
moveEntityPacket.setRuntimeEntityId(geyserId);
|
moveEntityPacket.setRuntimeEntityId(geyserId);
|
||||||
// Minimal glitching when ClientboundMoveVehiclePacket is sent
|
// Minimal glitching when ClientboundMoveVehiclePacket is sent
|
||||||
moveEntityPacket.setPosition(session.getRidingVehicleEntity() == this ? position.up(EntityType.PLAYER.getOffset() - this.entityType.getOffset()) : this.position);
|
moveEntityPacket.setPosition(session.getRidingVehicleEntity() == this ? position.up(EntityDefinitions.PLAYER.offset() - this.definition.offset()) : this.position);
|
||||||
moveEntityPacket.setRotation(getBedrockRotation());
|
moveEntityPacket.setRotation(getBedrockRotation());
|
||||||
moveEntityPacket.setOnGround(isOnGround);
|
moveEntityPacket.setOnGround(isOnGround);
|
||||||
moveEntityPacket.setTeleported(teleported);
|
moveEntityPacket.setTeleported(teleported);
|
||||||
@ -84,47 +95,32 @@ public class BoatEntity extends Entity {
|
|||||||
/**
|
/**
|
||||||
* Move the boat without making the adjustments needed to translate from Java
|
* Move the boat without making the adjustments needed to translate from Java
|
||||||
*/
|
*/
|
||||||
public void moveAbsoluteWithoutAdjustments(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
public void moveAbsoluteWithoutAdjustments(Vector3f position, float yaw, boolean isOnGround, boolean teleported) {
|
||||||
super.moveAbsolute(session, position, Vector3f.from(rotation.getX(), 0, rotation.getX()), isOnGround, teleported);
|
super.moveAbsolute(position, yaw, 0, yaw, isOnGround, teleported);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) {
|
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, float headYaw, boolean isOnGround) {
|
||||||
super.moveRelative(session, relX, relY, relZ, Vector3f.from(rotation.getX(), 0, rotation.getX()), isOnGround);
|
super.moveRelative(relX, relY, relZ, yaw, 0, yaw, isOnGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updatePositionAndRotation(GeyserSession session, double moveX, double moveY, double moveZ, float yaw, float pitch, boolean isOnGround) {
|
public void updatePositionAndRotation(double moveX, double moveY, double moveZ, float yaw, float pitch, boolean isOnGround) {
|
||||||
moveRelative(session, moveX, moveY, moveZ, yaw + 90, pitch, isOnGround);
|
moveRelative(moveX, moveY, moveZ, yaw + 90, pitch, isOnGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateRotation(GeyserSession session, float yaw, float pitch, boolean isOnGround) {
|
public void updateRotation(float yaw, float pitch, boolean isOnGround) {
|
||||||
moveRelative(session, 0, 0, 0, Vector3f.from(yaw + 90, 0, 0), isOnGround);
|
moveRelative(0, 0, 0, yaw + 90, 0, 0, isOnGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setVariant(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
variant = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
// Time since last hit
|
dirtyMetadata.put(EntityData.VARIANT, variant);
|
||||||
if (entityMetadata.getId() == 8) {
|
|
||||||
metadata.put(EntityData.HURT_TIME, entityMetadata.getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rocking direction
|
public void setPaddlingLeft(EntityMetadata<Boolean> entityMetadata) {
|
||||||
if (entityMetadata.getId() == 9) {
|
isPaddlingLeft = ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
metadata.put(EntityData.HURT_DIRECTION, entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 'Health' in Bedrock, damage taken in Java
|
|
||||||
if (entityMetadata.getId() == 10) {
|
|
||||||
// Not exactly health but it makes motion in Bedrock
|
|
||||||
metadata.put(EntityData.HEALTH, 40 - ((int) (float) entityMetadata.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entityMetadata.getId() == 11) {
|
|
||||||
metadata.put(EntityData.VARIANT, entityMetadata.getValue());
|
|
||||||
} else if (entityMetadata.getId() == 12) {
|
|
||||||
isPaddlingLeft = (boolean) entityMetadata.getValue();
|
|
||||||
if (isPaddlingLeft) {
|
if (isPaddlingLeft) {
|
||||||
// Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing
|
// Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing
|
||||||
// This is an asynchronous method that emulates Bedrock rowing until "false" is sent.
|
// This is an asynchronous method that emulates Bedrock rowing until "false" is sent.
|
||||||
@ -138,11 +134,12 @@ public class BoatEntity extends Entity {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Indicate that the row position should be reset
|
// Indicate that the row position should be reset
|
||||||
metadata.put(EntityData.ROW_TIME_LEFT, 0.0f);
|
dirtyMetadata.put(EntityData.ROW_TIME_LEFT, 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (entityMetadata.getId() == 13) {
|
|
||||||
isPaddlingRight = (boolean) entityMetadata.getValue();
|
public void setPaddlingRight(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
isPaddlingRight = ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (isPaddlingRight) {
|
if (isPaddlingRight) {
|
||||||
paddleTimeRight = 0f;
|
paddleTimeRight = 0f;
|
||||||
if (!this.passengers.isEmpty()) {
|
if (!this.passengers.isEmpty()) {
|
||||||
@ -152,23 +149,8 @@ public class BoatEntity extends Entity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
metadata.put(EntityData.ROW_TIME_RIGHT, 0.0f);
|
dirtyMetadata.put(EntityData.ROW_TIME_RIGHT, 0.0f);
|
||||||
}
|
}
|
||||||
} else if (entityMetadata.getId() == 14) {
|
|
||||||
// Possibly - I don't think this does anything?
|
|
||||||
metadata.put(EntityData.BOAT_BUBBLE_TIME, entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBedrockMetadata(GeyserSession session) {
|
|
||||||
super.updateBedrockMetadata(session);
|
|
||||||
|
|
||||||
// As these indicate to reset rowing, remove them until it is time to send them out again.
|
|
||||||
metadata.remove(EntityData.ROW_TIME_LEFT);
|
|
||||||
metadata.remove(EntityData.ROW_TIME_RIGHT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLeftPaddle(GeyserSession session, Entity rower) {
|
private void updateLeftPaddle(GeyserSession session, Entity rower) {
|
||||||
|
@ -25,42 +25,33 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.chat.MessageTranslator;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class CommandBlockMinecartEntity extends DefaultBlockMinecartEntity {
|
public class CommandBlockMinecartEntity extends DefaultBlockMinecartEntity {
|
||||||
|
|
||||||
public CommandBlockMinecartEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public CommandBlockMinecartEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
// Required, or else the GUI will not open
|
|
||||||
metadata.put(EntityData.CONTAINER_TYPE, (byte) 16);
|
|
||||||
metadata.put(EntityData.CONTAINER_BASE_SIZE, 1);
|
|
||||||
// Required, or else the client does not bother to send a packet back with the new information
|
|
||||||
metadata.put(EntityData.COMMAND_BLOCK_ENABLED, (byte) 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
protected void initializeMetadata() {
|
||||||
if (entityMetadata.getId() == 14) {
|
// Required, or else the GUI will not open
|
||||||
metadata.put(EntityData.COMMAND_BLOCK_COMMAND, entityMetadata.getValue());
|
dirtyMetadata.put(EntityData.CONTAINER_TYPE, (byte) 16);
|
||||||
}
|
dirtyMetadata.put(EntityData.CONTAINER_BASE_SIZE, 1);
|
||||||
if (entityMetadata.getId() == 15) {
|
// Required, or else the client does not bother to send a packet back with the new information
|
||||||
metadata.put(EntityData.COMMAND_BLOCK_LAST_OUTPUT, MessageTranslator.convertMessage((Component) entityMetadata.getValue()));
|
dirtyMetadata.put(EntityData.COMMAND_BLOCK_ENABLED, (byte) 1);
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* By default, the command block shown is purple on Bedrock, which does not match Java Edition's orange.
|
* By default, the command block shown is purple on Bedrock, which does not match Java Edition's orange.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updateDefaultBlockMetadata(GeyserSession session) {
|
public void updateDefaultBlockMetadata() {
|
||||||
metadata.put(EntityData.DISPLAY_ITEM, session.getBlockMappings().getCommandBlockRuntimeId());
|
dirtyMetadata.put(EntityData.DISPLAY_ITEM, session.getBlockMappings().getCommandBlockRuntimeId());
|
||||||
metadata.put(EntityData.DISPLAY_OFFSET, 6);
|
dirtyMetadata.put(EntityData.DISPLAY_OFFSET, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,14 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used as a base for minecarts with a default block to display like furnaces and spawners
|
* This class is used as a base for minecarts with a default block to display like furnaces and spawners
|
||||||
*/
|
*/
|
||||||
@ -40,53 +43,48 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
|
|||||||
public int customBlockOffset = 0;
|
public int customBlockOffset = 0;
|
||||||
public boolean showCustomBlock = false;
|
public boolean showCustomBlock = false;
|
||||||
|
|
||||||
public DefaultBlockMinecartEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public DefaultBlockMinecartEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
metadata.put(EntityData.CUSTOM_DISPLAY, (byte) 1);
|
dirtyMetadata.put(EntityData.CUSTOM_DISPLAY, (byte) 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnEntity(GeyserSession session) {
|
public void spawnEntity() {
|
||||||
updateDefaultBlockMetadata(session);
|
updateDefaultBlockMetadata();
|
||||||
super.spawnEntity(session);
|
super.spawnEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void setCustomBlock(EntityMetadata<Integer> entityMetadata) {
|
||||||
|
customBlock = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
// Custom block
|
|
||||||
if (entityMetadata.getId() == 11) {
|
|
||||||
customBlock = (int) entityMetadata.getValue();
|
|
||||||
|
|
||||||
if (showCustomBlock) {
|
if (showCustomBlock) {
|
||||||
metadata.put(EntityData.DISPLAY_ITEM, session.getBlockMappings().getBedrockBlockId(customBlock));
|
dirtyMetadata.put(EntityData.DISPLAY_ITEM, session.getBlockMappings().getBedrockBlockId(customBlock));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom block offset
|
@Override
|
||||||
if (entityMetadata.getId() == 12) {
|
public void setCustomBlockOffset(EntityMetadata<Integer> entityMetadata) {
|
||||||
customBlockOffset = (int) entityMetadata.getValue();
|
customBlockOffset = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
|
||||||
if (showCustomBlock) {
|
if (showCustomBlock) {
|
||||||
metadata.put(EntityData.DISPLAY_OFFSET, customBlockOffset);
|
dirtyMetadata.put(EntityData.DISPLAY_OFFSET, customBlockOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the custom block should be enabled
|
@Override
|
||||||
if (entityMetadata.getId() == 13) {
|
public void setShowCustomBlock(EntityMetadata<Boolean> entityMetadata) {
|
||||||
if ((boolean) entityMetadata.getValue()) {
|
if (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()) {
|
||||||
showCustomBlock = true;
|
showCustomBlock = true;
|
||||||
metadata.put(EntityData.DISPLAY_ITEM, session.getBlockMappings().getBedrockBlockId(customBlock));
|
dirtyMetadata.put(EntityData.DISPLAY_ITEM, session.getBlockMappings().getBedrockBlockId(customBlock));
|
||||||
metadata.put(EntityData.DISPLAY_OFFSET, customBlockOffset);
|
dirtyMetadata.put(EntityData.DISPLAY_OFFSET, customBlockOffset);
|
||||||
} else {
|
} else {
|
||||||
showCustomBlock = false;
|
showCustomBlock = false;
|
||||||
updateDefaultBlockMetadata(session);
|
updateDefaultBlockMetadata();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
public void updateDefaultBlockMetadata() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateDefaultBlockMetadata(GeyserSession session) { }
|
|
||||||
}
|
}
|
||||||
|
@ -31,33 +31,31 @@ import com.nukkitx.math.vector.Vector3f;
|
|||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class EnderCrystalEntity extends Entity {
|
public class EnderCrystalEntity extends Entity {
|
||||||
|
|
||||||
public EnderCrystalEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public EnderCrystalEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
// Bedrock 1.16.100+ - prevents the entity from appearing on fire itself when fire is underneath it
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
protected void initializeMetadata() {
|
||||||
|
super.initializeMetadata();
|
||||||
|
// Bedrock 1.16.100+ - prevents the entity from appearing on fire itself when fire is underneath it
|
||||||
|
dirtyMetadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlockTarget(EntityMetadata<Position> entityMetadata) {
|
||||||
// Show beam
|
// Show beam
|
||||||
// Usually performed client-side on Bedrock except for Ender Dragon respawn event
|
// Usually performed client-side on Bedrock except for Ender Dragon respawn event
|
||||||
if (entityMetadata.getId() == 8) {
|
Position position = entityMetadata.getValue();
|
||||||
if (entityMetadata.getValue() instanceof Position pos) {
|
if (position != null) {
|
||||||
metadata.put(EntityData.BLOCK_TARGET, Vector3i.from(pos.getX(), pos.getY(), pos.getZ()));
|
dirtyMetadata.put(EntityData.BLOCK_TARGET, Vector3i.from(position.getX(), position.getY(), position.getZ()));
|
||||||
} else {
|
} else {
|
||||||
metadata.put(EntityData.BLOCK_TARGET, Vector3i.ZERO);
|
dirtyMetadata.put(EntityData.BLOCK_TARGET, Vector3i.ZERO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// There is a base located on the ender crystal
|
|
||||||
if (entityMetadata.getId() == 9) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.SHOW_BOTTOM, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,10 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
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.data.game.entity.metadata.Pose;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityDataMap;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityDataMap;
|
||||||
@ -38,19 +40,24 @@ import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
|||||||
import com.nukkitx.protocol.bedrock.packet.RemoveEntityPacket;
|
import com.nukkitx.protocol.bedrock.packet.RemoveEntityPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
||||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||||
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.chat.MessageTranslator;
|
import org.geysermc.connector.network.translators.chat.MessageTranslator;
|
||||||
import org.geysermc.connector.utils.MathUtils;
|
import org.geysermc.connector.utils.MathUtils;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class Entity {
|
public class Entity {
|
||||||
|
protected final GeyserSession session;
|
||||||
|
|
||||||
protected long entityId;
|
protected long entityId;
|
||||||
protected final long geyserId;
|
protected final long geyserId;
|
||||||
|
protected UUID uuid;
|
||||||
|
|
||||||
protected Vector3f position;
|
protected Vector3f position;
|
||||||
protected Vector3f motion;
|
protected Vector3f motion;
|
||||||
@ -58,85 +65,120 @@ public class Entity {
|
|||||||
/**
|
/**
|
||||||
* x = Yaw, y = Pitch, z = HeadYaw
|
* x = Yaw, y = Pitch, z = HeadYaw
|
||||||
*/
|
*/
|
||||||
protected Vector3f rotation;
|
protected float yaw;
|
||||||
|
protected float pitch;
|
||||||
|
protected float headYaw;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves if the entity should be on the ground. Otherwise entities like parrots are flapping when rotating
|
* Saves if the entity should be on the ground. Otherwise entities like parrots are flapping when rotating
|
||||||
*/
|
*/
|
||||||
protected boolean onGround;
|
protected boolean onGround;
|
||||||
|
|
||||||
protected EntityType entityType;
|
protected EntityDefinition<?> definition;
|
||||||
|
|
||||||
protected boolean valid;
|
protected boolean valid;
|
||||||
|
|
||||||
protected LongOpenHashSet passengers = new LongOpenHashSet();
|
/* Metadata about this specific entity */
|
||||||
protected EntityDataMap metadata = new EntityDataMap();
|
@Setter(AccessLevel.NONE)
|
||||||
|
protected float boundingBoxHeight;
|
||||||
|
@Setter(AccessLevel.NONE)
|
||||||
|
protected float boundingBoxWidth;
|
||||||
|
/* Metadata end */
|
||||||
|
|
||||||
|
protected LongOpenHashSet passengers = new LongOpenHashSet();
|
||||||
|
/**
|
||||||
|
* A container to store temporary metadata before it's sent to Bedrock.
|
||||||
|
*/
|
||||||
|
protected final EntityDataMap dirtyMetadata = new EntityDataMap();
|
||||||
|
/**
|
||||||
|
* The entity flags for the Bedrock entity.
|
||||||
|
* These must always be saved - if flags are updated and the other values aren't present, the Bedrock client will
|
||||||
|
* think they are set to false.
|
||||||
|
*/
|
||||||
|
@Getter(AccessLevel.NONE)
|
||||||
|
protected final EntityFlags flags = new EntityFlags();
|
||||||
|
/**
|
||||||
|
* Indicates if flags have been updated and need to be sent to the client.
|
||||||
|
*/
|
||||||
|
@Getter(AccessLevel.NONE)
|
||||||
|
@Setter(AccessLevel.PROTECTED) // For players
|
||||||
|
private boolean flagsDirty = false;
|
||||||
|
|
||||||
|
public Entity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
|
this.session = session;
|
||||||
|
|
||||||
public Entity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
|
||||||
this.entityId = entityId;
|
this.entityId = entityId;
|
||||||
this.geyserId = geyserId;
|
this.geyserId = geyserId;
|
||||||
this.entityType = entityType;
|
this.uuid = uuid;
|
||||||
|
this.definition = definition;
|
||||||
this.motion = motion;
|
this.motion = motion;
|
||||||
this.rotation = rotation;
|
this.yaw = yaw;
|
||||||
|
this.pitch = pitch;
|
||||||
|
this.headYaw = headYaw;
|
||||||
|
|
||||||
this.valid = false;
|
this.valid = false;
|
||||||
|
|
||||||
setPosition(position);
|
setPosition(position);
|
||||||
setAir(getMaxAir());
|
setAir(getMaxAir());
|
||||||
|
|
||||||
metadata.put(EntityData.SCALE, 1f);
|
initializeMetadata();
|
||||||
metadata.put(EntityData.COLOR, 0);
|
|
||||||
metadata.put(EntityData.MAX_AIR_SUPPLY, getMaxAir());
|
|
||||||
metadata.put(EntityData.LEASH_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) {
|
/**
|
||||||
|
* Called on entity spawn. Used to populate the entity metadata and flags with default values.
|
||||||
|
*/
|
||||||
|
protected void initializeMetadata() {
|
||||||
|
dirtyMetadata.put(EntityData.SCALE, 1f);
|
||||||
|
dirtyMetadata.put(EntityData.COLOR, 0);
|
||||||
|
dirtyMetadata.put(EntityData.MAX_AIR_SUPPLY, getMaxAir());
|
||||||
|
setDimensions(Pose.STANDING);
|
||||||
|
setFlag(EntityFlag.HAS_GRAVITY, true);
|
||||||
|
setFlag(EntityFlag.HAS_COLLISION, true);
|
||||||
|
setFlag(EntityFlag.CAN_SHOW_NAME, true);
|
||||||
|
setFlag(EntityFlag.CAN_CLIMB, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void spawnEntity() {
|
||||||
AddEntityPacket addEntityPacket = new AddEntityPacket();
|
AddEntityPacket addEntityPacket = new AddEntityPacket();
|
||||||
addEntityPacket.setIdentifier(entityType.getIdentifier());
|
addEntityPacket.setIdentifier(definition.identifier());
|
||||||
addEntityPacket.setRuntimeEntityId(geyserId);
|
addEntityPacket.setRuntimeEntityId(geyserId);
|
||||||
addEntityPacket.setUniqueEntityId(geyserId);
|
addEntityPacket.setUniqueEntityId(geyserId);
|
||||||
addEntityPacket.setPosition(position);
|
addEntityPacket.setPosition(position);
|
||||||
addEntityPacket.setMotion(motion);
|
addEntityPacket.setMotion(motion);
|
||||||
addEntityPacket.setRotation(getBedrockRotation());
|
addEntityPacket.setRotation(getBedrockRotation());
|
||||||
addEntityPacket.setEntityType(entityType.getType());
|
addEntityPacket.setEntityType(definition.bedrockId());
|
||||||
addEntityPacket.getMetadata().putAll(metadata);
|
addEntityPacket.getMetadata().putFlags(flags)
|
||||||
|
.putAll(dirtyMetadata);
|
||||||
addAdditionalSpawnData(addEntityPacket);
|
addAdditionalSpawnData(addEntityPacket);
|
||||||
|
|
||||||
valid = true;
|
valid = true;
|
||||||
session.sendUpstreamPacket(addEntityPacket);
|
session.sendUpstreamPacket(addEntityPacket);
|
||||||
|
|
||||||
session.getConnector().getLogger().debug("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");
|
dirtyMetadata.clear();
|
||||||
|
flagsDirty = false;
|
||||||
|
|
||||||
|
session.getConnector().getLogger().debug("Spawned entity " + getClass().getName() + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To be overridden in other entity classes, if additional things need to be done to the spawn entity packet.
|
* To be overridden in other entity classes, if additional things need to be done to the spawn entity packet.
|
||||||
*/
|
*/
|
||||||
public void addAdditionalSpawnData(AddEntityPacket addEntityPacket) {
|
public void addAdditionalSpawnData(AddEntityPacket addEntityPacket) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Despawns the entity
|
* Despawns the entity
|
||||||
*
|
*
|
||||||
* @param session The GeyserSession
|
|
||||||
* @return can be deleted
|
* @return can be deleted
|
||||||
*/
|
*/
|
||||||
public boolean despawnEntity(GeyserSession session) {
|
public boolean despawnEntity() {
|
||||||
if (!valid) return true;
|
if (!valid) return true;
|
||||||
|
|
||||||
for (long passenger : passengers) { // Make sure all passengers on the despawned entity are updated
|
for (long passenger : passengers) { // Make sure all passengers on the despawned entity are updated
|
||||||
Entity entity = session.getEntityCache().getEntityByJavaId(passenger);
|
Entity entity = session.getEntityCache().getEntityByJavaId(passenger);
|
||||||
if (entity == null) continue;
|
if (entity == null) continue;
|
||||||
entity.getMetadata().getOrCreateFlags().setFlag(EntityFlag.RIDING, false);
|
entity.setFlag(EntityFlag.RIDING, false);
|
||||||
entity.updateBedrockMetadata(session);
|
entity.updateBedrockMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveEntityPacket removeEntityPacket = new RemoveEntityPacket();
|
RemoveEntityPacket removeEntityPacket = new RemoveEntityPacket();
|
||||||
@ -147,12 +189,14 @@ public class Entity {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void moveRelative(GeyserSession session, double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) {
|
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) {
|
||||||
moveRelative(session, relX, relY, relZ, Vector3f.from(yaw, pitch, this.rotation.getZ()), isOnGround);
|
moveRelative(relX, relY, relZ, yaw, pitch, this.headYaw, isOnGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) {
|
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, float headYaw, boolean isOnGround) {
|
||||||
setRotation(rotation);
|
setYaw(yaw);
|
||||||
|
setPitch(pitch);
|
||||||
|
setHeadYaw(headYaw);
|
||||||
setOnGround(isOnGround);
|
setOnGround(isOnGround);
|
||||||
this.position = Vector3f.from(position.getX() + relX, position.getY() + relY, position.getZ() + relZ);
|
this.position = Vector3f.from(position.getX() + relX, position.getY() + relY, position.getZ() + relZ);
|
||||||
|
|
||||||
@ -166,13 +210,16 @@ public class Entity {
|
|||||||
session.sendUpstreamPacket(moveEntityPacket);
|
session.sendUpstreamPacket(moveEntityPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void moveAbsolute(GeyserSession session, Vector3f position, float yaw, float pitch, boolean isOnGround, boolean teleported) {
|
public void moveAbsolute(Vector3f position, float yaw, float pitch, boolean isOnGround, boolean teleported) {
|
||||||
moveAbsolute(session, position, Vector3f.from(yaw, pitch, this.rotation.getZ()), isOnGround, teleported);
|
moveAbsolute(position, yaw, pitch, this.headYaw, isOnGround, teleported);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
|
||||||
setPosition(position);
|
setPosition(position);
|
||||||
setRotation(rotation);
|
// Setters are intentional so it can be overridden in places like AbstractArrowEntity
|
||||||
|
setYaw(yaw);
|
||||||
|
setPitch(pitch);
|
||||||
|
setHeadYaw(headYaw);
|
||||||
setOnGround(isOnGround);
|
setOnGround(isOnGround);
|
||||||
|
|
||||||
MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
|
MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
|
||||||
@ -187,28 +234,25 @@ public class Entity {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Teleports an entity to a new location. Used in JavaTeleportEntityTranslator.
|
* Teleports an entity to a new location. Used in JavaTeleportEntityTranslator.
|
||||||
* @param session GeyserSession.
|
|
||||||
* @param position The new position of the entity.
|
* @param position The new position of the entity.
|
||||||
* @param yaw The new yaw of the entity.
|
* @param yaw The new yaw of the entity.
|
||||||
* @param pitch The new pitch of the entity.
|
* @param pitch The new pitch of the entity.
|
||||||
* @param isOnGround Whether the entity is currently on the ground.
|
* @param isOnGround Whether the entity is currently on the ground.
|
||||||
*/
|
*/
|
||||||
public void teleport(GeyserSession session, Vector3f position, float yaw, float pitch, boolean isOnGround) {
|
public void teleport(Vector3f position, float yaw, float pitch, boolean isOnGround) {
|
||||||
moveAbsolute(session, position, yaw, pitch, isOnGround, false);
|
moveAbsolute(position, yaw, pitch, isOnGround, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates an entity's head position. Used in JavaRotateHeadTranslator.
|
* Updates an entity's head position. Used in JavaRotateHeadTranslator.
|
||||||
* @param session GeyserSession.
|
|
||||||
* @param headYaw The new head rotation of the entity.
|
* @param headYaw The new head rotation of the entity.
|
||||||
*/
|
*/
|
||||||
public void updateHeadLookRotation(GeyserSession session, float headYaw) {
|
public void updateHeadLookRotation(float headYaw) {
|
||||||
moveRelative(session, 0, 0, 0, Vector3f.from(headYaw, rotation.getY(), rotation.getZ()), onGround);
|
moveRelative(0, 0, 0, headYaw, pitch, this.headYaw, onGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates an entity's position and rotation. Used in JavaMoveEntityPosRotTranslator.
|
* Updates an entity's position and rotation. Used in JavaMoveEntityPosRotTranslator.
|
||||||
* @param session GeyserSession
|
|
||||||
* @param moveX The new X offset of the current position.
|
* @param moveX The new X offset of the current position.
|
||||||
* @param moveY The new Y offset of the current position.
|
* @param moveY The new Y offset of the current position.
|
||||||
* @param moveZ The new Z offset of the current position.
|
* @param moveZ The new Z offset of the current position.
|
||||||
@ -216,106 +260,115 @@ public class Entity {
|
|||||||
* @param pitch The new pitch of the entity.
|
* @param pitch The new pitch of the entity.
|
||||||
* @param isOnGround Whether the entity is currently on the ground.
|
* @param isOnGround Whether the entity is currently on the ground.
|
||||||
*/
|
*/
|
||||||
public void updatePositionAndRotation(GeyserSession session, double moveX, double moveY, double moveZ, float yaw, float pitch, boolean isOnGround) {
|
public void updatePositionAndRotation(double moveX, double moveY, double moveZ, float yaw, float pitch, boolean isOnGround) {
|
||||||
moveRelative(session, moveX, moveY, moveZ, Vector3f.from(rotation.getX(), pitch, yaw), isOnGround);
|
moveRelative(moveX, moveY, moveZ, this.yaw, pitch, yaw, isOnGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates an entity's rotation. Used in JavaMoveEntityRotTranslator.
|
* Updates an entity's rotation. Used in JavaMoveEntityRotTranslator.
|
||||||
* @param session GeyserSession.
|
|
||||||
* @param yaw The new yaw of the entity.
|
* @param yaw The new yaw of the entity.
|
||||||
* @param pitch The new pitch of the entity.
|
* @param pitch The new pitch of the entity.
|
||||||
* @param isOnGround Whether the entity is currently on the ground.
|
* @param isOnGround Whether the entity is currently on the ground.
|
||||||
*/
|
*/
|
||||||
public void updateRotation(GeyserSession session, float yaw, float pitch, boolean isOnGround) {
|
public void updateRotation(float yaw, float pitch, boolean isOnGround) {
|
||||||
updatePositionAndRotation(session, 0, 0, 0, yaw, pitch, isOnGround);
|
updatePositionAndRotation(0, 0, 0, yaw, pitch, isOnGround);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean getFlag(EntityFlag flag) {
|
||||||
|
return flags.getFlag(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the Java metadata to the local Bedrock metadata copy
|
* Updates a flag value and determines if the flags would need synced with the Bedrock client.
|
||||||
* @param entityMetadata the Java entity metadata
|
|
||||||
* @param session GeyserSession
|
|
||||||
*/
|
*/
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public final void setFlag(EntityFlag flag, boolean value) {
|
||||||
switch (entityMetadata.getId()) {
|
flagsDirty |= flags.setFlag(flag, value);
|
||||||
case 0:
|
|
||||||
if (entityMetadata.getType() == MetadataType.BYTE) {
|
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !metadata.getFlags().getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.SNEAKING, (xd & 0x02) == 0x02);
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08);
|
|
||||||
// Swimming is ignored here and instead we rely on the pose
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80);
|
|
||||||
|
|
||||||
setInvisible(session, (xd & 0x20) == 0x20);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1: // Air/bubbles
|
|
||||||
setAir((int) entityMetadata.getValue());
|
|
||||||
break;
|
|
||||||
case 2: // custom name
|
|
||||||
setDisplayName(session, (Component) entityMetadata.getValue());
|
|
||||||
break;
|
|
||||||
case 3: // is custom name visible
|
|
||||||
setDisplayNameVisible(entityMetadata);
|
|
||||||
break;
|
|
||||||
case 4: // silent
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.SILENT, (boolean) entityMetadata.getValue());
|
|
||||||
break;
|
|
||||||
case 5: // no gravity
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, !(boolean) entityMetadata.getValue());
|
|
||||||
break;
|
|
||||||
case 6: // Pose change - typically used for bounding box and not animation
|
|
||||||
Pose pose = (Pose) entityMetadata.getValue();
|
|
||||||
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.SLEEPING, pose.equals(Pose.SLEEPING));
|
|
||||||
// Triggered when crawling
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.SWIMMING, pose.equals(Pose.SWIMMING));
|
|
||||||
setDimensions(pose);
|
|
||||||
break;
|
|
||||||
case 7: // Freezing ticks
|
|
||||||
// The value that Java edition gives us is in ticks, but Bedrock uses a float percentage of the strength 0.0 -> 1.0
|
|
||||||
// The Java client caps its freezing tick percentage at 140
|
|
||||||
int freezingTicks = Math.min((int) entityMetadata.getValue(), 140);
|
|
||||||
setFreezing(session, freezingTicks / 140f);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the Bedrock metadata to the client
|
* Sends the Bedrock metadata to the client
|
||||||
* @param session GeyserSession
|
|
||||||
*/
|
*/
|
||||||
public void updateBedrockMetadata(GeyserSession session) {
|
public void updateBedrockMetadata() {
|
||||||
if (!valid) return;
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dirtyMetadata.isEmpty() || flagsDirty) {
|
||||||
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
||||||
entityDataPacket.setRuntimeEntityId(geyserId);
|
entityDataPacket.setRuntimeEntityId(geyserId);
|
||||||
entityDataPacket.getMetadata().putAll(metadata);
|
entityDataPacket.getMetadata().putFlags(flags);
|
||||||
|
entityDataPacket.getMetadata().putAll(dirtyMetadata);
|
||||||
session.sendUpstreamPacket(entityDataPacket);
|
session.sendUpstreamPacket(entityDataPacket);
|
||||||
|
|
||||||
|
dirtyMetadata.clear();
|
||||||
|
flagsDirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire
|
||||||
|
setFlag(EntityFlag.SNEAKING, (xd & 0x02) == 0x02);
|
||||||
|
setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08);
|
||||||
|
// Swimming is ignored here and instead we rely on the pose
|
||||||
|
setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80);
|
||||||
|
|
||||||
|
setInvisible((xd & 0x20) == 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, the entity should be shaking on the client's end.
|
* Set a boolean - whether the entity is invisible or visible
|
||||||
*
|
*
|
||||||
* @return whether {@link EntityFlag#SHAKING} should be set to true.
|
* @param value true if the entity is invisible
|
||||||
*/
|
*/
|
||||||
protected boolean isShaking(GeyserSession session) {
|
protected void setInvisible(boolean value) {
|
||||||
return false;
|
setFlag(EntityFlag.INVISIBLE, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setDisplayName(GeyserSession session, Component name) {
|
/**
|
||||||
|
* Set an int from 0 - this entity's maximum air - (air / maxAir) represents the percentage of bubbles left
|
||||||
|
*/
|
||||||
|
public final void setAir(EntityMetadata<?> entityMetadata) {
|
||||||
|
setAir(((IntEntityMetadata) entityMetadata).getPrimitiveValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setAir(int amount) {
|
||||||
|
dirtyMetadata.put(EntityData.AIR_SUPPLY, (short) MathUtils.constrain(amount, 0, getMaxAir()));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getMaxAir() {
|
||||||
|
return 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(EntityMetadata<Component> entityMetadata) {
|
||||||
|
Component name = entityMetadata.getValue();
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
String displayName = MessageTranslator.convertMessage(name, session.getLocale());
|
String displayName = MessageTranslator.convertMessage(name, session.getLocale());
|
||||||
metadata.put(EntityData.NAMETAG, displayName);
|
dirtyMetadata.put(EntityData.NAMETAG, displayName);
|
||||||
} else if (!metadata.getString(EntityData.NAMETAG).isEmpty()) {
|
} else if (!dirtyMetadata.getString(EntityData.NAMETAG).isEmpty()) { //TODO
|
||||||
// Clear nametag
|
// Clear nametag
|
||||||
metadata.put(EntityData.NAMETAG, "");
|
dirtyMetadata.put(EntityData.NAMETAG, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setDisplayNameVisible(EntityMetadata entityMetadata) {
|
public void setDisplayNameVisible(EntityMetadata<Boolean> entityMetadata) {
|
||||||
metadata.put(EntityData.NAMETAG_ALWAYS_SHOW, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
dirtyMetadata.put(EntityData.NAMETAG_ALWAYS_SHOW, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGravity(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
setFlag(EntityFlag.HAS_GRAVITY, !((BooleanEntityMetadata) entityMetadata).getPrimitiveValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usually used for bounding box and not animation.
|
||||||
|
*/
|
||||||
|
public void setPose(EntityMetadata<Pose> entityMetadata) {
|
||||||
|
Pose pose = entityMetadata.getValue();
|
||||||
|
|
||||||
|
setFlag(EntityFlag.SLEEPING, pose.equals(Pose.SLEEPING));
|
||||||
|
// Triggered when crawling
|
||||||
|
setFlag(EntityFlag.SWIMMING, pose.equals(Pose.SWIMMING));
|
||||||
|
setDimensions(pose);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -323,38 +376,33 @@ public class Entity {
|
|||||||
*/
|
*/
|
||||||
protected void setDimensions(Pose pose) {
|
protected void setDimensions(Pose pose) {
|
||||||
// No flexibility options for basic entities
|
// No flexibility options for basic entities
|
||||||
//TODO don't even set this for basic entities since we already set it on entity initialization
|
if (boundingBoxHeight != definition.height() || boundingBoxWidth != definition.width()) {
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, entityType.getWidth());
|
boundingBoxWidth = definition.width();
|
||||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, entityType.getHeight());
|
boundingBoxHeight = definition.height();
|
||||||
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, boundingBoxWidth);
|
||||||
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, boundingBoxHeight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a float from 0-1 - how strong the "frozen" overlay should be on screen.
|
* Set a float from 0-1 - how strong the "frozen" overlay should be on screen.
|
||||||
*/
|
*/
|
||||||
protected void setFreezing(GeyserSession session, float amount) {
|
public float setFreezing(EntityMetadata<Integer> entityMetadata) {
|
||||||
metadata.put(EntityData.FREEZING_EFFECT_STRENGTH, amount);
|
// The value that Java edition gives us is in ticks, but Bedrock uses a float percentage of the strength 0.0 -> 1.0
|
||||||
|
// The Java client caps its freezing tick percentage at 140
|
||||||
|
int freezingTicks = Math.min(((IntEntityMetadata) entityMetadata).getPrimitiveValue(), 140);
|
||||||
|
float freezingPercentage = freezingTicks / 140f;
|
||||||
|
dirtyMetadata.put(EntityData.FREEZING_EFFECT_STRENGTH, freezingPercentage);
|
||||||
|
return freezingPercentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set an int from 0 - this entity's maximum air - (air / maxAir) represents the percentage of bubbles left
|
* If true, the entity should be shaking on the client's end.
|
||||||
* @param amount the amount of air
|
|
||||||
*/
|
|
||||||
protected void setAir(int amount) {
|
|
||||||
metadata.put(EntityData.AIR_SUPPLY, (short) MathUtils.constrain(amount, 0, getMaxAir()));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int getMaxAir() {
|
|
||||||
return 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a boolean - whether the entity is invisible or visible
|
|
||||||
*
|
*
|
||||||
* @param session the Geyser session
|
* @return whether {@link EntityFlag#SHAKING} should be set to true.
|
||||||
* @param value true if the entity is invisible
|
|
||||||
*/
|
*/
|
||||||
protected void setInvisible(GeyserSession session, boolean value) {
|
protected boolean isShaking() {
|
||||||
metadata.getFlags().setFlag(EntityFlag.INVISIBLE, value);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -363,7 +411,7 @@ public class Entity {
|
|||||||
* @return the bedrock rotation
|
* @return the bedrock rotation
|
||||||
*/
|
*/
|
||||||
public Vector3f getBedrockRotation() {
|
public Vector3f getBedrockRotation() {
|
||||||
return Vector3f.from(rotation.getY(), rotation.getZ(), rotation.getX());
|
return Vector3f.from(pitch, headYaw, yaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.connector.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.data.game.entity.type.EntityType;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.geysermc.connector.entity.factory.BaseEntityFactory;
|
||||||
|
import org.geysermc.connector.entity.factory.EntityFactory;
|
||||||
|
import org.geysermc.connector.registry.Registries;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents data for an entity. This includes properties such as height and width, as well as the list of entity
|
||||||
|
* metadata translators needed to translate the properties sent from the server. The translators are structured in such
|
||||||
|
* a way that inserting a new one (for example in version updates) is convenient.
|
||||||
|
*
|
||||||
|
* @param <T> the entity type this definition represents
|
||||||
|
*/
|
||||||
|
public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, EntityType entityType, int bedrockId, String identifier,
|
||||||
|
float width, float height, float offset, List<EntityMetadataTranslator<? super T, ?>> translators) {
|
||||||
|
|
||||||
|
public static <T extends Entity> Builder<T> inherited(BaseEntityFactory<T> factory, EntityDefinition<? super T> parent) {
|
||||||
|
return inherited((EntityFactory<T>) factory, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Entity> Builder<T> inherited(EntityFactory<T> factory, EntityDefinition<? super T> parent) {
|
||||||
|
return new Builder<>(factory, parent.entityType, parent.bedrockId, parent.identifier, parent.width, parent.height, parent.offset, new ObjectArrayList<>(parent.translators));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Entity> Builder<T> builder(EntityFactory<T> factory) {
|
||||||
|
return new Builder<>(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Accessors(fluent = true, chain = true)
|
||||||
|
public static class Builder<T extends Entity> {
|
||||||
|
private final EntityFactory<T> factory;
|
||||||
|
private EntityType type;
|
||||||
|
private int bedrockId;
|
||||||
|
private String identifier;
|
||||||
|
private float width;
|
||||||
|
private float height;
|
||||||
|
private float offset;
|
||||||
|
private final List<EntityMetadataTranslator<? super T, ?>> translators;
|
||||||
|
|
||||||
|
private Builder(EntityFactory<T> factory) {
|
||||||
|
this.factory = factory;
|
||||||
|
translators = new ObjectArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder(EntityFactory<T> factory, EntityType type, int bedrockId, String identifier, float width, float height, float offset, List<EntityMetadataTranslator<? super T, ?>> translators) {
|
||||||
|
this.factory = factory;
|
||||||
|
this.type = type;
|
||||||
|
this.bedrockId = bedrockId;
|
||||||
|
this.identifier = identifier;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.offset = offset;
|
||||||
|
this.translators = translators;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the height and width as one value
|
||||||
|
*/
|
||||||
|
public Builder<T> heightAndWidth(float value) {
|
||||||
|
height = value;
|
||||||
|
width = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the identifier as well
|
||||||
|
*/
|
||||||
|
public Builder<T> type(EntityType type) {
|
||||||
|
this.type = type;
|
||||||
|
identifier = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <U> Builder<T> addTranslator(MetadataType type, BiConsumer<T, EntityMetadata<U>> translateFunction) {
|
||||||
|
translators.add(new EntityMetadataTranslator<>(type, translateFunction));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> addTranslator(EntityMetadataTranslator<T, ?> translator) {
|
||||||
|
translators.add(translator);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityDefinition<T> build() {
|
||||||
|
return build(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param register whether to register this entity in the Registries for entity types. Generally this should be
|
||||||
|
* set to false if we're not expecting this entity to spawn from the network.
|
||||||
|
*/
|
||||||
|
public EntityDefinition<T> build(boolean register) {
|
||||||
|
if (identifier == null && type != null) {
|
||||||
|
identifier = "minecraft:" + type.name().toLowerCase(Locale.ROOT);
|
||||||
|
}
|
||||||
|
EntityDefinition<T> definition = new EntityDefinition<>(factory, type, bedrockId, identifier, width, height, offset, translators);
|
||||||
|
if (register && definition.entityType() != null) {
|
||||||
|
Registries.ENTITY_DEFINITIONS.get().putIfAbsent(definition.entityType(), definition);
|
||||||
|
Registries.JAVA_ENTITY_IDENTIFIERS.get().putIfAbsent(definition.identifier(), definition);
|
||||||
|
}
|
||||||
|
return definition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,999 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.geysermc.connector.entity.factory.BaseEntityFactory;
|
||||||
|
import org.geysermc.connector.entity.factory.EntityFactory;
|
||||||
|
import org.geysermc.connector.entity.factory.ExperienceOrbEntityFactory;
|
||||||
|
import org.geysermc.connector.entity.factory.PaintingEntityFactory;
|
||||||
|
import org.geysermc.connector.entity.living.*;
|
||||||
|
import org.geysermc.connector.entity.living.animal.*;
|
||||||
|
import org.geysermc.connector.entity.living.animal.horse.*;
|
||||||
|
import org.geysermc.connector.entity.living.animal.tameable.CatEntity;
|
||||||
|
import org.geysermc.connector.entity.living.animal.tameable.ParrotEntity;
|
||||||
|
import org.geysermc.connector.entity.living.animal.tameable.TameableEntity;
|
||||||
|
import org.geysermc.connector.entity.living.animal.tameable.WolfEntity;
|
||||||
|
import org.geysermc.connector.entity.living.merchant.AbstractMerchantEntity;
|
||||||
|
import org.geysermc.connector.entity.living.merchant.VillagerEntity;
|
||||||
|
import org.geysermc.connector.entity.living.monster.*;
|
||||||
|
import org.geysermc.connector.entity.living.monster.raid.PillagerEntity;
|
||||||
|
import org.geysermc.connector.entity.living.monster.raid.RaidParticipantEntity;
|
||||||
|
import org.geysermc.connector.entity.living.monster.raid.SpellcasterIllagerEntity;
|
||||||
|
import org.geysermc.connector.entity.living.monster.raid.VindicatorEntity;
|
||||||
|
import org.geysermc.connector.entity.player.PlayerEntity;
|
||||||
|
import org.geysermc.connector.network.translators.chat.MessageTranslator;
|
||||||
|
|
||||||
|
public final class EntityDefinitions {
|
||||||
|
public static final EntityDefinition<AreaEffectCloudEntity> AREA_EFFECT_CLOUD;
|
||||||
|
public static final EntityDefinition<ArmorStandEntity> ARMOR_STAND;
|
||||||
|
public static final EntityDefinition<TippedArrowEntity> ARROW;
|
||||||
|
public static final EntityDefinition<AxolotlEntity> AXOLOTL;
|
||||||
|
public static final EntityDefinition<BatEntity> BAT;
|
||||||
|
public static final EntityDefinition<BeeEntity> BEE;
|
||||||
|
public static final EntityDefinition<BlazeEntity> BLAZE;
|
||||||
|
public static final EntityDefinition<BoatEntity> BOAT;
|
||||||
|
public static final EntityDefinition<CatEntity> CAT;
|
||||||
|
public static final EntityDefinition<MonsterEntity> CAVE_SPIDER;
|
||||||
|
public static final EntityDefinition<ChickenEntity> CHICKEN;
|
||||||
|
public static final EntityDefinition<CreeperEntity> CREEPER;
|
||||||
|
public static final EntityDefinition<AbstractFishEntity> COD;
|
||||||
|
public static final EntityDefinition<AnimalEntity> COW;
|
||||||
|
public static final EntityDefinition<ChestedHorseEntity> DONKEY;
|
||||||
|
public static final EntityDefinition<WaterEntity> DOLPHIN;
|
||||||
|
public static final EntityDefinition<ItemedFireballEntity> DRAGON_FIREBALL;
|
||||||
|
public static final EntityDefinition<ZombieEntity> DROWNED;
|
||||||
|
public static final EntityDefinition<ElderGuardianEntity> ELDER_GUARDIAN;
|
||||||
|
public static final EntityDefinition<EndermanEntity> ENDERMAN;
|
||||||
|
public static final EntityDefinition<MonsterEntity> ENDERMITE;
|
||||||
|
public static final EntityDefinition<EnderDragonEntity> ENDER_DRAGON;
|
||||||
|
public static final EntityDefinition<EnderCrystalEntity> END_CRYSTAL;
|
||||||
|
public static final EntityDefinition<SpellcasterIllagerEntity> EVOKER;
|
||||||
|
public static final EntityDefinition<Entity> EVOKER_FANGS;
|
||||||
|
public static final EntityDefinition<ExpOrbEntity> EXPERIENCE_ORB;
|
||||||
|
public static final EntityDefinition<Entity> EYE_OF_ENDER;
|
||||||
|
public static final EntityDefinition<FallingBlockEntity> FALLING_BLOCK;
|
||||||
|
public static final EntityDefinition<ItemedFireballEntity> FIREBALL;
|
||||||
|
public static final EntityDefinition<FishingHookEntity> FISHING_BOBBER;
|
||||||
|
public static final EntityDefinition<FireworkEntity> FIREWORK_ROCKET;
|
||||||
|
public static final EntityDefinition<FoxEntity> FOX;
|
||||||
|
public static final EntityDefinition<GiantEntity> GIANT;
|
||||||
|
public static final EntityDefinition<GhastEntity> GHAST;
|
||||||
|
public static final EntityDefinition<ItemFrameEntity> GLOW_ITEM_FRAME;
|
||||||
|
public static final EntityDefinition<GlowSquidEntity> GLOW_SQUID;
|
||||||
|
public static final EntityDefinition<GoatEntity> GOAT;
|
||||||
|
public static final EntityDefinition<GuardianEntity> GUARDIAN;
|
||||||
|
public static final EntityDefinition<HoglinEntity> HOGLIN;
|
||||||
|
public static final EntityDefinition<HorseEntity> HORSE;
|
||||||
|
public static final EntityDefinition<ZombieEntity> HUSK;
|
||||||
|
public static final EntityDefinition<SpellcasterIllagerEntity> ILLUSIONER; // Not present on Bedrock
|
||||||
|
public static final EntityDefinition<IronGolemEntity> IRON_GOLEM;
|
||||||
|
public static final EntityDefinition<ItemEntity> ITEM;
|
||||||
|
public static final EntityDefinition<ItemFrameEntity> ITEM_FRAME;
|
||||||
|
public static final EntityDefinition<LeashKnotEntity> LEASH_KNOT;
|
||||||
|
public static final EntityDefinition<LightningEntity> LIGHTNING_BOLT;
|
||||||
|
public static final EntityDefinition<LlamaEntity> LLAMA;
|
||||||
|
public static final EntityDefinition<ThrowableEntity> LLAMA_SPIT;
|
||||||
|
public static final EntityDefinition<MagmaCubeEntity> MAGMA_CUBE;
|
||||||
|
public static final EntityDefinition<MinecartEntity> MINECART;
|
||||||
|
public static final EntityDefinition<MinecartEntity> MINECART_CHEST;
|
||||||
|
public static final EntityDefinition<CommandBlockMinecartEntity> MINECART_COMMAND_BLOCK;
|
||||||
|
public static final EntityDefinition<MinecartEntity> MINECART_HOPPER;
|
||||||
|
public static final EntityDefinition<FurnaceMinecartEntity> MINECART_FURNACE; // Not present on Bedrock
|
||||||
|
public static final EntityDefinition<SpawnerMinecartEntity> MINECART_SPAWNER; // Not present on Bedrock
|
||||||
|
public static final EntityDefinition<MinecartEntity> MINECART_TNT;
|
||||||
|
public static final EntityDefinition<MooshroomEntity> MOOSHROOM;
|
||||||
|
public static final EntityDefinition<ChestedHorseEntity> MULE;
|
||||||
|
public static final EntityDefinition<OcelotEntity> OCELOT;
|
||||||
|
public static final EntityDefinition<PaintingEntity> PAINTING;
|
||||||
|
public static final EntityDefinition<PandaEntity> PANDA;
|
||||||
|
public static final EntityDefinition<ParrotEntity> PARROT;
|
||||||
|
public static final EntityDefinition<PhantomEntity> PHANTOM;
|
||||||
|
public static final EntityDefinition<PigEntity> PIG;
|
||||||
|
public static final EntityDefinition<PiglinEntity> PIGLIN;
|
||||||
|
public static final EntityDefinition<BasePiglinEntity> PIGLIN_BRUTE;
|
||||||
|
public static final EntityDefinition<PillagerEntity> PILLAGER;
|
||||||
|
public static final EntityDefinition<PlayerEntity> PLAYER;
|
||||||
|
public static final EntityDefinition<PolarBearEntity> POLAR_BEAR;
|
||||||
|
public static final EntityDefinition<TNTEntity> PRIMED_TNT;
|
||||||
|
public static final EntityDefinition<PufferFishEntity> PUFFERFISH;
|
||||||
|
public static final EntityDefinition<RabbitEntity> RABBIT;
|
||||||
|
public static final EntityDefinition<RaidParticipantEntity> RAVAGER;
|
||||||
|
public static final EntityDefinition<AbstractFishEntity> SALMON;
|
||||||
|
public static final EntityDefinition<SheepEntity> SHEEP;
|
||||||
|
public static final EntityDefinition<ShulkerEntity> SHULKER;
|
||||||
|
public static final EntityDefinition<ThrowableEntity> SHULKER_BULLET;
|
||||||
|
public static final EntityDefinition<MonsterEntity> SILVERFISH;
|
||||||
|
public static final EntityDefinition<SkeletonEntity> SKELETON;
|
||||||
|
public static final EntityDefinition<AbstractHorseEntity> SKELETON_HORSE;
|
||||||
|
public static final EntityDefinition<SlimeEntity> SLIME;
|
||||||
|
public static final EntityDefinition<ItemedFireballEntity> SMALL_FIREBALL;
|
||||||
|
public static final EntityDefinition<ThrowableItemEntity> SNOWBALL;
|
||||||
|
public static final EntityDefinition<SnowGolemEntity> SNOW_GOLEM;
|
||||||
|
public static final EntityDefinition<AbstractArrowEntity> SPECTRAL_ARROW;
|
||||||
|
public static final EntityDefinition<SpiderEntity> SPIDER;
|
||||||
|
public static final EntityDefinition<SquidEntity> SQUID;
|
||||||
|
public static final EntityDefinition<AbstractSkeletonEntity> STRAY;
|
||||||
|
public static final EntityDefinition<StriderEntity> STRIDER;
|
||||||
|
public static final EntityDefinition<ThrowableItemEntity> THROWN_EGG;
|
||||||
|
public static final EntityDefinition<ThrowableItemEntity> THROWN_ENDERPEARL;
|
||||||
|
public static final EntityDefinition<ThrowableItemEntity> THROWN_EXP_BOTTLE;
|
||||||
|
public static final EntityDefinition<ThrownPotionEntity> THROWN_POTION;
|
||||||
|
public static final EntityDefinition<TropicalFishEntity> TROPICAL_FISH;
|
||||||
|
public static final EntityDefinition<TurtleEntity> TURTLE;
|
||||||
|
public static final EntityDefinition<TraderLlamaEntity> TRADER_LLAMA;
|
||||||
|
public static final EntityDefinition<TridentEntity> TRIDENT;
|
||||||
|
public static final EntityDefinition<AbstractMerchantEntity> WANDERING_TRADER;
|
||||||
|
public static final EntityDefinition<RaidParticipantEntity> WITCH;
|
||||||
|
public static final EntityDefinition<WitherEntity> WITHER;
|
||||||
|
public static final EntityDefinition<AbstractSkeletonEntity> WITHER_SKELETON;
|
||||||
|
public static final EntityDefinition<WitherSkullEntity> WITHER_SKULL;
|
||||||
|
public static final EntityDefinition<WolfEntity> WOLF;
|
||||||
|
public static final EntityDefinition<VillagerEntity> VILLAGER;
|
||||||
|
public static final EntityDefinition<VindicatorEntity> VINDICATOR;
|
||||||
|
public static final EntityDefinition<VexEntity> VEX;
|
||||||
|
public static final EntityDefinition<ZoglinEntity> ZOGLIN;
|
||||||
|
public static final EntityDefinition<ZombieEntity> ZOMBIE;
|
||||||
|
public static final EntityDefinition<AbstractHorseEntity> ZOMBIE_HORSE;
|
||||||
|
public static final EntityDefinition<ZombieVillagerEntity> ZOMBIE_VILLAGER;
|
||||||
|
public static final EntityDefinition<ZombifiedPiglinEntity> ZOMBIFIED_PIGLIN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is not sent over the network
|
||||||
|
*/
|
||||||
|
public static final EntityDefinition<EnderDragonPartEntity> ENDER_DRAGON_PART;
|
||||||
|
/**
|
||||||
|
* Special Bedrock type
|
||||||
|
*/
|
||||||
|
public static final EntityDefinition<WitherSkullEntity> WITHER_SKULL_DANGEROUS;
|
||||||
|
|
||||||
|
static {
|
||||||
|
EntityDefinition<Entity> entityBase = EntityDefinition.builder((BaseEntityFactory<Entity>) Entity::new)
|
||||||
|
.addTranslator(MetadataType.BYTE, Entity::setFlags)
|
||||||
|
.addTranslator(MetadataType.INT, Entity::setAir) // Air/bubbles
|
||||||
|
.addTranslator(MetadataType.OPTIONAL_CHAT, Entity::setDisplayName)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, Entity::setDisplayNameVisible)
|
||||||
|
.<Boolean>addTranslator(MetadataType.BOOLEAN, (entity, entityMetadata) -> entity.setFlag(EntityFlag.SILENT, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, Entity::setGravity)
|
||||||
|
.addTranslator(MetadataType.POSE, Entity::setPose)
|
||||||
|
.addTranslator(MetadataType.INT, Entity::setFreezing)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Extends entity
|
||||||
|
{
|
||||||
|
AREA_EFFECT_CLOUD = EntityDefinition.inherited(AreaEffectCloudEntity::new, entityBase)
|
||||||
|
.type(EntityType.AREA_EFFECT_CLOUD)
|
||||||
|
.bedrockId(95)
|
||||||
|
.height(0.5f).width(1.0f)
|
||||||
|
.addTranslator(MetadataType.FLOAT, AreaEffectCloudEntity::setRadius)
|
||||||
|
.addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.EFFECT_COLOR, entityMetadata.getValue()))
|
||||||
|
.addTranslator(null) // Waiting
|
||||||
|
.addTranslator(MetadataType.PARTICLE, AreaEffectCloudEntity::setParticle)
|
||||||
|
.build();
|
||||||
|
BOAT = EntityDefinition.inherited(BoatEntity::new, entityBase)
|
||||||
|
.type(EntityType.BOAT)
|
||||||
|
.bedrockId(90)
|
||||||
|
.height(0.6f).width(1.6f)
|
||||||
|
.offset(0.35f)
|
||||||
|
.addTranslator(MetadataType.INT, (boatEntity, entityMetadata) -> boatEntity.getDirtyMetadata().put(EntityData.HURT_TIME, entityMetadata.getValue())) // Time since last hit
|
||||||
|
.addTranslator(MetadataType.INT, (boatEntity, entityMetadata) -> boatEntity.getDirtyMetadata().put(EntityData.HURT_DIRECTION, entityMetadata.getValue())) // Rocking direction
|
||||||
|
.<Float>addTranslator(MetadataType.FLOAT, (boatEntity, entityMetadata) ->
|
||||||
|
// 'Health' in Bedrock, damage taken in Java - it makes motion in Bedrock
|
||||||
|
boatEntity.getDirtyMetadata().put(EntityData.HEALTH, 40 - ((int) ((FloatEntityMetadata) entityMetadata).getPrimitiveValue())))
|
||||||
|
.addTranslator(MetadataType.INT, BoatEntity::setVariant)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, BoatEntity::setPaddlingLeft)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, BoatEntity::setPaddlingRight)
|
||||||
|
.addTranslator(MetadataType.INT, (boatEntity, entityMetadata) -> boatEntity.getDirtyMetadata().put(EntityData.BOAT_BUBBLE_TIME, entityMetadata.getValue())) // May not actually do anything
|
||||||
|
.build();
|
||||||
|
DRAGON_FIREBALL = EntityDefinition.inherited(ItemedFireballEntity::new, entityBase)
|
||||||
|
.type(EntityType.DRAGON_FIREBALL)
|
||||||
|
.bedrockId(79)
|
||||||
|
.heightAndWidth(1.0f)
|
||||||
|
.build();
|
||||||
|
END_CRYSTAL = EntityDefinition.inherited(EnderCrystalEntity::new, entityBase)
|
||||||
|
.type(EntityType.END_CRYSTAL)
|
||||||
|
.bedrockId(71)
|
||||||
|
.heightAndWidth(2.0f)
|
||||||
|
.addTranslator(MetadataType.OPTIONAL_POSITION, EnderCrystalEntity::setBlockTarget)
|
||||||
|
.<Boolean>addTranslator(MetadataType.BOOLEAN,
|
||||||
|
(enderCrystalEntity, entityMetadata) -> enderCrystalEntity.setFlag(EntityFlag.SHOW_BOTTOM, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) // There is a base located on the ender crystal
|
||||||
|
.build();
|
||||||
|
EXPERIENCE_ORB = EntityDefinition.inherited((ExperienceOrbEntityFactory) ExpOrbEntity::new, entityBase)
|
||||||
|
.type(EntityType.EXPERIENCE_ORB)
|
||||||
|
.bedrockId(69)
|
||||||
|
.identifier("minecraft:xp_orb")
|
||||||
|
.build();
|
||||||
|
EVOKER_FANGS = EntityDefinition.inherited(entityBase.factory(), entityBase)
|
||||||
|
.type(EntityType.EVOKER_FANGS)
|
||||||
|
.bedrockId(103)
|
||||||
|
.height(0.8f).width(0.5f)
|
||||||
|
.identifier("minecraft:evocation_fang")
|
||||||
|
.build();
|
||||||
|
EYE_OF_ENDER = EntityDefinition.inherited(Entity::new, entityBase)
|
||||||
|
.type(EntityType.EYE_OF_ENDER)
|
||||||
|
.bedrockId(70)
|
||||||
|
.heightAndWidth(0.25f)
|
||||||
|
.identifier("minecraft:eye_of_ender_signal")
|
||||||
|
.build();
|
||||||
|
FALLING_BLOCK = EntityDefinition.inherited(new EntityFactory<FallingBlockEntity>() {
|
||||||
|
}, entityBase) // TODO
|
||||||
|
.type(EntityType.FALLING_BLOCK)
|
||||||
|
.bedrockId(66)
|
||||||
|
.heightAndWidth(0.98f)
|
||||||
|
.build();
|
||||||
|
FIREBALL = EntityDefinition.inherited(ItemedFireballEntity::new, entityBase)
|
||||||
|
.type(EntityType.FIREBALL)
|
||||||
|
.bedrockId(85)
|
||||||
|
.heightAndWidth(1.0f)
|
||||||
|
.build();
|
||||||
|
FIREWORK_ROCKET = EntityDefinition.inherited(FireworkEntity::new, entityBase)
|
||||||
|
.type(EntityType.FIREWORK_ROCKET)
|
||||||
|
.bedrockId(72)
|
||||||
|
.heightAndWidth(0.25f)
|
||||||
|
.identifier("minecraft:fireworks_rocket")
|
||||||
|
.addTranslator(MetadataType.ITEM, FireworkEntity::setFireworkItem)
|
||||||
|
.addTranslator(MetadataType.OPTIONAL_VARINT, FireworkEntity::setPlayerGliding)
|
||||||
|
.build();
|
||||||
|
FISHING_BOBBER = EntityDefinition.inherited(new EntityFactory<FishingHookEntity>() {
|
||||||
|
}, entityBase) //TODO
|
||||||
|
.type(EntityType.FISHING_BOBBER)
|
||||||
|
.bedrockId(77)
|
||||||
|
.identifier("minecraft:fishing_book")
|
||||||
|
.addTranslator(MetadataType.INT, FishingHookEntity::setHookedEntity)
|
||||||
|
.build();
|
||||||
|
ITEM = EntityDefinition.inherited(ItemEntity::new, entityBase)
|
||||||
|
.type(EntityType.ITEM)
|
||||||
|
.bedrockId(64)
|
||||||
|
.heightAndWidth(0.25f)
|
||||||
|
.offset(0.125f)
|
||||||
|
.addTranslator(MetadataType.ITEM, ItemEntity::setItem)
|
||||||
|
.build();
|
||||||
|
LEASH_KNOT = EntityDefinition.inherited(LeashKnotEntity::new, entityBase)
|
||||||
|
.type(EntityType.LEASH_KNOT)
|
||||||
|
.bedrockId(88)
|
||||||
|
.height(0.5f).width(0.375f)
|
||||||
|
.build();
|
||||||
|
LIGHTNING_BOLT = EntityDefinition.inherited(LightningEntity::new, entityBase)
|
||||||
|
.type(EntityType.LIGHTNING_BOLT)
|
||||||
|
.bedrockId(93)
|
||||||
|
.build();
|
||||||
|
LLAMA_SPIT = EntityDefinition.inherited(ThrowableEntity::new, entityBase)
|
||||||
|
.type(EntityType.LLAMA_SPIT)
|
||||||
|
.bedrockId(102)
|
||||||
|
.heightAndWidth(0.25f)
|
||||||
|
.build();
|
||||||
|
PAINTING = EntityDefinition.inherited((PaintingEntityFactory) PaintingEntity::new, entityBase)
|
||||||
|
.type(EntityType.PAINTING)
|
||||||
|
.bedrockId(83)
|
||||||
|
.build();
|
||||||
|
PRIMED_TNT = EntityDefinition.inherited(TNTEntity::new, entityBase)
|
||||||
|
.type(EntityType.PRIMED_TNT)
|
||||||
|
.bedrockId(65)
|
||||||
|
.heightAndWidth(0.98f)
|
||||||
|
.identifier("minecraft:tnt")
|
||||||
|
.addTranslator(MetadataType.INT, TNTEntity::setFuseLength)
|
||||||
|
.build();
|
||||||
|
SHULKER_BULLET = EntityDefinition.inherited(ThrowableEntity::new, entityBase)
|
||||||
|
.type(EntityType.SHULKER_BULLET)
|
||||||
|
.bedrockId(76)
|
||||||
|
.heightAndWidth(0.3125f)
|
||||||
|
.build();
|
||||||
|
SMALL_FIREBALL = EntityDefinition.inherited(ItemedFireballEntity::new, entityBase)
|
||||||
|
.type(EntityType.SMALL_FIREBALL)
|
||||||
|
.bedrockId(94)
|
||||||
|
.heightAndWidth(0.3125f)
|
||||||
|
.build();
|
||||||
|
SNOWBALL = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase)
|
||||||
|
.type(EntityType.SNOWBALL)
|
||||||
|
.bedrockId(81)
|
||||||
|
.heightAndWidth(0.25f)
|
||||||
|
.build();
|
||||||
|
THROWN_ENDERPEARL = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase)
|
||||||
|
.type(EntityType.THROWN_ENDERPEARL)
|
||||||
|
.bedrockId(87)
|
||||||
|
.heightAndWidth(0.25f)
|
||||||
|
.identifier("minecraft:ender_pearl")
|
||||||
|
.build();
|
||||||
|
THROWN_EGG = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase)
|
||||||
|
.type(EntityType.THROWN_EGG)
|
||||||
|
.bedrockId(82)
|
||||||
|
.heightAndWidth(0.25f)
|
||||||
|
.identifier("minecraft:egg")
|
||||||
|
.build();
|
||||||
|
THROWN_EXP_BOTTLE = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase)
|
||||||
|
.type(EntityType.THROWN_EXP_BOTTLE)
|
||||||
|
.bedrockId(68)
|
||||||
|
.heightAndWidth(0.25f)
|
||||||
|
.identifier("minecraft:xp_bottle")
|
||||||
|
.build();
|
||||||
|
THROWN_POTION = EntityDefinition.inherited(ThrownPotionEntity::new, entityBase)
|
||||||
|
.type(EntityType.THROWN_POTION)
|
||||||
|
.bedrockId(86)
|
||||||
|
.heightAndWidth(0.25f)
|
||||||
|
.identifier("minecraft:splash_potion")
|
||||||
|
.addTranslator(MetadataType.ITEM, ThrownPotionEntity::setPotion)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EntityDefinition<AbstractArrowEntity> abstractArrowBase = EntityDefinition.inherited(AbstractArrowEntity::new, entityBase)
|
||||||
|
.addTranslator(MetadataType.BYTE, AbstractArrowEntity::setArrowFlags)
|
||||||
|
.addTranslator(null) // "Piercing level"
|
||||||
|
.build();
|
||||||
|
ARROW = EntityDefinition.inherited(TippedArrowEntity::new, abstractArrowBase)
|
||||||
|
.type(EntityType.ARROW)
|
||||||
|
.bedrockId(80)
|
||||||
|
.heightAndWidth(0.25f)
|
||||||
|
.addTranslator(MetadataType.INT, TippedArrowEntity::setPotionEffectColor)
|
||||||
|
.build();
|
||||||
|
SPECTRAL_ARROW = EntityDefinition.inherited(abstractArrowBase.factory(), abstractArrowBase)
|
||||||
|
.type(EntityType.SPECTRAL_ARROW)
|
||||||
|
.bedrockId(80)
|
||||||
|
.heightAndWidth(0.25f)
|
||||||
|
.identifier("minecraft:arrow")
|
||||||
|
.build();
|
||||||
|
TRIDENT = EntityDefinition.inherited(TridentEntity::new, abstractArrowBase) // TODO remove class
|
||||||
|
.type(EntityType.TRIDENT)
|
||||||
|
.bedrockId(73)
|
||||||
|
.identifier("minecraft:thrown_trident")
|
||||||
|
.addTranslator(null) // Loyalty
|
||||||
|
.<Boolean>addTranslator(MetadataType.BOOLEAN, (tridentEntity, entityMetadata) -> tridentEntity.setFlag(EntityFlag.ENCHANTED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Item frames are handled differently as they are blocks, not items, in Bedrock
|
||||||
|
ITEM_FRAME = EntityDefinition.inherited(new EntityFactory<ItemFrameEntity>() {
|
||||||
|
}, entityBase) // TODO
|
||||||
|
.type(EntityType.ITEM_FRAME)
|
||||||
|
.addTranslator(MetadataType.ITEM, ItemFrameEntity::setItemInFrame)
|
||||||
|
.addTranslator(MetadataType.ITEM, ItemFrameEntity::setItemRotation)
|
||||||
|
.build();
|
||||||
|
GLOW_ITEM_FRAME = EntityDefinition.inherited(ITEM_FRAME.factory(), ITEM_FRAME)
|
||||||
|
.type(EntityType.GLOW_ITEM_FRAME)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
MINECART = EntityDefinition.inherited(MinecartEntity::new, entityBase)
|
||||||
|
.type(EntityType.MINECART)
|
||||||
|
.bedrockId(84)
|
||||||
|
.height(0.7f).width(0.98f)
|
||||||
|
.offset(0.35f)
|
||||||
|
.addTranslator(MetadataType.INT, (minecartEntity, entityMetadata) -> minecartEntity.getDirtyMetadata().put(EntityData.HEALTH, entityMetadata.getValue()))
|
||||||
|
.addTranslator(MetadataType.INT, (minecartEntity, entityMetadata) -> minecartEntity.getDirtyMetadata().put(EntityData.HURT_DIRECTION, entityMetadata.getValue())) // Direction in which the minecart is shaking
|
||||||
|
.<Float>addTranslator(MetadataType.FLOAT, (minecartEntity, entityMetadata) ->
|
||||||
|
// Power in Java, time in Bedrock
|
||||||
|
minecartEntity.getDirtyMetadata().put(EntityData.HURT_TIME, Math.min((int) ((FloatEntityMetadata) entityMetadata).getPrimitiveValue(), 15)))
|
||||||
|
.addTranslator(MetadataType.BLOCK_STATE, MinecartEntity::setCustomBlock)
|
||||||
|
.addTranslator(MetadataType.INT, MinecartEntity::setCustomBlockOffset)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, MinecartEntity::setShowCustomBlock)
|
||||||
|
.build();
|
||||||
|
MINECART_CHEST = EntityDefinition.inherited(MINECART.factory(), MINECART)
|
||||||
|
.type(EntityType.MINECART_CHEST)
|
||||||
|
.identifier("minecraft:chest_minecart")
|
||||||
|
.build();
|
||||||
|
MINECART_COMMAND_BLOCK = EntityDefinition.inherited(CommandBlockMinecartEntity::new, MINECART)
|
||||||
|
.type(EntityType.MINECART_COMMAND_BLOCK)
|
||||||
|
.bedrockId(100)
|
||||||
|
.identifier("minecraft:command_block_minecart")
|
||||||
|
.addTranslator(MetadataType.STRING, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.COMMAND_BLOCK_COMMAND, entityMetadata.getValue()))
|
||||||
|
.<Component>addTranslator(MetadataType.CHAT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.COMMAND_BLOCK_LAST_OUTPUT, MessageTranslator.convertMessage(entityMetadata.getValue())))
|
||||||
|
.build();
|
||||||
|
MINECART_FURNACE = EntityDefinition.inherited(FurnaceMinecartEntity::new, MINECART)
|
||||||
|
.type(EntityType.MINECART_FURNACE)
|
||||||
|
.identifier("minecraft:minecart")
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, FurnaceMinecartEntity::setHasFuel)
|
||||||
|
.build();
|
||||||
|
MINECART_HOPPER = EntityDefinition.inherited(MINECART.factory(), MINECART)
|
||||||
|
.type(EntityType.MINECART_HOPPER)
|
||||||
|
.identifier("minecraft:hopper_minecart")
|
||||||
|
.build();
|
||||||
|
MINECART_SPAWNER = EntityDefinition.inherited(SpawnerMinecartEntity::new, MINECART)
|
||||||
|
.type(EntityType.MINECART_SPAWNER)
|
||||||
|
.identifier("minecraft:minecart")
|
||||||
|
.build();
|
||||||
|
MINECART_TNT = EntityDefinition.inherited(MINECART.factory(), MINECART)
|
||||||
|
.type(EntityType.MINECART_TNT)
|
||||||
|
.identifier("minecraft:tnt_minecart")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
WITHER_SKULL = EntityDefinition.inherited(WitherSkullEntity::new, entityBase)
|
||||||
|
.type(EntityType.WITHER_SKULL)
|
||||||
|
.bedrockId(89)
|
||||||
|
.heightAndWidth(0.3125f)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, WitherSkullEntity::setDangerous)
|
||||||
|
.build();
|
||||||
|
WITHER_SKULL_DANGEROUS = EntityDefinition.inherited(WITHER_SKULL.factory(), WITHER_SKULL)
|
||||||
|
.bedrockId(91)
|
||||||
|
.build(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityDefinition<LivingEntity> livingEntityBase = EntityDefinition.inherited(LivingEntity::new, entityBase)
|
||||||
|
.addTranslator(MetadataType.BYTE, LivingEntity::setLivingEntityFlags)
|
||||||
|
.addTranslator(MetadataType.FLOAT, LivingEntity::setHealth)
|
||||||
|
.<Float>addTranslator(MetadataType.FLOAT,
|
||||||
|
(livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityData.EFFECT_COLOR, entityMetadata.getValue()))
|
||||||
|
.<Boolean>addTranslator(MetadataType.BOOLEAN,
|
||||||
|
(livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityData.EFFECT_AMBIENT, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0)))
|
||||||
|
.addTranslator(null) // Arrow count
|
||||||
|
.addTranslator(null) // Stinger count
|
||||||
|
.addTranslator(MetadataType.POSITION, LivingEntity::setBedPosition)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ARMOR_STAND = EntityDefinition.inherited(ArmorStandEntity::new, livingEntityBase)
|
||||||
|
.type(EntityType.ARMOR_STAND)
|
||||||
|
.bedrockId(61)
|
||||||
|
.height(1.975f).width(0.5f)
|
||||||
|
.addTranslator(MetadataType.BYTE, ArmorStandEntity::setArmorStandFlags)
|
||||||
|
.addTranslator(MetadataType.ROTATION, ArmorStandEntity::setHeadRotation)
|
||||||
|
.addTranslator(MetadataType.ROTATION, ArmorStandEntity::setBodyRotation)
|
||||||
|
.addTranslator(MetadataType.ROTATION, ArmorStandEntity::setLeftArmRotation)
|
||||||
|
.addTranslator(MetadataType.ROTATION, ArmorStandEntity::setRightArmRotation)
|
||||||
|
.addTranslator(MetadataType.ROTATION, ArmorStandEntity::setLeftLegRotation)
|
||||||
|
.addTranslator(MetadataType.ROTATION, ArmorStandEntity::setRightLegRotation)
|
||||||
|
.build();
|
||||||
|
PLAYER = EntityDefinition.<PlayerEntity>inherited(null, livingEntityBase)
|
||||||
|
.type(EntityType.PLAYER)
|
||||||
|
.bedrockId(63)
|
||||||
|
.height(1.8f).width(0.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.addTranslator(MetadataType.FLOAT, PlayerEntity::setAbsorptionHearts)
|
||||||
|
.addTranslator(null) // Player score
|
||||||
|
.addTranslator(MetadataType.BYTE, PlayerEntity::setSkinVisibility)
|
||||||
|
.addTranslator(null) // Player main hand
|
||||||
|
.addTranslator(MetadataType.NBT_TAG, PlayerEntity::setLeftParrot)
|
||||||
|
.addTranslator(MetadataType.NBT_TAG, PlayerEntity::setRightParrot)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EntityDefinition<MobEntity> mobEntityBase = EntityDefinition.inherited(MobEntity::new, livingEntityBase)
|
||||||
|
.addTranslator(MetadataType.BYTE, MobEntity::setMobFlags)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Extends mob
|
||||||
|
{
|
||||||
|
BAT = EntityDefinition.inherited(BatEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.BAT)
|
||||||
|
.bedrockId(19)
|
||||||
|
.height(0.9f).width(0.5f)
|
||||||
|
.addTranslator(MetadataType.BYTE, BatEntity::setBatFlags)
|
||||||
|
.build();
|
||||||
|
BLAZE = EntityDefinition.inherited(BlazeEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.BLAZE)
|
||||||
|
.bedrockId(43)
|
||||||
|
.height(1.8f).width(0.6f)
|
||||||
|
.addTranslator(MetadataType.BYTE, BlazeEntity::setBlazeFlags)
|
||||||
|
.build();
|
||||||
|
CAVE_SPIDER = EntityDefinition.inherited(MonsterEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.CAVE_SPIDER)
|
||||||
|
.bedrockId(40)
|
||||||
|
.height(0.5f).width(0.7f)
|
||||||
|
.build();
|
||||||
|
CREEPER = EntityDefinition.inherited(CreeperEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.CREEPER)
|
||||||
|
.bedrockId(33)
|
||||||
|
.height(1.7f).width(0.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.addTranslator(MetadataType.INT, CreeperEntity::setSwelling)
|
||||||
|
.<Boolean>addTranslator(MetadataType.BOOLEAN, (entity, entityMetadata) -> entity.setFlag(EntityFlag.POWERED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, CreeperEntity::setIgnited)
|
||||||
|
.build();
|
||||||
|
DOLPHIN = EntityDefinition.inherited(WaterEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.DOLPHIN)
|
||||||
|
.bedrockId(31)
|
||||||
|
.height(0.6f).width(0.9f)
|
||||||
|
//TODO check
|
||||||
|
.addTranslator(null) // treasure position
|
||||||
|
.addTranslator(null) // "got fish"
|
||||||
|
.addTranslator(null) // "moistness level"
|
||||||
|
.build();
|
||||||
|
ENDERMAN = EntityDefinition.inherited(EndermanEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.ENDERMAN)
|
||||||
|
.bedrockId(38)
|
||||||
|
.height(2.9f).width(0.6f)
|
||||||
|
.addTranslator(MetadataType.BLOCK_STATE, EndermanEntity::setCarriedBlock)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, EndermanEntity::setScreaming)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, EndermanEntity::setAngry)
|
||||||
|
.build();
|
||||||
|
ENDERMITE = EntityDefinition.inherited(MonsterEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.ENDERMITE)
|
||||||
|
.bedrockId(55)
|
||||||
|
.height(0.3f).width(0.4f)
|
||||||
|
.build();
|
||||||
|
ENDER_DRAGON = EntityDefinition.inherited(EnderDragonEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.ENDER_DRAGON)
|
||||||
|
.bedrockId(53)
|
||||||
|
.addTranslator(MetadataType.INT, EnderDragonEntity::setPhase)
|
||||||
|
.build();
|
||||||
|
GHAST = EntityDefinition.inherited(GhastEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.GHAST)
|
||||||
|
.bedrockId(41)
|
||||||
|
.heightAndWidth(4.0f)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, GhastEntity::setGhastAttacking)
|
||||||
|
.build();
|
||||||
|
GIANT = EntityDefinition.inherited(GiantEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.GIANT)
|
||||||
|
.bedrockId(32)
|
||||||
|
.height(1.8f).width(1.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.identifier("minecraft:zombie")
|
||||||
|
.build();
|
||||||
|
IRON_GOLEM = EntityDefinition.inherited(IronGolemEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.IRON_GOLEM)
|
||||||
|
.bedrockId(20)
|
||||||
|
.height(2.7f).width(1.4f)
|
||||||
|
.build();
|
||||||
|
PHANTOM = EntityDefinition.inherited(PhantomEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.PHANTOM)
|
||||||
|
.bedrockId(58)
|
||||||
|
.height(0.5f).width(0.9f)
|
||||||
|
.offset(0.6f)
|
||||||
|
.addTranslator(MetadataType.INT, PhantomEntity::setPhantomScale)
|
||||||
|
.build();
|
||||||
|
SILVERFISH = EntityDefinition.inherited(MonsterEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.SILVERFISH)
|
||||||
|
.bedrockId(39)
|
||||||
|
.height(0.3f).width(0.4f)
|
||||||
|
.build();
|
||||||
|
SHULKER = EntityDefinition.inherited(ShulkerEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.SHULKER)
|
||||||
|
.bedrockId(54)
|
||||||
|
.heightAndWidth(1f)
|
||||||
|
.addTranslator(MetadataType.DIRECTION, ShulkerEntity::setAttachedFace)
|
||||||
|
.addTranslator(MetadataType.BYTE, ShulkerEntity::setShulkerHeight)
|
||||||
|
.addTranslator(MetadataType.BYTE, ShulkerEntity::setShulkerColor)
|
||||||
|
.build();
|
||||||
|
SKELETON = EntityDefinition.inherited(SkeletonEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.SKELETON)
|
||||||
|
.bedrockId(34)
|
||||||
|
.height(1.8f).width(0.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, SkeletonEntity::setConvertingToStray)
|
||||||
|
.build();
|
||||||
|
SNOW_GOLEM = EntityDefinition.inherited(SnowGolemEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.SNOW_GOLEM)
|
||||||
|
.bedrockId(21)
|
||||||
|
.height(1.9f).width(0.7f)
|
||||||
|
.addTranslator(MetadataType.BYTE, SnowGolemEntity::setSnowGolemFlags)
|
||||||
|
.build();
|
||||||
|
SPIDER = EntityDefinition.inherited(SpiderEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.SPIDER)
|
||||||
|
.bedrockId(35)
|
||||||
|
.height(0.9f).width(1.4f)
|
||||||
|
.offset(1f)
|
||||||
|
.addTranslator(MetadataType.BYTE, SpiderEntity::setSpiderFlags)
|
||||||
|
.build();
|
||||||
|
SQUID = EntityDefinition.inherited(SquidEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.SQUID)
|
||||||
|
.bedrockId(17)
|
||||||
|
.heightAndWidth(0.8f)
|
||||||
|
.build();
|
||||||
|
STRAY = EntityDefinition.inherited(AbstractSkeletonEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.STRAY)
|
||||||
|
.bedrockId(46)
|
||||||
|
.height(1.8f).width(0.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.build();
|
||||||
|
VEX = EntityDefinition.inherited(VexEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.VEX)
|
||||||
|
.bedrockId(105)
|
||||||
|
.height(0.8f).width(0.4f)
|
||||||
|
.addTranslator(MetadataType.BYTE, VexEntity::setVexFlags)
|
||||||
|
.build();
|
||||||
|
WITHER = EntityDefinition.inherited(WitherEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.WITHER)
|
||||||
|
.bedrockId(52)
|
||||||
|
.height(3.5f).width(0.9f)
|
||||||
|
.addTranslator(MetadataType.INT, WitherEntity::setTarget1)
|
||||||
|
.addTranslator(MetadataType.INT, WitherEntity::setTarget2)
|
||||||
|
.addTranslator(MetadataType.INT, WitherEntity::setTarget3)
|
||||||
|
.addTranslator(MetadataType.INT, WitherEntity::setInvulnerableTicks)
|
||||||
|
.build();
|
||||||
|
WITHER_SKELETON = EntityDefinition.inherited(AbstractSkeletonEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.WITHER_SKELETON)
|
||||||
|
.bedrockId(48)
|
||||||
|
.height(2.4f).width(0.7f)
|
||||||
|
.build();
|
||||||
|
ZOGLIN = EntityDefinition.inherited(ZoglinEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.ZOGLIN)
|
||||||
|
.bedrockId(126)
|
||||||
|
.height(1.4f).width(1.3965f)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, ZoglinEntity::setBaby)
|
||||||
|
.build();
|
||||||
|
ZOMBIE = EntityDefinition.inherited(ZombieEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.ZOMBIE)
|
||||||
|
.bedrockId(32)
|
||||||
|
.height(1.8f).width(0.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, ZombieEntity::setZombieBaby)
|
||||||
|
.addTranslator(null) // "set special type", doesn't do anything
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, ZombieEntity::setConvertingToDrowned)
|
||||||
|
.build();
|
||||||
|
ZOMBIE_VILLAGER = EntityDefinition.inherited(ZombieVillagerEntity::new, ZOMBIE)
|
||||||
|
.type(EntityType.ZOMBIE_VILLAGER)
|
||||||
|
.bedrockId(44)
|
||||||
|
.height(1.8f).width(0.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.identifier("minecraft:zombie_villager_v2")
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, ZombieVillagerEntity::setTransforming)
|
||||||
|
.addTranslator(MetadataType.VILLAGER_DATA, ZombieVillagerEntity::setZombieVillagerData)
|
||||||
|
.build();
|
||||||
|
ZOMBIFIED_PIGLIN = EntityDefinition.inherited(ZombifiedPiglinEntity::new, ZOMBIE) //TODO test how zombie entity metadata is handled?
|
||||||
|
.type(EntityType.ZOMBIFIED_PIGLIN)
|
||||||
|
.bedrockId(36)
|
||||||
|
.height(1.95f).width(0.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.identifier("minecraft:zombie_pigman")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
DROWNED = EntityDefinition.inherited(ZOMBIE.factory(), ZOMBIE)
|
||||||
|
.type(EntityType.DROWNED)
|
||||||
|
.bedrockId(110)
|
||||||
|
.height(1.95f).width(0.6f)
|
||||||
|
.build();
|
||||||
|
HUSK = EntityDefinition.inherited(ZOMBIE.factory(), ZOMBIE)
|
||||||
|
.type(EntityType.HUSK)
|
||||||
|
.bedrockId(47)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
GUARDIAN = EntityDefinition.inherited(GuardianEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.GUARDIAN)
|
||||||
|
.bedrockId(49)
|
||||||
|
.heightAndWidth(0.85f)
|
||||||
|
.addTranslator(null) // Moving //TODO
|
||||||
|
.addTranslator(MetadataType.INT, GuardianEntity::setGuardianTarget)
|
||||||
|
.build();
|
||||||
|
ELDER_GUARDIAN = EntityDefinition.inherited(ElderGuardianEntity::new, GUARDIAN)
|
||||||
|
.type(EntityType.ELDER_GUARDIAN)
|
||||||
|
.bedrockId(50)
|
||||||
|
.heightAndWidth(1.9975f)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SLIME = EntityDefinition.inherited(SlimeEntity::new, mobEntityBase)
|
||||||
|
.type(EntityType.SLIME)
|
||||||
|
.bedrockId(37)
|
||||||
|
.heightAndWidth(0.51f)
|
||||||
|
.addTranslator(MetadataType.INT, SlimeEntity::setScale)
|
||||||
|
.build();
|
||||||
|
MAGMA_CUBE = EntityDefinition.inherited(MagmaCubeEntity::new, SLIME)
|
||||||
|
.type(EntityType.MAGMA_CUBE)
|
||||||
|
.bedrockId(42)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EntityDefinition<AbstractFishEntity> abstractFishEntityBase = EntityDefinition.inherited(AbstractFishEntity::new, mobEntityBase)
|
||||||
|
.addTranslator(null) // From bucket
|
||||||
|
.build();
|
||||||
|
COD = EntityDefinition.inherited(abstractFishEntityBase.factory(), abstractFishEntityBase)
|
||||||
|
.type(EntityType.COD)
|
||||||
|
.bedrockId(112)
|
||||||
|
.height(0.25f).width(0.5f)
|
||||||
|
.build();
|
||||||
|
PUFFERFISH = EntityDefinition.inherited(PufferFishEntity::new, abstractFishEntityBase)
|
||||||
|
.type(EntityType.PUFFERFISH)
|
||||||
|
.bedrockId(108)
|
||||||
|
.heightAndWidth(0.7f)
|
||||||
|
.addTranslator(MetadataType.INT, PufferFishEntity::setPufferfishSize)
|
||||||
|
.build();
|
||||||
|
SALMON = EntityDefinition.inherited(abstractFishEntityBase.factory(), abstractFishEntityBase)
|
||||||
|
.type(EntityType.SALMON)
|
||||||
|
.bedrockId(109)
|
||||||
|
.height(0.5f).width(0.7f)
|
||||||
|
.build();
|
||||||
|
TROPICAL_FISH = EntityDefinition.inherited(TropicalFishEntity::new, abstractFishEntityBase)
|
||||||
|
.type(EntityType.TROPICAL_FISH)
|
||||||
|
.bedrockId(111)
|
||||||
|
.heightAndWidth(0.6f)
|
||||||
|
.identifier("minecraft:tropicalfish")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EntityDefinition<BasePiglinEntity> abstractPiglinEntityBase = EntityDefinition.inherited(BasePiglinEntity::new, mobEntityBase)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, BasePiglinEntity::setImmuneToZombification)
|
||||||
|
.build();
|
||||||
|
PIGLIN = EntityDefinition.inherited(PiglinEntity::new, abstractPiglinEntityBase)
|
||||||
|
.type(EntityType.PIGLIN)
|
||||||
|
.bedrockId(123)
|
||||||
|
.height(1.95f).width(0.6f)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, PiglinEntity::setBaby)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, PiglinEntity::setChargingCrossbow)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, PiglinEntity::setDancing)
|
||||||
|
.build();
|
||||||
|
PIGLIN_BRUTE = EntityDefinition.inherited(abstractPiglinEntityBase.factory(), abstractPiglinEntityBase)
|
||||||
|
.type(EntityType.PIGLIN_BRUTE)
|
||||||
|
.bedrockId(127)
|
||||||
|
.height(1.95f).width(0.6f)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
GLOW_SQUID = EntityDefinition.inherited(GlowSquidEntity::new, SQUID)
|
||||||
|
.type(EntityType.GLOW_SQUID)
|
||||||
|
.addTranslator(null) // Set dark ticks remaining, possible TODO
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EntityDefinition<RaidParticipantEntity> raidParticipantEntityBase = EntityDefinition.inherited(RaidParticipantEntity::new, mobEntityBase)
|
||||||
|
.addTranslator(null) // Celebrating //TODO
|
||||||
|
.build();
|
||||||
|
EntityDefinition<SpellcasterIllagerEntity> spellcasterEntityBase = EntityDefinition.inherited(SpellcasterIllagerEntity::new, raidParticipantEntityBase)
|
||||||
|
.addTranslator(MetadataType.BYTE, SpellcasterIllagerEntity::setSpellType)
|
||||||
|
.build();
|
||||||
|
EVOKER = EntityDefinition.inherited(spellcasterEntityBase.factory(), spellcasterEntityBase)
|
||||||
|
.type(EntityType.EVOKER)
|
||||||
|
.bedrockId(104)
|
||||||
|
.height(1.95f).width(0.6f)
|
||||||
|
.identifier("minecraft:evocation_illager")
|
||||||
|
.build();
|
||||||
|
ILLUSIONER = EntityDefinition.inherited(spellcasterEntityBase.factory(), spellcasterEntityBase)
|
||||||
|
.type(EntityType.ILLUSIONER)
|
||||||
|
.bedrockId(104)
|
||||||
|
.height(1.95f).width(0.6f)
|
||||||
|
.identifier("minecraft:evocation_illager")
|
||||||
|
.build();
|
||||||
|
PILLAGER = EntityDefinition.inherited(PillagerEntity::new, raidParticipantEntityBase)
|
||||||
|
.type(EntityType.PILLAGER)
|
||||||
|
.bedrockId(114)
|
||||||
|
.height(1.8f).width(0.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.addTranslator(null) // Charging; doesn't have an equivalent on Bedrock //TODO check
|
||||||
|
.build();
|
||||||
|
RAVAGER = EntityDefinition.inherited(raidParticipantEntityBase.factory(), raidParticipantEntityBase)
|
||||||
|
.type(EntityType.RAVAGER)
|
||||||
|
.bedrockId(59)
|
||||||
|
.height(1.9f).width(1.2f)
|
||||||
|
.build();
|
||||||
|
VINDICATOR = EntityDefinition.inherited(VindicatorEntity::new, raidParticipantEntityBase)
|
||||||
|
.type(EntityType.VINDICATOR)
|
||||||
|
.bedrockId(57)
|
||||||
|
.height(1.8f).width(0.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.build();
|
||||||
|
WITCH = EntityDefinition.inherited(raidParticipantEntityBase.factory(), raidParticipantEntityBase)
|
||||||
|
.type(EntityType.WITCH)
|
||||||
|
.bedrockId(45)
|
||||||
|
.height(1.8f).width(0.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityDefinition<AgeableEntity> ageableEntityBase = EntityDefinition.inherited(AgeableEntity::new, mobEntityBase)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, AgeableEntity::setBaby)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Extends ageable
|
||||||
|
{
|
||||||
|
AXOLOTL = EntityDefinition.inherited(AxolotlEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.AXOLOTL)
|
||||||
|
.height(0.42f).width(0.7f)
|
||||||
|
.addTranslator(MetadataType.INT, AxolotlEntity::setVariant)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, AxolotlEntity::setPlayingDead)
|
||||||
|
.build();
|
||||||
|
BEE = EntityDefinition.inherited(BeeEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.BEE)
|
||||||
|
.bedrockId(122)
|
||||||
|
.heightAndWidth(0.6f)
|
||||||
|
.addTranslator(MetadataType.BYTE, BeeEntity::setBeeFlags)
|
||||||
|
.addTranslator(MetadataType.INT, BeeEntity::setAngerTime)
|
||||||
|
.build();
|
||||||
|
CHICKEN = EntityDefinition.inherited(ChickenEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.CHICKEN)
|
||||||
|
.bedrockId(10)
|
||||||
|
.height(0.7f).width(0.4f)
|
||||||
|
.build();
|
||||||
|
COW = EntityDefinition.inherited(AnimalEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.COW)
|
||||||
|
.bedrockId(11)
|
||||||
|
.height(1.4f).width(0.9f)
|
||||||
|
.build();
|
||||||
|
FOX = EntityDefinition.inherited(FoxEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.FOX)
|
||||||
|
.bedrockId(121)
|
||||||
|
.height(0.5f).width(1.25f)
|
||||||
|
.addTranslator(MetadataType.INT, FoxEntity::setFoxVariant)
|
||||||
|
.addTranslator(MetadataType.BYTE, FoxEntity::setFoxFlags)
|
||||||
|
.build();
|
||||||
|
HOGLIN = EntityDefinition.inherited(HoglinEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.HOGLIN)
|
||||||
|
.bedrockId(124)
|
||||||
|
.height(1.4f).width(1.3965f)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, HoglinEntity::setImmuneToZombification)
|
||||||
|
.build();
|
||||||
|
GOAT = EntityDefinition.inherited(GoatEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.GOAT)
|
||||||
|
.height(1.3f).width(0.9f)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, GoatEntity::setScreamer)
|
||||||
|
.build();
|
||||||
|
MOOSHROOM = EntityDefinition.inherited(MooshroomEntity::new, ageableEntityBase) // TODO remove class
|
||||||
|
.type(EntityType.MOOSHROOM)
|
||||||
|
.bedrockId(16)
|
||||||
|
.height(1.4f).width(0.9f)
|
||||||
|
.<String>addTranslator(MetadataType.STRING, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.VARIANT, entityMetadata.getValue().equals("brown") ? 1 : 0))
|
||||||
|
.build();
|
||||||
|
OCELOT = EntityDefinition.inherited(OcelotEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.OCELOT)
|
||||||
|
.bedrockId(22)
|
||||||
|
.height(0.35f).width(0.3f)
|
||||||
|
.<Boolean>addTranslator(MetadataType.BOOLEAN, (ocelotEntity, entityMetadata) -> ocelotEntity.setFlag(EntityFlag.TRUSTING, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||||
|
.build();
|
||||||
|
PANDA = EntityDefinition.inherited(PandaEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.PANDA)
|
||||||
|
.bedrockId(113)
|
||||||
|
.height(1.25f).width(1.125f)
|
||||||
|
.addTranslator(null) // Unhappy counter
|
||||||
|
.addTranslator(null) // Sneeze counter
|
||||||
|
.addTranslator(MetadataType.INT, PandaEntity::setEatingCounter)
|
||||||
|
.addTranslator(MetadataType.BYTE, PandaEntity::setMainGene)
|
||||||
|
.addTranslator(MetadataType.BYTE, PandaEntity::setHiddenGene)
|
||||||
|
.addTranslator(MetadataType.BYTE, PandaEntity::setPandaFlags)
|
||||||
|
.build();
|
||||||
|
PIG = EntityDefinition.inherited(PigEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.PIG)
|
||||||
|
.bedrockId(12)
|
||||||
|
.heightAndWidth(0.9f)
|
||||||
|
.<Boolean>addTranslator(MetadataType.BOOLEAN, (pigEntity, entityMetadata) -> pigEntity.setFlag(EntityFlag.SADDLED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||||
|
.addTranslator(null) // Boost time
|
||||||
|
.build();
|
||||||
|
POLAR_BEAR = EntityDefinition.inherited(PolarBearEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.POLAR_BEAR)
|
||||||
|
.bedrockId(28)
|
||||||
|
.height(1.4f).width(1.3f)
|
||||||
|
.<Boolean>addTranslator(MetadataType.BOOLEAN, (entity, entityMetadata) -> entity.setFlag(EntityFlag.STANDING, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||||
|
.build();
|
||||||
|
RABBIT = EntityDefinition.inherited(RabbitEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.RABBIT)
|
||||||
|
.bedrockId(18)
|
||||||
|
.height(0.5f).width(0.4f)
|
||||||
|
.addTranslator(MetadataType.INT, RabbitEntity::setRabbitVariant)
|
||||||
|
.build();
|
||||||
|
SHEEP = EntityDefinition.inherited(SheepEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.SHEEP)
|
||||||
|
.bedrockId(13)
|
||||||
|
.heightAndWidth(0.9f)
|
||||||
|
.addTranslator(MetadataType.BYTE, SheepEntity::setSheepFlags)
|
||||||
|
.build();
|
||||||
|
STRIDER = EntityDefinition.inherited(StriderEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.STRIDER)
|
||||||
|
.bedrockId(125)
|
||||||
|
.height(1.7f).width(0.9f)
|
||||||
|
.addTranslator(null) // Boost time
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, StriderEntity::setCold)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, StriderEntity::setSaddled)
|
||||||
|
.build();
|
||||||
|
TURTLE = EntityDefinition.inherited(TurtleEntity::new, ageableEntityBase)
|
||||||
|
.type(EntityType.TURTLE)
|
||||||
|
.bedrockId(74)
|
||||||
|
.height(0.4f).width(1.2f)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, TurtleEntity::setPregnant)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, TurtleEntity::setLayingEgg)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EntityDefinition<AbstractMerchantEntity> abstractVillagerEntityBase = EntityDefinition.inherited(AbstractMerchantEntity::new, ageableEntityBase)
|
||||||
|
.addTranslator(null) // Unhappy ticks
|
||||||
|
.build();
|
||||||
|
VILLAGER = EntityDefinition.inherited(VillagerEntity::new, abstractVillagerEntityBase)
|
||||||
|
.type(EntityType.VILLAGER)
|
||||||
|
.bedrockId(15)
|
||||||
|
.height(1.8f).width(0.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.identifier("minecraft:villager_v2")
|
||||||
|
.addTranslator(MetadataType.VILLAGER_DATA, VillagerEntity::setVillagerData)
|
||||||
|
.build();
|
||||||
|
WANDERING_TRADER = EntityDefinition.inherited(abstractVillagerEntityBase.factory(), abstractVillagerEntityBase)
|
||||||
|
.type(EntityType.WANDERING_TRADER)
|
||||||
|
.bedrockId(118)
|
||||||
|
.height(1.8f).width(0.6f)
|
||||||
|
.offset(1.62f)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Horses
|
||||||
|
{
|
||||||
|
EntityDefinition<AbstractHorseEntity> abstractHorseEntityBase = EntityDefinition.inherited(AbstractHorseEntity::new, ageableEntityBase)
|
||||||
|
.addTranslator(MetadataType.BYTE, AbstractHorseEntity::setHorseFlags)
|
||||||
|
.addTranslator(null) // UUID of owner
|
||||||
|
.build();
|
||||||
|
HORSE = EntityDefinition.inherited(HorseEntity::new, abstractHorseEntityBase)
|
||||||
|
.type(EntityType.HORSE)
|
||||||
|
.bedrockId(23)
|
||||||
|
.height(1.6f).width(1.3965f)
|
||||||
|
.addTranslator(MetadataType.BYTE, HorseEntity::setHorseVariant)
|
||||||
|
.build();
|
||||||
|
SKELETON_HORSE = EntityDefinition.inherited(abstractHorseEntityBase.factory(), abstractHorseEntityBase)
|
||||||
|
.type(EntityType.SKELETON_HORSE)
|
||||||
|
.bedrockId(26)
|
||||||
|
.height(1.6f).width(1.3965f)
|
||||||
|
.build();
|
||||||
|
ZOMBIE_HORSE = EntityDefinition.inherited(abstractHorseEntityBase.factory(), abstractHorseEntityBase)
|
||||||
|
.type(EntityType.ZOMBIE_HORSE)
|
||||||
|
.bedrockId(27)
|
||||||
|
.height(1.6f).width(1.3965f)
|
||||||
|
.build();
|
||||||
|
EntityDefinition<ChestedHorseEntity> chestedHorseEntityBase = EntityDefinition.inherited(ChestedHorseEntity::new, abstractHorseEntityBase)
|
||||||
|
.<Boolean>addTranslator(MetadataType.BOOLEAN, (horseEntity, entityMetadata) -> horseEntity.setFlag(EntityFlag.CHESTED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||||
|
.build();
|
||||||
|
DONKEY = EntityDefinition.inherited(chestedHorseEntityBase.factory(), chestedHorseEntityBase)
|
||||||
|
.type(EntityType.DONKEY)
|
||||||
|
.bedrockId(24)
|
||||||
|
.height(1.6f).width(1.3965f)
|
||||||
|
.build();
|
||||||
|
MULE = EntityDefinition.inherited(chestedHorseEntityBase.factory(), chestedHorseEntityBase)
|
||||||
|
.type(EntityType.MULE)
|
||||||
|
.bedrockId(25)
|
||||||
|
.height(1.6f).width(1.3965f)
|
||||||
|
.build();
|
||||||
|
LLAMA = EntityDefinition.inherited(LlamaEntity::new, chestedHorseEntityBase)
|
||||||
|
.type(EntityType.LLAMA)
|
||||||
|
.bedrockId(29)
|
||||||
|
.height(1.87f).width(0.9f)
|
||||||
|
.<Integer>addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.STRENGTH, entityMetadata.getValue()))
|
||||||
|
.addTranslator(MetadataType.INT, LlamaEntity::setCarpetedColor)
|
||||||
|
.addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.VARIANT, entityMetadata.getValue()))
|
||||||
|
.build();
|
||||||
|
TRADER_LLAMA = EntityDefinition.inherited(TraderLlamaEntity::new, LLAMA)
|
||||||
|
.type(EntityType.TRADER_LLAMA)
|
||||||
|
.identifier("minecraft:llama")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityDefinition<TameableEntity> tameableEntityBase = EntityDefinition.inherited(TameableEntity::new, ageableEntityBase)
|
||||||
|
.addTranslator(MetadataType.BYTE, TameableEntity::setTameableFlags)
|
||||||
|
.addTranslator(MetadataType.OPTIONAL_UUID, TameableEntity::setOwner)
|
||||||
|
.build();
|
||||||
|
CAT = EntityDefinition.inherited(CatEntity::new, tameableEntityBase)
|
||||||
|
.type(EntityType.CAT)
|
||||||
|
.bedrockId(75)
|
||||||
|
.height(0.35f).width(0.3f)
|
||||||
|
.addTranslator(MetadataType.INT, CatEntity::setCatVariant)
|
||||||
|
.addTranslator(MetadataType.BOOLEAN, CatEntity::setResting)
|
||||||
|
.addTranslator(null) // "resting state one" //TODO
|
||||||
|
.addTranslator(MetadataType.INT, CatEntity::setCollarColor)
|
||||||
|
.build();
|
||||||
|
PARROT = EntityDefinition.inherited(ParrotEntity::new, tameableEntityBase)
|
||||||
|
.type(EntityType.PARROT)
|
||||||
|
.bedrockId(30)
|
||||||
|
.height(0.9f).width(0.5f)
|
||||||
|
.addTranslator(MetadataType.INT, (parrotEntity, entityMetadata) -> parrotEntity.getDirtyMetadata().put(EntityData.VARIANT, entityMetadata.getValue())) // Parrot color
|
||||||
|
.build();
|
||||||
|
WOLF = EntityDefinition.inherited(WolfEntity::new, tameableEntityBase)
|
||||||
|
.type(EntityType.WOLF)
|
||||||
|
.bedrockId(14)
|
||||||
|
.height(0.85f).width(0.6f)
|
||||||
|
// "Begging" on wiki.vg, "Interested" in Nukkit - the tilt of the head
|
||||||
|
.<Boolean>addTranslator(MetadataType.BOOLEAN, (wolfEntity, entityMetadata) -> wolfEntity.setFlag(EntityFlag.INTERESTED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||||
|
.addTranslator(MetadataType.INT, WolfEntity::setCollarColor)
|
||||||
|
.addTranslator(MetadataType.INT, WolfEntity::setWolfAngerTime)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// As of 1.18 these don't track entity data at all
|
||||||
|
ENDER_DRAGON_PART = EntityDefinition.<EnderDragonPartEntity>builder(null)
|
||||||
|
.bedrockId(32)
|
||||||
|
.identifier("minecraft:armor_stand") // Emulated
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntityDefinitions() {
|
||||||
|
}
|
||||||
|
}
|
@ -23,29 +23,18 @@
|
|||||||
* @link https://github.com/GeyserMC/Geyser
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
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.data.game.entity.metadata.MetadataType;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
|
||||||
import org.geysermc.connector.entity.LivingEntity;
|
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
|
||||||
|
|
||||||
public class InsentientEntity extends LivingEntity {
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
public InsentientEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
/**
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
* Translates a given Java {@link EntityMetadata} into a similar/same construct for Bedrock
|
||||||
}
|
*/
|
||||||
|
|
||||||
@Override
|
public record EntityMetadataTranslator<E extends Entity, T>(
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
MetadataType acceptedType,
|
||||||
if (entityMetadata.getId() == 15 && entityMetadata.getType() == MetadataType.BYTE) {
|
BiConsumer<E, EntityMetadata<T>> translateFunction) {
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.NO_AI, (xd & 0x01) == 0x01);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -27,22 +27,21 @@ package org.geysermc.connector.entity;
|
|||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
public class ExpOrbEntity extends Entity {
|
public class ExpOrbEntity extends Entity {
|
||||||
|
|
||||||
private final int amount;
|
private final int amount;
|
||||||
|
|
||||||
public ExpOrbEntity(int amount, long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ExpOrbEntity(GeyserSession session, int amount, long entityId, long geyserId, Vector3f position) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, null, EntityDefinitions.EXPERIENCE_ORB, position, Vector3f.ZERO, 0, 0, 0);
|
||||||
|
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnEntity(GeyserSession session) {
|
protected void initializeMetadata() {
|
||||||
this.metadata.put(EntityData.EXPERIENCE_VALUE, amount);
|
super.initializeMetadata();
|
||||||
super.spawnEntity(session);
|
this.dirtyMetadata.put(EntityData.EXPERIENCE_VALUE, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,31 +26,32 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class FallingBlockEntity extends Entity {
|
public class FallingBlockEntity extends Entity {
|
||||||
private final int javaId;
|
private final int javaId;
|
||||||
|
|
||||||
public FallingBlockEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, int javaId) {
|
public FallingBlockEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, Vector3f position, Vector3f motion, float yaw, float pitch, int javaId) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, EntityDefinitions.FALLING_BLOCK, position, motion, yaw, pitch, 0f);
|
||||||
this.javaId = javaId;
|
this.javaId = javaId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnEntity(GeyserSession session) {
|
protected void initializeMetadata() {
|
||||||
this.metadata.put(EntityData.VARIANT, session.getBlockMappings().getBedrockBlockId(javaId));
|
super.initializeMetadata();
|
||||||
super.spawnEntity(session);
|
this.dirtyMetadata.put(EntityData.VARIANT, session.getBlockMappings().getBedrockBlockId(javaId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void setGravity(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
super.setGravity(entityMetadata);
|
||||||
// Set the NO_AI flag based on the no gravity flag to prevent movement
|
// Set the NO_AI flag based on the no gravity flag to prevent movement
|
||||||
if (entityMetadata.getId() == 5) {
|
setFlag(EntityFlag.NO_AI, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue());
|
||||||
this.metadata.getFlags().setFlag(EntityFlag.NO_AI, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,6 @@ import com.nukkitx.nbt.NbtType;
|
|||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket;
|
import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket;
|
||||||
import org.geysermc.connector.entity.player.PlayerEntity;
|
import org.geysermc.connector.entity.player.PlayerEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.utils.FireworkColor;
|
import org.geysermc.connector.utils.FireworkColor;
|
||||||
import org.geysermc.connector.utils.MathUtils;
|
import org.geysermc.connector.utils.MathUtils;
|
||||||
@ -46,17 +45,16 @@ import org.geysermc.floodgate.util.DeviceOs;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.OptionalInt;
|
import java.util.OptionalInt;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class FireworkEntity extends Entity {
|
public class FireworkEntity extends Entity {
|
||||||
|
|
||||||
public FireworkEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public FireworkEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setFireworkItem(EntityMetadata<ItemStack> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
ItemStack item = entityMetadata.getValue();
|
||||||
if (entityMetadata.getId() == 8) {
|
|
||||||
ItemStack item = (ItemStack) entityMetadata.getValue();
|
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -134,16 +132,18 @@ public class FireworkEntity extends Entity {
|
|||||||
|
|
||||||
NbtMapBuilder builder = NbtMap.builder();
|
NbtMapBuilder builder = NbtMap.builder();
|
||||||
builder.put("Fireworks", fireworksBuilder.build());
|
builder.put("Fireworks", fireworksBuilder.build());
|
||||||
metadata.put(EntityData.DISPLAY_ITEM, builder.build());
|
dirtyMetadata.put(EntityData.DISPLAY_ITEM, builder.build());
|
||||||
} else if (entityMetadata.getId() == 9) {
|
}
|
||||||
OptionalInt optional = (OptionalInt) entityMetadata.getValue();
|
|
||||||
|
public void setPlayerGliding(EntityMetadata<OptionalInt> entityMetadata) {
|
||||||
|
OptionalInt optional = entityMetadata.getValue();
|
||||||
// Checks if the firework has an entity ID (used when a player is gliding)
|
// Checks if the firework has an entity ID (used when a player is gliding)
|
||||||
// and checks to make sure the player that is gliding is the one getting sent the packet
|
// and checks to make sure the player that is gliding is the one getting sent the packet
|
||||||
// or else every player near the gliding player will boost too.
|
// or else every player near the gliding player will boost too.
|
||||||
if (optional.isPresent() && optional.getAsInt() == session.getPlayerEntity().getEntityId()) {
|
if (optional.isPresent() && optional.getAsInt() == session.getPlayerEntity().getEntityId()) {
|
||||||
PlayerEntity entity = session.getPlayerEntity();
|
PlayerEntity entity = session.getPlayerEntity();
|
||||||
float yaw = entity.getRotation().getX();
|
float yaw = entity.getYaw();
|
||||||
float pitch = entity.getRotation().getY();
|
float pitch = entity.getPitch();
|
||||||
// Uses math from NukkitX
|
// Uses math from NukkitX
|
||||||
entity.setMotion(Vector3f.from(
|
entity.setMotion(Vector3f.from(
|
||||||
-Math.sin(Math.toRadians(yaw)) * Math.cos(Math.toRadians(pitch)) * 2,
|
-Math.sin(Math.toRadians(yaw)) * Math.cos(Math.toRadians(pitch)) * 2,
|
||||||
@ -157,7 +157,4 @@ public class FireworkEntity extends Entity {
|
|||||||
session.sendUpstreamPacket(entityMotionPacket);
|
session.sendUpstreamPacket(entityMotionPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,12 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket;
|
import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket;
|
||||||
import org.geysermc.connector.entity.player.PlayerEntity;
|
import org.geysermc.connector.entity.player.PlayerEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.collision.BoundingBox;
|
import org.geysermc.connector.network.translators.collision.BoundingBox;
|
||||||
import org.geysermc.connector.network.translators.collision.translators.BlockCollision;
|
import org.geysermc.connector.network.translators.collision.translators.BlockCollision;
|
||||||
@ -40,6 +40,7 @@ import org.geysermc.connector.registry.BlockRegistries;
|
|||||||
import org.geysermc.connector.utils.BlockPositionIterator;
|
import org.geysermc.connector.utils.BlockPositionIterator;
|
||||||
import org.geysermc.connector.utils.BlockUtils;
|
import org.geysermc.connector.utils.BlockUtils;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
public class FishingHookEntity extends ThrowableEntity {
|
public class FishingHookEntity extends ThrowableEntity {
|
||||||
@ -50,41 +51,44 @@ public class FishingHookEntity extends ThrowableEntity {
|
|||||||
|
|
||||||
private boolean inWater = false;
|
private boolean inWater = false;
|
||||||
|
|
||||||
public FishingHookEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, PlayerEntity owner) {
|
public FishingHookEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, Vector3f position, Vector3f motion, float yaw, float pitch, PlayerEntity owner) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, EntityDefinitions.FISHING_BOBBER, position, motion, yaw, pitch, 0f);
|
||||||
|
|
||||||
this.boundingBox = new BoundingBox(0.125, 0.125, 0.125, 0.25, 0.25, 0.25);
|
this.boundingBox = new BoundingBox(0.125, 0.125, 0.125, 0.25, 0.25, 0.25);
|
||||||
|
|
||||||
// In Java, the splash sound depends on the entity's velocity, but in Bedrock the volume doesn't change.
|
// In Java, the splash sound depends on the entity's velocity, but in Bedrock the volume doesn't change.
|
||||||
// This splash can be confused with the sound from catching a fish. This silences the splash from Bedrock,
|
// This splash can be confused with the sound from catching a fish. This silences the splash from Bedrock,
|
||||||
// so that it can be handled by moveAbsoluteImmediate.
|
// so that it can be handled by moveAbsoluteImmediate.
|
||||||
this.metadata.putFloat(EntityData.BOUNDING_BOX_HEIGHT, 128);
|
this.dirtyMetadata.putFloat(EntityData.BOUNDING_BOX_HEIGHT, 128);
|
||||||
|
|
||||||
this.metadata.put(EntityData.OWNER_EID, owner.getGeyserId());
|
this.dirtyMetadata.put(EntityData.OWNER_EID, owner.getGeyserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void spawnEntity() {
|
||||||
if (entityMetadata.getId() == 8) { // Hooked entity
|
|
||||||
int hookedEntityId = (int) entityMetadata.getValue() - 1;
|
super.spawnEntity();
|
||||||
Entity entity = session.getEntityCache().getEntityByJavaId(hookedEntityId);
|
}
|
||||||
if (entity == null && session.getPlayerEntity().getEntityId() == hookedEntityId) {
|
|
||||||
|
public void setHookedEntity(EntityMetadata<Integer> entityMetadata) {
|
||||||
|
int hookedEntityId = ((IntEntityMetadata) entityMetadata).getPrimitiveValue() - 1;
|
||||||
|
Entity entity;
|
||||||
|
if (session.getPlayerEntity().getEntityId() == hookedEntityId) {
|
||||||
entity = session.getPlayerEntity();
|
entity = session.getPlayerEntity();
|
||||||
|
} else {
|
||||||
|
entity = session.getEntityCache().getEntityByJavaId(hookedEntityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
metadata.put(EntityData.TARGET_EID, entity.getGeyserId());
|
dirtyMetadata.put(EntityData.TARGET_EID, entity.getGeyserId());
|
||||||
hooked = true;
|
hooked = true;
|
||||||
} else {
|
} else {
|
||||||
hooked = false;
|
hooked = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void moveAbsoluteImmediate(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
protected void moveAbsoluteImmediate(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
|
||||||
boundingBox.setMiddleX(position.getX());
|
boundingBox.setMiddleX(position.getX());
|
||||||
boundingBox.setMiddleY(position.getY() + boundingBox.getSizeY() / 2);
|
boundingBox.setMiddleY(position.getY() + boundingBox.getSizeY() / 2);
|
||||||
boundingBox.setMiddleZ(position.getZ());
|
boundingBox.setMiddleZ(position.getZ());
|
||||||
@ -123,14 +127,14 @@ public class FishingHookEntity extends ThrowableEntity {
|
|||||||
inWater = touchingWater;
|
inWater = touchingWater;
|
||||||
|
|
||||||
if (!collided) {
|
if (!collided) {
|
||||||
super.moveAbsoluteImmediate(session, position, rotation, isOnGround, teleported);
|
super.moveAbsoluteImmediate(position, yaw, pitch, headYaw, isOnGround, teleported);
|
||||||
} else {
|
} else {
|
||||||
super.moveAbsoluteImmediate(session, this.position, rotation, true, true);
|
super.moveAbsoluteImmediate(this.position, yaw, pitch, headYaw, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendSplashSound(GeyserSession session) {
|
private void sendSplashSound(GeyserSession session) {
|
||||||
if (!metadata.getFlags().getFlag(EntityFlag.SILENT)) {
|
if (!getFlag(EntityFlag.SILENT)) {
|
||||||
float volume = (float) (0.2f * Math.sqrt(0.2 * (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) + motion.getY() * motion.getY()));
|
float volume = (float) (0.2f * Math.sqrt(0.2 * (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) + motion.getY() * motion.getY()));
|
||||||
if (volume > 1) {
|
if (volume > 1) {
|
||||||
volume = 1;
|
volume = 1;
|
||||||
@ -145,39 +149,38 @@ public class FishingHookEntity extends ThrowableEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(GeyserSession session) {
|
public void tick() {
|
||||||
if (hooked || !isInAir(session) && !isInWater(session) || isOnGround()) {
|
if (hooked || !isInAir() && !isInWater() || isOnGround()) {
|
||||||
motion = Vector3f.ZERO;
|
motion = Vector3f.ZERO;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float gravity = getGravity(session);
|
float gravity = getGravity();
|
||||||
motion = motion.down(gravity);
|
motion = motion.down(gravity);
|
||||||
|
|
||||||
moveAbsoluteImmediate(session, position.add(motion), rotation, onGround, false);
|
moveAbsoluteImmediate(position.add(motion), yaw, pitch, headYaw, onGround, false);
|
||||||
|
|
||||||
float drag = getDrag(session);
|
float drag = getDrag();
|
||||||
motion = motion.mul(drag);
|
motion = motion.mul(drag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected float getGravity(GeyserSession session) {
|
protected float getGravity() {
|
||||||
if (!isInWater(session) && !onGround) {
|
if (!isInWater() && !onGround) {
|
||||||
return 0.03f;
|
return 0.03f;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param session the session of the Bedrock client.
|
|
||||||
* @return true if this entity is currently in air.
|
* @return true if this entity is currently in air.
|
||||||
*/
|
*/
|
||||||
protected boolean isInAir(GeyserSession session) {
|
protected boolean isInAir() {
|
||||||
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
||||||
return block == BlockStateValues.JAVA_AIR_ID;
|
return block == BlockStateValues.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected float getDrag(GeyserSession session) {
|
protected float getDrag() {
|
||||||
return 0.92f;
|
return 0.92f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,33 +26,29 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
||||||
|
|
||||||
public class FurnaceMinecartEntity extends DefaultBlockMinecartEntity {
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class FurnaceMinecartEntity extends DefaultBlockMinecartEntity {
|
||||||
private boolean hasFuel = false;
|
private boolean hasFuel = false;
|
||||||
|
|
||||||
public FurnaceMinecartEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public FurnaceMinecartEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHasFuel(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
hasFuel = ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
updateDefaultBlockMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void updateDefaultBlockMetadata() {
|
||||||
if (entityMetadata.getId() == 14 && !showCustomBlock) {
|
dirtyMetadata.put(EntityData.DISPLAY_ITEM, session.getBlockMappings().getBedrockBlockId(hasFuel ? BlockStateValues.JAVA_FURNACE_LIT_ID : BlockStateValues.JAVA_FURNACE_ID));
|
||||||
hasFuel = (boolean) entityMetadata.getValue();
|
dirtyMetadata.put(EntityData.DISPLAY_OFFSET, 6);
|
||||||
updateDefaultBlockMetadata(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateDefaultBlockMetadata(GeyserSession session) {
|
|
||||||
metadata.put(EntityData.DISPLAY_ITEM, session.getBlockMappings().getBedrockBlockId(hasFuel ? BlockStateValues.JAVA_FURNACE_LIT_ID : BlockStateValues.JAVA_FURNACE_ID));
|
|
||||||
metadata.put(EntityData.DISPLAY_OFFSET, 6);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,23 +34,24 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
|||||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.AddItemEntityPacket;
|
import com.nukkitx.protocol.bedrock.packet.AddItemEntityPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
|
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ItemEntity extends ThrowableEntity {
|
public class ItemEntity extends ThrowableEntity {
|
||||||
|
|
||||||
protected ItemData item;
|
protected ItemData item;
|
||||||
|
|
||||||
private int waterLevel = -1;
|
private int waterLevel = -1;
|
||||||
|
|
||||||
public ItemEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ItemEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnEntity(GeyserSession session) {
|
public void spawnEntity() {
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -58,69 +59,33 @@ public class ItemEntity extends ThrowableEntity {
|
|||||||
AddItemEntityPacket itemPacket = new AddItemEntityPacket();
|
AddItemEntityPacket itemPacket = new AddItemEntityPacket();
|
||||||
itemPacket.setRuntimeEntityId(geyserId);
|
itemPacket.setRuntimeEntityId(geyserId);
|
||||||
itemPacket.setUniqueEntityId(geyserId);
|
itemPacket.setUniqueEntityId(geyserId);
|
||||||
itemPacket.setPosition(position.add(0d, this.entityType.getOffset(), 0d));
|
itemPacket.setPosition(position.add(0d, this.definition.offset(), 0d));
|
||||||
itemPacket.setMotion(motion);
|
itemPacket.setMotion(motion);
|
||||||
itemPacket.setFromFishing(false);
|
itemPacket.setFromFishing(false);
|
||||||
itemPacket.setItemInHand(item);
|
itemPacket.setItemInHand(item);
|
||||||
itemPacket.getMetadata().putAll(metadata);
|
itemPacket.getMetadata().putAll(dirtyMetadata);
|
||||||
session.sendUpstreamPacket(itemPacket);
|
session.sendUpstreamPacket(itemPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(GeyserSession session) {
|
public void tick() {
|
||||||
if (isInWater(session)) {
|
if (isInWater()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!onGround || (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) > 0.00001) {
|
if (!onGround || (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) > 0.00001) {
|
||||||
float gravity = getGravity(session);
|
float gravity = getGravity();
|
||||||
motion = motion.down(gravity);
|
motion = motion.down(gravity);
|
||||||
moveAbsoluteImmediate(session, position.add(motion), rotation, onGround, false);
|
moveAbsoluteImmediate(position.add(motion), yaw, pitch, headYaw, onGround, false);
|
||||||
float drag = getDrag(session);
|
float drag = getDrag();
|
||||||
motion = motion.mul(drag, 0.98f, drag);
|
motion = motion.mul(drag, 0.98f, drag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setItem(EntityMetadata<ItemStack> entityMetadata) {
|
||||||
protected void moveAbsoluteImmediate(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
ItemData item = ItemTranslator.translateToBedrock(session, entityMetadata.getValue());
|
||||||
float offset = entityType.getOffset();
|
|
||||||
if (waterLevel == 0) { // Item is in a full block of water
|
|
||||||
// Move the item entity down so it doesn't float above the water
|
|
||||||
offset = -entityType.getOffset();
|
|
||||||
}
|
|
||||||
super.moveAbsoluteImmediate(session, position.add(0, offset, 0), Vector3f.ZERO, isOnGround, teleported);
|
|
||||||
this.position = position;
|
|
||||||
|
|
||||||
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
|
||||||
waterLevel = BlockStateValues.getWaterLevel(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected float getGravity(GeyserSession session) {
|
|
||||||
if (metadata.getFlags().getFlag(EntityFlag.HAS_GRAVITY) && !onGround && !isInWater(session)) {
|
|
||||||
// Gravity can change if the item is in water/lava, but
|
|
||||||
// the server calculates the motion & position for us
|
|
||||||
return 0.04f;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected float getDrag(GeyserSession session) {
|
|
||||||
if (onGround) {
|
|
||||||
Vector3i groundBlockPos = position.toInt().down(1);
|
|
||||||
int blockState = session.getConnector().getWorldManager().getBlockAt(session, groundBlockPos);
|
|
||||||
return BlockStateValues.getSlipperiness(blockState) * 0.98f;
|
|
||||||
}
|
|
||||||
return 0.98f;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
|
||||||
if (entityMetadata.getId() == 8) {
|
|
||||||
ItemData item = ItemTranslator.translateToBedrock(session, (ItemStack) entityMetadata.getValue());
|
|
||||||
if (this.item == null) {
|
if (this.item == null) {
|
||||||
this.item = item;
|
this.item = item;
|
||||||
spawnEntity(session);
|
spawnEntity();
|
||||||
} else if (item.equals(this.item, false, true, true)) {
|
} else if (item.equals(this.item, false, true, true)) {
|
||||||
// Don't bother respawning the entity if items are equal
|
// Don't bother respawning the entity if items are equal
|
||||||
if (this.item.getCount() != item.getCount()) {
|
if (this.item.getCount() != item.getCount()) {
|
||||||
@ -134,16 +99,47 @@ public class ItemEntity extends ThrowableEntity {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.item = item;
|
this.item = item;
|
||||||
despawnEntity(session);
|
despawnEntity();
|
||||||
spawnEntity(session);
|
spawnEntity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isInWater(GeyserSession session) {
|
protected void moveAbsoluteImmediate(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
|
||||||
|
float offset = definition.offset();
|
||||||
|
if (waterLevel == 0) { // Item is in a full block of water
|
||||||
|
// Move the item entity down so it doesn't float above the water
|
||||||
|
offset = -definition.offset();
|
||||||
|
}
|
||||||
|
super.moveAbsoluteImmediate(position.add(0, offset, 0), 0, 0, 0, isOnGround, teleported);
|
||||||
|
this.position = position;
|
||||||
|
|
||||||
|
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
||||||
|
waterLevel = BlockStateValues.getWaterLevel(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getGravity() {
|
||||||
|
if (getFlag(EntityFlag.HAS_GRAVITY) && !onGround && !isInWater()) {
|
||||||
|
// Gravity can change if the item is in water/lava, but
|
||||||
|
// the server calculates the motion & position for us
|
||||||
|
return 0.04f;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getDrag() {
|
||||||
|
if (onGround) {
|
||||||
|
Vector3i groundBlockPos = position.toInt().down(1);
|
||||||
|
int blockState = session.getConnector().getWorldManager().getBlockAt(session, groundBlockPos);
|
||||||
|
return BlockStateValues.getSlipperiness(blockState) * 0.98f;
|
||||||
|
}
|
||||||
|
return 0.98f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isInWater() {
|
||||||
return waterLevel != -1;
|
return waterLevel != -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,9 @@ package org.geysermc.connector.entity;
|
|||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.object.HangingDirection;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.nbt.NbtMap;
|
import com.nukkitx.nbt.NbtMap;
|
||||||
@ -37,29 +39,25 @@ import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
|
|||||||
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
||||||
import com.nukkitx.protocol.bedrock.v465.Bedrock_v465;
|
import com.nukkitx.protocol.bedrock.v465.Bedrock_v465;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Item frames are an entity in Java but a block entity in Bedrock.
|
* Item frames are an entity in Java but a block entity in Bedrock.
|
||||||
*/
|
*/
|
||||||
public class ItemFrameEntity extends Entity {
|
public class ItemFrameEntity extends Entity {
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to construct the block entity tag on spawning.
|
|
||||||
*/
|
|
||||||
private final HangingDirection direction;
|
|
||||||
/**
|
/**
|
||||||
* Used for getting the Bedrock block position.
|
* Used for getting the Bedrock block position.
|
||||||
* Blocks deal with integers whereas entities deal with floats.
|
* Blocks deal with integers whereas entities deal with floats.
|
||||||
*/
|
*/
|
||||||
private Vector3i bedrockPosition;
|
private final Vector3i bedrockPosition;
|
||||||
/**
|
/**
|
||||||
* Specific block 'state' we are emulating in Bedrock.
|
* Specific block 'state' we are emulating in Bedrock.
|
||||||
*/
|
*/
|
||||||
private int bedrockRuntimeId;
|
private final int bedrockRuntimeId;
|
||||||
/**
|
/**
|
||||||
* Rotation of item in frame.
|
* Rotation of item in frame.
|
||||||
*/
|
*/
|
||||||
@ -73,16 +71,16 @@ public class ItemFrameEntity extends Entity {
|
|||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
private ItemStack heldItem = null;
|
private ItemStack heldItem = null;
|
||||||
|
/**
|
||||||
|
* Determines if this entity needs updated on the client end/
|
||||||
|
*/
|
||||||
|
private boolean changed = true;
|
||||||
|
|
||||||
public ItemFrameEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, HangingDirection direction) {
|
public ItemFrameEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, Direction direction) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, 0f);
|
||||||
this.direction = direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void spawnEntity(GeyserSession session) {
|
|
||||||
NbtMapBuilder blockBuilder = NbtMap.builder()
|
NbtMapBuilder blockBuilder = NbtMap.builder()
|
||||||
.putString("name", this.entityType == EntityType.GLOW_ITEM_FRAME ? "minecraft:glow_frame" : "minecraft:frame")
|
.putString("name", this.definition.entityType() == EntityType.GLOW_ITEM_FRAME ? "minecraft:glow_frame" : "minecraft:frame")
|
||||||
.putInt("version", session.getBlockMappings().getBlockStateVersion());
|
.putInt("version", session.getBlockMappings().getBlockStateVersion());
|
||||||
NbtMapBuilder statesBuilder = NbtMap.builder()
|
NbtMapBuilder statesBuilder = NbtMap.builder()
|
||||||
.putInt("facing_direction", direction.ordinal())
|
.putInt("facing_direction", direction.ordinal())
|
||||||
@ -96,18 +94,26 @@ public class ItemFrameEntity extends Entity {
|
|||||||
bedrockPosition = Vector3i.from(position.getFloorX(), position.getFloorY(), position.getFloorZ());
|
bedrockPosition = Vector3i.from(position.getFloorX(), position.getFloorY(), position.getFloorZ());
|
||||||
|
|
||||||
session.getItemFrameCache().put(bedrockPosition, this);
|
session.getItemFrameCache().put(bedrockPosition, this);
|
||||||
|
}
|
||||||
|
|
||||||
updateBlock(session);
|
@Override
|
||||||
|
protected void initializeMetadata() {
|
||||||
|
// lol nah don't do anything
|
||||||
|
// This isn't a real entity for Bedrock so it isn't going to do anything
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawnEntity() {
|
||||||
|
updateBlock();
|
||||||
session.getConnector().getLogger().debug("Spawned item frame at location " + bedrockPosition + " with java id " + entityId);
|
session.getConnector().getLogger().debug("Spawned item frame at location " + bedrockPosition + " with java id " + entityId);
|
||||||
valid = true;
|
valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setItemInFrame(EntityMetadata<ItemStack> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
if (entityMetadata.getValue() != null) {
|
||||||
if (entityMetadata.getId() == 8 && entityMetadata.getValue() != null) {
|
this.heldItem = entityMetadata.getValue();
|
||||||
this.heldItem = (ItemStack) entityMetadata.getValue();
|
|
||||||
ItemData itemData = ItemTranslator.translateToBedrock(session, heldItem);
|
ItemData itemData = ItemTranslator.translateToBedrock(session, heldItem);
|
||||||
ItemMapping mapping = session.getItemMappings().getMapping((ItemStack) entityMetadata.getValue());
|
ItemMapping mapping = session.getItemMappings().getMapping(entityMetadata.getValue());
|
||||||
NbtMapBuilder builder = NbtMap.builder();
|
NbtMapBuilder builder = NbtMap.builder();
|
||||||
|
|
||||||
builder.putByte("Count", (byte) itemData.getCount());
|
builder.putByte("Count", (byte) itemData.getCount());
|
||||||
@ -121,34 +127,30 @@ public class ItemFrameEntity extends Entity {
|
|||||||
tag.putFloat("ItemDropChance", 1.0f);
|
tag.putFloat("ItemDropChance", 1.0f);
|
||||||
tag.putFloat("ItemRotation", rotation);
|
tag.putFloat("ItemRotation", rotation);
|
||||||
cachedTag = tag.build();
|
cachedTag = tag.build();
|
||||||
updateBlock(session);
|
changed = true;
|
||||||
}
|
} else if (cachedTag != null) {
|
||||||
else if (entityMetadata.getId() == 8 && entityMetadata.getValue() == null && cachedTag != null) {
|
|
||||||
cachedTag = getDefaultTag();
|
cachedTag = getDefaultTag();
|
||||||
updateBlock(session);
|
changed = true;
|
||||||
}
|
}
|
||||||
else if (entityMetadata.getId() == 9) {
|
}
|
||||||
rotation = ((int) entityMetadata.getValue()) * 45;
|
|
||||||
|
public void setItemRotation(EntityMetadata<Integer> entityMetadata) {
|
||||||
|
rotation = ((IntEntityMetadata) entityMetadata).getPrimitiveValue() * 45;
|
||||||
if (cachedTag == null) {
|
if (cachedTag == null) {
|
||||||
updateBlock(session);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NbtMapBuilder builder = cachedTag.toBuilder();
|
NbtMapBuilder builder = cachedTag.toBuilder();
|
||||||
builder.putFloat("ItemRotation", rotation);
|
builder.putFloat("ItemRotation", rotation);
|
||||||
cachedTag = builder.build();
|
cachedTag = builder.build();
|
||||||
updateBlock(session);
|
changed = true;
|
||||||
}
|
|
||||||
else {
|
|
||||||
updateBlock(session);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean despawnEntity(GeyserSession session) {
|
public boolean despawnEntity() {
|
||||||
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
||||||
updateBlockPacket.setDataLayer(0);
|
updateBlockPacket.setDataLayer(0);
|
||||||
updateBlockPacket.setBlockPosition(bedrockPosition);
|
updateBlockPacket.setBlockPosition(bedrockPosition);
|
||||||
updateBlockPacket.setRuntimeId(session.getBlockMappings().getBedrockAirId());
|
updateBlockPacket.setRuntimeId(session.getBlockMappings().getBedrockAirId()); //TODO maybe set this to the world block or another item frame?
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY);
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS);
|
||||||
@ -166,15 +168,23 @@ public class ItemFrameEntity extends Entity {
|
|||||||
builder.putInt("y", bedrockPosition.getY());
|
builder.putInt("y", bedrockPosition.getY());
|
||||||
builder.putInt("z", bedrockPosition.getZ());
|
builder.putInt("z", bedrockPosition.getZ());
|
||||||
builder.putByte("isMovable", (byte) 1);
|
builder.putByte("isMovable", (byte) 1);
|
||||||
builder.putString("id", this.entityType == EntityType.GLOW_ITEM_FRAME ? "GlowItemFrame" : "ItemFrame");
|
builder.putString("id", this.definition.entityType() == EntityType.GLOW_ITEM_FRAME ? "GlowItemFrame" : "ItemFrame");
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBedrockMetadata() {
|
||||||
|
updateBlock();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the item frame as a block
|
* Updates the item frame as a block
|
||||||
* @param session GeyserSession.
|
|
||||||
*/
|
*/
|
||||||
public void updateBlock(GeyserSession session) {
|
public void updateBlock() {
|
||||||
|
if (!changed) {
|
||||||
|
// Don't send a block update packet - nothing changed
|
||||||
|
return;
|
||||||
|
}
|
||||||
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
||||||
updateBlockPacket.setDataLayer(0);
|
updateBlockPacket.setDataLayer(0);
|
||||||
updateBlockPacket.setBlockPosition(bedrockPosition);
|
updateBlockPacket.setBlockPosition(bedrockPosition);
|
||||||
@ -193,6 +203,8 @@ public class ItemFrameEntity extends Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
session.sendUpstreamPacket(blockEntityDataPacket);
|
session.sendUpstreamPacket(blockEntityDataPacket);
|
||||||
|
|
||||||
|
changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,9 +26,10 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ItemedFireballEntity extends ThrowableEntity {
|
public class ItemedFireballEntity extends ThrowableEntity {
|
||||||
private final Vector3f acceleration;
|
private final Vector3f acceleration;
|
||||||
|
|
||||||
@ -37,8 +38,8 @@ public class ItemedFireballEntity extends ThrowableEntity {
|
|||||||
*/
|
*/
|
||||||
protected int futureTicks = 3;
|
protected int futureTicks = 3;
|
||||||
|
|
||||||
public ItemedFireballEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ItemedFireballEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, Vector3f.ZERO, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, Vector3f.ZERO, yaw, pitch, headYaw);
|
||||||
|
|
||||||
float magnitude = motion.length();
|
float magnitude = motion.length();
|
||||||
if (magnitude != 0) {
|
if (magnitude != 0) {
|
||||||
@ -48,28 +49,28 @@ public class ItemedFireballEntity extends ThrowableEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector3f tickMovement(GeyserSession session, Vector3f position) {
|
private Vector3f tickMovement(Vector3f position) {
|
||||||
position = position.add(motion);
|
position = position.add(motion);
|
||||||
float drag = getDrag(session);
|
float drag = getDrag();
|
||||||
motion = motion.add(acceleration).mul(drag);
|
motion = motion.add(acceleration).mul(drag);
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void moveAbsoluteImmediate(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
protected void moveAbsoluteImmediate(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
|
||||||
// Advance the position by a few ticks before sending it to Bedrock
|
// Advance the position by a few ticks before sending it to Bedrock
|
||||||
Vector3f lastMotion = motion;
|
Vector3f lastMotion = motion;
|
||||||
Vector3f newPosition = position;
|
Vector3f newPosition = position;
|
||||||
for (int i = 0; i < futureTicks; i++) {
|
for (int i = 0; i < futureTicks; i++) {
|
||||||
newPosition = tickMovement(session, newPosition);
|
newPosition = tickMovement(newPosition);
|
||||||
}
|
}
|
||||||
super.moveAbsoluteImmediate(session, newPosition, rotation, isOnGround, teleported);
|
super.moveAbsoluteImmediate(newPosition, yaw, pitch, headYaw, isOnGround, teleported);
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.motion = lastMotion;
|
this.motion = lastMotion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(GeyserSession session) {
|
public void tick() {
|
||||||
moveAbsoluteImmediate(session, tickMovement(session, position), rotation, false, false);
|
moveAbsoluteImmediate(tickMovement(position), yaw, pitch, headYaw, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,13 +26,15 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class LeashKnotEntity extends Entity {
|
public class LeashKnotEntity extends Entity {
|
||||||
|
|
||||||
public LeashKnotEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public LeashKnotEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
// Position is incorrect by default
|
// Position is incorrect by default
|
||||||
super(entityId, geyserId, entityType, position.add(0.5f, 0.25f, 0.5f), motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position.add(0.5f, 0.25f, 0.5f), motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,20 +27,20 @@ package org.geysermc.connector.entity;
|
|||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket;
|
import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
public class LightningEntity extends Entity {
|
public class LightningEntity extends Entity {
|
||||||
|
|
||||||
public LightningEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public LightningEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnEntity(GeyserSession session) {
|
public void spawnEntity() {
|
||||||
super.spawnEntity(session);
|
super.spawnEntity();
|
||||||
|
|
||||||
// Add these two sound effects - they're done completely clientside on Java Edition as of 1.17.1
|
// Add these two sound effects - they're done completely clientside on Java Edition as of 1.17.1
|
||||||
ThreadLocalRandom random = ThreadLocalRandom.current();
|
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||||
|
@ -29,6 +29,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute;
|
|||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.protocol.bedrock.data.AttributeData;
|
import com.nukkitx.protocol.bedrock.data.AttributeData;
|
||||||
@ -43,7 +45,6 @@ import lombok.AccessLevel;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.geysermc.connector.entity.attribute.GeyserAttributeType;
|
import org.geysermc.connector.entity.attribute.GeyserAttributeType;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
import org.geysermc.connector.utils.AttributeUtils;
|
import org.geysermc.connector.utils.AttributeUtils;
|
||||||
@ -52,6 +53,7 @@ import org.geysermc.connector.utils.ChunkUtils;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@ -74,32 +76,34 @@ public class LivingEntity extends Entity {
|
|||||||
*/
|
*/
|
||||||
private boolean isMaxFrozenState = false;
|
private boolean isMaxFrozenState = false;
|
||||||
|
|
||||||
public LivingEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public LivingEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
// Matches Bedrock behavior; is always set to this
|
|
||||||
metadata.put(EntityData.HEALTH, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
protected void initializeMetadata() {
|
||||||
switch (entityMetadata.getId()) {
|
super.initializeMetadata();
|
||||||
case 8 -> { // blocking
|
// Matches Bedrock behavior; is always set to this
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
dirtyMetadata.put(EntityData.HEALTH, 1);
|
||||||
|
}
|
||||||
|
|
||||||
//blocking gets triggered when using a bow, but if we set USING_ITEM for all items, it may look like
|
public void setLivingEntityFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
|
||||||
|
// Blocking gets triggered when using a bow, but if we set USING_ITEM for all items, it may look like
|
||||||
// you're "mining" with ex. a shield.
|
// you're "mining" with ex. a shield.
|
||||||
ItemMapping shield = session.getItemMappings().getStoredItems().shield();
|
ItemMapping shield = session.getItemMappings().getStoredItems().shield();
|
||||||
boolean isUsingShield = (getHand().getId() == shield.getBedrockId() ||
|
boolean isUsingShield = (getHand().getId() == shield.getBedrockId() ||
|
||||||
getHand().equals(ItemData.AIR) && getOffHand().getId() == shield.getBedrockId());
|
getHand().equals(ItemData.AIR) && getOffHand().getId() == shield.getBedrockId());
|
||||||
metadata.getFlags().setFlag(EntityFlag.USING_ITEM, (xd & 0x01) == 0x01 && !isUsingShield);
|
setFlag(EntityFlag.USING_ITEM, (xd & 0x01) == 0x01 && !isUsingShield);
|
||||||
metadata.getFlags().setFlag(EntityFlag.BLOCKING, (xd & 0x01) == 0x01);
|
setFlag(EntityFlag.BLOCKING, (xd & 0x01) == 0x01);
|
||||||
|
|
||||||
// Riptide spin attack
|
// Riptide spin attack
|
||||||
metadata.getFlags().setFlag(EntityFlag.DAMAGE_NEARBY_MOBS, (xd & 0x04) == 0x04);
|
setFlag(EntityFlag.DAMAGE_NEARBY_MOBS, (xd & 0x04) == 0x04);
|
||||||
}
|
}
|
||||||
case 9 -> {
|
|
||||||
this.health = (float) entityMetadata.getValue();
|
public void setHealth(EntityMetadata<Float> entityMetadata) {
|
||||||
|
this.health = ((FloatEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
|
||||||
AttributeData healthData = createHealthAttribute();
|
AttributeData healthData = createHealthAttribute();
|
||||||
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
||||||
@ -107,49 +111,52 @@ public class LivingEntity extends Entity {
|
|||||||
attributesPacket.setAttributes(Collections.singletonList(healthData));
|
attributesPacket.setAttributes(Collections.singletonList(healthData));
|
||||||
session.sendUpstreamPacket(attributesPacket);
|
session.sendUpstreamPacket(attributesPacket);
|
||||||
}
|
}
|
||||||
case 10 -> metadata.put(EntityData.EFFECT_COLOR, entityMetadata.getValue());
|
|
||||||
case 11 -> metadata.put(EntityData.EFFECT_AMBIENT, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
public Vector3i setBedPosition(EntityMetadata<Position> entityMetadata) {
|
||||||
case 14 -> { // Bed Position
|
Position bedPosition = entityMetadata.getValue();
|
||||||
Position bedPosition = (Position) entityMetadata.getValue();
|
|
||||||
if (bedPosition != null) {
|
if (bedPosition != null) {
|
||||||
metadata.put(EntityData.BED_POSITION, Vector3i.from(bedPosition.getX(), bedPosition.getY(), bedPosition.getZ()));
|
Vector3i vector = Vector3i.from(bedPosition.getX(), bedPosition.getY(), bedPosition.getZ());
|
||||||
|
dirtyMetadata.put(EntityData.BED_POSITION, vector);
|
||||||
int bed = session.getConnector().getWorldManager().getBlockAt(session, bedPosition);
|
int bed = session.getConnector().getWorldManager().getBlockAt(session, bedPosition);
|
||||||
// Bed has to be updated, or else player is floating in the air
|
// Bed has to be updated, or else player is floating in the air
|
||||||
ChunkUtils.updateBlock(session, bed, bedPosition);
|
ChunkUtils.updateBlock(session, bed, bedPosition);
|
||||||
// Indicate that the player should enter the sleep cycle
|
// Indicate that the player should enter the sleep cycle
|
||||||
// Has to be a byte or it does not work
|
// Has to be a byte or it does not work
|
||||||
// (Bed position is what actually triggers sleep - "pose" is only optional)
|
// (Bed position is what actually triggers sleep - "pose" is only optional)
|
||||||
metadata.put(EntityData.PLAYER_FLAGS, (byte) 2);
|
dirtyMetadata.put(EntityData.PLAYER_FLAGS, (byte) 2);
|
||||||
|
return vector;
|
||||||
} else {
|
} else {
|
||||||
// Player is no longer sleeping
|
// Player is no longer sleeping
|
||||||
metadata.put(EntityData.PLAYER_FLAGS, (byte) 0);
|
dirtyMetadata.put(EntityData.PLAYER_FLAGS, (byte) 0);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isShaking(GeyserSession session) {
|
protected boolean isShaking() {
|
||||||
return isMaxFrozenState;
|
return isMaxFrozenState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setDimensions(Pose pose) {
|
protected void setDimensions(Pose pose) {
|
||||||
if (pose == Pose.SLEEPING) {
|
if (pose == Pose.SLEEPING) {
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, 0.2f);
|
boundingBoxWidth = 0.2f;
|
||||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, 0.2f);
|
boundingBoxHeight = 0.2f;
|
||||||
|
if (boundingBoxWidth != definition.width() || boundingBoxHeight != definition.height()) {
|
||||||
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, boundingBoxWidth);
|
||||||
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, boundingBoxHeight);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
super.setDimensions(pose);
|
super.setDimensions(pose);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setFreezing(GeyserSession session, float amount) {
|
public float setFreezing(EntityMetadata<Integer> entityMetadata) {
|
||||||
super.setFreezing(session, amount);
|
float freezingPercentage = super.setFreezing(entityMetadata);
|
||||||
this.isMaxFrozenState = amount >= 1.0f;
|
this.isMaxFrozenState = freezingPercentage >= 1.0f;
|
||||||
metadata.getFlags().setFlag(EntityFlag.SHAKING, isShaking(session));
|
setFlag(EntityFlag.SHAKING, isShaking());
|
||||||
|
return freezingPercentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,63 +26,42 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class MinecartEntity extends Entity {
|
public class MinecartEntity extends Entity {
|
||||||
|
|
||||||
public MinecartEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public MinecartEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position.add(0d, entityType.getOffset(), 0d), motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position.add(0d, definition.offset(), 0d), motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setCustomBlock(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
dirtyMetadata.put(EntityData.DISPLAY_ITEM, session.getBlockMappings().getBedrockBlockId(((IntEntityMetadata) entityMetadata).getPrimitiveValue()));
|
||||||
|
|
||||||
if (entityMetadata.getId() == 8) {
|
|
||||||
metadata.put(EntityData.HEALTH, entityMetadata.getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Direction in which the minecart is shaking
|
public void setCustomBlockOffset(EntityMetadata<Integer> entityMetadata) {
|
||||||
if (entityMetadata.getId() == 9) {
|
dirtyMetadata.put(EntityData.DISPLAY_OFFSET, entityMetadata.getValue());
|
||||||
metadata.put(EntityData.HURT_DIRECTION, entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Power in Java, time in Bedrock
|
|
||||||
if (entityMetadata.getId() == 10) {
|
|
||||||
metadata.put(EntityData.HURT_TIME, Math.min((int) (float) entityMetadata.getValue(), 15));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(this instanceof DefaultBlockMinecartEntity)) { // Handled in the DefaultBlockMinecartEntity class
|
|
||||||
// Custom block
|
|
||||||
if (entityMetadata.getId() == 11) {
|
|
||||||
metadata.put(EntityData.DISPLAY_ITEM, session.getBlockMappings().getBedrockBlockId((int) entityMetadata.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Custom block offset
|
|
||||||
if (entityMetadata.getId() == 12) {
|
|
||||||
metadata.put(EntityData.DISPLAY_OFFSET, entityMetadata.getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setShowCustomBlock(EntityMetadata<Boolean> entityMetadata) {
|
||||||
// If the custom block should be enabled
|
// If the custom block should be enabled
|
||||||
if (entityMetadata.getId() == 13) {
|
|
||||||
// Needs a byte based off of Java's boolean
|
// Needs a byte based off of Java's boolean
|
||||||
metadata.put(EntityData.CUSTOM_DISPLAY, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
dirtyMetadata.put(EntityData.CUSTOM_DISPLAY, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
|
||||||
super.moveAbsolute(session, position.add(0d, this.entityType.getOffset(), 0d), rotation, isOnGround, teleported);
|
super.moveAbsolute(position.add(0d, this.definition.offset(), 0d), yaw, pitch, headYaw, isOnGround, teleported);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector3f getBedrockRotation() {
|
public Vector3f getBedrockRotation() {
|
||||||
// Note: minecart rotation on rails does not care about the actual rotation value
|
// Note: minecart rotation on rails does not care about the actual rotation value
|
||||||
return Vector3f.from(0, rotation.getX(), 0);
|
return Vector3f.from(0, yaw, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,23 +27,24 @@ package org.geysermc.connector.entity;
|
|||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.packet.AddPaintingPacket;
|
import com.nukkitx.protocol.bedrock.packet.AddPaintingPacket;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.utils.PaintingType;
|
import org.geysermc.connector.utils.PaintingType;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PaintingEntity extends Entity {
|
public class PaintingEntity extends Entity {
|
||||||
private static final double OFFSET = -0.46875;
|
private static final double OFFSET = -0.46875;
|
||||||
private final PaintingType paintingName;
|
private final PaintingType paintingName;
|
||||||
private final int direction;
|
private final int direction;
|
||||||
|
|
||||||
public PaintingEntity(long entityId, long geyserId, Vector3f position, PaintingType paintingName, int direction) {
|
public PaintingEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, Vector3f position, PaintingType paintingName, int direction) {
|
||||||
super(entityId, geyserId, EntityType.PAINTING, position, Vector3f.ZERO, Vector3f.ZERO);
|
super(session, entityId, geyserId, uuid, EntityDefinitions.PAINTING, position, Vector3f.ZERO, 0f, 0f, 0f);
|
||||||
this.paintingName = paintingName;
|
this.paintingName = paintingName;
|
||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnEntity(GeyserSession session) {
|
public void spawnEntity() {
|
||||||
AddPaintingPacket addPaintingPacket = new AddPaintingPacket();
|
AddPaintingPacket addPaintingPacket = new AddPaintingPacket();
|
||||||
addPaintingPacket.setUniqueEntityId(geyserId);
|
addPaintingPacket.setUniqueEntityId(geyserId);
|
||||||
addPaintingPacket.setRuntimeEntityId(geyserId);
|
addPaintingPacket.setRuntimeEntityId(geyserId);
|
||||||
@ -58,7 +59,7 @@ public class PaintingEntity extends Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateHeadLookRotation(GeyserSession session, float headYaw) {
|
public void updateHeadLookRotation(float headYaw) {
|
||||||
// Do nothing, as head look messes up paintings
|
// Do nothing, as head look messes up paintings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,19 +27,20 @@ package org.geysermc.connector.entity;
|
|||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class SpawnerMinecartEntity extends DefaultBlockMinecartEntity {
|
public class SpawnerMinecartEntity extends DefaultBlockMinecartEntity {
|
||||||
|
|
||||||
public SpawnerMinecartEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public SpawnerMinecartEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateDefaultBlockMetadata(GeyserSession session) {
|
public void updateDefaultBlockMetadata() {
|
||||||
metadata.put(EntityData.DISPLAY_ITEM, session.getBlockMappings().getBedrockBlockId(BlockStateValues.JAVA_SPAWNER_ID));
|
dirtyMetadata.put(EntityData.DISPLAY_ITEM, session.getBlockMappings().getBedrockBlockId(BlockStateValues.JAVA_SPAWNER_ID));
|
||||||
metadata.put(EntityData.DISPLAY_OFFSET, 6);
|
dirtyMetadata.put(EntityData.DISPLAY_OFFSET, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,41 +26,37 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
public class TNTEntity extends Entity implements Tickable {
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class TNTEntity extends Entity implements Tickable {
|
||||||
private int currentTick;
|
private int currentTick;
|
||||||
|
|
||||||
public TNTEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public TNTEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFuseLength(EntityMetadata<Integer> entityMetadata) {
|
||||||
|
currentTick = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
setFlag(EntityFlag.IGNITED, true);
|
||||||
|
dirtyMetadata.put(EntityData.FUSE_LENGTH, currentTick);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void tick() {
|
||||||
if (entityMetadata.getId() == 8) {
|
|
||||||
currentTick = (int) entityMetadata.getValue();
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.IGNITED, true);
|
|
||||||
metadata.put(EntityData.FUSE_LENGTH, currentTick);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick(GeyserSession session) {
|
|
||||||
if (currentTick == 0) {
|
if (currentTick == 0) {
|
||||||
// No need to update the fuse when there is none
|
// No need to update the fuse when there is none
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentTick % 5 == 0) {
|
if (currentTick % 5 == 0) {
|
||||||
metadata.put(EntityData.FUSE_LENGTH, currentTick);
|
dirtyMetadata.put(EntityData.FUSE_LENGTH, currentTick);
|
||||||
|
|
||||||
SetEntityDataPacket packet = new SetEntityDataPacket();
|
SetEntityDataPacket packet = new SetEntityDataPacket();
|
||||||
packet.setRuntimeEntityId(geyserId);
|
packet.setRuntimeEntityId(geyserId);
|
||||||
|
@ -25,15 +25,17 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
|
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.MoveEntityDeltaPacket;
|
import com.nukkitx.protocol.bedrock.packet.MoveEntityDeltaPacket;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used as a class for any object-like entity that moves as a projectile
|
* Used as a class for any object-like entity that moves as a projectile
|
||||||
*/
|
*/
|
||||||
@ -41,8 +43,8 @@ public class ThrowableEntity extends Entity implements Tickable {
|
|||||||
|
|
||||||
protected Vector3f lastJavaPosition;
|
protected Vector3f lastJavaPosition;
|
||||||
|
|
||||||
public ThrowableEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ThrowableEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
this.lastJavaPosition = position;
|
this.lastJavaPosition = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,14 +54,14 @@ public class ThrowableEntity extends Entity implements Tickable {
|
|||||||
* Java clients assume the next positions of moving items. Bedrock needs to be explicitly told positions
|
* Java clients assume the next positions of moving items. Bedrock needs to be explicitly told positions
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void tick(GeyserSession session) {
|
public void tick() {
|
||||||
moveAbsoluteImmediate(session, position.add(motion), rotation, onGround, false);
|
moveAbsoluteImmediate(position.add(motion), yaw, pitch, headYaw, onGround, false);
|
||||||
float drag = getDrag(session);
|
float drag = getDrag();
|
||||||
float gravity = getGravity(session);
|
float gravity = getGravity();
|
||||||
motion = motion.mul(drag).down(gravity);
|
motion = motion.mul(drag).down(gravity);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void moveAbsoluteImmediate(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
protected void moveAbsoluteImmediate(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
|
||||||
MoveEntityDeltaPacket moveEntityDeltaPacket = new MoveEntityDeltaPacket();
|
MoveEntityDeltaPacket moveEntityDeltaPacket = new MoveEntityDeltaPacket();
|
||||||
moveEntityDeltaPacket.setRuntimeEntityId(geyserId);
|
moveEntityDeltaPacket.setRuntimeEntityId(geyserId);
|
||||||
|
|
||||||
@ -86,19 +88,21 @@ public class ThrowableEntity extends Entity implements Tickable {
|
|||||||
}
|
}
|
||||||
setPosition(position);
|
setPosition(position);
|
||||||
|
|
||||||
if (this.rotation.getX() != rotation.getX()) {
|
if (this.yaw != yaw) {
|
||||||
moveEntityDeltaPacket.getFlags().add(MoveEntityDeltaPacket.Flag.HAS_YAW);
|
moveEntityDeltaPacket.getFlags().add(MoveEntityDeltaPacket.Flag.HAS_YAW);
|
||||||
moveEntityDeltaPacket.setYaw(rotation.getX());
|
moveEntityDeltaPacket.setYaw(yaw);
|
||||||
|
this.yaw = yaw;
|
||||||
}
|
}
|
||||||
if (this.rotation.getY() != rotation.getY()) {
|
if (this.pitch != pitch) {
|
||||||
moveEntityDeltaPacket.getFlags().add(MoveEntityDeltaPacket.Flag.HAS_PITCH);
|
moveEntityDeltaPacket.getFlags().add(MoveEntityDeltaPacket.Flag.HAS_PITCH);
|
||||||
moveEntityDeltaPacket.setPitch(rotation.getY());
|
moveEntityDeltaPacket.setPitch(pitch);
|
||||||
|
this.pitch = pitch;
|
||||||
}
|
}
|
||||||
if (this.rotation.getZ() != rotation.getZ()) {
|
if (this.headYaw != headYaw) {
|
||||||
moveEntityDeltaPacket.getFlags().add(MoveEntityDeltaPacket.Flag.HAS_HEAD_YAW);
|
moveEntityDeltaPacket.getFlags().add(MoveEntityDeltaPacket.Flag.HAS_HEAD_YAW);
|
||||||
moveEntityDeltaPacket.setHeadYaw(rotation.getZ());
|
moveEntityDeltaPacket.setHeadYaw(headYaw);
|
||||||
|
this.headYaw = headYaw;
|
||||||
}
|
}
|
||||||
setRotation(rotation);
|
|
||||||
|
|
||||||
if (!moveEntityDeltaPacket.getFlags().isEmpty()) {
|
if (!moveEntityDeltaPacket.getFlags().isEmpty()) {
|
||||||
session.sendUpstreamPacket(moveEntityDeltaPacket);
|
session.sendUpstreamPacket(moveEntityDeltaPacket);
|
||||||
@ -108,14 +112,12 @@ public class ThrowableEntity extends Entity implements Tickable {
|
|||||||
/**
|
/**
|
||||||
* Get the gravity of this entity type. Used for applying gravity while the entity is in motion.
|
* Get the gravity of this entity type. Used for applying gravity while the entity is in motion.
|
||||||
*
|
*
|
||||||
* @param session the session of the Bedrock client.
|
|
||||||
* @return the amount of gravity to apply to this entity while in motion.
|
* @return the amount of gravity to apply to this entity while in motion.
|
||||||
*/
|
*/
|
||||||
protected float getGravity(GeyserSession session) {
|
protected float getGravity() {
|
||||||
if (metadata.getFlags().getFlag(EntityFlag.HAS_GRAVITY)) {
|
if (getFlag(EntityFlag.HAS_GRAVITY)) {
|
||||||
switch (entityType) {
|
switch (definition.entityType()) {
|
||||||
case THROWN_POTION:
|
case THROWN_POTION:
|
||||||
case LINGERING_POTION:
|
|
||||||
return 0.05f;
|
return 0.05f;
|
||||||
case THROWN_EXP_BOTTLE:
|
case THROWN_EXP_BOTTLE:
|
||||||
return 0.07f;
|
return 0.07f;
|
||||||
@ -134,16 +136,14 @@ public class ThrowableEntity extends Entity implements Tickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param session the session of the Bedrock client.
|
|
||||||
* @return the drag that should be multiplied to the entity's motion
|
* @return the drag that should be multiplied to the entity's motion
|
||||||
*/
|
*/
|
||||||
protected float getDrag(GeyserSession session) {
|
protected float getDrag() {
|
||||||
if (isInWater(session)) {
|
if (isInWater()) {
|
||||||
return 0.8f;
|
return 0.8f;
|
||||||
} else {
|
} else {
|
||||||
switch (entityType) {
|
switch (definition.entityType()) {
|
||||||
case THROWN_POTION:
|
case THROWN_POTION:
|
||||||
case LINGERING_POTION:
|
|
||||||
case THROWN_EXP_BOTTLE:
|
case THROWN_EXP_BOTTLE:
|
||||||
case SNOWBALL:
|
case SNOWBALL:
|
||||||
case THROWN_EGG:
|
case THROWN_EGG:
|
||||||
@ -162,34 +162,33 @@ public class ThrowableEntity extends Entity implements Tickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param session the session of the Bedrock client.
|
|
||||||
* @return true if this entity is currently in water.
|
* @return true if this entity is currently in water.
|
||||||
*/
|
*/
|
||||||
protected boolean isInWater(GeyserSession session) {
|
protected boolean isInWater() {
|
||||||
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
||||||
return BlockStateValues.getWaterLevel(block) != -1;
|
return BlockStateValues.getWaterLevel(block) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean despawnEntity(GeyserSession session) {
|
public boolean despawnEntity() {
|
||||||
if (entityType == EntityType.THROWN_ENDERPEARL) {
|
if (definition.entityType() == EntityType.THROWN_ENDERPEARL) {
|
||||||
LevelEventPacket particlePacket = new LevelEventPacket();
|
LevelEventPacket particlePacket = new LevelEventPacket();
|
||||||
particlePacket.setType(LevelEventType.PARTICLE_TELEPORT);
|
particlePacket.setType(LevelEventType.PARTICLE_TELEPORT);
|
||||||
particlePacket.setPosition(position);
|
particlePacket.setPosition(position);
|
||||||
session.sendUpstreamPacket(particlePacket);
|
session.sendUpstreamPacket(particlePacket);
|
||||||
}
|
}
|
||||||
return super.despawnEntity(session);
|
return super.despawnEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) {
|
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, float headYaw, boolean isOnGround) {
|
||||||
moveAbsoluteImmediate(session, lastJavaPosition.add(relX, relY, relZ), rotation, isOnGround, false);
|
moveAbsoluteImmediate(lastJavaPosition.add(relX, relY, relZ), yaw, pitch, headYaw, isOnGround, false);
|
||||||
lastJavaPosition = position;
|
lastJavaPosition = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
|
||||||
moveAbsoluteImmediate(session, position, rotation, isOnGround, teleported);
|
moveAbsoluteImmediate(position, yaw, pitch, headYaw, isOnGround, teleported);
|
||||||
lastJavaPosition = position;
|
lastJavaPosition = position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,10 @@ package org.geysermc.connector.entity;
|
|||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used as a class for any projectile entity that looks like an item
|
* Used as a class for any projectile entity that looks like an item
|
||||||
*/
|
*/
|
||||||
@ -40,37 +41,37 @@ public class ThrowableItemEntity extends ThrowableEntity {
|
|||||||
private int age;
|
private int age;
|
||||||
private boolean invisible;
|
private boolean invisible;
|
||||||
|
|
||||||
public ThrowableItemEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ThrowableItemEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
metadata.getFlags().setFlag(EntityFlag.INVISIBLE, true);
|
setFlag(EntityFlag.INVISIBLE, true);
|
||||||
invisible = false;
|
invisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkVisibility(GeyserSession session) {
|
private void checkVisibility() {
|
||||||
if (invisible != metadata.getFlags().getFlag(EntityFlag.INVISIBLE)) {
|
if (invisible != getFlag(EntityFlag.INVISIBLE)) {
|
||||||
if (!invisible) {
|
if (!invisible) {
|
||||||
Vector3f playerPos = session.getPlayerEntity().getPosition();
|
Vector3f playerPos = session.getPlayerEntity().getPosition();
|
||||||
// Prevent projectiles from blocking the player's screen
|
// Prevent projectiles from blocking the player's screen
|
||||||
if (age >= 4 || position.distanceSquared(playerPos) > 16) {
|
if (age >= 4 || position.distanceSquared(playerPos) > 16) {
|
||||||
metadata.getFlags().setFlag(EntityFlag.INVISIBLE, false);
|
setFlag(EntityFlag.INVISIBLE, false);
|
||||||
updateBedrockMetadata(session);
|
updateBedrockMetadata();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
metadata.getFlags().setFlag(EntityFlag.INVISIBLE, true);
|
setFlag(EntityFlag.INVISIBLE, true);
|
||||||
updateBedrockMetadata(session);
|
updateBedrockMetadata();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
age++;
|
age++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(GeyserSession session) {
|
public void tick() {
|
||||||
checkVisibility(session);
|
checkVisibility();
|
||||||
super.tick(session);
|
super.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setInvisible(GeyserSession session, boolean value) {
|
protected void setInvisible(boolean value) {
|
||||||
invisible = value;
|
invisible = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,50 +27,44 @@ package org.geysermc.connector.entity;
|
|||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.item.Potion;
|
import org.geysermc.connector.network.translators.item.Potion;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ThrownPotionEntity extends ThrowableItemEntity {
|
public class ThrownPotionEntity extends ThrowableItemEntity {
|
||||||
private static final EnumSet<Potion> NON_ENCHANTED_POTIONS = EnumSet.of(Potion.WATER, Potion.MUNDANE, Potion.THICK, Potion.AWKWARD);
|
private static final EnumSet<Potion> NON_ENCHANTED_POTIONS = EnumSet.of(Potion.WATER, Potion.MUNDANE, Potion.THICK, Potion.AWKWARD);
|
||||||
|
|
||||||
public ThrownPotionEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ThrownPotionEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setPotion(EntityMetadata<ItemStack> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
ItemStack itemStack = entityMetadata.getValue();
|
||||||
if (entityMetadata.getId() == 8 && entityMetadata.getType() == MetadataType.ITEM) {
|
|
||||||
ItemStack itemStack = (ItemStack) entityMetadata.getValue();
|
|
||||||
ItemMapping mapping = session.getItemMappings().getMapping(itemStack);
|
ItemMapping mapping = session.getItemMappings().getMapping(itemStack);
|
||||||
if (mapping.getJavaIdentifier().endsWith("potion") && itemStack.getNbt() != null) {
|
if (mapping.getJavaIdentifier().endsWith("potion") && itemStack.getNbt() != null) {
|
||||||
Tag potionTag = itemStack.getNbt().get("Potion");
|
Tag potionTag = itemStack.getNbt().get("Potion");
|
||||||
if (potionTag instanceof StringTag) {
|
if (potionTag instanceof StringTag) {
|
||||||
Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue());
|
Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue());
|
||||||
if (potion != null) {
|
if (potion != null) {
|
||||||
metadata.put(EntityData.POTION_AUX_VALUE, potion.getBedrockId());
|
dirtyMetadata.put(EntityData.POTION_AUX_VALUE, potion.getBedrockId());
|
||||||
metadata.getFlags().setFlag(EntityFlag.ENCHANTED, !NON_ENCHANTED_POTIONS.contains(potion));
|
setFlag(EntityFlag.ENCHANTED, !NON_ENCHANTED_POTIONS.contains(potion));
|
||||||
} else {
|
} else {
|
||||||
metadata.put(EntityData.POTION_AUX_VALUE, 0);
|
dirtyMetadata.put(EntityData.POTION_AUX_VALUE, 0);
|
||||||
GeyserConnector.getInstance().getLogger().debug("Unknown java potion: " + potionTag.getValue());
|
GeyserConnector.getInstance().getLogger().debug("Unknown java potion: " + potionTag.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isLingering = mapping.getJavaIdentifier().equals("minecraft:lingering_potion");
|
boolean isLingering = mapping.getJavaIdentifier().equals("minecraft:lingering_potion");
|
||||||
metadata.getFlags().setFlag(EntityFlag.LINGERING, isLingering);
|
setFlag(EntityFlag.LINGERING, isLingering);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,9 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implemented onto anything that should have code ran every Minecraft tick - 50 milliseconds.
|
* Implemented onto anything that should have code ran every Minecraft tick - 50 milliseconds.
|
||||||
*/
|
*/
|
||||||
public interface Tickable {
|
public interface Tickable {
|
||||||
void tick(GeyserSession session);
|
void tick();
|
||||||
}
|
}
|
||||||
|
@ -26,38 +26,35 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.item.TippedArrowPotion;
|
import org.geysermc.connector.network.translators.item.TippedArrowPotion;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internally this is known as TippedArrowEntity but is used with tipped arrows and normal arrows
|
* Internally this is known as TippedArrowEntity but is used with tipped arrows and normal arrows
|
||||||
*/
|
*/
|
||||||
public class TippedArrowEntity extends AbstractArrowEntity {
|
public class TippedArrowEntity extends AbstractArrowEntity {
|
||||||
|
|
||||||
public TippedArrowEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public TippedArrowEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setPotionEffectColor(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
int potionColor = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
// Arrow potion effect color
|
|
||||||
if (entityMetadata.getId() == 10) {
|
|
||||||
int potionColor = (int) entityMetadata.getValue();
|
|
||||||
// -1 means no color
|
// -1 means no color
|
||||||
if (potionColor == -1) {
|
if (potionColor == -1) {
|
||||||
metadata.put(EntityData.CUSTOM_DISPLAY, 0);
|
dirtyMetadata.put(EntityData.CUSTOM_DISPLAY, 0);
|
||||||
} else {
|
} else {
|
||||||
TippedArrowPotion potion = TippedArrowPotion.getByJavaColor(potionColor);
|
TippedArrowPotion potion = TippedArrowPotion.getByJavaColor(potionColor);
|
||||||
if (potion != null && potion.getJavaColor() != -1) {
|
if (potion != null && potion.getJavaColor() != -1) {
|
||||||
metadata.put(EntityData.CUSTOM_DISPLAY, (byte) potion.getBedrockId());
|
dirtyMetadata.put(EntityData.CUSTOM_DISPLAY, (byte) potion.getBedrockId());
|
||||||
} else {
|
} else {
|
||||||
metadata.put(EntityData.CUSTOM_DISPLAY, 0);
|
dirtyMetadata.put(EntityData.CUSTOM_DISPLAY, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,24 +25,14 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class TridentEntity extends AbstractArrowEntity {
|
public class TridentEntity extends AbstractArrowEntity {
|
||||||
|
|
||||||
public TridentEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public TridentEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
|
||||||
if (entityMetadata.getId() == 11) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.ENCHANTED, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,35 +26,34 @@
|
|||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class WitherSkullEntity extends ItemedFireballEntity {
|
public class WitherSkullEntity extends ItemedFireballEntity {
|
||||||
private boolean isCharged;
|
private boolean isCharged;
|
||||||
|
|
||||||
public WitherSkullEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public WitherSkullEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
this.futureTicks = 1;
|
this.futureTicks = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setDangerous(EntityMetadata<Boolean> entityMetadata) {
|
||||||
protected float getDrag(GeyserSession session) {
|
boolean newDangerous = ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
return isCharged ? 0.73f : super.getDrag(session);
|
if (newDangerous != isCharged) {
|
||||||
|
isCharged = newDangerous;
|
||||||
|
// Is an entirely new entity in Bedrock but just a metadata type in Java
|
||||||
|
definition = isCharged ? EntityDefinitions.WITHER_SKULL_DANGEROUS : EntityDefinitions.WITHER_SKULL;
|
||||||
|
despawnEntity();
|
||||||
|
spawnEntity();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
protected float getDrag() {
|
||||||
if (entityMetadata.getId() == 8) {
|
return isCharged ? 0.73f : super.getDrag();
|
||||||
boolean newIsCharged = (boolean) entityMetadata.getValue();
|
|
||||||
if (newIsCharged != isCharged) {
|
|
||||||
isCharged = newIsCharged;
|
|
||||||
entityType = isCharged ? EntityType.WITHER_SKULL_DANGEROUS : EntityType.WITHER_SKULL;
|
|
||||||
despawnEntity(session);
|
|
||||||
spawnEntity(session);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.connector.entity.factory;
|
||||||
|
|
||||||
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
|
import org.geysermc.connector.entity.Entity;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface BaseEntityFactory<T extends Entity> extends EntityFactory<T> {
|
||||||
|
|
||||||
|
T create(GeyserSession session, long javaId, long bedrockId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw);
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.connector.entity.factory;
|
||||||
|
|
||||||
|
import org.geysermc.connector.entity.Entity;
|
||||||
|
|
||||||
|
public interface EntityFactory<T extends Entity> {
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.connector.entity.factory;
|
||||||
|
|
||||||
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
|
import org.geysermc.connector.entity.ExpOrbEntity;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ExperienceOrbEntityFactory extends EntityFactory<ExpOrbEntity> {
|
||||||
|
|
||||||
|
ExpOrbEntity create(GeyserSession session, int amount, long entityId, long geyserId, Vector3f position);
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.connector.entity.factory;
|
||||||
|
|
||||||
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
|
import org.geysermc.connector.entity.PaintingEntity;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
import org.geysermc.connector.utils.PaintingType;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface PaintingEntityFactory extends EntityFactory<PaintingEntity> {
|
||||||
|
|
||||||
|
PaintingEntity create(GeyserSession session, long entityId, long geyserId, UUID uuid, Vector3f position, PaintingType paintingName, int direction);
|
||||||
|
}
|
@ -27,16 +27,19 @@ package org.geysermc.connector.entity.living;
|
|||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class AbstractFishEntity extends WaterEntity {
|
public class AbstractFishEntity extends WaterEntity {
|
||||||
|
|
||||||
public AbstractFishEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public AbstractFishEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.CAN_SWIM, true);
|
setFlag(EntityFlag.CAN_SWIM, true);
|
||||||
metadata.getFlags().setFlag(EntityFlag.BREATHING, true);
|
setFlag(EntityFlag.BREATHING, true);
|
||||||
metadata.getFlags().setFlag(EntityFlag.CAN_CLIMB, false);
|
setFlag(EntityFlag.CAN_CLIMB, false);
|
||||||
metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, false);
|
setFlag(EntityFlag.HAS_GRAVITY, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,29 +26,46 @@
|
|||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class AgeableEntity extends CreatureEntity {
|
public class AgeableEntity extends CreatureEntity {
|
||||||
|
|
||||||
public AgeableEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public AgeableEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setBaby(EntityMetadata<Boolean> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
boolean isBaby = ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 16) {
|
dirtyMetadata.put(EntityData.SCALE, isBaby ? getBabySize() : getAdultSize());
|
||||||
boolean isBaby = (boolean) entityMetadata.getValue();
|
setFlag(EntityFlag.BABY, isBaby);
|
||||||
metadata.put(EntityData.SCALE, isBaby ? .55f : 1f);
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.BABY, isBaby);
|
|
||||||
|
|
||||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, entityType.getHeight() * (isBaby ? 0.55f : 1f));
|
// TODO save this?
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, entityType.getWidth() * (isBaby ? 0.55f : 1f));
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, definition.height() * (isBaby ? getBabySize() : getAdultSize()));
|
||||||
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, definition.width() * (isBaby ? getBabySize() : getAdultSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
/**
|
||||||
|
* The scale that should be used when this entity is not a baby.
|
||||||
|
*/
|
||||||
|
protected float getAdultSize() {
|
||||||
|
return 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The scale that should be used when this entity is a baby.
|
||||||
|
*/
|
||||||
|
protected float getBabySize() {
|
||||||
|
return 0.55f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBaby() {
|
||||||
|
return getFlag(EntityFlag.BABY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,14 @@
|
|||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
public class AmbientEntity extends InsentientEntity {
|
import java.util.UUID;
|
||||||
|
|
||||||
public AmbientEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public class AmbientEntity extends MobEntity {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
|
||||||
|
public AmbientEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,18 +26,22 @@
|
|||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
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.data.game.entity.metadata.Rotation;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Rotation;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinitions;
|
||||||
import org.geysermc.connector.entity.LivingEntity;
|
import org.geysermc.connector.entity.LivingEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ArmorStandEntity extends LivingEntity {
|
public class ArmorStandEntity extends LivingEntity {
|
||||||
|
|
||||||
// These are used to store the state of the armour stand for use when handling invisibility
|
// These are used to store the state of the armour stand for use when handling invisibility
|
||||||
@ -72,54 +76,54 @@ public class ArmorStandEntity extends LivingEntity {
|
|||||||
* Whether we should update the position of this armor stand after metadata updates.
|
* Whether we should update the position of this armor stand after metadata updates.
|
||||||
*/
|
*/
|
||||||
private boolean positionUpdateRequired = false;
|
private boolean positionUpdateRequired = false;
|
||||||
private GeyserSession session;
|
|
||||||
|
|
||||||
public ArmorStandEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ArmorStandEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnEntity(GeyserSession session) {
|
public void spawnEntity() {
|
||||||
this.session = session;
|
this.pitch = yaw;
|
||||||
this.rotation = Vector3f.from(rotation.getX(), rotation.getX(), rotation.getX());
|
this.headYaw = yaw;
|
||||||
super.spawnEntity(session);
|
super.spawnEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean despawnEntity(GeyserSession session) {
|
public boolean despawnEntity() {
|
||||||
if (secondEntity != null) {
|
if (secondEntity != null) {
|
||||||
secondEntity.despawnEntity(session);
|
secondEntity.despawnEntity();
|
||||||
}
|
}
|
||||||
return super.despawnEntity(session);
|
return super.despawnEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) {
|
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, float headYaw, boolean isOnGround) {
|
||||||
if (secondEntity != null) {
|
if (secondEntity != null) {
|
||||||
secondEntity.moveRelative(session, relX, relY, relZ, rotation, isOnGround);
|
secondEntity.moveRelative(relX, relY, relZ, yaw, pitch, headYaw, isOnGround);
|
||||||
}
|
}
|
||||||
super.moveRelative(session, relX, relY, relZ, rotation, isOnGround);
|
super.moveRelative(relX, relY, relZ, yaw, pitch, headYaw, isOnGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
|
||||||
if (secondEntity != null) {
|
if (secondEntity != null) {
|
||||||
secondEntity.moveAbsolute(session, applyOffsetToPosition(position), rotation, isOnGround, teleported);
|
secondEntity.moveAbsolute(applyOffsetToPosition(position), yaw, pitch, headYaw, isOnGround, teleported);
|
||||||
} else if (positionRequiresOffset) {
|
} else if (positionRequiresOffset) {
|
||||||
// Fake the height to be above where it is so the nametag appears in the right location for invisible non-marker armour stands
|
// Fake the height to be above where it is so the nametag appears in the right location for invisible non-marker armour stands
|
||||||
position = applyOffsetToPosition(position);
|
position = applyOffsetToPosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
super.moveAbsolute(session, position, Vector3f.from(rotation.getX(), rotation.getX(), rotation.getX()), isOnGround, teleported);
|
super.moveAbsolute(position, yaw, yaw, yaw, isOnGround, teleported);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void setDisplayName(EntityMetadata<Component> entityMetadata) {
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
super.setDisplayName(entityMetadata);
|
||||||
if (entityMetadata.getId() == 2) {
|
|
||||||
updateSecondEntityStatus(false);
|
updateSecondEntityStatus(false);
|
||||||
} else if (entityMetadata.getId() == 15 && entityMetadata.getType() == MetadataType.BYTE) {
|
}
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
|
||||||
|
public void setArmorStandFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
|
||||||
// isSmall
|
// isSmall
|
||||||
boolean newIsSmall = (xd & 0x01) == 0x01;
|
boolean newIsSmall = (xd & 0x01) == 0x01;
|
||||||
@ -141,9 +145,9 @@ public class ArmorStandEntity extends LivingEntity {
|
|||||||
isMarker = (xd & 0x10) == 0x10;
|
isMarker = (xd & 0x10) == 0x10;
|
||||||
if (oldIsMarker != isMarker) {
|
if (oldIsMarker != isMarker) {
|
||||||
if (isMarker) {
|
if (isMarker) {
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, 0.0f);
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, 0.0f);
|
||||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, 0.0f);
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, 0.0f);
|
||||||
metadata.put(EntityData.SCALE, 0f);
|
dirtyMetadata.put(EntityData.SCALE, 0f);
|
||||||
} else {
|
} else {
|
||||||
toggleSmallStatus();
|
toggleSmallStatus();
|
||||||
}
|
}
|
||||||
@ -153,56 +157,49 @@ public class ArmorStandEntity extends LivingEntity {
|
|||||||
|
|
||||||
// The following values don't do anything on normal Bedrock.
|
// The following values don't do anything on normal Bedrock.
|
||||||
// But if given a resource pack, then we can use these values to control armor stand visual properties
|
// But if given a resource pack, then we can use these values to control armor stand visual properties
|
||||||
metadata.getFlags().setFlag(EntityFlag.ANGRY, (xd & 0x04) != 0x04); // Has arms
|
setFlag(EntityFlag.ANGRY, (xd & 0x04) != 0x04); // Has arms
|
||||||
metadata.getFlags().setFlag(EntityFlag.ADMIRING, (xd & 0x08) == 0x08); // Has no baseplate
|
setFlag(EntityFlag.ADMIRING, (xd & 0x08) == 0x08); // Has no baseplate
|
||||||
} else {
|
|
||||||
EntityData dataLeech = null;
|
|
||||||
EntityFlag negativeXToggle = null;
|
|
||||||
EntityFlag negativeYToggle = null;
|
|
||||||
EntityFlag negativeZToggle = null;
|
|
||||||
switch (entityMetadata.getId()) {
|
|
||||||
case 16 -> { // Head
|
|
||||||
dataLeech = EntityData.MARK_VARIANT;
|
|
||||||
negativeXToggle = EntityFlag.INTERESTED;
|
|
||||||
negativeYToggle = EntityFlag.CHARGED;
|
|
||||||
negativeZToggle = EntityFlag.POWERED;
|
|
||||||
}
|
}
|
||||||
case 17 -> { // Body
|
|
||||||
dataLeech = EntityData.VARIANT;
|
|
||||||
negativeXToggle = EntityFlag.IN_LOVE;
|
|
||||||
negativeYToggle = EntityFlag.CELEBRATING;
|
|
||||||
negativeZToggle = EntityFlag.CELEBRATING_SPECIAL;
|
|
||||||
}
|
|
||||||
case 18 -> { // Left arm
|
|
||||||
dataLeech = EntityData.TRADE_TIER;
|
|
||||||
negativeXToggle = EntityFlag.CHARGING;
|
|
||||||
negativeYToggle = EntityFlag.CRITICAL;
|
|
||||||
negativeZToggle = EntityFlag.DANCING;
|
|
||||||
}
|
|
||||||
case 19 -> { // Right arm
|
|
||||||
dataLeech = EntityData.MAX_TRADE_TIER;
|
|
||||||
negativeXToggle = EntityFlag.ELDER;
|
|
||||||
negativeYToggle = EntityFlag.EMOTING;
|
|
||||||
negativeZToggle = EntityFlag.IDLING;
|
|
||||||
}
|
|
||||||
case 20 -> { // Left leg
|
|
||||||
dataLeech = EntityData.SKIN_ID;
|
|
||||||
negativeXToggle = EntityFlag.IS_ILLAGER_CAPTAIN;
|
|
||||||
negativeYToggle = EntityFlag.IS_IN_UI;
|
|
||||||
negativeZToggle = EntityFlag.LINGERING;
|
|
||||||
}
|
|
||||||
case 21 -> { // Right leg
|
|
||||||
dataLeech = EntityData.HURT_DIRECTION;
|
|
||||||
negativeXToggle = EntityFlag.IS_PREGNANT;
|
|
||||||
negativeYToggle = EntityFlag.SHEARED;
|
|
||||||
negativeZToggle = EntityFlag.STALKING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dataLeech != null) {
|
|
||||||
// Indicate that rotation should be checked
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.BRIBED, true);
|
|
||||||
|
|
||||||
Rotation rotation = (Rotation) entityMetadata.getValue();
|
public void setHeadRotation(EntityMetadata<Rotation> entityMetadata) {
|
||||||
|
onRotationUpdate(EntityData.MARK_VARIANT, EntityFlag.INTERESTED, EntityFlag.CHARGED, EntityFlag.POWERED, entityMetadata.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBodyRotation(EntityMetadata<Rotation> entityMetadata) {
|
||||||
|
onRotationUpdate(EntityData.VARIANT, EntityFlag.IN_LOVE, EntityFlag.CELEBRATING, EntityFlag.CELEBRATING_SPECIAL, entityMetadata.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeftArmRotation(EntityMetadata<Rotation> entityMetadata) {
|
||||||
|
onRotationUpdate(EntityData.TRADE_TIER, EntityFlag.CHARGING, EntityFlag.CRITICAL, EntityFlag.DANCING, entityMetadata.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRightArmRotation(EntityMetadata<Rotation> entityMetadata) {
|
||||||
|
onRotationUpdate(EntityData.MAX_TRADE_TIER, EntityFlag.ELDER, EntityFlag.EMOTING, EntityFlag.IDLING, entityMetadata.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeftLegRotation(EntityMetadata<Rotation> entityMetadata) {
|
||||||
|
onRotationUpdate(EntityData.SKIN_ID, EntityFlag.IS_ILLAGER_CAPTAIN, EntityFlag.IS_IN_UI, EntityFlag.LINGERING, entityMetadata.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRightLegRotation(EntityMetadata<Rotation> entityMetadata) {
|
||||||
|
onRotationUpdate(EntityData.HURT_DIRECTION, EntityFlag.IS_PREGNANT, EntityFlag.SHEARED, EntityFlag.STALKING, entityMetadata.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates rotation on the armor stand by hijacking other unused Bedrock entity data/flags.
|
||||||
|
* Do note: as of recent Bedrock versions there is a custom entity data system that can be replaced with this,
|
||||||
|
* but at this time there is no need to implement this.
|
||||||
|
*
|
||||||
|
* @param dataLeech the entity data to "leech" off of that stores a compressed version of the rotation
|
||||||
|
* @param negativeXToggle the flag to set true if the X value of rotation is negative
|
||||||
|
* @param negativeYToggle the flag to set true if the Y value of rotation is negative
|
||||||
|
* @param negativeZToggle the flag to set true if the Z value of rotation is negative
|
||||||
|
* @param rotation the Java rotation value
|
||||||
|
*/
|
||||||
|
private void onRotationUpdate(EntityData dataLeech, EntityFlag negativeXToggle, EntityFlag negativeYToggle, EntityFlag negativeZToggle, Rotation rotation) {
|
||||||
|
// Indicate that rotation should be checked
|
||||||
|
setFlag(EntityFlag.BRIBED, true);
|
||||||
|
|
||||||
int rotationX = getRotation(rotation.getPitch());
|
int rotationX = getRotation(rotation.getPitch());
|
||||||
int rotationY = getRotation(rotation.getYaw());
|
int rotationY = getRotation(rotation.getYaw());
|
||||||
int rotationZ = getRotation(rotation.getRoll());
|
int rotationZ = getRotation(rotation.getRoll());
|
||||||
@ -210,24 +207,19 @@ public class ArmorStandEntity extends LivingEntity {
|
|||||||
// We don't do this for the negative values out of concerns of the number being too big
|
// We don't do this for the negative values out of concerns of the number being too big
|
||||||
int topBit = (Math.abs(rotationX) >= 100 ? 4 : 0) + (Math.abs(rotationY) >= 100 ? 2 : 0) + (Math.abs(rotationZ) >= 100 ? 1 : 0);
|
int topBit = (Math.abs(rotationX) >= 100 ? 4 : 0) + (Math.abs(rotationY) >= 100 ? 2 : 0) + (Math.abs(rotationZ) >= 100 ? 1 : 0);
|
||||||
int value = (topBit * 1000000) + ((Math.abs(rotationX) % 100) * 10000) + ((Math.abs(rotationY) % 100) * 100) + (Math.abs(rotationZ) % 100);
|
int value = (topBit * 1000000) + ((Math.abs(rotationX) % 100) * 10000) + ((Math.abs(rotationY) % 100) * 100) + (Math.abs(rotationZ) % 100);
|
||||||
metadata.put(dataLeech, value);
|
dirtyMetadata.put(dataLeech, value);
|
||||||
// Set the entity flags if a value is negative
|
// Set the entity flags if a value is negative
|
||||||
metadata.getFlags().setFlag(negativeXToggle, rotationX < 0);
|
setFlag(negativeXToggle, rotationX < 0);
|
||||||
metadata.getFlags().setFlag(negativeYToggle, rotationY < 0);
|
setFlag(negativeYToggle, rotationY < 0);
|
||||||
metadata.getFlags().setFlag(negativeZToggle, rotationZ < 0);
|
setFlag(negativeZToggle, rotationZ < 0);
|
||||||
}
|
|
||||||
}
|
|
||||||
if (secondEntity != null) {
|
|
||||||
secondEntity.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(GeyserSession session) {
|
public void updateBedrockMetadata() {
|
||||||
if (secondEntity != null) {
|
if (secondEntity != null) {
|
||||||
secondEntity.updateBedrockMetadata(session);
|
secondEntity.updateBedrockMetadata();
|
||||||
}
|
}
|
||||||
super.updateBedrockMetadata(session);
|
super.updateBedrockMetadata();
|
||||||
if (positionUpdateRequired) {
|
if (positionUpdateRequired) {
|
||||||
positionUpdateRequired = false;
|
positionUpdateRequired = false;
|
||||||
updatePosition();
|
updatePosition();
|
||||||
@ -235,7 +227,7 @@ public class ArmorStandEntity extends LivingEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setInvisible(GeyserSession session, boolean value) {
|
protected void setInvisible(boolean value) {
|
||||||
// Check if the armour stand is invisible and store accordingly
|
// Check if the armour stand is invisible and store accordingly
|
||||||
if (primaryEntity) {
|
if (primaryEntity) {
|
||||||
isInvisible = value;
|
isInvisible = value;
|
||||||
@ -289,7 +281,7 @@ public class ArmorStandEntity extends LivingEntity {
|
|||||||
if (!primaryEntity) return;
|
if (!primaryEntity) return;
|
||||||
if (!isInvisible || isMarker) {
|
if (!isInvisible || isMarker) {
|
||||||
// It is either impossible to show armor, or the armor stand isn't invisible. We good.
|
// It is either impossible to show armor, or the armor stand isn't invisible. We good.
|
||||||
metadata.getFlags().setFlag(EntityFlag.INVISIBLE, false);
|
setFlag(EntityFlag.INVISIBLE, false);
|
||||||
updateOffsetRequirement(false);
|
updateOffsetRequirement(false);
|
||||||
if (positionUpdateRequired) {
|
if (positionUpdateRequired) {
|
||||||
positionUpdateRequired = false;
|
positionUpdateRequired = false;
|
||||||
@ -297,13 +289,13 @@ public class ArmorStandEntity extends LivingEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (secondEntity != null) {
|
if (secondEntity != null) {
|
||||||
secondEntity.despawnEntity(session);
|
secondEntity.despawnEntity();
|
||||||
secondEntity = null;
|
secondEntity = null;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//boolean isNametagEmpty = metadata.getString(EntityData.NAMETAG).isEmpty() || metadata.getByte(EntityData.NAMETAG_ALWAYS_SHOW, (byte) -1) == (byte) 0; - may not be necessary?
|
//boolean isNametagEmpty = metadata.getString(EntityData.NAMETAG).isEmpty() || metadata.getByte(EntityData.NAMETAG_ALWAYS_SHOW, (byte) -1) == (byte) 0; - may not be necessary?
|
||||||
boolean isNametagEmpty = metadata.getString(EntityData.NAMETAG).isEmpty();
|
boolean isNametagEmpty = dirtyMetadata.getString(EntityData.NAMETAG).isEmpty(); // TODO
|
||||||
if (!isNametagEmpty && (!helmet.equals(ItemData.AIR) || !chestplate.equals(ItemData.AIR) || !leggings.equals(ItemData.AIR)
|
if (!isNametagEmpty && (!helmet.equals(ItemData.AIR) || !chestplate.equals(ItemData.AIR) || !leggings.equals(ItemData.AIR)
|
||||||
|| !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offHand.equals(ItemData.AIR))) {
|
|| !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offHand.equals(ItemData.AIR))) {
|
||||||
// If the second entity exists, no need to recreate it.
|
// If the second entity exists, no need to recreate it.
|
||||||
@ -312,8 +304,8 @@ public class ArmorStandEntity extends LivingEntity {
|
|||||||
|
|
||||||
// Create the second entity. It doesn't need to worry about the items, but it does need to worry about
|
// Create the second entity. It doesn't need to worry about the items, but it does need to worry about
|
||||||
// the metadata as it will hold the name tag.
|
// the metadata as it will hold the name tag.
|
||||||
secondEntity = new ArmorStandEntity(0, session.getEntityCache().getNextEntityId().incrementAndGet(),
|
secondEntity = new ArmorStandEntity(session, 0, session.getEntityCache().getNextEntityId().incrementAndGet(), null,
|
||||||
EntityType.ARMOR_STAND, position, motion, rotation);
|
EntityDefinitions.ARMOR_STAND, position, motion, yaw, pitch, headYaw);
|
||||||
secondEntity.primaryEntity = false;
|
secondEntity.primaryEntity = false;
|
||||||
if (!this.positionRequiresOffset) {
|
if (!this.positionRequiresOffset) {
|
||||||
// Ensure the offset is applied for the 0 scale
|
// Ensure the offset is applied for the 0 scale
|
||||||
@ -321,52 +313,51 @@ public class ArmorStandEntity extends LivingEntity {
|
|||||||
}
|
}
|
||||||
// Copy metadata
|
// Copy metadata
|
||||||
secondEntity.isSmall = isSmall;
|
secondEntity.isSmall = isSmall;
|
||||||
secondEntity.getMetadata().putAll(metadata);
|
secondEntity.getDirtyMetadata().putAll(dirtyMetadata); //TODO check
|
||||||
// Copy the flags so they aren't the same object in memory
|
secondEntity.flags.merge(this.flags);
|
||||||
secondEntity.getMetadata().putFlags(metadata.getFlags().copy());
|
|
||||||
// Guarantee this copy is NOT invisible
|
// Guarantee this copy is NOT invisible
|
||||||
secondEntity.getMetadata().getFlags().setFlag(EntityFlag.INVISIBLE, false);
|
secondEntity.setFlag(EntityFlag.INVISIBLE, false);
|
||||||
// Scale to 0 to show nametag
|
// Scale to 0 to show nametag
|
||||||
secondEntity.getMetadata().put(EntityData.SCALE, 0.0f);
|
secondEntity.getDirtyMetadata().put(EntityData.SCALE, 0.0f);
|
||||||
// No bounding box as we don't want to interact with this entity
|
// No bounding box as we don't want to interact with this entity
|
||||||
secondEntity.getMetadata().put(EntityData.BOUNDING_BOX_WIDTH, 0.0f);
|
secondEntity.getDirtyMetadata().put(EntityData.BOUNDING_BOX_WIDTH, 0.0f);
|
||||||
secondEntity.getMetadata().put(EntityData.BOUNDING_BOX_HEIGHT, 0.0f);
|
secondEntity.getDirtyMetadata().put(EntityData.BOUNDING_BOX_HEIGHT, 0.0f);
|
||||||
secondEntity.spawnEntity(session);
|
secondEntity.spawnEntity();
|
||||||
|
|
||||||
// Reset scale of the proper armor stand
|
// Reset scale of the proper armor stand
|
||||||
this.metadata.put(EntityData.SCALE, isSmall ? 0.55f : 1f);
|
this.dirtyMetadata.put(EntityData.SCALE, isSmall ? 0.55f : 1f);
|
||||||
// Set the proper armor stand to invisible to show armor
|
// Set the proper armor stand to invisible to show armor
|
||||||
this.metadata.getFlags().setFlag(EntityFlag.INVISIBLE, true);
|
setFlag(EntityFlag.INVISIBLE, true);
|
||||||
// Update the position of the armor stand
|
// Update the position of the armor stand
|
||||||
updateOffsetRequirement(false);
|
updateOffsetRequirement(false);
|
||||||
} else if (isNametagEmpty) {
|
} else if (isNametagEmpty) {
|
||||||
// We can just make an invisible entity
|
// We can just make an invisible entity
|
||||||
// Reset scale of the proper armor stand
|
// Reset scale of the proper armor stand
|
||||||
metadata.put(EntityData.SCALE, isSmall ? 0.55f : 1f);
|
dirtyMetadata.put(EntityData.SCALE, isSmall ? 0.55f : 1f);
|
||||||
// Set the proper armor stand to invisible to show armor
|
// Set the proper armor stand to invisible to show armor
|
||||||
metadata.getFlags().setFlag(EntityFlag.INVISIBLE, true);
|
setFlag(EntityFlag.INVISIBLE, true);
|
||||||
// Update offset
|
// Update offset
|
||||||
updateOffsetRequirement(false);
|
updateOffsetRequirement(false);
|
||||||
|
|
||||||
if (secondEntity != null) {
|
if (secondEntity != null) {
|
||||||
secondEntity.despawnEntity(session);
|
secondEntity.despawnEntity();
|
||||||
secondEntity = null;
|
secondEntity = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Nametag is not empty and there is no armor
|
// Nametag is not empty and there is no armor
|
||||||
// We don't need to make a new entity
|
// We don't need to make a new entity
|
||||||
metadata.getFlags().setFlag(EntityFlag.INVISIBLE, false);
|
setFlag(EntityFlag.INVISIBLE, false);
|
||||||
metadata.put(EntityData.SCALE, 0.0f);
|
dirtyMetadata.put(EntityData.SCALE, 0.0f);
|
||||||
// As the above is applied, we need an offset
|
// As the above is applied, we need an offset
|
||||||
updateOffsetRequirement(true);
|
updateOffsetRequirement(true);
|
||||||
|
|
||||||
if (secondEntity != null) {
|
if (secondEntity != null) {
|
||||||
secondEntity.despawnEntity(session);
|
secondEntity.despawnEntity();
|
||||||
secondEntity = null;
|
secondEntity = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sendMetadata) {
|
if (sendMetadata) {
|
||||||
this.updateBedrockMetadata(session);
|
this.updateBedrockMetadata();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,16 +376,16 @@ public class ArmorStandEntity extends LivingEntity {
|
|||||||
* If this armor stand is not a marker, set its bounding box size and scale.
|
* If this armor stand is not a marker, set its bounding box size and scale.
|
||||||
*/
|
*/
|
||||||
private void toggleSmallStatus() {
|
private void toggleSmallStatus() {
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, isSmall ? 0.25f : entityType.getWidth());
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, isSmall ? 0.25f : definition.width());
|
||||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, isSmall ? 0.9875f : entityType.getHeight());
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, isSmall ? 0.9875f : definition.height());
|
||||||
metadata.put(EntityData.SCALE, isSmall ? 0.55f : 1f);
|
dirtyMetadata.put(EntityData.SCALE, isSmall ? 0.55f : 1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the selected position with the position offset applied.
|
* @return the selected position with the position offset applied.
|
||||||
*/
|
*/
|
||||||
private Vector3f applyOffsetToPosition(Vector3f position) {
|
private Vector3f applyOffsetToPosition(Vector3f position) {
|
||||||
return position.add(0d, entityType.getHeight() * (isSmall ? 0.55d : 1d), 0d);
|
return position.add(0d, definition.height() * (isSmall ? 0.55d : 1d), 0d);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -402,14 +393,14 @@ public class ArmorStandEntity extends LivingEntity {
|
|||||||
*/
|
*/
|
||||||
private Vector3f fixOffsetForSize(Vector3f position, boolean isNowSmall) {
|
private Vector3f fixOffsetForSize(Vector3f position, boolean isNowSmall) {
|
||||||
position = removeOffsetFromPosition(position);
|
position = removeOffsetFromPosition(position);
|
||||||
return position.add(0d, entityType.getHeight() * (isNowSmall ? 0.55d : 1d), 0d);
|
return position.add(0d, definition.height() * (isNowSmall ? 0.55d : 1d), 0d);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the selected position with the position offset removed.
|
* @return the selected position with the position offset removed.
|
||||||
*/
|
*/
|
||||||
private Vector3f removeOffsetFromPosition(Vector3f position) {
|
private Vector3f removeOffsetFromPosition(Vector3f position) {
|
||||||
return position.sub(0d, entityType.getHeight() * (isSmall ? 0.55d : 1d), 0d);
|
return position.sub(0d, definition.height() * (isSmall ? 0.55d : 1d), 0d);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -434,7 +425,7 @@ public class ArmorStandEntity extends LivingEntity {
|
|||||||
MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
|
MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
|
||||||
moveEntityPacket.setRuntimeEntityId(geyserId);
|
moveEntityPacket.setRuntimeEntityId(geyserId);
|
||||||
moveEntityPacket.setPosition(position);
|
moveEntityPacket.setPosition(position);
|
||||||
moveEntityPacket.setRotation(Vector3f.from(rotation.getX(), rotation.getX(), rotation.getX()));
|
moveEntityPacket.setRotation(Vector3f.from(yaw, yaw, yaw));
|
||||||
moveEntityPacket.setOnGround(onGround);
|
moveEntityPacket.setOnGround(onGround);
|
||||||
moveEntityPacket.setTeleported(false);
|
moveEntityPacket.setTeleported(false);
|
||||||
session.sendUpstreamPacket(moveEntityPacket);
|
session.sendUpstreamPacket(moveEntityPacket);
|
||||||
|
@ -26,23 +26,22 @@
|
|||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class BatEntity extends AmbientEntity {
|
public class BatEntity extends AmbientEntity {
|
||||||
|
|
||||||
public BatEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public BatEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setBatFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 16) {
|
setFlag(EntityFlag.RESTING, (xd & 0x01) == 0x01);
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.RESTING, (xd & 0x01) == 0x01);
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,14 @@
|
|||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
public class CreatureEntity extends InsentientEntity {
|
import java.util.UUID;
|
||||||
|
|
||||||
public CreatureEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public class CreatureEntity extends MobEntity {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
|
||||||
|
public CreatureEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,14 @@
|
|||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
public class FlyingEntity extends InsentientEntity {
|
import java.util.UUID;
|
||||||
|
|
||||||
public FlyingEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public class FlyingEntity extends MobEntity {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
|
||||||
|
public FlyingEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,19 +25,14 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
public class GlowSquidEntity extends SquidEntity {
|
import java.util.UUID;
|
||||||
public GlowSquidEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public class GlowSquidEntity extends SquidEntity {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public GlowSquidEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
// TODO "dark ticks remaining" ??? does this have a Bedrock equivalent?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,14 @@
|
|||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class GolemEntity extends CreatureEntity {
|
public class GolemEntity extends CreatureEntity {
|
||||||
|
|
||||||
public GolemEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public GolemEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,15 +28,18 @@ package org.geysermc.connector.entity.living;
|
|||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class IronGolemEntity extends GolemEntity {
|
public class IronGolemEntity extends GolemEntity {
|
||||||
|
|
||||||
public IronGolemEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public IronGolemEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
// Indicate that we should show cracks through a resource pack
|
// Indicate that we should show cracks through a resource pack
|
||||||
metadata.getFlags().setFlag(EntityFlag.BRIBED, true);
|
setFlag(EntityFlag.BRIBED, true);
|
||||||
// Required, or else the overlay is black
|
// Required, or else the overlay is black
|
||||||
metadata.put(EntityData.COLOR_2, (byte) 0);
|
dirtyMetadata.put(EntityData.COLOR_2, (byte) 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,32 +27,34 @@ package org.geysermc.connector.entity.living;
|
|||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class MagmaCubeEntity extends SlimeEntity {
|
public class MagmaCubeEntity extends SlimeEntity {
|
||||||
|
|
||||||
public MagmaCubeEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public MagmaCubeEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) {
|
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, float headYaw, boolean isOnGround) {
|
||||||
updateJump(session, isOnGround);
|
updateJump(isOnGround);
|
||||||
super.moveRelative(session, relX, relY, relZ, rotation, isOnGround);
|
super.moveRelative(relX, relY, relZ, yaw, pitch, headYaw, isOnGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
|
||||||
updateJump(session, isOnGround);
|
updateJump(isOnGround);
|
||||||
super.moveAbsolute(session, position, rotation, isOnGround, teleported);
|
super.moveAbsolute(position, yaw, pitch, headYaw, isOnGround, teleported);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateJump(GeyserSession session, boolean newOnGround) {
|
public void updateJump(boolean newOnGround) {
|
||||||
if (newOnGround != onGround) {
|
if (newOnGround != onGround) {
|
||||||
// Add the jumping effect to the magma cube
|
// Add the jumping effect to the magma cube
|
||||||
metadata.put(EntityData.CLIENT_EVENT, (byte) (newOnGround ? 1 : 2));
|
dirtyMetadata.put(EntityData.CLIENT_EVENT, (byte) (newOnGround ? 1 : 2));
|
||||||
updateBedrockMetadata(session);
|
updateBedrockMetadata();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
|
import org.geysermc.connector.entity.LivingEntity;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MobEntity extends LivingEntity {
|
||||||
|
/**
|
||||||
|
* If another mob is holding this mob by a leash, this variable tracks their Bedrock entity ID.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private long leashHolderBedrockId;
|
||||||
|
|
||||||
|
public MobEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initializeMetadata() {
|
||||||
|
super.initializeMetadata();
|
||||||
|
setLeashHolderBedrockId(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMobFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
setFlag(EntityFlag.NO_AI, (xd & 0x01) == 0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeashHolderBedrockId(long bedrockId) {
|
||||||
|
this.leashHolderBedrockId = bedrockId;
|
||||||
|
dirtyMetadata.put(EntityData.LEASH_HOLDER_EID, bedrockId);
|
||||||
|
}
|
||||||
|
}
|
@ -26,22 +26,21 @@
|
|||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
public class SlimeEntity extends InsentientEntity {
|
import java.util.UUID;
|
||||||
|
|
||||||
public SlimeEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public class SlimeEntity extends MobEntity {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
|
||||||
|
public SlimeEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setScale(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
dirtyMetadata.put(EntityData.SCALE, 0.10f + ((IntEntityMetadata) entityMetadata).getPrimitiveValue());
|
||||||
if (entityMetadata.getId() == 16) {
|
|
||||||
this.metadata.put(EntityData.SCALE, 0.10f + (int) entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,24 +26,23 @@
|
|||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class SnowGolemEntity extends GolemEntity {
|
public class SnowGolemEntity extends GolemEntity {
|
||||||
|
|
||||||
public SnowGolemEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public SnowGolemEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setSnowGolemFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 16) {
|
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
|
||||||
// Handle the visibility of the pumpkin
|
// Handle the visibility of the pumpkin
|
||||||
metadata.getFlags().setFlag(EntityFlag.SHEARED, (xd & 0x10) != 0x10);
|
setFlag(EntityFlag.SHEARED, (xd & 0x10) != 0x10);
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,28 +28,25 @@ package org.geysermc.connector.entity.living;
|
|||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import com.nukkitx.protocol.bedrock.packet.MoveEntityDeltaPacket;
|
import com.nukkitx.protocol.bedrock.packet.MoveEntityDeltaPacket;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.Tickable;
|
import org.geysermc.connector.entity.Tickable;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class SquidEntity extends WaterEntity implements Tickable {
|
public class SquidEntity extends WaterEntity implements Tickable {
|
||||||
|
|
||||||
private float pitch;
|
|
||||||
private float yaw;
|
|
||||||
|
|
||||||
private float targetPitch;
|
private float targetPitch;
|
||||||
private float targetYaw;
|
private float targetYaw;
|
||||||
|
|
||||||
private boolean inWater;
|
private boolean inWater;
|
||||||
|
|
||||||
public SquidEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public SquidEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
this.yaw = rotation.getX();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(GeyserSession session) {
|
public void tick() {
|
||||||
boolean pitchChanged;
|
boolean pitchChanged;
|
||||||
boolean yawChanged;
|
boolean yawChanged;
|
||||||
float oldPitch = pitch;
|
float oldPitch = pitch;
|
||||||
@ -82,25 +79,33 @@ public class SquidEntity extends WaterEntity implements Tickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) {
|
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, float headYaw, boolean isOnGround) {
|
||||||
super.moveRelative(session, relX, relY, relZ, rotation, isOnGround);
|
super.moveRelative(relX, relY, relZ, yaw, pitch, headYaw, isOnGround);
|
||||||
checkInWater(session);
|
checkInWater();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
|
||||||
super.moveAbsolute(session, position, rotation, isOnGround, teleported);
|
super.moveAbsolute(position, yaw, pitch, headYaw, isOnGround, teleported);
|
||||||
checkInWater(session);
|
checkInWater();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setRotation(Vector3f rotation) {
|
public void setYaw(float yaw) {
|
||||||
// Let the Java server control yaw when the squid is out of water
|
// Let the Java server control yaw when the squid is out of water
|
||||||
if (!inWater) {
|
if (!inWater) {
|
||||||
yaw = rotation.getX();
|
this.yaw = yaw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPitch(float pitch) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeadYaw(float headYaw) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMotion(Vector3f motion) {
|
public void setMotion(Vector3f motion) {
|
||||||
super.setMotion(motion);
|
super.setMotion(motion);
|
||||||
@ -115,8 +120,8 @@ public class SquidEntity extends WaterEntity implements Tickable {
|
|||||||
return Vector3f.from(pitch, yaw, yaw);
|
return Vector3f.from(pitch, yaw, yaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkInWater(GeyserSession session) {
|
private void checkInWater() {
|
||||||
if (getMetadata().getFlags().getFlag(EntityFlag.RIDING)) {
|
if (getFlag(EntityFlag.RIDING)) {
|
||||||
inWater = false;
|
inWater = false;
|
||||||
} else {
|
} else {
|
||||||
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
||||||
|
@ -26,11 +26,14 @@
|
|||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class WaterEntity extends CreatureEntity {
|
public class WaterEntity extends CreatureEntity {
|
||||||
|
|
||||||
public WaterEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public WaterEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,17 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.living.AgeableEntity;
|
import org.geysermc.connector.entity.living.AgeableEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class AnimalEntity extends AgeableEntity {
|
public class AnimalEntity extends AgeableEntity {
|
||||||
|
|
||||||
public AnimalEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public AnimalEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,32 +26,33 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class AxolotlEntity extends AnimalEntity {
|
public class AxolotlEntity extends AnimalEntity {
|
||||||
public AxolotlEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public AxolotlEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setVariant(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
int variant = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
if (entityMetadata.getId() == 17) {
|
|
||||||
int variant = (int) entityMetadata.getValue();
|
|
||||||
switch (variant) {
|
switch (variant) {
|
||||||
case 1 -> variant = 3; // Java - "Wild" (brown)
|
case 1 -> variant = 3; // Java - "Wild" (brown)
|
||||||
case 3 -> variant = 1; // Java - cyan
|
case 3 -> variant = 1; // Java - cyan
|
||||||
}
|
}
|
||||||
metadata.put(EntityData.VARIANT, variant);
|
dirtyMetadata.put(EntityData.VARIANT, variant);
|
||||||
}
|
|
||||||
else if (entityMetadata.getId() == 18) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.PLAYING_DEAD, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPlayingDead(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
setFlag(EntityFlag.PLAYING_DEAD, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,25 +26,27 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
|
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class BeeEntity extends AnimalEntity {
|
public class BeeEntity extends AnimalEntity {
|
||||||
|
|
||||||
public BeeEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public BeeEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setBeeFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 17) {
|
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
|
||||||
// Bee is performing sting attack; trigger animation
|
// Bee is performing sting attack; trigger animation
|
||||||
if ((xd & 0x02) == 0x02) {
|
if ((xd & 0x02) == 0x02) {
|
||||||
EntityEventPacket packet = new EntityEventPacket();
|
EntityEventPacket packet = new EntityEventPacket();
|
||||||
@ -54,15 +56,14 @@ public class BeeEntity extends AnimalEntity {
|
|||||||
session.sendUpstreamPacket(packet);
|
session.sendUpstreamPacket(packet);
|
||||||
}
|
}
|
||||||
// If the bee has stung
|
// If the bee has stung
|
||||||
metadata.put(EntityData.MARK_VARIANT, (xd & 0x04) == 0x04 ? 1 : 0);
|
dirtyMetadata.put(EntityData.MARK_VARIANT, (xd & 0x04) == 0x04 ? 1 : 0);
|
||||||
// If the bee has nectar or not
|
// If the bee has nectar or not
|
||||||
metadata.getFlags().setFlag(EntityFlag.POWERED, (xd & 0x08) == 0x08);
|
setFlag(EntityFlag.POWERED, (xd & 0x08) == 0x08);
|
||||||
}
|
}
|
||||||
if (entityMetadata.getId() == 18) {
|
|
||||||
|
public void setAngerTime(EntityMetadata<Integer> entityMetadata) {
|
||||||
// Converting "anger time" to a boolean
|
// Converting "anger time" to a boolean
|
||||||
metadata.getFlags().setFlag(EntityFlag.ANGRY, (int) entityMetadata.getValue() > 0);
|
setFlag(EntityFlag.ANGRY, ((IntEntityMetadata) entityMetadata).getPrimitiveValue() > 0);
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,14 +26,16 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ChickenEntity extends AnimalEntity {
|
public class ChickenEntity extends AnimalEntity {
|
||||||
|
|
||||||
public ChickenEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ChickenEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,32 +26,32 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class FoxEntity extends AnimalEntity {
|
public class FoxEntity extends AnimalEntity {
|
||||||
|
|
||||||
public FoxEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public FoxEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setFoxVariant(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
dirtyMetadata.put(EntityData.VARIANT, entityMetadata.getValue());
|
||||||
if (entityMetadata.getId() == 17) {
|
|
||||||
metadata.put(EntityData.VARIANT, entityMetadata.getValue());
|
|
||||||
}
|
}
|
||||||
if (entityMetadata.getId() == 18) {
|
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
public void setFoxFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
metadata.getFlags().setFlag(EntityFlag.SITTING, (xd & 0x01) == 0x01);
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
metadata.getFlags().setFlag(EntityFlag.SNEAKING, (xd & 0x04) == 0x04);
|
setFlag(EntityFlag.SITTING, (xd & 0x01) == 0x01);
|
||||||
metadata.getFlags().setFlag(EntityFlag.INTERESTED, (xd & 0x08) == 0x08);
|
setFlag(EntityFlag.SNEAKING, (xd & 0x04) == 0x04);
|
||||||
metadata.getFlags().setFlag(EntityFlag.SLEEPING, (xd & 0x20) == 0x20);
|
setFlag(EntityFlag.INTERESTED, (xd & 0x08) == 0x08);
|
||||||
}
|
setFlag(EntityFlag.SLEEPING, (xd & 0x20) == 0x20);
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,12 +27,15 @@ package org.geysermc.connector.entity.living.animal;
|
|||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class GoatEntity extends AnimalEntity {
|
public class GoatEntity extends AnimalEntity {
|
||||||
private static final float LONG_JUMPING_HEIGHT = 1.3f * 0.7f;
|
private static final float LONG_JUMPING_HEIGHT = 1.3f * 0.7f;
|
||||||
private static final float LONG_JUMPING_WIDTH = 0.9f * 0.7f;
|
private static final float LONG_JUMPING_WIDTH = 0.9f * 0.7f;
|
||||||
@ -40,24 +43,20 @@ public class GoatEntity extends AnimalEntity {
|
|||||||
@Getter
|
@Getter
|
||||||
private boolean isScreamer;
|
private boolean isScreamer;
|
||||||
|
|
||||||
public GoatEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public GoatEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setScreamer(EntityMetadata<Boolean> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
// Metadata not used in Bedrock Edition
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
isScreamer = ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 17) {
|
|
||||||
// Not used in Bedrock Edition
|
|
||||||
isScreamer = (boolean) entityMetadata.getValue();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setDimensions(Pose pose) {
|
protected void setDimensions(Pose pose) {
|
||||||
if (pose == Pose.LONG_JUMPING) {
|
if (pose == Pose.LONG_JUMPING) {
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, LONG_JUMPING_WIDTH);
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, LONG_JUMPING_WIDTH);
|
||||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, LONG_JUMPING_HEIGHT);
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, LONG_JUMPING_HEIGHT);
|
||||||
} else {
|
} else {
|
||||||
super.setDimensions(pose);
|
super.setDimensions(pose);
|
||||||
}
|
}
|
||||||
|
@ -26,34 +26,32 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
import org.geysermc.connector.utils.DimensionUtils;
|
import org.geysermc.connector.utils.DimensionUtils;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class HoglinEntity extends AnimalEntity {
|
public class HoglinEntity extends AnimalEntity {
|
||||||
private boolean isImmuneToZombification;
|
private boolean isImmuneToZombification;
|
||||||
|
|
||||||
public HoglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public HoglinEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setImmuneToZombification(EntityMetadata<Boolean> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
|
||||||
if (entityMetadata.getId() == 17) {
|
|
||||||
// Immune to zombification?
|
|
||||||
// Apply shaking effect if not in the nether and zombification is possible
|
// Apply shaking effect if not in the nether and zombification is possible
|
||||||
this.isImmuneToZombification = (boolean) entityMetadata.getValue();
|
this.isImmuneToZombification = ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
metadata.getFlags().setFlag(EntityFlag.SHAKING, isShaking(session));
|
setFlag(EntityFlag.SHAKING, isShaking());
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isShaking(GeyserSession session) {
|
protected boolean isShaking() {
|
||||||
return (!isImmuneToZombification && !session.getDimension().equals(DimensionUtils.NETHER)) || super.isShaking(session);
|
return (!isImmuneToZombification && !session.getDimension().equals(DimensionUtils.NETHER)) || super.isShaking();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,23 +25,15 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class MooshroomEntity extends AnimalEntity {
|
public class MooshroomEntity extends AnimalEntity {
|
||||||
|
|
||||||
public MooshroomEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public MooshroomEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
|
||||||
if (entityMetadata.getId() == 17) {
|
|
||||||
metadata.put(EntityData.VARIANT, entityMetadata.getValue().equals("brown") ? 1 : 0);
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,25 +25,17 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class OcelotEntity extends AnimalEntity {
|
public class OcelotEntity extends AnimalEntity {
|
||||||
|
|
||||||
public OcelotEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public OcelotEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
|
||||||
if (entityMetadata.getId() == 17) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.TRUSTING, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,30 +26,32 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
|
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
public class PandaEntity extends AnimalEntity {
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PandaEntity extends AnimalEntity {
|
||||||
private int mainGene;
|
private int mainGene;
|
||||||
private int hiddenGene;
|
private int hiddenGene;
|
||||||
|
|
||||||
public PandaEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public PandaEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setEatingCounter(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
int count = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 19) {
|
setFlag(EntityFlag.EATING, count > 0);
|
||||||
metadata.getFlags().setFlag(EntityFlag.EATING, (int) entityMetadata.getValue() > 0);
|
dirtyMetadata.put(EntityData.EATING_COUNTER, count);
|
||||||
metadata.put(EntityData.EATING_COUNTER, entityMetadata.getValue());
|
if (count != 0) {
|
||||||
if ((int) entityMetadata.getValue() != 0) {
|
|
||||||
// Particles and sound
|
// Particles and sound
|
||||||
EntityEventPacket packet = new EntityEventPacket();
|
EntityEventPacket packet = new EntityEventPacket();
|
||||||
packet.setRuntimeEntityId(geyserId);
|
packet.setRuntimeEntityId(geyserId);
|
||||||
@ -58,25 +60,26 @@ public class PandaEntity extends AnimalEntity {
|
|||||||
session.sendUpstreamPacket(packet);
|
session.sendUpstreamPacket(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (entityMetadata.getId() == 20) {
|
|
||||||
mainGene = (int) (byte) entityMetadata.getValue();
|
public void setMainGene(EntityMetadata<Byte> entityMetadata) {
|
||||||
|
mainGene = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
updateAppearance();
|
updateAppearance();
|
||||||
}
|
}
|
||||||
if (entityMetadata.getId() == 21) {
|
|
||||||
hiddenGene = (int) (byte) entityMetadata.getValue();
|
public void setHiddenGene(EntityMetadata<Byte> entityMetadata) {
|
||||||
|
hiddenGene = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
updateAppearance();
|
updateAppearance();
|
||||||
}
|
}
|
||||||
if (entityMetadata.getId() == 22) {
|
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
public void setPandaFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
metadata.getFlags().setFlag(EntityFlag.SNEEZING, (xd & 0x02) == 0x02);
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
metadata.getFlags().setFlag(EntityFlag.ROLLING, (xd & 0x04) == 0x04);
|
setFlag(EntityFlag.SNEEZING, (xd & 0x02) == 0x02);
|
||||||
metadata.getFlags().setFlag(EntityFlag.SITTING, (xd & 0x08) == 0x08);
|
setFlag(EntityFlag.ROLLING, (xd & 0x04) == 0x04);
|
||||||
|
setFlag(EntityFlag.SITTING, (xd & 0x08) == 0x08);
|
||||||
// Required to put these both for sitting to actually show
|
// Required to put these both for sitting to actually show
|
||||||
metadata.put(EntityData.SITTING_AMOUNT, (xd & 0x08) == 0x08 ? 1f : 0f);
|
dirtyMetadata.put(EntityData.SITTING_AMOUNT, (xd & 0x08) == 0x08 ? 1f : 0f);
|
||||||
metadata.put(EntityData.SITTING_AMOUNT_PREVIOUS, (xd & 0x08) == 0x08 ? 1f : 0f);
|
dirtyMetadata.put(EntityData.SITTING_AMOUNT_PREVIOUS, (xd & 0x08) == 0x08 ? 1f : 0f);
|
||||||
metadata.getFlags().setFlag(EntityFlag.LAYING_DOWN, (xd & 0x10) == 0x10);
|
setFlag(EntityFlag.LAYING_DOWN, (xd & 0x10) == 0x10);
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -93,14 +96,14 @@ public class PandaEntity extends AnimalEntity {
|
|||||||
// Main gene is a recessive trait
|
// Main gene is a recessive trait
|
||||||
if (mainGene == hiddenGene) {
|
if (mainGene == hiddenGene) {
|
||||||
// Main and hidden genes match; this is what the panda looks like.
|
// Main and hidden genes match; this is what the panda looks like.
|
||||||
metadata.put(EntityData.VARIANT, mainGene);
|
dirtyMetadata.put(EntityData.VARIANT, mainGene);
|
||||||
} else {
|
} else {
|
||||||
// Genes have no effect on appearance
|
// Genes have no effect on appearance
|
||||||
metadata.put(EntityData.VARIANT, 0);
|
dirtyMetadata.put(EntityData.VARIANT, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No need to worry about hidden gene
|
// No need to worry about hidden gene
|
||||||
metadata.put(EntityData.VARIANT, mainGene);
|
dirtyMetadata.put(EntityData.VARIANT, mainGene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,25 +25,17 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PigEntity extends AnimalEntity {
|
public class PigEntity extends AnimalEntity {
|
||||||
|
|
||||||
public PigEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public PigEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
|
||||||
if (entityMetadata.getId() == 17) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,25 +25,17 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PolarBearEntity extends AnimalEntity {
|
public class PolarBearEntity extends AnimalEntity {
|
||||||
|
|
||||||
public PolarBearEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public PolarBearEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
|
||||||
if (entityMetadata.getId() == 17) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.STANDING, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,25 +26,24 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.living.AbstractFishEntity;
|
import org.geysermc.connector.entity.living.AbstractFishEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PufferFishEntity extends AbstractFishEntity {
|
public class PufferFishEntity extends AbstractFishEntity {
|
||||||
|
|
||||||
public PufferFishEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public PufferFishEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setPufferfishSize(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
int puffsize = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 17) {
|
dirtyMetadata.put(EntityData.PUFFERFISH_SIZE, (byte) puffsize);
|
||||||
int puffsize = (int) entityMetadata.getValue();
|
dirtyMetadata.put(EntityData.VARIANT, puffsize);
|
||||||
metadata.put(EntityData.PUFFERFISH_SIZE, (byte) puffsize);
|
|
||||||
metadata.put(EntityData.VARIANT, puffsize);
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,31 +26,29 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class RabbitEntity extends AnimalEntity {
|
public class RabbitEntity extends AnimalEntity {
|
||||||
|
|
||||||
public RabbitEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public RabbitEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void setBaby(EntityMetadata<Boolean> entityMetadata) {
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
super.setBaby(entityMetadata);
|
||||||
if (entityMetadata.getId() == 16) {
|
|
||||||
metadata.put(EntityData.SCALE, .55f);
|
|
||||||
boolean isBaby = (boolean) entityMetadata.getValue();
|
|
||||||
if (isBaby) {
|
|
||||||
metadata.put(EntityData.SCALE, .35f);
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.BABY, true);
|
|
||||||
}
|
}
|
||||||
} else if (entityMetadata.getId() == 17) {
|
|
||||||
int variant = (int) entityMetadata.getValue();
|
public void setRabbitVariant(EntityMetadata<Integer> entityMetadata) {
|
||||||
|
int variant = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
|
||||||
// Change the killer bunny to display as white since it only exists on Java Edition
|
// Change the killer bunny to display as white since it only exists on Java Edition
|
||||||
boolean isKillerBunny = variant == 99;
|
boolean isKillerBunny = variant == 99;
|
||||||
@ -58,10 +56,19 @@ public class RabbitEntity extends AnimalEntity {
|
|||||||
variant = 1;
|
variant = 1;
|
||||||
}
|
}
|
||||||
// Allow the resource pack to adjust to the killer bunny
|
// Allow the resource pack to adjust to the killer bunny
|
||||||
metadata.getFlags().setFlag(EntityFlag.BRIBED, isKillerBunny);
|
setFlag(EntityFlag.BRIBED, isKillerBunny);
|
||||||
|
|
||||||
metadata.put(EntityData.VARIANT, variant);
|
dirtyMetadata.put(EntityData.VARIANT, variant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getAdultSize() {
|
||||||
|
return 0.55f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getBabySize() {
|
||||||
|
return 0.35f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,26 +26,24 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class SheepEntity extends AnimalEntity {
|
public class SheepEntity extends AnimalEntity {
|
||||||
|
|
||||||
public SheepEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public SheepEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setSheepFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 17) {
|
setFlag(EntityFlag.SHEARED, (xd & 0x10) == 0x10);
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
dirtyMetadata.put(EntityData.COLOR, xd);
|
||||||
metadata.getFlags().setFlag(EntityFlag.SHEARED, (xd & 0x10) == 0x10);
|
|
||||||
metadata.put(EntityData.COLOR, xd);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -26,70 +26,70 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.Entity;
|
import org.geysermc.connector.entity.Entity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class StriderEntity extends AnimalEntity {
|
public class StriderEntity extends AnimalEntity {
|
||||||
|
|
||||||
private boolean isCold = false;
|
private boolean isCold = false;
|
||||||
|
|
||||||
public StriderEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public StriderEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true);
|
setFlag(EntityFlag.FIRE_IMMUNE, true);
|
||||||
metadata.getFlags().setFlag(EntityFlag.BREATHING, true);
|
setFlag(EntityFlag.BREATHING, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCold(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
isCold = ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSaddled(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
setFlag(EntityFlag.SADDLED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void updateBedrockMetadata() {
|
||||||
if (entityMetadata.getId() == 18) {
|
|
||||||
isCold = (boolean) entityMetadata.getValue();
|
|
||||||
}
|
|
||||||
if (entityMetadata.getId() == 19) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBedrockMetadata(GeyserSession session) {
|
|
||||||
// Make sure they are not shaking when riding another entity
|
// Make sure they are not shaking when riding another entity
|
||||||
// Needs to copy the parent state
|
// Needs to copy the parent state
|
||||||
if (metadata.getFlags().getFlag(EntityFlag.RIDING)) {
|
if (getFlag(EntityFlag.RIDING)) {
|
||||||
boolean parentShaking = false;
|
boolean parentShaking = false;
|
||||||
|
//TODO optimize
|
||||||
for (Entity ent : session.getEntityCache().getEntities().values()) {
|
for (Entity ent : session.getEntityCache().getEntities().values()) {
|
||||||
if (ent.getPassengers().contains(entityId) && ent instanceof StriderEntity) {
|
if (ent.getPassengers().contains(entityId) && ent instanceof StriderEntity) {
|
||||||
parentShaking = ent.getMetadata().getFlags().getFlag(EntityFlag.SHAKING);
|
parentShaking = ent.getFlag(EntityFlag.SHAKING);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.BREATHING, !parentShaking);
|
setFlag(EntityFlag.BREATHING, !parentShaking);
|
||||||
metadata.getFlags().setFlag(EntityFlag.SHAKING, parentShaking);
|
setFlag(EntityFlag.SHAKING, parentShaking);
|
||||||
} else {
|
} else {
|
||||||
metadata.getFlags().setFlag(EntityFlag.BREATHING, !isCold);
|
setFlag(EntityFlag.BREATHING, !isCold);
|
||||||
metadata.getFlags().setFlag(EntityFlag.SHAKING, isShaking(session));
|
setFlag(EntityFlag.SHAKING, isShaking());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the passengers if we have any
|
// Update the passengers if we have any
|
||||||
for (long passenger : passengers) {
|
for (long passenger : passengers) {
|
||||||
Entity passengerEntity = session.getEntityCache().getEntityByJavaId(passenger);
|
Entity passengerEntity = session.getEntityCache().getEntityByJavaId(passenger);
|
||||||
if (passengerEntity != null) {
|
if (passengerEntity != null) {
|
||||||
passengerEntity.updateBedrockMetadata(session);
|
passengerEntity.updateBedrockMetadata();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateBedrockMetadata(session);
|
super.updateBedrockMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isShaking(GeyserSession session) {
|
protected boolean isShaking() {
|
||||||
return isCold || super.isShaking(session);
|
return isCold || super.isShaking();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,15 +26,17 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.living.AbstractFishEntity;
|
import org.geysermc.connector.entity.living.AbstractFishEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class TropicalFishEntity extends AbstractFishEntity {
|
public class TropicalFishEntity extends AbstractFishEntity {
|
||||||
|
|
||||||
@ -47,21 +49,17 @@ public class TropicalFishEntity extends AbstractFishEntity {
|
|||||||
private static final List<String> VARIANT_NAMES = ImmutableList.of("kob", "sunstreak", "snooper", "dasher", "brinely", "spotty", "flopper", "stripey", "glitter", "blockfish", "betty", "clayfish");
|
private static final List<String> VARIANT_NAMES = ImmutableList.of("kob", "sunstreak", "snooper", "dasher", "brinely", "spotty", "flopper", "stripey", "glitter", "blockfish", "betty", "clayfish");
|
||||||
private static final List<String> COLOR_NAMES = ImmutableList.of("white", "orange", "magenta", "light_blue", "yellow", "lime", "pink", "gray", "light_gray", "cyan", "purple", "blue", "brown", "green", "red", "black");
|
private static final List<String> COLOR_NAMES = ImmutableList.of("white", "orange", "magenta", "light_blue", "yellow", "lime", "pink", "gray", "light_gray", "cyan", "purple", "blue", "brown", "green", "red", "black");
|
||||||
|
|
||||||
public TropicalFishEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public TropicalFishEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setFishVariant(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
int varNumber = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 17) {
|
|
||||||
int varNumber = (int) entityMetadata.getValue();
|
|
||||||
|
|
||||||
metadata.put(EntityData.VARIANT, getShape(varNumber)); // Shape 0-1
|
dirtyMetadata.put(EntityData.VARIANT, getShape(varNumber)); // Shape 0-1
|
||||||
metadata.put(EntityData.MARK_VARIANT, getPattern(varNumber)); // Pattern 0-5
|
dirtyMetadata.put(EntityData.MARK_VARIANT, getPattern(varNumber)); // Pattern 0-5
|
||||||
metadata.put(EntityData.COLOR, getBaseColor(varNumber)); // Base color 0-15
|
dirtyMetadata.put(EntityData.COLOR, getBaseColor(varNumber)); // Base color 0-15
|
||||||
metadata.put(EntityData.COLOR_2, getPatternColor(varNumber)); // Pattern color 0-15
|
dirtyMetadata.put(EntityData.COLOR_2, getPatternColor(varNumber)); // Pattern color 0-15
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getShape(int variant) {
|
public static int getShape(int variant) {
|
||||||
|
@ -26,26 +26,27 @@
|
|||||||
package org.geysermc.connector.entity.living.animal;
|
package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class TurtleEntity extends AnimalEntity {
|
public class TurtleEntity extends AnimalEntity {
|
||||||
|
|
||||||
public TurtleEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public TurtleEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setPregnant(EntityMetadata<Boolean> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
setFlag(EntityFlag.IS_PREGNANT, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue());
|
||||||
if (entityMetadata.getId() == 18) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.IS_PREGNANT, (boolean) entityMetadata.getValue());
|
|
||||||
} else if (entityMetadata.getId() == 19) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.LAYING_EGG, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
}
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
|
public void setLayingEgg(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
setFlag(EntityFlag.LAYING_EGG, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
package org.geysermc.connector.entity.living.animal.horse;
|
package org.geysermc.connector.entity.living.animal.horse;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
@ -34,13 +35,14 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
|||||||
import com.nukkitx.protocol.bedrock.data.inventory.ContainerType;
|
import com.nukkitx.protocol.bedrock.data.inventory.ContainerType;
|
||||||
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
|
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket;
|
import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.attribute.GeyserAttributeType;
|
import org.geysermc.connector.entity.attribute.GeyserAttributeType;
|
||||||
import org.geysermc.connector.entity.living.animal.AnimalEntity;
|
import org.geysermc.connector.entity.living.animal.AnimalEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class AbstractHorseEntity extends AnimalEntity {
|
public class AbstractHorseEntity extends AnimalEntity {
|
||||||
/**
|
/**
|
||||||
@ -50,18 +52,22 @@ public class AbstractHorseEntity extends AnimalEntity {
|
|||||||
private static final Set<String> DONKEY_AND_HORSE_FOODS = ImmutableSet.of("golden_apple", "enchanted_golden_apple",
|
private static final Set<String> DONKEY_AND_HORSE_FOODS = ImmutableSet.of("golden_apple", "enchanted_golden_apple",
|
||||||
"golden_carrot", "sugar", "apple", "wheat", "hay_block");
|
"golden_carrot", "sugar", "apple", "wheat", "hay_block");
|
||||||
|
|
||||||
public AbstractHorseEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public AbstractHorseEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
// Specifies the size of the entity's inventory. Required to place slots in the entity.
|
// Specifies the size of the entity's inventory. Required to place slots in the entity.
|
||||||
metadata.put(EntityData.CONTAINER_BASE_SIZE, 2);
|
dirtyMetadata.put(EntityData.CONTAINER_BASE_SIZE, getContainerBaseSize());
|
||||||
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.WASD_CONTROLLED, true);
|
setFlag(EntityFlag.WASD_CONTROLLED, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getContainerBaseSize() {
|
||||||
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnEntity(GeyserSession session) {
|
public void spawnEntity() {
|
||||||
super.spawnEntity(session);
|
super.spawnEntity();
|
||||||
|
|
||||||
// Add horse jump strength attribute to allow donkeys and mules to jump, if they don't send the attribute themselves.
|
// Add horse jump strength attribute to allow donkeys and mules to jump, if they don't send the attribute themselves.
|
||||||
// Confirmed broken without this code by making a new donkey in vanilla 1.17.1
|
// Confirmed broken without this code by making a new donkey in vanilla 1.17.1
|
||||||
@ -73,16 +79,14 @@ public class AbstractHorseEntity extends AnimalEntity {
|
|||||||
session.sendUpstreamPacket(attributesPacket);
|
session.sendUpstreamPacket(attributesPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setHorseFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 17) {
|
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
|
||||||
boolean tamed = (xd & 0x02) == 0x02;
|
boolean tamed = (xd & 0x02) == 0x02;
|
||||||
boolean saddled = (xd & 0x04) == 0x04;
|
boolean saddled = (xd & 0x04) == 0x04;
|
||||||
metadata.getFlags().setFlag(EntityFlag.TAMED, tamed);
|
setFlag(EntityFlag.TAMED, tamed);
|
||||||
metadata.getFlags().setFlag(EntityFlag.SADDLED, saddled);
|
setFlag(EntityFlag.SADDLED, saddled);
|
||||||
metadata.getFlags().setFlag(EntityFlag.EATING, (xd & 0x10) == 0x10);
|
setFlag(EntityFlag.EATING, (xd & 0x10) == 0x10);
|
||||||
metadata.getFlags().setFlag(EntityFlag.STANDING, (xd & 0x20) == 0x20);
|
setFlag(EntityFlag.STANDING, (xd & 0x20) == 0x20);
|
||||||
|
|
||||||
// HorseFlags
|
// HorseFlags
|
||||||
// Bred 0x10
|
// Bred 0x10
|
||||||
@ -95,7 +99,7 @@ public class AbstractHorseEntity extends AnimalEntity {
|
|||||||
horseFlags = (xd & 0x10) == 0x10 && (xd & 0x40) != 0x40 ? horseFlags | 0x20 : horseFlags;
|
horseFlags = (xd & 0x10) == 0x10 && (xd & 0x40) != 0x40 ? horseFlags | 0x20 : horseFlags;
|
||||||
|
|
||||||
// Set the flags into the display item
|
// Set the flags into the display item
|
||||||
metadata.put(EntityData.DISPLAY_ITEM, horseFlags);
|
dirtyMetadata.put(EntityData.DISPLAY_ITEM, horseFlags);
|
||||||
|
|
||||||
// Send the eating particles
|
// Send the eating particles
|
||||||
// We use the wheat metadata as static particles since Java
|
// We use the wheat metadata as static particles since Java
|
||||||
@ -109,13 +113,10 @@ public class AbstractHorseEntity extends AnimalEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set container type if tamed
|
// Set container type if tamed
|
||||||
metadata.put(EntityData.CONTAINER_TYPE, tamed ? (byte) ContainerType.HORSE.getId() : (byte) 0);
|
dirtyMetadata.put(EntityData.CONTAINER_TYPE, tamed ? (byte) ContainerType.HORSE.getId() : (byte) 0);
|
||||||
|
|
||||||
// Shows the jump meter
|
// Shows the jump meter
|
||||||
metadata.getFlags().setFlag(EntityFlag.CAN_POWER_JUMP, saddled);
|
setFlag(EntityFlag.CAN_POWER_JUMP, saddled);
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,26 +25,20 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.entity.living.animal.horse;
|
package org.geysermc.connector.entity.living.animal.horse;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ChestedHorseEntity extends AbstractHorseEntity {
|
public class ChestedHorseEntity extends AbstractHorseEntity {
|
||||||
|
|
||||||
public ChestedHorseEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ChestedHorseEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
metadata.put(EntityData.CONTAINER_BASE_SIZE, 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
protected int getContainerBaseSize() {
|
||||||
if (entityMetadata.getId() == 19) {
|
return 16;
|
||||||
metadata.getFlags().setFlag(EntityFlag.CHESTED, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,24 +26,23 @@
|
|||||||
package org.geysermc.connector.entity.living.animal.horse;
|
package org.geysermc.connector.entity.living.animal.horse;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class HorseEntity extends AbstractHorseEntity {
|
public class HorseEntity extends AbstractHorseEntity {
|
||||||
|
|
||||||
public HorseEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public HorseEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setHorseVariant(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
int value = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 19) {
|
dirtyMetadata.put(EntityData.VARIANT, value & 255);
|
||||||
metadata.put(EntityData.VARIANT, ((int) entityMetadata.getValue()) & 255);
|
dirtyMetadata.put(EntityData.MARK_VARIANT, (value >> 8) % 5);
|
||||||
metadata.put(EntityData.MARK_VARIANT, (((int) entityMetadata.getValue()) >> 8) % 5);
|
|
||||||
}
|
}
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -26,35 +26,34 @@
|
|||||||
package org.geysermc.connector.entity.living.animal.horse;
|
package org.geysermc.connector.entity.living.animal.horse;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket;
|
import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class LlamaEntity extends ChestedHorseEntity {
|
public class LlamaEntity extends ChestedHorseEntity {
|
||||||
|
|
||||||
public LlamaEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public LlamaEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
metadata.put(EntityData.CONTAINER_STRENGTH_MODIFIER, 3); // Presumably 3 slots for every 1 strength
|
dirtyMetadata.put(EntityData.CONTAINER_STRENGTH_MODIFIER, 3); // Presumably 3 slots for every 1 strength
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
* Color equipped on the llama
|
||||||
// Strength
|
*/
|
||||||
if (entityMetadata.getId() == 20) {
|
public void setCarpetedColor(EntityMetadata<Integer> entityMetadata) {
|
||||||
metadata.put(EntityData.STRENGTH, entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
// Color equipped on the llama
|
|
||||||
if (entityMetadata.getId() == 21) {
|
|
||||||
// Bedrock treats llama decoration as armor
|
// Bedrock treats llama decoration as armor
|
||||||
MobArmorEquipmentPacket equipmentPacket = new MobArmorEquipmentPacket();
|
MobArmorEquipmentPacket equipmentPacket = new MobArmorEquipmentPacket();
|
||||||
equipmentPacket.setRuntimeEntityId(geyserId);
|
equipmentPacket.setRuntimeEntityId(geyserId);
|
||||||
// -1 means no armor
|
// -1 means no armor
|
||||||
int carpetIndex = (int) entityMetadata.getValue();
|
int carpetIndex = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (carpetIndex > -1 && carpetIndex <= 15) {
|
if (carpetIndex > -1 && carpetIndex <= 15) {
|
||||||
// The damage value is the dye color that Java sends us, for pre-1.16.220
|
// The damage value is the dye color that Java sends us, for pre-1.16.220
|
||||||
// The item is always going to be a carpet
|
// The item is always going to be a carpet
|
||||||
@ -69,12 +68,6 @@ public class LlamaEntity extends ChestedHorseEntity {
|
|||||||
|
|
||||||
session.sendUpstreamPacket(equipmentPacket);
|
session.sendUpstreamPacket(equipmentPacket);
|
||||||
}
|
}
|
||||||
// Color of the llama
|
|
||||||
if (entityMetadata.getId() == 22) {
|
|
||||||
metadata.put(EntityData.VARIANT, entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||||
|
@ -27,18 +27,20 @@ package org.geysermc.connector.entity.living.animal.horse;
|
|||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class TraderLlamaEntity extends LlamaEntity {
|
public class TraderLlamaEntity extends LlamaEntity {
|
||||||
|
|
||||||
public TraderLlamaEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public TraderLlamaEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnEntity(GeyserSession session) {
|
protected void initializeMetadata() {
|
||||||
this.metadata.put(EntityData.MARK_VARIANT, 1);
|
super.initializeMetadata();
|
||||||
super.spawnEntity(session);
|
this.dirtyMetadata.put(EntityData.MARK_VARIANT, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,40 +26,52 @@
|
|||||||
package org.geysermc.connector.entity.living.animal.tameable;
|
package org.geysermc.connector.entity.living.animal.tameable;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class CatEntity extends TameableEntity {
|
public class CatEntity extends TameableEntity {
|
||||||
|
|
||||||
private byte collarColor;
|
private byte collarColor;
|
||||||
|
|
||||||
public CatEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public CatEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateRotation(GeyserSession session, float yaw, float pitch, boolean isOnGround) {
|
public void updateRotation(float yaw, float pitch, boolean isOnGround) {
|
||||||
moveRelative(session, 0, 0, 0, Vector3f.from(this.rotation.getX(), pitch, yaw), isOnGround);
|
moveRelative(0, 0, 0, yaw, pitch, yaw, isOnGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
protected float getAdultSize() {
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
return 0.8f;
|
||||||
if (entityMetadata.getId() == 16) {
|
}
|
||||||
metadata.put(EntityData.SCALE, (boolean) entityMetadata.getValue() ? 0.4f : 0.8f);
|
|
||||||
} else if (entityMetadata.getId() == 17) {
|
@Override
|
||||||
|
protected float getBabySize() {
|
||||||
|
return 0.4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTameableFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
|
super.setTameableFlags(entityMetadata);
|
||||||
// Update collar color if tamed
|
// Update collar color if tamed
|
||||||
if (metadata.getFlags().getFlag(EntityFlag.TAMED)) {
|
if (getFlag(EntityFlag.TAMED)) {
|
||||||
metadata.put(EntityData.COLOR, collarColor);
|
dirtyMetadata.put(EntityData.COLOR, collarColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (entityMetadata.getId() == 19) {
|
|
||||||
|
public void setCatVariant(EntityMetadata<Integer> entityMetadata) {
|
||||||
// Different colors in Java and Bedrock for some reason
|
// Different colors in Java and Bedrock for some reason
|
||||||
int metadataValue = (int) entityMetadata.getValue();
|
int metadataValue = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
int variantColor = switch (metadataValue) {
|
int variantColor = switch (metadataValue) {
|
||||||
case 0 -> 8;
|
case 0 -> 8;
|
||||||
case 8 -> 0;
|
case 8 -> 0;
|
||||||
@ -67,17 +79,18 @@ public class CatEntity extends TameableEntity {
|
|||||||
case 10 -> 9;
|
case 10 -> 9;
|
||||||
default -> metadataValue;
|
default -> metadataValue;
|
||||||
};
|
};
|
||||||
metadata.put(EntityData.VARIANT, variantColor);
|
dirtyMetadata.put(EntityData.VARIANT, variantColor);
|
||||||
}
|
}
|
||||||
if (entityMetadata.getId() == 20) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.RESTING, (boolean) entityMetadata.getValue());
|
public void setResting(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
setFlag(EntityFlag.RESTING, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue());
|
||||||
}
|
}
|
||||||
if (entityMetadata.getId() == 22) {
|
|
||||||
collarColor = (byte) (int) entityMetadata.getValue();
|
public void setCollarColor(EntityMetadata<Integer> entityMetadata) {
|
||||||
|
collarColor = (byte) ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
// Needed or else wild cats are a red color
|
// Needed or else wild cats are a red color
|
||||||
if (metadata.getFlags().getFlag(EntityFlag.TAMED)) {
|
if (getFlag(EntityFlag.TAMED)) {
|
||||||
metadata.put(EntityData.COLOR, collarColor);
|
dirtyMetadata.put(EntityData.COLOR, collarColor);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,26 +25,17 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.entity.living.animal.tameable;
|
package org.geysermc.connector.entity.living.animal.tameable;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ParrotEntity extends TameableEntity {
|
public class ParrotEntity extends TameableEntity {
|
||||||
|
|
||||||
public ParrotEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ParrotEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
|
||||||
// Parrot color
|
|
||||||
if (entityMetadata.getId() == 19) {
|
|
||||||
metadata.put(EntityData.VARIANT, entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,46 +26,51 @@
|
|||||||
package org.geysermc.connector.entity.living.animal.tameable;
|
package org.geysermc.connector.entity.living.animal.tameable;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
|
import lombok.Getter;
|
||||||
import org.geysermc.connector.entity.Entity;
|
import org.geysermc.connector.entity.Entity;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.living.animal.AnimalEntity;
|
import org.geysermc.connector.entity.living.animal.AnimalEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class TameableEntity extends AnimalEntity {
|
public class TameableEntity extends AnimalEntity {
|
||||||
|
/**
|
||||||
|
* Used in the interactive tag manager to track if the session player owns this entity
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
protected long ownerBedrockId;
|
||||||
|
|
||||||
public TameableEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public TameableEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setTameableFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 17) {
|
setFlag(EntityFlag.SITTING, (xd & 0x01) == 0x01);
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
setFlag(EntityFlag.ANGRY, (xd & 0x02) == 0x02);
|
||||||
metadata.getFlags().setFlag(EntityFlag.SITTING, (xd & 0x01) == 0x01);
|
setFlag(EntityFlag.TAMED, (xd & 0x04) == 0x04);
|
||||||
metadata.getFlags().setFlag(EntityFlag.ANGRY, (xd & 0x02) == 0x02);
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.TAMED, (xd & 0x04) == 0x04);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOwner(EntityMetadata<UUID> entityMetadata) {
|
||||||
// Note: Must be set for wolf collar color to work
|
// Note: Must be set for wolf collar color to work
|
||||||
if (entityMetadata.getId() == 18) {
|
|
||||||
if (entityMetadata.getValue() != null) {
|
if (entityMetadata.getValue() != null) {
|
||||||
// Owner UUID of entity
|
// Owner UUID of entity
|
||||||
Entity entity = session.getEntityCache().getPlayerEntity((UUID) entityMetadata.getValue());
|
Entity entity = session.getEntityCache().getPlayerEntity(entityMetadata.getValue());
|
||||||
// Used as both a check since the player isn't in the entity cache and a normal fallback
|
// Used as both a check since the player isn't in the entity cache and a normal fallback
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
entity = session.getPlayerEntity();
|
entity = session.getPlayerEntity();
|
||||||
}
|
}
|
||||||
// Translate to entity ID
|
// Translate to entity ID
|
||||||
metadata.put(EntityData.OWNER_EID, entity.getGeyserId());
|
ownerBedrockId = entity.getGeyserId();
|
||||||
} else {
|
} else {
|
||||||
metadata.put(EntityData.OWNER_EID, 0L); // Reset
|
// Reset
|
||||||
}
|
ownerBedrockId = 0L;
|
||||||
}
|
}
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
dirtyMetadata.put(EntityData.OWNER_EID, ownerBedrockId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,18 @@
|
|||||||
package org.geysermc.connector.entity.living.animal.tameable;
|
package org.geysermc.connector.entity.living.animal.tameable;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.type.ItemMapping;
|
import org.geysermc.connector.registry.type.ItemMapping;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class WolfEntity extends TameableEntity {
|
public class WolfEntity extends TameableEntity {
|
||||||
/**
|
/**
|
||||||
@ -47,49 +50,45 @@ public class WolfEntity extends TameableEntity {
|
|||||||
|
|
||||||
private byte collarColor;
|
private byte collarColor;
|
||||||
|
|
||||||
public WolfEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public WolfEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void setTameableFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
|
super.setFlags(entityMetadata);
|
||||||
// Reset wolf color
|
// Reset wolf color
|
||||||
if (entityMetadata.getId() == 17) {
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
|
||||||
boolean angry = (xd & 0x02) == 0x02;
|
boolean angry = (xd & 0x02) == 0x02;
|
||||||
if (angry) {
|
if (angry) {
|
||||||
metadata.put(EntityData.COLOR, (byte) 0);
|
dirtyMetadata.put(EntityData.COLOR, (byte) 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Begging" on wiki.vg, "Interested" in Nukkit - the tilt of the head
|
public void setCollarColor(EntityMetadata<Integer> entityMetadata) {
|
||||||
if (entityMetadata.getId() == 19) {
|
collarColor = (byte) ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
metadata.getFlags().setFlag(EntityFlag.INTERESTED, (boolean) entityMetadata.getValue());
|
if (getFlag(EntityFlag.ANGRY)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wolf collar color
|
dirtyMetadata.put(EntityData.COLOR, collarColor);
|
||||||
// Relies on EntityData.OWNER_EID being set in TameableEntity.java
|
if (ownerBedrockId == 0) {
|
||||||
if (entityMetadata.getId() == 20 && !metadata.getFlags().getFlag(EntityFlag.ANGRY)) {
|
|
||||||
metadata.put(EntityData.COLOR, collarColor = (byte) (int) entityMetadata.getValue());
|
|
||||||
if (!metadata.containsKey(EntityData.OWNER_EID)) {
|
|
||||||
// If a color is set and there is no owner entity ID, set one.
|
// If a color is set and there is no owner entity ID, set one.
|
||||||
// Otherwise, the entire wolf is set to that color: https://user-images.githubusercontent.com/9083212/99209989-92691200-2792-11eb-911d-9a315c955be9.png
|
// Otherwise, the entire wolf is set to that color: https://user-images.githubusercontent.com/9083212/99209989-92691200-2792-11eb-911d-9a315c955be9.png
|
||||||
metadata.put(EntityData.OWNER_EID, session.getPlayerEntity().getGeyserId());
|
dirtyMetadata.put(EntityData.OWNER_EID, session.getPlayerEntity().getGeyserId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wolf anger (1.16+)
|
// 1.16+
|
||||||
if (entityMetadata.getId() == 21) {
|
public void setWolfAngerTime(EntityMetadata<Integer> entityMetadata) {
|
||||||
metadata.getFlags().setFlag(EntityFlag.ANGRY, (int) entityMetadata.getValue() != 0);
|
int time = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
metadata.put(EntityData.COLOR, (int) entityMetadata.getValue() != 0 ? (byte) 0 : collarColor);
|
setFlag(EntityFlag.ANGRY, time != 0);
|
||||||
}
|
dirtyMetadata.put(EntityData.COLOR, time != 0 ? (byte) 0 : collarColor);
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||||
// Cannot be a baby to eat these foods
|
// Cannot be a baby to eat these foods
|
||||||
return WOLF_FOODS.contains(javaIdentifierStripped) && !metadata.getFlags().getFlag(EntityFlag.BABY);
|
return WOLF_FOODS.contains(javaIdentifierStripped) && !getFlag(EntityFlag.BABY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,18 +26,15 @@
|
|||||||
package org.geysermc.connector.entity.living.merchant;
|
package org.geysermc.connector.entity.living.merchant;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.living.AgeableEntity;
|
import org.geysermc.connector.entity.living.AgeableEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class AbstractMerchantEntity extends AgeableEntity {
|
public class AbstractMerchantEntity extends AgeableEntity {
|
||||||
|
|
||||||
public AbstractMerchantEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public AbstractMerchantEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void teleport(GeyserSession session, Vector3f position, float yaw, float pitch, boolean isOnGround) {
|
|
||||||
super.teleport(session, position, yaw - 180, pitch, isOnGround);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
package org.geysermc.connector.entity.living.merchant;
|
package org.geysermc.connector.entity.living.merchant;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
@ -34,12 +35,12 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
|||||||
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import lombok.Getter;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.registry.BlockRegistries;
|
import org.geysermc.connector.registry.BlockRegistries;
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class VillagerEntity extends AbstractMerchantEntity {
|
public class VillagerEntity extends AbstractMerchantEntity {
|
||||||
|
|
||||||
@ -79,32 +80,41 @@ public class VillagerEntity extends AbstractMerchantEntity {
|
|||||||
VILLAGER_REGIONS.put(6, 6);
|
VILLAGER_REGIONS.put(6, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VillagerEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
private Vector3i bedPosition;
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
/**
|
||||||
|
* Used in the interactive tag manager
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private boolean canTradeWith;
|
||||||
|
|
||||||
|
public VillagerEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setVillagerData(EntityMetadata<VillagerData> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
VillagerData villagerData = entityMetadata.getValue();
|
||||||
if (entityMetadata.getId() == 18) {
|
|
||||||
VillagerData villagerData = (VillagerData) entityMetadata.getValue();
|
|
||||||
// Profession
|
// Profession
|
||||||
metadata.put(EntityData.VARIANT, VILLAGER_PROFESSIONS.get(villagerData.getProfession()));
|
int profession = VILLAGER_PROFESSIONS.get(villagerData.getProfession());
|
||||||
|
canTradeWith = profession != 14 && profession != 0; // Not a notwit and not professionless
|
||||||
|
dirtyMetadata.put(EntityData.VARIANT, profession);
|
||||||
//metadata.put(EntityData.SKIN_ID, villagerData.getType()); Looks like this is modified but for any reason?
|
//metadata.put(EntityData.SKIN_ID, villagerData.getType()); Looks like this is modified but for any reason?
|
||||||
// Region
|
// Region
|
||||||
metadata.put(EntityData.MARK_VARIANT, VILLAGER_REGIONS.get(villagerData.getType()));
|
dirtyMetadata.put(EntityData.MARK_VARIANT, VILLAGER_REGIONS.get(villagerData.getType()));
|
||||||
// Trade tier - different indexing in Bedrock
|
// Trade tier - different indexing in Bedrock
|
||||||
metadata.put(EntityData.TRADE_TIER, villagerData.getLevel() - 1);
|
dirtyMetadata.put(EntityData.TRADE_TIER, villagerData.getLevel() - 1);
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) {
|
public Vector3i setBedPosition(EntityMetadata<Position> entityMetadata) {
|
||||||
|
return bedPosition = super.setBedPosition(entityMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, float headYaw, boolean isOnGround) {
|
||||||
// The bed block position, if it exists
|
// The bed block position, if it exists
|
||||||
Vector3i bedPosition;
|
if (!getFlag(EntityFlag.SLEEPING) || bedPosition == null) {
|
||||||
if (!metadata.getFlags().getFlag(EntityFlag.SLEEPING) || (bedPosition = metadata.getPos(EntityData.BED_POSITION, null)) == null) {
|
|
||||||
// No need to worry about extra processing to compensate for sleeping
|
// No need to worry about extra processing to compensate for sleeping
|
||||||
super.moveRelative(session, relX, relY, relZ, rotation, isOnGround);
|
super.moveRelative(relX, relY, relZ, yaw, pitch, headYaw, isOnGround);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +143,9 @@ public class VillagerEntity extends AbstractMerchantEntity {
|
|||||||
zOffset = .5f;
|
zOffset = .5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
setRotation(rotation);
|
setYaw(yaw);
|
||||||
|
setPitch(pitch);
|
||||||
|
setHeadYaw(headYaw);
|
||||||
setOnGround(isOnGround);
|
setOnGround(isOnGround);
|
||||||
this.position = Vector3f.from(position.getX() + relX, position.getY() + relY, position.getZ() + relZ);
|
this.position = Vector3f.from(position.getX() + relX, position.getY() + relY, position.getZ() + relZ);
|
||||||
|
|
||||||
|
@ -26,24 +26,25 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class AbstractSkeletonEntity extends MonsterEntity {
|
public class AbstractSkeletonEntity extends MonsterEntity {
|
||||||
|
|
||||||
public AbstractSkeletonEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public AbstractSkeletonEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void setMobFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
if (entityMetadata.getId() == 15) {
|
super.setMobFlags(entityMetadata);
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
// A bit of a loophole so the hands get raised - set the target ID to its own ID
|
// A bit of a loophole so the hands get raised - set the target ID to its own ID
|
||||||
metadata.put(EntityData.TARGET_EID, ((xd & 4) == 4) ? geyserId : 0);
|
dirtyMetadata.put(EntityData.TARGET_EID, ((xd & 4) == 4) ? geyserId : 0);
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,32 +26,30 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.utils.DimensionUtils;
|
import org.geysermc.connector.utils.DimensionUtils;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class BasePiglinEntity extends MonsterEntity {
|
public class BasePiglinEntity extends MonsterEntity {
|
||||||
private boolean isImmuneToZombification;
|
private boolean isImmuneToZombification;
|
||||||
|
|
||||||
public BasePiglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public BasePiglinEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setImmuneToZombification(EntityMetadata<Boolean> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
|
||||||
if (entityMetadata.getId() == 16) {
|
|
||||||
// Immune to zombification?
|
|
||||||
// Apply shaking effect if not in the nether and zombification is possible
|
// Apply shaking effect if not in the nether and zombification is possible
|
||||||
this.isImmuneToZombification = (boolean) entityMetadata.getValue();
|
this.isImmuneToZombification = ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
metadata.getFlags().setFlag(EntityFlag.SHAKING, isShaking(session));
|
setFlag(EntityFlag.SHAKING, isShaking());
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isShaking(GeyserSession session) {
|
protected boolean isShaking() {
|
||||||
return (!isImmuneToZombification && !session.getDimension().equals(DimensionUtils.NETHER)) || super.isShaking(session);
|
return (!isImmuneToZombification && !session.getDimension().equals(DimensionUtils.NETHER)) || super.isShaking();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,24 +26,22 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class BlazeEntity extends MonsterEntity {
|
public class BlazeEntity extends MonsterEntity {
|
||||||
|
|
||||||
public BlazeEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public BlazeEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setBlazeFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 16) {
|
setFlag(EntityFlag.ON_FIRE, (xd & 0x01) == 0x01);
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.ON_FIRE, (xd & 0x01) == 0x01);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,38 +26,34 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
public class CreeperEntity extends MonsterEntity {
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class CreeperEntity extends MonsterEntity {
|
||||||
/**
|
/**
|
||||||
* Whether the creeper has been ignited and is using ID 17.
|
* Whether the creeper has been ignited and is using {@link #setIgnited(EntityMetadata)}.
|
||||||
* In this instance we ignore ID 15 since it's sending us -1 which confuses poor Bedrock.
|
* In this instance we ignore {@link #setSwelling(EntityMetadata)} since it's sending us -1 which confuses poor Bedrock.
|
||||||
*/
|
*/
|
||||||
private boolean ignitedByFlintAndSteel = false;
|
private boolean ignitedByFlintAndSteel = false;
|
||||||
|
|
||||||
public CreeperEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public CreeperEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setSwelling(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
|
||||||
if (entityMetadata.getId() == 16) {
|
|
||||||
if (!ignitedByFlintAndSteel) {
|
if (!ignitedByFlintAndSteel) {
|
||||||
metadata.getFlags().setFlag(EntityFlag.IGNITED, (int) entityMetadata.getValue() == 1);
|
setFlag(EntityFlag.IGNITED, ((IntEntityMetadata) entityMetadata).getPrimitiveValue() == 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (entityMetadata.getId() == 17) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.POWERED, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
if (entityMetadata.getId() == 18) {
|
|
||||||
ignitedByFlintAndSteel = (boolean) entityMetadata.getValue();
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.IGNITED, ignitedByFlintAndSteel);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
public void setIgnited(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
ignitedByFlintAndSteel = ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
setFlag(EntityFlag.IGNITED, ignitedByFlintAndSteel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,14 +27,21 @@ package org.geysermc.connector.entity.living.monster;
|
|||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ElderGuardianEntity extends GuardianEntity {
|
public class ElderGuardianEntity extends GuardianEntity {
|
||||||
|
|
||||||
public ElderGuardianEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ElderGuardianEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
// Otherwise it just looks like a normal guardian but bigger
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.ELDER, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initializeMetadata() {
|
||||||
|
super.initializeMetadata();
|
||||||
|
// Otherwise it just looks like a normal guardian but bigger
|
||||||
|
setFlag(EntityFlag.ELDER, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
@ -33,17 +34,18 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
|
|||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import com.nukkitx.protocol.bedrock.packet.*;
|
import com.nukkitx.protocol.bedrock.packet.*;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.Tickable;
|
import org.geysermc.connector.entity.Tickable;
|
||||||
import org.geysermc.connector.entity.living.InsentientEntity;
|
import org.geysermc.connector.entity.living.MobEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.utils.DimensionUtils;
|
import org.geysermc.connector.utils.DimensionUtils;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
public class EnderDragonEntity extends MobEntity implements Tickable {
|
||||||
/**
|
/**
|
||||||
* The Ender Dragon has multiple hit boxes, which
|
* The Ender Dragon has multiple hit boxes, which
|
||||||
* are each its own invisible entity
|
* are each its own invisible entity
|
||||||
@ -78,23 +80,19 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
|||||||
private float wingPosition;
|
private float wingPosition;
|
||||||
private float lastWingPosition;
|
private float lastWingPosition;
|
||||||
|
|
||||||
public EnderDragonEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public EnderDragonEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
protected void initializeMetadata() {
|
||||||
if (entityMetadata.getId() == 16) { // Phase
|
super.initializeMetadata();
|
||||||
phase = (int) entityMetadata.getValue();
|
setFlag(EntityFlag.FIRE_IMMUNE, true);
|
||||||
phaseTicks = 0;
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.SITTING, isSitting());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
@Override
|
||||||
|
public void setHealth(EntityMetadata<Float> entityMetadata) {
|
||||||
if (entityMetadata.getId() == 9) {
|
super.setHealth(entityMetadata);
|
||||||
if (phase == 9 && this.health <= 0) { // Dying phase
|
if (phase == 9 && this.health <= 0) { // Dying phase
|
||||||
EntityEventPacket entityEventPacket = new EntityEventPacket();
|
EntityEventPacket entityEventPacket = new EntityEventPacket();
|
||||||
entityEventPacket.setType(EntityEventType.ENDER_DRAGON_DEATH);
|
entityEventPacket.setType(EntityEventType.ENDER_DRAGON_DEATH);
|
||||||
@ -103,21 +101,26 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
|||||||
session.sendUpstreamPacket(entityEventPacket);
|
session.sendUpstreamPacket(entityEventPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPhase(EntityMetadata<Integer> entityMetadata) {
|
||||||
|
phase = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
phaseTicks = 0;
|
||||||
|
setFlag(EntityFlag.SITTING, isSitting());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnEntity(GeyserSession session) {
|
public void spawnEntity() {
|
||||||
super.spawnEntity(session);
|
super.spawnEntity();
|
||||||
|
|
||||||
AtomicLong nextEntityId = session.getEntityCache().getNextEntityId();
|
AtomicLong nextEntityId = session.getEntityCache().getNextEntityId();
|
||||||
head = new EnderDragonPartEntity(entityId + 1, nextEntityId.incrementAndGet(), EntityType.ENDER_DRAGON_PART, 1, 1);
|
head = new EnderDragonPartEntity(session, entityId + 1, nextEntityId.incrementAndGet(), 1, 1);
|
||||||
neck = new EnderDragonPartEntity(entityId + 2, nextEntityId.incrementAndGet(), EntityType.ENDER_DRAGON_PART, 3, 3);
|
neck = new EnderDragonPartEntity(session, entityId + 2, nextEntityId.incrementAndGet(), 3, 3);
|
||||||
body = new EnderDragonPartEntity(entityId + 3, nextEntityId.incrementAndGet(), EntityType.ENDER_DRAGON_PART, 5, 3);
|
body = new EnderDragonPartEntity(session, entityId + 3, nextEntityId.incrementAndGet(), 5, 3);
|
||||||
leftWing = new EnderDragonPartEntity(entityId + 4, nextEntityId.incrementAndGet(), EntityType.ENDER_DRAGON_PART, 4, 2);
|
leftWing = new EnderDragonPartEntity(session, entityId + 4, nextEntityId.incrementAndGet(), 4, 2);
|
||||||
rightWing = new EnderDragonPartEntity(entityId + 5, nextEntityId.incrementAndGet(), EntityType.ENDER_DRAGON_PART, 4, 2);
|
rightWing = new EnderDragonPartEntity(session, entityId + 5, nextEntityId.incrementAndGet(), 4, 2);
|
||||||
tail = new EnderDragonPartEntity[3];
|
tail = new EnderDragonPartEntity[3];
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
tail[i] = new EnderDragonPartEntity(entityId + 6 + i, nextEntityId.incrementAndGet(), EntityType.ENDER_DRAGON_PART, 2, 2);
|
tail[i] = new EnderDragonPartEntity(session, entityId + 6 + i, nextEntityId.incrementAndGet(), 2, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
allParts = new EnderDragonPartEntity[]{head, neck, body, leftWing, rightWing, tail[0], tail[1], tail[2]};
|
allParts = new EnderDragonPartEntity[]{head, neck, body, leftWing, rightWing, tail[0], tail[1], tail[2]};
|
||||||
@ -128,7 +131,7 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
|||||||
|
|
||||||
for (int i = 0; i < segmentHistory.length; i++) {
|
for (int i = 0; i < segmentHistory.length; i++) {
|
||||||
segmentHistory[i] = new Segment();
|
segmentHistory[i] = new Segment();
|
||||||
segmentHistory[i].yaw = rotation.getZ();
|
segmentHistory[i].yaw = headYaw;
|
||||||
segmentHistory[i].y = position.getY();
|
segmentHistory[i].y = position.getY();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,29 +144,27 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean despawnEntity(GeyserSession session) {
|
public boolean despawnEntity() {
|
||||||
for (EnderDragonPartEntity part : allParts) {
|
for (EnderDragonPartEntity part : allParts) {
|
||||||
part.despawnEntity(session);
|
part.despawnEntity();
|
||||||
}
|
}
|
||||||
return super.despawnEntity(session);
|
return super.despawnEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(GeyserSession session) {
|
public void tick() {
|
||||||
effectTick(session);
|
effectTick();
|
||||||
if (!metadata.getFlags().getFlag(EntityFlag.NO_AI) && isAlive()) {
|
if (!getFlag(EntityFlag.NO_AI) && isAlive()) {
|
||||||
pushSegment();
|
pushSegment();
|
||||||
updateBoundingBoxes(session);
|
updateBoundingBoxes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the positions of the Ender Dragon's multiple bounding boxes
|
* Updates the positions of the Ender Dragon's multiple bounding boxes
|
||||||
*
|
|
||||||
* @param session GeyserSession.
|
|
||||||
*/
|
*/
|
||||||
private void updateBoundingBoxes(GeyserSession session) {
|
private void updateBoundingBoxes() {
|
||||||
Vector3f facingDir = Vector3f.createDirectionDeg(0, rotation.getZ());
|
Vector3f facingDir = Vector3f.createDirectionDeg(0, headYaw);
|
||||||
Segment baseSegment = getSegment(5);
|
Segment baseSegment = getSegment(5);
|
||||||
// Used to angle the head, neck, and tail when the dragon flies up/down
|
// Used to angle the head, neck, and tail when the dragon flies up/down
|
||||||
float pitch = (float) Math.toRadians(10 * (baseSegment.getY() - getSegment(10).getY()));
|
float pitch = (float) Math.toRadians(10 * (baseSegment.getY() - getSegment(10).getY()));
|
||||||
@ -182,7 +183,7 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
|||||||
neck.setPosition(facingDir.up(pitchY).mul(pitchXZ, 1, -pitchXZ).mul(5.5f).up(headDuck));
|
neck.setPosition(facingDir.up(pitchY).mul(pitchXZ, 1, -pitchXZ).mul(5.5f).up(headDuck));
|
||||||
body.setPosition(facingDir.mul(0.5f, 0f, -0.5f));
|
body.setPosition(facingDir.mul(0.5f, 0f, -0.5f));
|
||||||
|
|
||||||
Vector3f wingPos = Vector3f.createDirectionDeg(0, 90f - rotation.getZ()).mul(4.5f).up(2f);
|
Vector3f wingPos = Vector3f.createDirectionDeg(0, 90f - headYaw).mul(4.5f).up(2f);
|
||||||
rightWing.setPosition(wingPos);
|
rightWing.setPosition(wingPos);
|
||||||
leftWing.setPosition(wingPos.mul(-1, 1, -1)); // Mirror horizontally
|
leftWing.setPosition(wingPos.mul(-1, 1, -1)); // Mirror horizontally
|
||||||
|
|
||||||
@ -191,24 +192,23 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
|||||||
float distance = (i + 1) * 2f;
|
float distance = (i + 1) * 2f;
|
||||||
// Curls the tail when the dragon turns
|
// Curls the tail when the dragon turns
|
||||||
Segment targetSegment = getSegment(12 + 2 * i);
|
Segment targetSegment = getSegment(12 + 2 * i);
|
||||||
float angle = rotation.getZ() + targetSegment.yaw - baseSegment.yaw;
|
float angle = headYaw + targetSegment.yaw - baseSegment.yaw;
|
||||||
|
|
||||||
float tailYOffset = targetSegment.y - baseSegment.y - (distance + 1.5f) * pitchY + 1.5f;
|
float tailYOffset = targetSegment.y - baseSegment.y - (distance + 1.5f) * pitchY + 1.5f;
|
||||||
tail[i].setPosition(Vector3f.createDirectionDeg(0, angle).mul(distance).add(tailBase).mul(-pitchXZ, 1, pitchXZ).up(tailYOffset));
|
tail[i].setPosition(Vector3f.createDirectionDeg(0, angle).mul(distance).add(tailBase).mul(-pitchXZ, 1, pitchXZ).up(tailYOffset));
|
||||||
}
|
}
|
||||||
// Send updated positions
|
// Send updated positions
|
||||||
for (EnderDragonPartEntity part : allParts) {
|
for (EnderDragonPartEntity part : allParts) {
|
||||||
part.moveAbsolute(session, part.getPosition().add(position), Vector3f.ZERO, false, false);
|
part.moveAbsolute(part.getPosition().add(position), 0, 0, 0, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the particles and sounds of the Ender Dragon
|
* Handles the particles and sounds of the Ender Dragon
|
||||||
* @param session GeyserSession.
|
|
||||||
*/
|
*/
|
||||||
private void effectTick(GeyserSession session) {
|
private void effectTick() {
|
||||||
Random random = ThreadLocalRandom.current();
|
Random random = ThreadLocalRandom.current();
|
||||||
if (!metadata.getFlags().getFlag(EntityFlag.SILENT)) {
|
if (!getFlag(EntityFlag.SILENT)) {
|
||||||
if (Math.cos(wingPosition * 2f * Math.PI) <= -0.3f && Math.cos(lastWingPosition * 2f * Math.PI) >= -0.3f) {
|
if (Math.cos(wingPosition * 2f * Math.PI) <= -0.3f && Math.cos(lastWingPosition * 2f * Math.PI) >= -0.3f) {
|
||||||
PlaySoundPacket playSoundPacket = new PlaySoundPacket();
|
PlaySoundPacket playSoundPacket = new PlaySoundPacket();
|
||||||
playSoundPacket.setSound("mob.enderdragon.flap");
|
playSoundPacket.setSound("mob.enderdragon.flap");
|
||||||
@ -219,14 +219,14 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isSitting() && !isHovering() && ticksTillNextGrowl-- == 0) {
|
if (!isSitting() && !isHovering() && ticksTillNextGrowl-- == 0) {
|
||||||
playGrowlSound(session);
|
playGrowlSound();
|
||||||
ticksTillNextGrowl = 200 + random.nextInt(200);
|
ticksTillNextGrowl = 200 + random.nextInt(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastWingPosition = wingPosition;
|
lastWingPosition = wingPosition;
|
||||||
}
|
}
|
||||||
if (isAlive()) {
|
if (isAlive()) {
|
||||||
if (metadata.getFlags().getFlag(EntityFlag.NO_AI)) {
|
if (getFlag(EntityFlag.NO_AI)) {
|
||||||
wingPosition = 0.5f;
|
wingPosition = 0.5f;
|
||||||
} else if (isHovering() || isSitting()) {
|
} else if (isHovering() || isSitting()) {
|
||||||
wingPosition += 0.1f;
|
wingPosition += 0.1f;
|
||||||
@ -237,7 +237,7 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
|||||||
|
|
||||||
phaseTicks++;
|
phaseTicks++;
|
||||||
if (phase == 3) { // Landing Phase
|
if (phase == 3) { // Landing Phase
|
||||||
float headHeight = head.getMetadata().getFloat(EntityData.BOUNDING_BOX_HEIGHT);
|
float headHeight = head.getDirtyMetadata().getFloat(EntityData.BOUNDING_BOX_HEIGHT); //TODO
|
||||||
Vector3f headCenter = head.getPosition().up(headHeight * 0.5f);
|
Vector3f headCenter = head.getPosition().up(headHeight * 0.5f);
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
@ -262,7 +262,7 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (phase == 7) { // Sitting Attacking Phase
|
} else if (phase == 7) { // Sitting Attacking Phase
|
||||||
playGrowlSound(session);
|
playGrowlSound();
|
||||||
} else if (phase == 9) { // Dying Phase
|
} else if (phase == 9) { // Dying Phase
|
||||||
// Send explosion particles as the dragon move towards the end portal
|
// Send explosion particles as the dragon move towards the end portal
|
||||||
if (phaseTicks % 10 == 0) {
|
if (phaseTicks % 10 == 0) {
|
||||||
@ -279,7 +279,7 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playGrowlSound(GeyserSession session) {
|
private void playGrowlSound() {
|
||||||
Random random = ThreadLocalRandom.current();
|
Random random = ThreadLocalRandom.current();
|
||||||
PlaySoundPacket playSoundPacket = new PlaySoundPacket();
|
PlaySoundPacket playSoundPacket = new PlaySoundPacket();
|
||||||
playSoundPacket.setSound("mob.enderdragon.growl");
|
playSoundPacket.setSound("mob.enderdragon.growl");
|
||||||
@ -306,7 +306,7 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
|||||||
*/
|
*/
|
||||||
private void pushSegment() {
|
private void pushSegment() {
|
||||||
latestSegment = (latestSegment + 1) % segmentHistory.length;
|
latestSegment = (latestSegment + 1) % segmentHistory.length;
|
||||||
segmentHistory[latestSegment].yaw = rotation.getZ();
|
segmentHistory[latestSegment].yaw = headYaw;
|
||||||
segmentHistory[latestSegment].y = position.getY();
|
segmentHistory[latestSegment].y = position.getY();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,15 +29,17 @@ import com.nukkitx.math.vector.Vector3f;
|
|||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.Entity;
|
import org.geysermc.connector.entity.Entity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinitions;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
public class EnderDragonPartEntity extends Entity {
|
public class EnderDragonPartEntity extends Entity {
|
||||||
public EnderDragonPartEntity(long entityId, long geyserId, EntityType entityType, float width, float height) {
|
|
||||||
super(entityId, geyserId, entityType, Vector3f.ZERO, Vector3f.ZERO, Vector3f.ZERO);
|
|
||||||
|
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, width);
|
public EnderDragonPartEntity(GeyserSession session, long entityId, long geyserId, float width, float height) {
|
||||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, height);
|
super(session, entityId, geyserId, null, EntityDefinitions.ENDER_DRAGON_PART, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0);
|
||||||
metadata.getFlags().setFlag(EntityFlag.INVISIBLE, true);
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true);
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, width);
|
||||||
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, height);
|
||||||
|
setFlag(EntityFlag.INVISIBLE, true);
|
||||||
|
setFlag(EntityFlag.FIRE_IMMUNE, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,29 +26,35 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.SoundEvent;
|
import com.nukkitx.protocol.bedrock.data.SoundEvent;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import com.nukkitx.protocol.bedrock.packet.LevelSoundEvent2Packet;
|
import com.nukkitx.protocol.bedrock.packet.LevelSoundEvent2Packet;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class EndermanEntity extends MonsterEntity {
|
public class EndermanEntity extends MonsterEntity {
|
||||||
|
|
||||||
public EndermanEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public EndermanEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setCarriedBlock(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
dirtyMetadata.put(EntityData.CARRIED_BLOCK, session.getBlockMappings().getBedrockBlockId(((IntEntityMetadata) entityMetadata).getPrimitiveValue()));
|
||||||
// Held block
|
|
||||||
if (entityMetadata.getId() == 16) {
|
|
||||||
metadata.put(EntityData.CARRIED_BLOCK, session.getBlockMappings().getBedrockBlockId((int) entityMetadata.getValue()));
|
|
||||||
}
|
}
|
||||||
// "Is screaming" - controls sound
|
|
||||||
if (entityMetadata.getId() == 17) {
|
/**
|
||||||
if ((boolean) entityMetadata.getValue()) {
|
* Controls the screaming sound
|
||||||
|
*/
|
||||||
|
public void setScreaming(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
//TODO see if Bedrock controls this differently
|
||||||
|
// Java Edition this controls which ambient sound is used
|
||||||
|
if (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()) {
|
||||||
LevelSoundEvent2Packet packet = new LevelSoundEvent2Packet();
|
LevelSoundEvent2Packet packet = new LevelSoundEvent2Packet();
|
||||||
packet.setSound(SoundEvent.STARE);
|
packet.setSound(SoundEvent.STARE);
|
||||||
packet.setPosition(this.position);
|
packet.setPosition(this.position);
|
||||||
@ -57,10 +63,9 @@ public class EndermanEntity extends MonsterEntity {
|
|||||||
session.sendUpstreamPacket(packet);
|
session.sendUpstreamPacket(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAngry(EntityMetadata<Boolean> entityMetadata) {
|
||||||
// "Is staring/provoked" - controls visuals
|
// "Is staring/provoked" - controls visuals
|
||||||
if (entityMetadata.getId() == 18) {
|
setFlag(EntityFlag.ANGRY, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue());
|
||||||
metadata.getFlags().setFlag(EntityFlag.ANGRY, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,24 +26,23 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.living.FlyingEntity;
|
import org.geysermc.connector.entity.living.FlyingEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class GhastEntity extends FlyingEntity {
|
public class GhastEntity extends FlyingEntity {
|
||||||
|
|
||||||
public GhastEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public GhastEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setGhastAttacking(EntityMetadata<Boolean> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
|
||||||
if (entityMetadata.getId() == 16) {
|
|
||||||
// If the ghast is attacking
|
// If the ghast is attacking
|
||||||
metadata.put(EntityData.CHARGE_AMOUNT, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
dirtyMetadata.put(EntityData.CHARGE_AMOUNT, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0));
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,13 +27,16 @@ package org.geysermc.connector.entity.living.monster;
|
|||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class GiantEntity extends MonsterEntity {
|
public class GiantEntity extends MonsterEntity {
|
||||||
|
|
||||||
public GiantEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public GiantEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
metadata.put(EntityData.SCALE, 6f);
|
dirtyMetadata.put(EntityData.SCALE, 6f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,33 +26,34 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.Entity;
|
import org.geysermc.connector.entity.Entity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class GuardianEntity extends MonsterEntity {
|
public class GuardianEntity extends MonsterEntity {
|
||||||
|
|
||||||
public GuardianEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public GuardianEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setGuardianTarget(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
int entityId = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 17) {
|
Entity entity;
|
||||||
Entity entity = session.getEntityCache().getEntityByJavaId((int) entityMetadata.getValue());
|
if (session.getPlayerEntity().getEntityId() == entityId) {
|
||||||
if (entity == null && session.getPlayerEntity().getEntityId() == (Integer) entityMetadata.getValue()) {
|
|
||||||
entity = session.getPlayerEntity();
|
entity = session.getPlayerEntity();
|
||||||
|
} else {
|
||||||
|
entity = session.getEntityCache().getEntityByJavaId(entityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
metadata.put(EntityData.TARGET_EID, entity.getGeyserId());
|
dirtyMetadata.put(EntityData.TARGET_EID, entity.getGeyserId());
|
||||||
} else {
|
} else {
|
||||||
metadata.put(EntityData.TARGET_EID, (long) 0);
|
dirtyMetadata.put(EntityData.TARGET_EID, (long) 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,15 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.living.CreatureEntity;
|
import org.geysermc.connector.entity.living.CreatureEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class MonsterEntity extends CreatureEntity {
|
public class MonsterEntity extends CreatureEntity {
|
||||||
|
|
||||||
public MonsterEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public MonsterEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,28 +26,27 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.living.FlyingEntity;
|
import org.geysermc.connector.entity.living.FlyingEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PhantomEntity extends FlyingEntity {
|
public class PhantomEntity extends FlyingEntity {
|
||||||
public PhantomEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public PhantomEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setPhantomScale(EntityMetadata<Integer> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
int size = ((IntEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 16) { // Size
|
|
||||||
int size = (int) entityMetadata.getValue();
|
|
||||||
float modelScale = 1f + 0.15f * size;
|
float modelScale = 1f + 0.15f * size;
|
||||||
float boundsScale = (1f + (0.2f * size) / EntityType.PHANTOM.getWidth()) / modelScale;
|
float boundsScale = (1f + (0.2f * size) / definition.width()) / modelScale;
|
||||||
|
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, boundsScale * EntityType.PHANTOM.getWidth());
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, boundsScale * definition.width());
|
||||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, boundsScale * EntityType.PHANTOM.getHeight());
|
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, boundsScale * definition.height());
|
||||||
metadata.put(EntityData.SCALE, modelScale);
|
dirtyMetadata.put(EntityData.SCALE, modelScale);
|
||||||
}
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,44 +26,40 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PiglinEntity extends BasePiglinEntity {
|
public class PiglinEntity extends BasePiglinEntity {
|
||||||
|
|
||||||
public PiglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public PiglinEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setBaby(EntityMetadata<Boolean> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
boolean isBaby = ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 17) {
|
dirtyMetadata.put(EntityData.SCALE, isBaby? .55f : 1f);
|
||||||
boolean isBaby = (boolean) entityMetadata.getValue();
|
setFlag(EntityFlag.BABY, isBaby);
|
||||||
if (isBaby) {
|
|
||||||
metadata.put(EntityData.SCALE, .55f);
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.BABY, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (entityMetadata.getId() == 18) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.CHARGING, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
|
||||||
if (entityMetadata.getId() == 19) {
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.DANCING, (boolean) entityMetadata.getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
public void setChargingCrossbow(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
setFlag(EntityFlag.CHARGING, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDancing(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
setFlag(EntityFlag.DANCING, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateOffHand(GeyserSession session) {
|
public void updateOffHand(GeyserSession session) {
|
||||||
// Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates
|
// Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates
|
||||||
boolean changed = metadata.getFlags().setFlag(EntityFlag.ADMIRING, session.getTagCache().shouldPiglinAdmire(session.getItemMappings().getMapping(this.offHand)));
|
setFlag(EntityFlag.ADMIRING, session.getTagCache().shouldPiglinAdmire(session.getItemMappings().getMapping(this.offHand)));
|
||||||
if (changed) {
|
super.updateBedrockMetadata();
|
||||||
super.updateBedrockMetadata(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateOffHand(session);
|
super.updateOffHand(session);
|
||||||
}
|
}
|
||||||
|
@ -26,44 +26,43 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockFace;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.entity.living.GolemEntity;
|
import org.geysermc.connector.entity.living.GolemEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
import org.geysermc.connector.utils.Direction;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ShulkerEntity extends GolemEntity {
|
public class ShulkerEntity extends GolemEntity {
|
||||||
|
|
||||||
public ShulkerEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ShulkerEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
// Indicate that invisibility should be fixed through the resource pack
|
// Indicate that invisibility should be fixed through the resource pack
|
||||||
metadata.getFlags().setFlag(EntityFlag.BRIBED, true);
|
setFlag(EntityFlag.BRIBED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setAttachedFace(EntityMetadata<Direction> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
Direction direction = entityMetadata.getValue();
|
||||||
if (entityMetadata.getId() == 16) {
|
dirtyMetadata.put(EntityData.SHULKER_ATTACH_FACE, (byte) direction.ordinal());
|
||||||
BlockFace blockFace = (BlockFace) entityMetadata.getValue();
|
|
||||||
metadata.put(EntityData.SHULKER_ATTACH_FACE, (byte) blockFace.ordinal());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entityMetadata.getId() == 17) {
|
public void setShulkerHeight(EntityMetadata<Byte> entityMetadata) {
|
||||||
int height = (byte) entityMetadata.getValue();
|
int height = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
metadata.put(EntityData.SHULKER_PEEK_ID, height);
|
dirtyMetadata.put(EntityData.SHULKER_PEEK_ID, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entityMetadata.getId() == 18) {
|
public void setShulkerColor(EntityMetadata<Byte> entityMetadata) {
|
||||||
byte color = (byte) entityMetadata.getValue();
|
byte color = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (color == 16) {
|
if (color == 16) {
|
||||||
// 16 is default on both editions
|
// 16 is default on both editions
|
||||||
metadata.put(EntityData.VARIANT, 16);
|
dirtyMetadata.put(EntityData.VARIANT, 16);
|
||||||
} else {
|
} else {
|
||||||
// Every other shulker color is offset 15 in bedrock edition
|
// Every other shulker color is offset 15 in bedrock edition
|
||||||
metadata.put(EntityData.VARIANT, Math.abs(color - 15));
|
dirtyMetadata.put(EntityData.VARIANT, Math.abs(color - 15));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -26,29 +26,28 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class SkeletonEntity extends AbstractSkeletonEntity {
|
public class SkeletonEntity extends AbstractSkeletonEntity {
|
||||||
private boolean convertingToStray = false;
|
private boolean convertingToStray = false;
|
||||||
|
|
||||||
public SkeletonEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public SkeletonEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConvertingToStray(EntityMetadata<Boolean> entityMetadata) {
|
||||||
|
this.convertingToStray = ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
|
setFlag(EntityFlag.SHAKING, isShaking());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
protected boolean isShaking() {
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
if (entityMetadata.getId() == 16) {
|
|
||||||
this.convertingToStray = (boolean) entityMetadata.getValue();
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.SHAKING, isShaking(session));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isShaking(GeyserSession session) {
|
|
||||||
return convertingToStray;
|
return convertingToStray;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,24 +26,22 @@
|
|||||||
package org.geysermc.connector.entity.living.monster;
|
package org.geysermc.connector.entity.living.monster;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.EntityDefinition;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class SpiderEntity extends MonsterEntity {
|
public class SpiderEntity extends MonsterEntity {
|
||||||
|
|
||||||
public SpiderEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public SpiderEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setSpiderFlags(EntityMetadata<Byte> entityMetadata) {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||||
if (entityMetadata.getId() == 16) {
|
setFlag(EntityFlag.WALL_CLIMBING, (xd & 0x01) == 0x01);
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.WALL_CLIMBING, (xd & 0x01) == 0x01);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren