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;
}
}
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));
}
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;
}
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;
}
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;
}
}
Aggregations