Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-25 15:50:14 +01:00
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
Dieser Commit ist enthalten in:
Ursprung
c30cb78e74
Commit
d93d4d0942
@ -26,11 +26,65 @@
|
||||
package org.geysermc.connector.entity;
|
||||
|
||||
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.network.session.GeyserSession;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
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) {
|
||||
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
|
||||
*/
|
||||
public static ItemEntry BUCKET;
|
||||
/**
|
||||
* Egg item entry, used in JavaEntityStatusTranslator.java
|
||||
*/
|
||||
public static ItemEntry EGG;
|
||||
/**
|
||||
* Gold item entry, used in PiglinEntity.java
|
||||
*/
|
||||
@ -141,6 +145,9 @@ public class ItemRegistry {
|
||||
case "minecraft:oak_boat":
|
||||
BOAT = ITEM_ENTRIES.get(itemIndex);
|
||||
break;
|
||||
case "minecraft:egg":
|
||||
EGG = ITEM_ENTRIES.get(itemIndex);
|
||||
break;
|
||||
case "minecraft:gold_ingot":
|
||||
GOLD = ITEM_ENTRIES.get(itemIndex);
|
||||
break;
|
||||
|
@ -25,10 +25,16 @@
|
||||
|
||||
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.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.EntityEventType;
|
||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||
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.SetEntityMotionPacket;
|
||||
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.translators.PacketTranslator;
|
||||
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)
|
||||
public class JavaEntityStatusTranslator extends PacketTranslator<ServerEntityStatusPacket> {
|
||||
@ -88,6 +97,22 @@ public class JavaEntityStatusTranslator extends PacketTranslator<ServerEntitySta
|
||||
break;
|
||||
case LIVING_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;
|
||||
case WOLF_SHAKE_WATER:
|
||||
entityEventPacket.setType(EntityEventType.SHAKE_WETNESS);
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 0fae8d3f0de6210a10435a36128db14cb7650ae6
|
||||
Subproject commit c87cc5fb05eb92beac638234906d836f9f1178ed
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren