Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-03 14:50:19 +01:00
Fix Item drop animation (#2406)
Dieser Commit ist enthalten in:
Ursprung
6b84e07c34
Commit
8f98162c69
@ -28,31 +28,23 @@ 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.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
|
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 org.geysermc.connector.entity.type.EntityType;
|
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;
|
||||||
|
|
||||||
public class ItemEntity extends Entity {
|
public class ItemEntity extends ThrowableEntity {
|
||||||
|
|
||||||
protected ItemData item;
|
protected ItemData item;
|
||||||
|
|
||||||
|
private int waterLevel = -1;
|
||||||
|
|
||||||
public ItemEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ItemEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
||||||
super(entityId, geyserId, entityType, position.add(0d, entityType.getOffset(), 0d), motion, rotation);
|
super(entityId, geyserId, entityType, position, motion, rotation);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMotion(Vector3f motion) {
|
|
||||||
if (isOnGround())
|
|
||||||
motion = Vector3f.from(motion.getX(), 0, motion.getZ());
|
|
||||||
|
|
||||||
super.setMotion(motion);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
|
||||||
super.moveAbsolute(session, position.add(0d, this.entityType.getOffset(), 0d), rotation, isOnGround, teleported);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -63,14 +55,63 @@ public class ItemEntity extends Entity {
|
|||||||
valid = true;
|
valid = true;
|
||||||
AddItemEntityPacket itemPacket = new AddItemEntityPacket();
|
AddItemEntityPacket itemPacket = new AddItemEntityPacket();
|
||||||
itemPacket.setRuntimeEntityId(geyserId);
|
itemPacket.setRuntimeEntityId(geyserId);
|
||||||
|
itemPacket.setUniqueEntityId(geyserId);
|
||||||
itemPacket.setPosition(position.add(0d, this.entityType.getOffset(), 0d));
|
itemPacket.setPosition(position.add(0d, this.entityType.getOffset(), 0d));
|
||||||
itemPacket.setMotion(motion);
|
itemPacket.setMotion(motion);
|
||||||
itemPacket.setUniqueEntityId(geyserId);
|
|
||||||
itemPacket.setFromFishing(false);
|
itemPacket.setFromFishing(false);
|
||||||
itemPacket.setItemInHand(item);
|
itemPacket.setItemInHand(item);
|
||||||
|
itemPacket.getMetadata().putAll(metadata);
|
||||||
session.sendUpstreamPacket(itemPacket);
|
session.sendUpstreamPacket(itemPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(GeyserSession session) {
|
||||||
|
if (isInWater(session)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!onGround || (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) > 0.00001) {
|
||||||
|
float gravity = getGravity(session);
|
||||||
|
motion = motion.down(gravity);
|
||||||
|
moveAbsoluteImmediate(session, position.add(motion), rotation, onGround, false);
|
||||||
|
float drag = getDrag(session);
|
||||||
|
motion = motion.mul(drag, 0.98f, drag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void moveAbsoluteImmediate(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
||||||
|
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
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||||
if (entityMetadata.getId() == 8) {
|
if (entityMetadata.getId() == 8) {
|
||||||
@ -81,4 +122,9 @@ public class ItemEntity extends Entity {
|
|||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
super.updateBedrockMetadata(entityMetadata, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isInWater(GeyserSession session) {
|
||||||
|
return waterLevel != -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
package org.geysermc.connector.network.translators.java.entity;
|
package org.geysermc.connector.network.translators.java.entity;
|
||||||
|
|
||||||
import org.geysermc.connector.entity.Entity;
|
import org.geysermc.connector.entity.Entity;
|
||||||
|
import org.geysermc.connector.entity.ItemEntity;
|
||||||
import org.geysermc.connector.entity.living.animal.horse.AbstractHorseEntity;
|
import org.geysermc.connector.entity.living.animal.horse.AbstractHorseEntity;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||||
@ -54,6 +55,12 @@ public class JavaEntityVelocityTranslator extends PacketTranslator<ServerEntityV
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (entity instanceof ItemEntity) {
|
||||||
|
// Don't bother sending entity motion packets for items
|
||||||
|
// since the client doesn't seem to care
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SetEntityMotionPacket entityMotionPacket = new SetEntityMotionPacket();
|
SetEntityMotionPacket entityMotionPacket = new SetEntityMotionPacket();
|
||||||
entityMotionPacket.setRuntimeEntityId(entity.getGeyserId());
|
entityMotionPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||||
entityMotionPacket.setMotion(entity.getMotion());
|
entityMotionPacket.setMotion(entity.getMotion());
|
||||||
|
@ -27,6 +27,7 @@ package org.geysermc.connector.network.translators.world.block;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import it.unimi.dsi.fastutil.ints.*;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
|
import org.geysermc.connector.registry.BlockRegistries;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
@ -301,4 +302,25 @@ public class BlockStateValues {
|
|||||||
public static int getWaterLevel(int state) {
|
public static int getWaterLevel(int state) {
|
||||||
return WATER_LEVEL.getOrDefault(state, -1);
|
return WATER_LEVEL.getOrDefault(state, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the slipperiness of a block.
|
||||||
|
* This is used in ItemEntity to calculate the friction on an item as it slides across the ground
|
||||||
|
*
|
||||||
|
* @param state BlockState of the block
|
||||||
|
* @return The block's slipperiness
|
||||||
|
*/
|
||||||
|
public static float getSlipperiness(int state) {
|
||||||
|
String blockIdentifier = BlockRegistries.JAVA_BLOCKS.get(state).getJavaIdentifier();
|
||||||
|
switch (blockIdentifier) {
|
||||||
|
case "minecraft:slime_block":
|
||||||
|
return 0.8f;
|
||||||
|
case "minecraft:ice":
|
||||||
|
case "minecraft:packed_ice":
|
||||||
|
return 0.98f;
|
||||||
|
case "minecraft:blue_ice":
|
||||||
|
return 0.989f;
|
||||||
|
}
|
||||||
|
return 0.6f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren