forked from GeyserMC/Geyser
Projectile fixes (#1451)
* Predict the trajectory of projectiles and add particles * Correct lingering potion gravity * Update last position on move absolute * Clean up * Add egg to ItemRegistry and update mappings
This commit is contained in:
parent
c30cb78e74
commit
d93d4d0942
4 changed files with 87 additions and 1 deletions
|
@ -26,11 +26,65 @@
|
||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
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.entity.EntityFlag;
|
||||||
|
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class ThrowableEntity extends Entity {
|
public class ThrowableEntity extends Entity {
|
||||||
|
|
||||||
|
private Vector3f lastPosition;
|
||||||
|
private ScheduledFuture<?> positionUpdater;
|
||||||
|
|
||||||
public ThrowableEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public ThrowableEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(entityId, geyserId, entityType, position, motion, rotation);
|
||||||
|
this.lastPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawnEntity(GeyserSession session) {
|
||||||
|
super.spawnEntity(session);
|
||||||
|
positionUpdater = session.getConnector().getGeneralThreadPool().scheduleAtFixedRate(() -> {
|
||||||
|
super.moveRelative(session, motion.getX(), motion.getY(), motion.getZ(), rotation, onGround);
|
||||||
|
|
||||||
|
if (metadata.getFlags().getFlag(EntityFlag.HAS_GRAVITY)) {
|
||||||
|
float gravity = 0.03f; // Snowball, Egg, and Ender Pearl
|
||||||
|
if (entityType == EntityType.THROWN_POTION || entityType == EntityType.LINGERING_POTION) {
|
||||||
|
gravity = 0.05f;
|
||||||
|
} else if (entityType == EntityType.THROWN_EXP_BOTTLE) {
|
||||||
|
gravity = 0.07f;
|
||||||
|
}
|
||||||
|
motion = motion.down(gravity);
|
||||||
|
}
|
||||||
|
}, 0, 50, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean despawnEntity(GeyserSession session) {
|
||||||
|
positionUpdater.cancel(true);
|
||||||
|
if (entityType == EntityType.THROWN_ENDERPEARL) {
|
||||||
|
LevelEventPacket particlePacket = new LevelEventPacket();
|
||||||
|
particlePacket.setType(LevelEventType.PARTICLE_TELEPORT);
|
||||||
|
particlePacket.setPosition(position);
|
||||||
|
session.sendUpstreamPacket(particlePacket);
|
||||||
|
}
|
||||||
|
return super.despawnEntity(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) {
|
||||||
|
position = lastPosition;
|
||||||
|
super.moveRelative(session, relX, relY, relZ, rotation, isOnGround);
|
||||||
|
lastPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
||||||
|
super.moveAbsolute(session, position, rotation, isOnGround, teleported);
|
||||||
|
lastPosition = position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,10 @@ public class ItemRegistry {
|
||||||
* Bucket item entry, used in BedrockInventoryTransactionTranslator.java
|
* Bucket item entry, used in BedrockInventoryTransactionTranslator.java
|
||||||
*/
|
*/
|
||||||
public static ItemEntry BUCKET;
|
public static ItemEntry BUCKET;
|
||||||
|
/**
|
||||||
|
* Egg item entry, used in JavaEntityStatusTranslator.java
|
||||||
|
*/
|
||||||
|
public static ItemEntry EGG;
|
||||||
/**
|
/**
|
||||||
* Gold item entry, used in PiglinEntity.java
|
* Gold item entry, used in PiglinEntity.java
|
||||||
*/
|
*/
|
||||||
|
@ -141,6 +145,9 @@ public class ItemRegistry {
|
||||||
case "minecraft:oak_boat":
|
case "minecraft:oak_boat":
|
||||||
BOAT = ITEM_ENTRIES.get(itemIndex);
|
BOAT = ITEM_ENTRIES.get(itemIndex);
|
||||||
break;
|
break;
|
||||||
|
case "minecraft:egg":
|
||||||
|
EGG = ITEM_ENTRIES.get(itemIndex);
|
||||||
|
break;
|
||||||
case "minecraft:gold_ingot":
|
case "minecraft:gold_ingot":
|
||||||
GOLD = ITEM_ENTRIES.get(itemIndex);
|
GOLD = ITEM_ENTRIES.get(itemIndex);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -25,10 +25,16 @@
|
||||||
|
|
||||||
package org.geysermc.connector.network.translators.java.entity;
|
package org.geysermc.connector.network.translators.java.entity;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.world.particle.ItemParticleData;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityStatusPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityStatusPacket;
|
||||||
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
||||||
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.inventory.ItemData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
|
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
|
||||||
|
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket;
|
import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket;
|
||||||
import org.geysermc.connector.entity.Entity;
|
import org.geysermc.connector.entity.Entity;
|
||||||
|
@ -36,6 +42,9 @@ 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.PacketTranslator;
|
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||||
import org.geysermc.connector.network.translators.Translator;
|
import org.geysermc.connector.network.translators.Translator;
|
||||||
|
import org.geysermc.connector.network.translators.item.ItemEntry;
|
||||||
|
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
||||||
|
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||||
|
|
||||||
@Translator(packet = ServerEntityStatusPacket.class)
|
@Translator(packet = ServerEntityStatusPacket.class)
|
||||||
public class JavaEntityStatusTranslator extends PacketTranslator<ServerEntityStatusPacket> {
|
public class JavaEntityStatusTranslator extends PacketTranslator<ServerEntityStatusPacket> {
|
||||||
|
@ -88,6 +97,22 @@ public class JavaEntityStatusTranslator extends PacketTranslator<ServerEntitySta
|
||||||
break;
|
break;
|
||||||
case LIVING_DEATH:
|
case LIVING_DEATH:
|
||||||
entityEventPacket.setType(EntityEventType.DEATH);
|
entityEventPacket.setType(EntityEventType.DEATH);
|
||||||
|
if (entity.getEntityType() == EntityType.THROWN_EGG) {
|
||||||
|
LevelEventPacket particlePacket = new LevelEventPacket();
|
||||||
|
particlePacket.setType(LevelEventType.PARTICLE_ITEM_BREAK);
|
||||||
|
particlePacket.setData(ItemRegistry.EGG.getBedrockId() << 16);
|
||||||
|
particlePacket.setPosition(entity.getPosition());
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
session.sendUpstreamPacket(particlePacket);
|
||||||
|
}
|
||||||
|
} else if (entity.getEntityType() == EntityType.SNOWBALL) {
|
||||||
|
LevelEventPacket particlePacket = new LevelEventPacket();
|
||||||
|
particlePacket.setType(LevelEventType.PARTICLE_SNOWBALL_POOF);
|
||||||
|
particlePacket.setPosition(entity.getPosition());
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
session.sendUpstreamPacket(particlePacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WOLF_SHAKE_WATER:
|
case WOLF_SHAKE_WATER:
|
||||||
entityEventPacket.setType(EntityEventType.SHAKE_WETNESS);
|
entityEventPacket.setType(EntityEventType.SHAKE_WETNESS);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0fae8d3f0de6210a10435a36128db14cb7650ae6
|
Subproject commit c87cc5fb05eb92beac638234906d836f9f1178ed
|
Loading…
Reference in a new issue