Search in sources :

Example 1 with EntityAccessor

use of org.spongepowered.common.accessor.world.entity.EntityAccessor in project SpongeCommon by SpongePowered.

the class FireworkRocketData method register.

// @formatter:off
public static void register(final DataProviderRegistrator registrator) {
    registrator.asMutable(FireworkRocketEntity.class).create(Keys.FIREWORK_EFFECTS).get(h -> FireworkUtil.getFireworkEffects(h).orElse(null)).set(FireworkUtil::setFireworkEffects).resetOnDelete(ImmutableList.of()).create(Keys.FIREWORK_FLIGHT_MODIFIER).get(h -> {
        final ItemStack item = FireworkUtil.getItem(h);
        final CompoundTag fireworks = item.getOrCreateTagElement(Constants.Item.Fireworks.FIREWORKS);
        if (fireworks.contains(Constants.Item.Fireworks.FLIGHT)) {
            return new SpongeTicks(fireworks.getByte(Constants.Item.Fireworks.FLIGHT));
        }
        return null;
    }).setAnd((h, v) -> {
        final int ticks = (int) v.ticks();
        if (ticks < 0 || ticks > Byte.MAX_VALUE) {
            return false;
        }
        final ItemStack item = FireworkUtil.getItem(h);
        final CompoundTag fireworks = item.getOrCreateTagElement(Constants.Item.Fireworks.FIREWORKS);
        fireworks.putByte(Constants.Item.Fireworks.FLIGHT, (byte) ticks);
        ((FireworkRocketEntityAccessor) h).accessor$lifetime(10 * ticks + ((EntityAccessor) h).accessor$random().nextInt(6) + ((EntityAccessor) h).accessor$random().nextInt(7));
        return true;
    });
}
Also used : FireworkRocketEntity(net.minecraft.world.entity.projectile.FireworkRocketEntity) Keys(org.spongepowered.api.data.Keys) FireworkRocketEntityAccessor(org.spongepowered.common.accessor.world.entity.projectile.FireworkRocketEntityAccessor) FireworkUtil(org.spongepowered.common.util.FireworkUtil) CompoundTag(net.minecraft.nbt.CompoundTag) ImmutableList(com.google.common.collect.ImmutableList) Constants(org.spongepowered.common.util.Constants) DataProviderRegistrator(org.spongepowered.common.data.provider.DataProviderRegistrator) EntityAccessor(org.spongepowered.common.accessor.world.entity.EntityAccessor) SpongeTicks(org.spongepowered.common.util.SpongeTicks) ItemStack(net.minecraft.world.item.ItemStack) FireworkRocketEntityAccessor(org.spongepowered.common.accessor.world.entity.projectile.FireworkRocketEntityAccessor) EntityAccessor(org.spongepowered.common.accessor.world.entity.EntityAccessor) FireworkUtil(org.spongepowered.common.util.FireworkUtil) FireworkRocketEntity(net.minecraft.world.entity.projectile.FireworkRocketEntity) ItemStack(net.minecraft.world.item.ItemStack) SpongeTicks(org.spongepowered.common.util.SpongeTicks) FireworkRocketEntityAccessor(org.spongepowered.common.accessor.world.entity.projectile.FireworkRocketEntityAccessor) CompoundTag(net.minecraft.nbt.CompoundTag)

Example 2 with EntityAccessor

use of org.spongepowered.common.accessor.world.entity.EntityAccessor in project SpongeCommon by SpongePowered.

the class LivingData method register.

// @formatter:off
public static void register(final DataProviderRegistrator registrator) {
    registrator.asMutable(LivingEntity.class).create(Keys.ABSORPTION).get(h -> (double) h.getAbsorptionAmount()).setAnd((h, v) -> {
        if (v < 0) {
            return false;
        }
        h.setAbsorptionAmount(v.floatValue());
        return true;
    }).create(Keys.ACTIVE_ITEM).get(h -> ItemStackUtil.snapshotOf(h.getUseItem())).setAnd((h, v) -> {
        if (v.isEmpty()) {
            h.releaseUsingItem();
            return true;
        }
        return false;
    }).delete(LivingEntity::releaseUsingItem).create(Keys.AUTO_SPIN_ATTACK_TICKS).get(h -> Ticks.of(((LivingEntityAccessor) h).accessor$autoSpinAttackTicks())).set((h, v) -> h.startAutoSpinAttack((int) v.ticks())).create(Keys.BODY_ROTATIONS).get(h -> {
        final double headYaw = h.getYHeadRot();
        final double pitch = h.xRot;
        final double yaw = h.yRot;
        return ImmutableMap.of(BodyParts.HEAD.get(), new Vector3d(pitch, headYaw, 0), BodyParts.CHEST.get(), new Vector3d(pitch, yaw, 0));
    }).set((h, v) -> {
        final Vector3d headRotation = v.get(BodyParts.HEAD.get());
        final Vector3d bodyRotation = v.get(BodyParts.CHEST.get());
        if (bodyRotation != null) {
            h.yRot = (float) bodyRotation.y();
            h.xRot = (float) bodyRotation.x();
        }
        if (headRotation != null) {
            h.yHeadRot = (float) headRotation.y();
            h.xRot = (float) headRotation.x();
        }
    }).create(Keys.CHEST_ROTATION).get(h -> new Vector3d(h.xRot, h.yRot, 0)).set((h, v) -> {
        final float yaw = (float) v.y();
        final float pitch = (float) v.x();
        h.yRot = yaw;
        h.xRot = pitch;
    }).create(Keys.HEAD_ROTATION).get(h -> new Vector3d(h.xRot, h.getYHeadRot(), 0)).set((h, v) -> {
        final float headYaw = (float) v.y();
        final float pitch = (float) v.x();
        h.yHeadRot = headYaw;
        h.xRot = pitch;
    }).create(Keys.HEALTH).get(h -> (double) h.getHealth()).setAnd((h, v) -> {
        final double maxHealth = h.getMaxHealth();
        // Check bounds
        if (v < 0 || v > maxHealth) {
            return false;
        }
        if (v == 0) {
            // Cause DestructEntityEvent to fire first
            h.hurt((DamageSource) SpongeDamageSources.IGNORED, Float.MAX_VALUE);
        }
        h.setHealth(v.floatValue());
        return true;
    }).create(Keys.IS_AUTO_SPIN_ATTACK).get(LivingEntity::isAutoSpinAttack).create(Keys.IS_ELYTRA_FLYING).get(LivingEntity::isFallFlying).set((h, v) -> ((EntityAccessor) h).invoker$setSharedFlag(Constants.Entity.ELYTRA_FLYING_FLAG, v)).create(Keys.LAST_ATTACKER).get(h -> (Entity) h.getLastHurtByMob()).setAnd((h, v) -> {
        if (v instanceof LivingEntity) {
            h.setLastHurtByMob((LivingEntity) v);
            return true;
        }
        return false;
    }).delete(h -> h.setLastHurtByMob(null)).create(Keys.MAX_HEALTH).get(h -> (double) h.getMaxHealth()).set((h, v) -> h.getAttribute(Attributes.MAX_HEALTH).setBaseValue(v)).create(Keys.POTION_EFFECTS).get(h -> {
        final Collection<MobEffectInstance> effects = h.getActiveEffects();
        return PotionEffectUtil.copyAsPotionEffects(effects);
    }).set((h, v) -> {
        h.removeAllEffects();
        for (final PotionEffect effect : v) {
            h.addEffect(PotionEffectUtil.copyAsEffectInstance(effect));
        }
    }).create(Keys.SCALE).get(h -> (double) h.getScale()).create(Keys.STUCK_ARROWS).get(LivingEntity::getArrowCount).setAnd((h, v) -> {
        if (v < 0 || v > Integer.MAX_VALUE) {
            return false;
        }
        h.setArrowCount(v);
        return true;
    }).create(Keys.WALKING_SPEED).get(h -> h.getAttribute(Attributes.MOVEMENT_SPEED).getValue()).setAnd((h, v) -> {
        if (v < 0) {
            return false;
        }
        h.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(v);
        return true;
    }).asMutable(LivingEntityAccessor.class).create(Keys.LAST_DAMAGE_RECEIVED).get(h -> (double) h.accessor$lastHurt()).set((h, v) -> h.accessor$lastHurt(v.floatValue()));
}
Also used : LivingEntity(net.minecraft.world.entity.LivingEntity) Ticks(org.spongepowered.api.util.Ticks) LivingEntity(net.minecraft.world.entity.LivingEntity) PotionEffectUtil(org.spongepowered.common.util.PotionEffectUtil) ImmutableMap(com.google.common.collect.ImmutableMap) Constants(org.spongepowered.common.util.Constants) SpongeDamageSources(org.spongepowered.common.event.cause.entity.damage.SpongeDamageSources) BodyParts(org.spongepowered.api.data.type.BodyParts) Collection(java.util.Collection) LivingEntityAccessor(org.spongepowered.common.accessor.world.entity.LivingEntityAccessor) MobEffectInstance(net.minecraft.world.effect.MobEffectInstance) Entity(org.spongepowered.api.entity.Entity) Keys(org.spongepowered.api.data.Keys) ItemStackUtil(org.spongepowered.common.item.util.ItemStackUtil) Vector3d(org.spongepowered.math.vector.Vector3d) DataProviderRegistrator(org.spongepowered.common.data.provider.DataProviderRegistrator) DamageSource(net.minecraft.world.damagesource.DamageSource) Attributes(net.minecraft.world.entity.ai.attributes.Attributes) EntityAccessor(org.spongepowered.common.accessor.world.entity.EntityAccessor) PotionEffect(org.spongepowered.api.effect.potion.PotionEffect) LivingEntityBridge(org.spongepowered.common.bridge.world.entity.LivingEntityBridge) LivingEntityAccessor(org.spongepowered.common.accessor.world.entity.LivingEntityAccessor) DamageSource(net.minecraft.world.damagesource.DamageSource) Vector3d(org.spongepowered.math.vector.Vector3d) PotionEffect(org.spongepowered.api.effect.potion.PotionEffect) Collection(java.util.Collection)

Example 3 with EntityAccessor

use of org.spongepowered.common.accessor.world.entity.EntityAccessor in project SpongeCommon by SpongePowered.

the class EntityMixin method bridge$dismountRidingEntity.

@Override
public boolean bridge$dismountRidingEntity(final DismountType type) {
    if (!this.level.isClientSide && ShouldFire.RIDE_ENTITY_EVENT_DISMOUNT) {
        try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
            frame.pushCause(this);
            frame.addContext(EventContextKeys.DISMOUNT_TYPE, type);
            if (SpongeCommon.post(SpongeEventFactory.createRideEntityEventDismount(frame.currentCause(), (org.spongepowered.api.entity.Entity) this.shadow$getVehicle()))) {
                return false;
            }
        }
    }
    final Entity tempEntity = this.shadow$getVehicle();
    if (tempEntity != null) {
        this.vehicle = null;
        ((EntityAccessor) tempEntity).invoker$removePassenger((Entity) (Object) this);
    }
    return true;
}
Also used : ChunkMap_TrackedEntityAccessor(org.spongepowered.common.accessor.server.level.ChunkMap_TrackedEntityAccessor) EntityAccessor(org.spongepowered.common.accessor.world.entity.EntityAccessor) LivingEntity(net.minecraft.world.entity.LivingEntity) ItemEntity(net.minecraft.world.entity.item.ItemEntity) Entity(net.minecraft.world.entity.Entity) CauseStackManager(org.spongepowered.api.event.CauseStackManager)

Example 4 with EntityAccessor

use of org.spongepowered.common.accessor.world.entity.EntityAccessor in project SpongeCommon by SpongePowered.

the class EntityData method register.

// @formatter:off
public static void register(final DataProviderRegistrator registrator) {
    registrator.asMutable(Entity.class).create(Keys.AGE).get(h -> h.tickCount).setAnd((h, v) -> {
        if (v < 0) {
            return false;
        }
        h.tickCount = v;
        return true;
    }).create(Keys.BASE_SIZE).get(h -> (double) h.getBbWidth()).create(Keys.BASE_VEHICLE).get(h -> {
        final Entity rootVehicle = h.getRootVehicle();
        if (rootVehicle == h) {
            return null;
        }
        return (org.spongepowered.api.entity.Entity) rootVehicle;
    }).create(Keys.CUSTOM_NAME).get(h -> h.hasCustomName() ? SpongeAdventure.asAdventure(h.getCustomName()) : null).set((h, v) -> h.setCustomName(SpongeAdventure.asVanilla(v))).delete(h -> {
        h.setCustomName(null);
        h.setCustomNameVisible(false);
    }).create(Keys.DISPLAY_NAME).get(h -> SpongeAdventure.asAdventure(h.getDisplayName())).create(Keys.EYE_HEIGHT).get(h -> (double) h.getEyeHeight()).create(Keys.EYE_POSITION).get(h -> VecHelper.toVector3d(h.getEyePosition(1f))).create(Keys.FALL_DISTANCE).get(h -> (double) h.fallDistance).setAnd((h, v) -> {
        if (v < 0) {
            return false;
        }
        h.fallDistance = v.floatValue();
        return true;
    }).create(Keys.FIRE_DAMAGE_DELAY).get(h -> new SpongeTicks(((EntityAccessor) h).invoker$getFireImmuneTicks())).setAnd((h, v) -> {
        final int ticks = (int) v.ticks();
        if (ticks < 1 || ticks > Short.MAX_VALUE) {
            return false;
        }
        ((EntityBridge) h).bridge$setFireImmuneTicks(ticks);
        return ((EntityAccessor) h).invoker$getFireImmuneTicks() == ticks;
    }).create(Keys.FIRE_TICKS).get(h -> ((EntityAccessor) h).accessor$remainingFireTicks() > 0 ? Ticks.of(((EntityAccessor) h).accessor$remainingFireTicks()) : null).set((h, v) -> {
        final int ticks = (int) v.ticks();
        ((EntityAccessor) h).accessor$remainingFireTicks(Math.max(ticks, Constants.Entity.MINIMUM_FIRE_TICKS));
    }).deleteAndGet(h -> {
        final EntityAccessor accessor = (EntityAccessor) h;
        final int ticks = accessor.accessor$remainingFireTicks();
        if (ticks < Constants.Entity.MINIMUM_FIRE_TICKS) {
            return DataTransactionResult.failNoData();
        }
        final DataTransactionResult.Builder dtrBuilder = DataTransactionResult.builder();
        dtrBuilder.replace(Value.immutableOf(Keys.FIRE_TICKS, new SpongeTicks(ticks)));
        dtrBuilder.replace(Value.immutableOf(Keys.FIRE_DAMAGE_DELAY, new SpongeTicks(((EntityAccessor) h).invoker$getFireImmuneTicks())));
        h.clearFire();
        return dtrBuilder.result(DataTransactionResult.Type.SUCCESS).build();
    }).create(Keys.HEIGHT).get(h -> (double) h.getBbHeight()).create(Keys.INVULNERABILITY_TICKS).get(h -> new SpongeTicks(h.invulnerableTime)).setAnd((h, v) -> {
        final int ticks = (int) v.ticks();
        if (ticks < 0) {
            return false;
        }
        h.invulnerableTime = ticks;
        if (h instanceof LivingEntity) {
            ((LivingEntity) h).hurtTime = ticks;
        }
        return true;
    }).create(Keys.IS_CUSTOM_NAME_VISIBLE).get(Entity::isCustomNameVisible).set(Entity::setCustomNameVisible).create(Keys.IS_FLYING).get(h -> h.hasImpulse).set((h, v) -> h.hasImpulse = v).supports(h -> !(h instanceof Player)).create(Keys.IS_GLOWING).get(Entity::isGlowing).set(Entity::setGlowing).create(Keys.IS_GRAVITY_AFFECTED).get(h -> !h.isNoGravity()).set((h, v) -> h.setNoGravity(!v)).create(Keys.IS_SNEAKING).get(Entity::isShiftKeyDown).set(Entity::setShiftKeyDown).create(Keys.IS_SPRINTING).get(Entity::isSprinting).set(Entity::setSprinting).create(Keys.IS_SILENT).get(Entity::isSilent).set(Entity::setSilent).create(Keys.IS_WET).get(Entity::isInWaterOrRain).create(Keys.ON_GROUND).get(Entity::isOnGround).create(Keys.PASSENGERS).get(h -> h.getPassengers().stream().map(org.spongepowered.api.entity.Entity.class::cast).collect(Collectors.toList())).set((h, v) -> {
        h.ejectPassengers();
        v.forEach(v1 -> ((Entity) v1).startRiding(h, true));
    }).create(Keys.REMAINING_AIR).get(h -> Math.max(0, h.getAirSupply())).setAnd((h, v) -> {
        if (v < 0 || v > h.getMaxAirSupply()) {
            return false;
        }
        if (v == 0 && h.getAirSupply() < 0) {
            return false;
        }
        h.setAirSupply(v);
        return true;
    }).create(Keys.SCALE).get(h -> 1d).create(Keys.SCOREBOARD_TAGS).get(Entity::getTags).set((h, v) -> {
        h.getTags().clear();
        h.getTags().addAll(v);
    }).create(Keys.TRANSIENT).get(h -> ((EntityAccessor) h).invoker$getEncodeId() == null).set((h, v) -> ((EntityBridge) h).bridge$setTransient(v)).create(Keys.VEHICLE).get(h -> (org.spongepowered.api.entity.Entity) h.getVehicle()).set((h, v) -> h.startRiding((Entity) v, true)).create(Keys.VELOCITY).get(h -> VecHelper.toVector3d(h.getDeltaMovement())).set((h, v) -> h.setDeltaMovement(VecHelper.toVanillaVector3d(v))).create(Keys.SWIFTNESS).get(m -> m.getDeltaMovement().length()).set((m, v) -> m.setDeltaMovement(m.getDeltaMovement().normalize().scale(v))).supports(m -> m.getDeltaMovement().lengthSqr() > 0).asMutable(EntityMaxAirBridge.class).create(Keys.MAX_AIR).get(EntityMaxAirBridge::bridge$getMaxAir).set(EntityMaxAirBridge::bridge$setMaxAir);
    registrator.spongeDataStore(ResourceKey.sponge("max_air"), EntityMaxAirBridge.class, Keys.MAX_AIR);
    registrator.newDataStore(SpongeEntitySnapshot.class, SpongeEntityArchetype.class).dataStore(Keys.CUSTOM_NAME, (dv, v) -> dv.set(Constants.Entity.CUSTOM_NAME, GsonComponentSerializer.gson().serialize(v)), dv -> dv.getString(Constants.Entity.CUSTOM_NAME).map(GsonComponentSerializer.gson()::deserialize));
// @formatter:on
}
Also used : GsonComponentSerializer(net.kyori.adventure.text.serializer.gson.GsonComponentSerializer) Ticks(org.spongepowered.api.util.Ticks) LivingEntity(net.minecraft.world.entity.LivingEntity) EntityMaxAirBridge(org.spongepowered.common.bridge.world.entity.EntityMaxAirBridge) Constants(org.spongepowered.common.util.Constants) SpongeEntityArchetype(org.spongepowered.common.entity.SpongeEntityArchetype) SpongeAdventure(org.spongepowered.common.adventure.SpongeAdventure) DataTransactionResult(org.spongepowered.api.data.DataTransactionResult) Collectors(java.util.stream.Collectors) Value(org.spongepowered.api.data.value.Value) SpongeEntitySnapshot(org.spongepowered.common.entity.SpongeEntitySnapshot) Player(net.minecraft.world.entity.player.Player) EntityBridge(org.spongepowered.common.bridge.world.entity.EntityBridge) Keys(org.spongepowered.api.data.Keys) Entity(net.minecraft.world.entity.Entity) DataProviderRegistrator(org.spongepowered.common.data.provider.DataProviderRegistrator) EntityAccessor(org.spongepowered.common.accessor.world.entity.EntityAccessor) VecHelper(org.spongepowered.common.util.VecHelper) ResourceKey(org.spongepowered.api.ResourceKey) SpongeTicks(org.spongepowered.common.util.SpongeTicks) EntityAccessor(org.spongepowered.common.accessor.world.entity.EntityAccessor) LivingEntity(net.minecraft.world.entity.LivingEntity) Entity(net.minecraft.world.entity.Entity) Player(net.minecraft.world.entity.player.Player) EntityMaxAirBridge(org.spongepowered.common.bridge.world.entity.EntityMaxAirBridge) SpongeEntityArchetype(org.spongepowered.common.entity.SpongeEntityArchetype) LivingEntity(net.minecraft.world.entity.LivingEntity) SpongeEntitySnapshot(org.spongepowered.common.entity.SpongeEntitySnapshot) SpongeTicks(org.spongepowered.common.util.SpongeTicks)

Example 5 with EntityAccessor

use of org.spongepowered.common.accessor.world.entity.EntityAccessor in project SpongeCommon by SpongePowered.

the class ServerGamePacketListenerImplMixin method impl$callMoveEntityEvent.

/**
 * Effectively, hooking into the following code block:
 * <pre>
 *       if (isMovePlayerPacketInvalid(packetIn)) {
 *          this.disconnect(new TranslationTextComponent("multiplayer.disconnect.invalid_player_movement"));
 *       } else {
 *          ServerWorld serverworld = this.server.world(this.player.dimension);
 *          if (!this.player.queuedEndExit) { // <---- Here is where we're injecting
 *             if (this.networkTickCount == 0) {
 *                this.captureCurrentPosition();
 *             }
 * </pre>
 * we can effectively short circuit the method to handle movement code where
 * returning {@code true} will escape the packet being processed further entirely and
 * {@code false} will allow the remaining processing of the method run.
 *
 * @param packetIn The movement packet
 */
@Inject(method = "handleMovePlayer", at = @At(value = "FIELD", opcode = Opcodes.GETFIELD, target = "Lnet/minecraft/server/network/ServerGamePacketListenerImpl;awaitingPositionFromClient:Lnet/minecraft/world/phys/Vec3;"), slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/server/level/ServerPlayer;wonGame:Z"), to = @At(value = "FIELD", target = "Lnet/minecraft/server/network/ServerGamePacketListenerImpl;tickCount:I", ordinal = 1)), cancellable = true)
private void impl$callMoveEntityEvent(final ServerboundMovePlayerPacket packetIn, final CallbackInfo ci) {
    // If the movement is modified we pretend that the player has queuedEndExit = true
    // so that vanilla wont process that packet further
    final ServerboundMovePlayerPacketAccessor packetInAccessor = (ServerboundMovePlayerPacketAccessor) packetIn;
    // We don't fire an event to avoid confusing plugins.
    if (!packetInAccessor.accessor$hasPos() && !packetInAccessor.accessor$hasRot()) {
        return;
    }
    final boolean goodMovementPacket = this.receivedMovePacketCount - this.knownMovePacketCount <= 5;
    final boolean fireMoveEvent = goodMovementPacket && packetInAccessor.accessor$hasPos() && ShouldFire.MOVE_ENTITY_EVENT;
    final boolean fireRotationEvent = goodMovementPacket && packetInAccessor.accessor$hasRot() && ShouldFire.ROTATE_ENTITY_EVENT;
    final ServerPlayer player = (ServerPlayer) this.player;
    final Vector3d fromRotation = new Vector3d(this.player.yRot, this.player.xRot, 0);
    // Use the position of the last movement with an event or the current player position if never called
    // We need this because we ignore very small position changes as to not spam as many move events.
    final Vector3d fromPosition = player.position();
    Vector3d toPosition = new Vector3d(packetIn.getX(this.player.getX()), packetIn.getY(this.player.getY()), packetIn.getZ(this.player.getZ()));
    Vector3d toRotation = new Vector3d(packetIn.getYRot(this.player.yRot), packetIn.getXRot(this.player.xRot), 0);
    final boolean significantRotation = fromRotation.distanceSquared(toRotation) > (.15f * .15f);
    final Vector3d originalToPosition = toPosition;
    boolean cancelMovement = false;
    boolean cancelRotation = false;
    // Call move & rotate event as needed...
    if (fireMoveEvent) {
        final MoveEntityEvent event = SpongeEventFactory.createMoveEntityEvent(PhaseTracker.getCauseStackManager().currentCause(), (ServerPlayer) this.player, fromPosition, toPosition, toPosition);
        if (SpongeCommon.post(event)) {
            cancelMovement = true;
        } else {
            toPosition = event.destinationPosition();
        }
    }
    if (significantRotation && fireRotationEvent) {
        final RotateEntityEvent event = SpongeEventFactory.createRotateEntityEvent(PhaseTracker.getCauseStackManager().currentCause(), (ServerPlayer) this.player, fromRotation, toRotation);
        if (SpongeCommon.post(event)) {
            cancelRotation = true;
            toRotation = fromRotation;
        } else {
            toRotation = event.toRotation();
        }
    }
    // player position and update the player's relation in the chunk manager.
    if (cancelMovement) {
        if (fromPosition.distanceSquared(toPosition) > 0) {
            // Set the location, as if the player was teleporting
            this.awaitingTeleportTime = this.tickCount;
            this.shadow$teleport(fromPosition.x(), fromPosition.y(), fromPosition.z(), (float) toRotation.x(), (float) toRotation.y());
        } else {
            // If this is only rotation do not teleport back
            this.player.absMoveTo(fromPosition.x(), fromPosition.y(), fromPosition.z(), (float) toRotation.x(), (float) toRotation.y());
        }
        ci.cancel();
        return;
    }
    // Handle event results
    if (!toPosition.equals(originalToPosition)) {
        // Check if we have to say it's a "teleport" vs a standard move
        final double d4 = packetIn.getX(this.player.getX());
        final double d5 = packetIn.getY(this.player.getY());
        final double d6 = packetIn.getZ(this.player.getZ());
        final double d7 = d4 - this.firstGoodX;
        final double d8 = d5 - this.firstGoodY;
        final double d9 = d6 - this.firstGoodZ;
        final double d10 = this.player.getDeltaMovement().lengthSqr();
        final double d11 = d7 * d7 + d8 * d8 + d9 * d9;
        final float f2 = this.player.isFallFlying() ? 300.0F : 100.0F;
        final int i = this.receivedMovePacketCount - this.knownMovePacketCount;
        if (d11 - d10 > (double) (f2 * (float) i) && !this.shadow$isSingleplayerOwner()) {
            // At this point, we need to set the target position so the teleport code forces it
            this.awaitingPositionFromClient = VecHelper.toVanillaVector3d(toPosition);
            ((EntityAccessor) this.player).invoker$setRot((float) toRotation.x(), (float) toRotation.y());
            // And reset the position update so the force set is done.
            this.awaitingTeleportTime = this.tickCount - Constants.Networking.MAGIC_TRIGGER_TELEPORT_CONFIRM_DIFF;
        } else {
            // otherwise, set the data back onto the packet
            packetInAccessor.accessor$hasPos(true);
            packetInAccessor.accessor$x(toPosition.x());
            packetInAccessor.accessor$y(toPosition.y());
            packetInAccessor.accessor$z(toPosition.z());
        }
    }
}
Also used : EntityAccessor(org.spongepowered.common.accessor.world.entity.EntityAccessor) ServerboundMovePlayerPacketAccessor(org.spongepowered.common.accessor.network.protocol.game.ServerboundMovePlayerPacketAccessor) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) Vector3d(org.spongepowered.math.vector.Vector3d) ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer) RotateEntityEvent(org.spongepowered.api.event.entity.RotateEntityEvent) Inject(org.spongepowered.asm.mixin.injection.Inject)

Aggregations

EntityAccessor (org.spongepowered.common.accessor.world.entity.EntityAccessor)7 Constants (org.spongepowered.common.util.Constants)4 LivingEntity (net.minecraft.world.entity.LivingEntity)3 Vector3d (org.spongepowered.math.vector.Vector3d)3 Collection (java.util.Collection)2 MinecraftServer (net.minecraft.server.MinecraftServer)2 Entity (net.minecraft.world.entity.Entity)2 Keys (org.spongepowered.api.data.Keys)2 Inject (org.spongepowered.asm.mixin.injection.Inject)2 SpongeAdventure (org.spongepowered.common.adventure.SpongeAdventure)2 DataProviderRegistrator (org.spongepowered.common.data.provider.DataProviderRegistrator)2 VecHelper (org.spongepowered.common.util.VecHelper)2 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 List (java.util.List)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 Random (java.util.Random)1