Search in sources :

Example 1 with IMixinEntityPlayer

use of org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer in project SpongeCommon by SpongePowered.

the class EntityUtil method playerDropItem.

@Nullable
public static EntityItem playerDropItem(IMixinEntityPlayer mixinPlayer, ItemStack droppedItem, boolean dropAround, boolean traceItem) {
    mixinPlayer.shouldRestoreInventory(false);
    final EntityPlayer player = EntityUtil.toNative(mixinPlayer);
    final double posX = player.posX;
    final double adjustedPosY = player.posY - 0.3 + player.getEyeHeight();
    final double posZ = player.posZ;
    // Now the real fun begins.
    final ItemStack item;
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(player);
        // FIRST we want to throw the DropItemEvent.PRE
        final ItemStackSnapshot snapshot = ItemStackUtil.snapshotOf(droppedItem);
        final List<ItemStackSnapshot> original = new ArrayList<>();
        original.add(snapshot);
        final DropItemEvent.Pre dropEvent = SpongeEventFactory.createDropItemEventPre(Sponge.getCauseStackManager().getCurrentCause(), ImmutableList.of(snapshot), original);
        SpongeImpl.postEvent(dropEvent);
        if (dropEvent.isCancelled()) {
            mixinPlayer.shouldRestoreInventory(true);
            return null;
        }
        if (dropEvent.getDroppedItems().isEmpty()) {
            return null;
        }
        // SECOND throw the ConstructEntityEvent
        Transform<World> suggested = new Transform<>(mixinPlayer.getWorld(), new Vector3d(posX, adjustedPosY, posZ));
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.DROPPED_ITEM);
        ConstructEntityEvent.Pre event = SpongeEventFactory.createConstructEntityEventPre(Sponge.getCauseStackManager().getCurrentCause(), EntityTypes.ITEM, suggested);
        SpongeImpl.postEvent(event);
        if (event.isCancelled()) {
            mixinPlayer.shouldRestoreInventory(true);
            return null;
        }
        item = event.isCancelled() ? null : ItemStackUtil.fromSnapshotToNative(dropEvent.getDroppedItems().get(0));
        if (item == null) {
            mixinPlayer.shouldRestoreInventory(true);
            return null;
        }
        final PhaseData peek = PhaseTracker.getInstance().getCurrentPhaseData();
        final IPhaseState currentState = peek.state;
        final PhaseContext<?> phaseContext = peek.context;
        if (!currentState.ignoresItemPreMerging() && SpongeImpl.getGlobalConfig().getConfig().getOptimizations().doDropsPreMergeItemDrops()) {
            final Collection<ItemDropData> itemStacks;
            if (currentState.tracksEntitySpecificDrops()) {
                final Multimap<UUID, ItemDropData> multimap = phaseContext.getCapturedEntityDropSupplier().get();
                itemStacks = multimap.get(player.getUniqueID());
            } else {
                itemStacks = phaseContext.getCapturedItemStackSupplier().get();
            }
            SpongeImplHooks.addItemStackToListForSpawning(itemStacks, ItemDropData.Player.player(player).stack(item).trace(traceItem).motion(createDropMotion(dropAround, player, mixinPlayer.getRandom())).dropAround(dropAround).position(new Vector3d(posX, adjustedPosY, posZ)).build());
            return null;
        }
        EntityItem entityitem = new EntityItem(player.world, posX, adjustedPosY, posZ, droppedItem);
        entityitem.setPickupDelay(40);
        if (traceItem) {
            entityitem.setThrower(player.getName());
        }
        final Random random = mixinPlayer.getRandom();
        if (dropAround) {
            float f = random.nextFloat() * 0.5F;
            float f1 = random.nextFloat() * ((float) Math.PI * 2F);
            entityitem.motionX = -MathHelper.sin(f1) * f;
            entityitem.motionZ = MathHelper.cos(f1) * f;
            entityitem.motionY = 0.20000000298023224D;
        } else {
            float f2 = 0.3F;
            entityitem.motionX = -MathHelper.sin(player.rotationYaw * 0.017453292F) * MathHelper.cos(player.rotationPitch * 0.017453292F) * f2;
            entityitem.motionZ = MathHelper.cos(player.rotationYaw * 0.017453292F) * MathHelper.cos(player.rotationPitch * 0.017453292F) * f2;
            entityitem.motionY = -MathHelper.sin(player.rotationPitch * 0.017453292F) * f2 + 0.1F;
            float f3 = random.nextFloat() * ((float) Math.PI * 2F);
            f2 = 0.02F * random.nextFloat();
            entityitem.motionX += Math.cos(f3) * f2;
            entityitem.motionY += (random.nextFloat() - random.nextFloat()) * 0.1F;
            entityitem.motionZ += Math.sin(f3) * f2;
        }
        // FIFTH - Capture the entity maybe?
        if (currentState.doesCaptureEntityDrops()) {
            if (currentState.tracksEntitySpecificDrops()) {
                // We are capturing per entity drop
                phaseContext.getCapturedEntityItemDropSupplier().get().put(player.getUniqueID(), entityitem);
            } else {
                // We are adding to a general list - usually for EntityPhase.State.DEATH
                phaseContext.getCapturedItemsSupplier().get().add(entityitem);
            }
            // Return the item, even if it wasn't spawned in the world.
            return entityitem;
        }
        ItemStack itemstack = dropItemAndGetStack(player, entityitem);
        if (traceItem) {
            if (!itemstack.isEmpty()) {
                player.addStat(StatList.getDroppedObjectStats(itemstack.getItem()), droppedItem.getCount());
            }
            player.addStat(StatList.DROP);
        }
        return entityitem;
    }
}
Also used : ArrayList(java.util.ArrayList) World(org.spongepowered.api.world.World) Random(java.util.Random) CauseStackManager(org.spongepowered.api.event.CauseStackManager) UUID(java.util.UUID) EntityItem(net.minecraft.entity.item.EntityItem) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) ConstructEntityEvent(org.spongepowered.api.event.entity.ConstructEntityEvent) Vector3d(com.flowpowered.math.vector.Vector3d) IMixinEntityPlayer(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer) EntityPlayer(net.minecraft.entity.player.EntityPlayer) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) ItemStack(net.minecraft.item.ItemStack) Transform(org.spongepowered.api.entity.Transform) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) Nullable(javax.annotation.Nullable)

Example 2 with IMixinEntityPlayer

use of org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer in project SpongeCommon by SpongePowered.

the class MixinEntityPlayerMP method onClonePlayer.

@Inject(method = "copyFrom", at = @At("HEAD"))
public void onClonePlayer(EntityPlayerMP oldPlayer, boolean respawnFromEnd, CallbackInfo ci) {
    // Copy over sponge data from the old player.
    // Allows plugins to specify data that persists after players respawn.
    IMixinEntity oldEntity = (IMixinEntity) oldPlayer;
    NBTTagCompound old = oldEntity.getEntityData();
    if (old.hasKey(NbtDataUtil.SPONGE_DATA)) {
        this.getEntityData().setTag(NbtDataUtil.SPONGE_DATA, old.getCompoundTag(NbtDataUtil.SPONGE_DATA));
        this.readFromNbt(this.getSpongeData());
    }
    // Copy overworld spawn pos
    ((IMixinEntityPlayer) this).setOverworldSpawnPoint(SpongeImplHooks.getBedLocation(oldPlayer, 0));
}
Also used : NBTTagCompound(net.minecraft.nbt.NBTTagCompound) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) IMixinEntityPlayer(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 3 with IMixinEntityPlayer

use of org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer in project SpongeCommon by SpongePowered.

the class MixinContainer method onDragDropSplit.

@Redirect(method = "slotClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/EntityPlayer;dropItem(Lnet/minecraft/item/ItemStack;Z)Lnet/minecraft/entity/item/EntityItem;", ordinal = 1))
public EntityItem onDragDropSplit(EntityPlayer player, ItemStack itemStackIn, boolean unused) {
    final EntityItem entityItem = player.dropItem(itemStackIn, unused);
    if (!((IMixinEntityPlayer) player).shouldRestoreInventory()) {
        return entityItem;
    }
    if (entityItem == null) {
        ItemStack original = null;
        if (player.inventory.getItemStack().isEmpty()) {
            original = itemStackIn;
        } else {
            player.inventory.getItemStack().grow(1);
            original = player.inventory.getItemStack();
        }
        player.inventory.setItemStack(original);
        ((EntityPlayerMP) player).connection.sendPacket(new SPacketSetSlot(-1, -1, original));
    }
    ((IMixinEntityPlayer) player).shouldRestoreInventory(false);
    return entityItem;
}
Also used : SPacketSetSlot(net.minecraft.network.play.server.SPacketSetSlot) ItemStack(net.minecraft.item.ItemStack) IMixinEntityPlayer(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer) EntityItem(net.minecraft.entity.item.EntityItem) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 4 with IMixinEntityPlayer

use of org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer in project SpongeCommon by SpongePowered.

the class MixinContainer method onThrowClick.

@Redirect(method = "slotClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/EntityPlayer;dropItem(Lnet/minecraft/item/ItemStack;Z)Lnet/minecraft/entity/item/EntityItem;", ordinal = 3))
public EntityItem onThrowClick(EntityPlayer player, ItemStack itemStackIn, boolean unused) {
    final EntityItem entityItem = player.dropItem(itemStackIn, true);
    if (entityItem == null && ((IMixinEntityPlayer) player).shouldRestoreInventory()) {
        final ItemStack original = ItemStackUtil.toNative(this.itemStackSnapshot.createStack());
        this.lastSlotUsed.putStack(original);
        player.openContainer.detectAndSendChanges();
        ((EntityPlayerMP) player).isChangingQuantityOnly = false;
        ((EntityPlayerMP) player).connection.sendPacket(new SPacketSetSlot(player.openContainer.windowId, this.lastSlotUsed.slotNumber, original));
    }
    this.itemStackSnapshot = null;
    this.lastSlotUsed = null;
    ((IMixinEntityPlayer) player).shouldRestoreInventory(false);
    return entityItem;
}
Also used : SPacketSetSlot(net.minecraft.network.play.server.SPacketSetSlot) ItemStack(net.minecraft.item.ItemStack) IMixinEntityPlayer(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer) EntityItem(net.minecraft.entity.item.EntityItem) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 5 with IMixinEntityPlayer

use of org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer in project SpongeCommon by SpongePowered.

the class EntityUtil method entityOnDropItem.

/**
 * A simple redirected static util method for {@link Entity#entityDropItem(ItemStack, float)}
 * for easy debugging.
 * @param entity
 * @param itemStack
 * @param offsetY
 * @return
 */
public static EntityItem entityOnDropItem(Entity entity, ItemStack itemStack, float offsetY) {
    final IMixinEntity mixinEntity = EntityUtil.toMixin(entity);
    final IMixinEntityPlayer mixinPlayer = entity instanceof Player ? (IMixinEntityPlayer) entity : null;
    // Now the real fun begins.
    final ItemStack item;
    final double posX = entity.posX;
    final double posY = entity.posY + offsetY;
    final double posZ = entity.posZ;
    if (itemStack.isEmpty()) {
        return null;
    }
    // FIRST we want to throw the DropItemEvent.PRE
    final ItemStackSnapshot snapshot = ItemStackUtil.snapshotOf(itemStack);
    final List<ItemStackSnapshot> original = new ArrayList<>();
    original.add(snapshot);
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(entity);
        final DropItemEvent.Pre dropEvent = SpongeEventFactory.createDropItemEventPre(Sponge.getCauseStackManager().getCurrentCause(), ImmutableList.of(snapshot), original);
        SpongeImpl.postEvent(dropEvent);
        if (dropEvent.isCancelled()) {
            if (mixinPlayer != null) {
                mixinPlayer.shouldRestoreInventory(true);
            }
            return null;
        }
        if (dropEvent.getDroppedItems().isEmpty()) {
            return null;
        }
        // SECOND throw the ConstructEntityEvent
        Transform<World> suggested = new Transform<>(mixinEntity.getWorld(), new Vector3d(posX, entity.posY + offsetY, posZ));
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.DROPPED_ITEM);
        ConstructEntityEvent.Pre event = SpongeEventFactory.createConstructEntityEventPre(Sponge.getCauseStackManager().getCurrentCause(), EntityTypes.ITEM, suggested);
        SpongeImpl.postEvent(event);
        item = event.isCancelled() ? null : ItemStackUtil.fromSnapshotToNative(dropEvent.getDroppedItems().get(0));
        if (item == null) {
            if (mixinPlayer != null) {
                mixinPlayer.shouldRestoreInventory(true);
            }
            return null;
        }
        final PhaseData peek = PhaseTracker.getInstance().getCurrentPhaseData();
        final IPhaseState currentState = peek.state;
        final PhaseContext<?> phaseContext = peek.context;
        if (item.isEmpty()) {
            return null;
        }
        if (!currentState.ignoresItemPreMerging() && SpongeImpl.getGlobalConfig().getConfig().getOptimizations().doDropsPreMergeItemDrops()) {
            if (currentState.tracksEntitySpecificDrops()) {
                final Multimap<UUID, ItemDropData> multimap = phaseContext.getCapturedEntityDropSupplier().get();
                final Collection<ItemDropData> itemStacks = multimap.get(entity.getUniqueID());
                SpongeImplHooks.addItemStackToListForSpawning(itemStacks, ItemDropData.item(item).position(new Vector3d(posX, posY, posZ)).build());
                return null;
            }
            final List<ItemDropData> itemStacks = phaseContext.getCapturedItemStackSupplier().get();
            SpongeImplHooks.addItemStackToListForSpawning(itemStacks, ItemDropData.item(item).position(new Vector3d(posX, posY, posZ)).build());
            return null;
        }
        EntityItem entityitem = new EntityItem(entity.world, posX, posY, posZ, item);
        entityitem.setDefaultPickupDelay();
        // FIFTH - Capture the entity maybe?
        if (currentState.doesCaptureEntityDrops()) {
            if (currentState.tracksEntitySpecificDrops()) {
                // We are capturing per entity drop
                phaseContext.getCapturedEntityItemDropSupplier().get().put(entity.getUniqueID(), entityitem);
            } else {
                // We are adding to a general list - usually for EntityPhase.State.DEATH
                phaseContext.getCapturedItemsSupplier().get().add(entityitem);
            }
            // Return the item, even if it wasn't spawned in the world.
            return entityitem;
        }
        // FINALLY - Spawn the entity in the world if all else didn't fail
        entity.world.spawnEntity(entityitem);
        return entityitem;
    }
}
Also used : ArrayList(java.util.ArrayList) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) World(org.spongepowered.api.world.World) CauseStackManager(org.spongepowered.api.event.CauseStackManager) IMixinEntityPlayer(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer) UUID(java.util.UUID) EntityItem(net.minecraft.entity.item.EntityItem) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) Player(org.spongepowered.api.entity.living.player.Player) IMixinEntityPlayer(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer) EntityPlayer(net.minecraft.entity.player.EntityPlayer) ConstructEntityEvent(org.spongepowered.api.event.entity.ConstructEntityEvent) Vector3d(com.flowpowered.math.vector.Vector3d) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) ItemStack(net.minecraft.item.ItemStack) Transform(org.spongepowered.api.entity.Transform) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData)

Aggregations

IMixinEntityPlayer (org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer)7 EntityItem (net.minecraft.entity.item.EntityItem)4 EntityPlayer (net.minecraft.entity.player.EntityPlayer)4 ItemStack (net.minecraft.item.ItemStack)4 Vector3d (com.flowpowered.math.vector.Vector3d)3 Transform (org.spongepowered.api.entity.Transform)3 ConstructEntityEvent (org.spongepowered.api.event.entity.ConstructEntityEvent)3 ArrayList (java.util.ArrayList)2 UUID (java.util.UUID)2 Nullable (javax.annotation.Nullable)2 SPacketSetSlot (net.minecraft.network.play.server.SPacketSetSlot)2 CauseStackManager (org.spongepowered.api.event.CauseStackManager)2 DropItemEvent (org.spongepowered.api.event.item.inventory.DropItemEvent)2 ItemStackSnapshot (org.spongepowered.api.item.inventory.ItemStackSnapshot)2 World (org.spongepowered.api.world.World)2 Redirect (org.spongepowered.asm.mixin.injection.Redirect)2 ItemDropData (org.spongepowered.common.event.tracking.context.ItemDropData)2 IMixinEntity (org.spongepowered.common.interfaces.entity.IMixinEntity)2 Random (java.util.Random)1 IBlockState (net.minecraft.block.state.IBlockState)1