Search in sources :

Example 1 with EntityUtil

use of org.spongepowered.common.entity.EntityUtil in project SpongeCommon by SpongePowered.

the class DeathPhase method unwind.

@Override
public void unwind(BasicEntityContext context) {
    final Entity dyingEntity = context.getSource(Entity.class).orElseThrow(TrackingUtil.throwWithContext("Dying entity not found!", context));
    final DamageSource damageSource = context.getDamageSource();
    try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(damageSource);
        Sponge.getCauseStackManager().pushCause(dyingEntity);
        final boolean isPlayer = dyingEntity instanceof EntityPlayer;
        final EntityPlayer entityPlayer = isPlayer ? (EntityPlayer) dyingEntity : null;
        final Optional<User> notifier = context.getNotifier();
        final Optional<User> owner = context.getOwner();
        final User entityCreator = notifier.orElseGet(() -> owner.orElse(null));
        context.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
            // Separate experience orbs from other entity drops
            final List<Entity> experience = entities.stream().filter(entity -> entity instanceof ExperienceOrb).collect(Collectors.toList());
            if (!experience.isEmpty()) {
                Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.EXPERIENCE);
                final SpawnEntityEvent spawnEntityEvent = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), experience);
                SpongeImpl.postEvent(spawnEntityEvent);
                if (!spawnEntityEvent.isCancelled()) {
                    for (Entity entity : spawnEntityEvent.getEntities()) {
                        EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                    }
                }
            }
            // Now process other entities, this is separate from item drops specifically
            final List<Entity> other = entities.stream().filter(entity -> !(entity instanceof ExperienceOrb)).collect(Collectors.toList());
            if (!other.isEmpty()) {
                Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.ENTITY_DEATH);
                final SpawnEntityEvent spawnEntityEvent = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), experience);
                SpongeImpl.postEvent(spawnEntityEvent);
                if (!spawnEntityEvent.isCancelled()) {
                    for (Entity entity : spawnEntityEvent.getEntities()) {
                        EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                    }
                }
            }
        });
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
        // This allows mods such as Draconic Evolution to add items to the drop list
        if (context.getCapturedEntityItemDropSupplier().isEmpty() && context.getCapturedEntityDropSupplier().isEmpty()) {
            final ArrayList<Entity> entities = new ArrayList<>();
            final DropItemEvent.Destruct destruct = SpongeEventFactory.createDropItemEventDestruct(frame.getCurrentCause(), entities);
            SpongeImpl.postEvent(destruct);
            if (!destruct.isCancelled()) {
                for (Entity entity : destruct.getEntities()) {
                    EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                }
            }
            return;
        }
        context.getCapturedEntityItemDropSupplier().acceptAndRemoveIfPresent(dyingEntity.getUniqueId(), items -> {
            final ArrayList<Entity> entities = new ArrayList<>();
            for (EntityItem item : items) {
                entities.add(EntityUtil.fromNative(item));
            }
            if (isPlayer) {
                // Forge and Vanilla always clear items on player death BEFORE drops occur
                // This will also provide the highest compatibility with mods such as Tinkers Construct
                entityPlayer.inventory.clear();
            }
            final DropItemEvent.Destruct destruct = SpongeEventFactory.createDropItemEventDestruct(Sponge.getCauseStackManager().getCurrentCause(), entities);
            SpongeImpl.postEvent(destruct);
            if (!destruct.isCancelled()) {
                for (Entity entity : destruct.getEntities()) {
                    EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                }
            }
        // Note: If cancelled, the items do not spawn in the world and are NOT copied back to player inventory.
        // This avoids many issues with mods such as Tinkers Construct's soulbound items.
        });
        // Note that this is only used if and when item pre-merging is enabled. Which is never enabled in forge.
        context.getCapturedEntityDropSupplier().acceptAndRemoveIfPresent(dyingEntity.getUniqueId(), itemStacks -> {
            final List<ItemDropData> items = new ArrayList<>();
            items.addAll(itemStacks);
            if (!items.isEmpty()) {
                final net.minecraft.entity.Entity minecraftEntity = EntityUtil.toNative(dyingEntity);
                final List<Entity> itemEntities = items.stream().map(data -> data.create((WorldServer) minecraftEntity.world)).map(EntityUtil::fromNative).collect(Collectors.toList());
                if (isPlayer) {
                    // Forge and Vanilla always clear items on player death BEFORE drops occur
                    // This will also provide the highest compatibility with mods such as Tinkers Construct
                    entityPlayer.inventory.clear();
                }
                final DropItemEvent.Destruct destruct = SpongeEventFactory.createDropItemEventDestruct(Sponge.getCauseStackManager().getCurrentCause(), itemEntities);
                SpongeImpl.postEvent(destruct);
                if (!destruct.isCancelled()) {
                    for (Entity entity : destruct.getEntities()) {
                        if (entityCreator != null) {
                            EntityUtil.toMixin(entity).setCreator(entityCreator.getUniqueId());
                        }
                        EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                    }
                }
            // Note: If cancelled, the items do not spawn in the world and are NOT copied back to player inventory.
            // This avoids many issues with mods such as Tinkers Construct's soulbound items.
            }
        });
    }
}
Also used : EntityItem(net.minecraft.entity.item.EntityItem) SpongeImpl(org.spongepowered.common.SpongeImpl) User(org.spongepowered.api.entity.living.player.User) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) EventContextKeys(org.spongepowered.api.event.cause.EventContextKeys) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) Sponge(org.spongepowered.api.Sponge) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) DamageSource(org.spongepowered.api.event.cause.entity.damage.source.DamageSource) InternalSpawnTypes(org.spongepowered.common.registry.type.event.InternalSpawnTypes) Entity(org.spongepowered.api.entity.Entity) Collectors(java.util.stream.Collectors) EntityUtil(org.spongepowered.common.entity.EntityUtil) ArrayList(java.util.ArrayList) List(java.util.List) TrackingUtil(org.spongepowered.common.event.tracking.TrackingUtil) EntityPlayer(net.minecraft.entity.player.EntityPlayer) ExperienceOrb(org.spongepowered.api.entity.ExperienceOrb) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) Optional(java.util.Optional) WorldServer(net.minecraft.world.WorldServer) Entity(org.spongepowered.api.entity.Entity) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) User(org.spongepowered.api.entity.living.player.User) DamageSource(org.spongepowered.api.event.cause.entity.damage.source.DamageSource) ArrayList(java.util.ArrayList) ExperienceOrb(org.spongepowered.api.entity.ExperienceOrb) WorldServer(net.minecraft.world.WorldServer) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) EntityPlayer(net.minecraft.entity.player.EntityPlayer) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) EntityItem(net.minecraft.entity.item.EntityItem)

Example 2 with EntityUtil

use of org.spongepowered.common.entity.EntityUtil in project SpongeCommon by SpongePowered.

the class CloseWindowState method unwind.

@Override
public void unwind(BasicPacketContext context) {
    final EntityPlayerMP player = context.getSource(EntityPlayerMP.class).get();
    final Container container = context.getOpenContainer();
    ItemStackSnapshot lastCursor = context.getCursor();
    ItemStackSnapshot newCursor = ItemStackUtil.snapshotOf(player.inventory.getItemStack());
    if (lastCursor != null) {
        Sponge.getCauseStackManager().pushCause(player);
        InteractInventoryEvent.Close event = SpongeCommonEventFactory.callInteractInventoryCloseEvent(container, player, lastCursor, newCursor, true);
        if (event.isCancelled()) {
            Sponge.getCauseStackManager().popCause();
            return;
        }
        Sponge.getCauseStackManager().popCause();
    }
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(player);
        // Non-merged
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.PLACEMENT);
        // items
        context.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(items -> {
            final List<Entity> entities = items.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
            if (!entities.isEmpty()) {
                DropItemEvent.Custom drop = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
                SpongeImpl.postEvent(drop);
                if (!drop.isCancelled()) {
                    for (Entity droppedItem : drop.getEntities()) {
                        droppedItem.setCreator(player.getUniqueID());
                        ((IMixinWorldServer) player.getServerWorld()).forceSpawnEntity(droppedItem);
                    }
                }
            }
        });
        // Pre-merged items
        context.getCapturedItemStackSupplier().acceptAndClearIfNotEmpty(stacks -> {
            final List<EntityItem> items = stacks.stream().map(drop -> drop.create(player.getServerWorld())).collect(Collectors.toList());
            final List<Entity> entities = items.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
            if (!entities.isEmpty()) {
                DropItemEvent.Custom drop = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
                SpongeImpl.postEvent(drop);
                if (!drop.isCancelled()) {
                    for (Entity droppedItem : drop.getEntities()) {
                        droppedItem.setCreator(player.getUniqueID());
                        ((IMixinWorldServer) player.getServerWorld()).forceSpawnEntity(droppedItem);
                    }
                }
            }
        });
    }
    context.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(blocks -> TrackingUtil.processBlockCaptures(blocks, this, context));
}
Also used : EntityItem(net.minecraft.entity.item.EntityItem) SpongeImpl(org.spongepowered.common.SpongeImpl) Packet(net.minecraft.network.Packet) EventContextKeys(org.spongepowered.api.event.cause.EventContextKeys) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) Sponge(org.spongepowered.api.Sponge) InteractInventoryEvent(org.spongepowered.api.event.item.inventory.InteractInventoryEvent) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) SpongeCommonEventFactory(org.spongepowered.common.event.SpongeCommonEventFactory) Entity(org.spongepowered.api.entity.Entity) ItemStackUtil(org.spongepowered.common.item.inventory.util.ItemStackUtil) Collectors(java.util.stream.Collectors) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) EntityUtil(org.spongepowered.common.entity.EntityUtil) SpawnTypes(org.spongepowered.api.event.cause.entity.spawn.SpawnTypes) List(java.util.List) TrackingUtil(org.spongepowered.common.event.tracking.TrackingUtil) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Container(net.minecraft.inventory.Container) Entity(org.spongepowered.api.entity.Entity) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) InteractInventoryEvent(org.spongepowered.api.event.item.inventory.InteractInventoryEvent) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) Container(net.minecraft.inventory.Container) CauseStackManager(org.spongepowered.api.event.CauseStackManager) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) EntityItem(net.minecraft.entity.item.EntityItem)

Example 3 with EntityUtil

use of org.spongepowered.common.entity.EntityUtil in project SpongeCommon by SpongePowered.

the class InteractAtEntityPacketState method unwind.

@Override
public void unwind(BasicPacketContext context) {
    final EntityPlayerMP player = context.getPacketPlayer();
    final CPacketUseEntity useEntityPacket = context.getPacket();
    final net.minecraft.entity.Entity entity = useEntityPacket.getEntityFromWorld(player.world);
    if (entity == null) {
        // Something happened?
        return;
    }
    final World spongeWorld = EntityUtil.getSpongeWorld(player);
    EntityUtil.toMixin(entity).setNotifier(player.getUniqueID());
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(player);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PLACEMENT);
        context.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
            SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), entities);
            SpongeImpl.postEvent(event);
            if (!event.isCancelled()) {
                processSpawnedEntities(player, event);
            }
        });
        context.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(entities -> {
            final List<Entity> items = entities.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
            SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), items);
            SpongeImpl.postEvent(event);
            if (!event.isCancelled()) {
                processSpawnedEntities(player, event);
            }
        });
        context.getCapturedEntityDropSupplier().acceptIfNotEmpty(map -> {
            final PrettyPrinter printer = new PrettyPrinter(80);
            printer.add("Processing Interact At Entity").centre().hr();
            printer.add("The item stacks captured are: ");
            for (Map.Entry<UUID, Collection<ItemDropData>> entry : map.asMap().entrySet()) {
                printer.add("  - Entity with UUID: %s", entry.getKey());
                for (ItemDropData stack : entry.getValue()) {
                    printer.add("    - %s", stack);
                }
            }
            printer.trace(System.err);
        });
        context.getCapturedEntityItemDropSupplier().acceptIfNotEmpty(map -> {
            for (Map.Entry<UUID, Collection<EntityItem>> entry : map.asMap().entrySet()) {
                final UUID entityUuid = entry.getKey();
                final net.minecraft.entity.Entity entityFromUuid = player.getServerWorld().getEntityFromUuid(entityUuid);
                if (entityFromUuid != null) {
                    final List<Entity> entities = entry.getValue().stream().map(EntityUtil::fromNative).collect(Collectors.toList());
                    if (!entities.isEmpty()) {
                        DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
                        SpongeImpl.postEvent(event);
                        if (!event.isCancelled()) {
                            processSpawnedEntities(player, event);
                        }
                    }
                }
            }
        });
        context.getCapturedItemStackSupplier().acceptAndClearIfNotEmpty(drops -> {
            final List<EntityItem> items = drops.stream().map(drop -> drop.create(player.getServerWorld())).collect(Collectors.toList());
            final List<Entity> entities = items.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
            if (!entities.isEmpty()) {
                DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
                SpongeImpl.postEvent(event);
                if (!event.isCancelled()) {
                    processSpawnedEntities(player, event);
                }
            }
        });
    }
    context.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(snapshots -> TrackingUtil.processBlockCaptures(snapshots, this, context));
}
Also used : SpongeImpl(org.spongepowered.common.SpongeImpl) EventContextKeys(org.spongepowered.api.event.cause.EventContextKeys) CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) PrettyPrinter(org.spongepowered.asm.util.PrettyPrinter) ItemStackUtil(org.spongepowered.common.item.inventory.util.ItemStackUtil) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) ItemStack(org.spongepowered.api.item.inventory.ItemStack) TrackingUtil(org.spongepowered.common.event.tracking.TrackingUtil) Map(java.util.Map) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Nullable(javax.annotation.Nullable) EntityItem(net.minecraft.entity.item.EntityItem) Packet(net.minecraft.network.Packet) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) Collection(java.util.Collection) Sponge(org.spongepowered.api.Sponge) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) UUID(java.util.UUID) InternalSpawnTypes(org.spongepowered.common.registry.type.event.InternalSpawnTypes) Entity(org.spongepowered.api.entity.Entity) Collectors(java.util.stream.Collectors) EntityUtil(org.spongepowered.common.entity.EntityUtil) List(java.util.List) World(org.spongepowered.api.world.World) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) Entity(org.spongepowered.api.entity.Entity) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) World(org.spongepowered.api.world.World) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) PrettyPrinter(org.spongepowered.asm.util.PrettyPrinter) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Collection(java.util.Collection) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) UUID(java.util.UUID) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) Map(java.util.Map) EntityItem(net.minecraft.entity.item.EntityItem)

Example 4 with EntityUtil

use of org.spongepowered.common.entity.EntityUtil in project SpongeCommon by SpongePowered.

the class UnknownPacketState method unwind.

@Override
public void unwind(BasicPacketContext context) {
    final EntityPlayerMP player = context.getPacketPlayer();
    try (CauseStackManager.StackFrame frame1 = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(player);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.PLACEMENT);
        context.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(blocks -> TrackingUtil.processBlockCaptures(blocks, this, context));
        context.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
            SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), entities);
            SpongeImpl.postEvent(event);
            if (!event.isCancelled()) {
                processSpawnedEntities(player, event);
            }
        });
        context.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(entities -> {
            final List<Entity> items = entities.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
            SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), items);
            SpongeImpl.postEvent(event);
            if (!event.isCancelled()) {
                processSpawnedEntities(player, event);
            }
        });
    }
    context.getCapturedEntityDropSupplier().acceptIfNotEmpty(map -> {
        final PrettyPrinter printer = new PrettyPrinter(80);
        printer.add("Processing An Unknown Packet for Entity Drops").centre().hr();
        printer.add("The item stacks captured are: ");
        for (Map.Entry<UUID, Collection<ItemDropData>> entry : map.asMap().entrySet()) {
            printer.add("  - Entity with UUID: %s", entry.getKey());
            for (ItemDropData stack : entry.getValue()) {
                printer.add("    - %s", stack);
            }
        }
        printer.trace(System.err);
    });
    context.getCapturedEntityItemDropSupplier().acceptIfNotEmpty(map -> {
        for (Map.Entry<UUID, Collection<EntityItem>> entry : map.asMap().entrySet()) {
            final UUID entityUuid = entry.getKey();
            final net.minecraft.entity.Entity entityFromUuid = player.getServerWorld().getEntityFromUuid(entityUuid);
            final Entity affectedEntity = EntityUtil.fromNative(entityFromUuid);
            if (entityFromUuid != null) {
                final List<Entity> entities = entry.getValue().stream().map(EntityUtil::fromNative).collect(Collectors.toList());
                if (!entities.isEmpty()) {
                    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
                        Sponge.getCauseStackManager().pushCause(player);
                        Sponge.getCauseStackManager().pushCause(affectedEntity);
                        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.CUSTOM);
                        DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
                        SpongeImpl.postEvent(event);
                        if (!event.isCancelled()) {
                            processSpawnedEntities(player, event);
                        }
                    }
                }
            }
        }
    });
    context.getCapturedItemStackSupplier().acceptAndClearIfNotEmpty(drops -> {
        final List<EntityItem> items = drops.stream().map(drop -> drop.create(player.getServerWorld())).collect(Collectors.toList());
        final List<Entity> entities = items.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
        if (!entities.isEmpty()) {
            try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
                Sponge.getCauseStackManager().pushCause(player);
                Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.CUSTOM);
                DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
                SpongeImpl.postEvent(event);
                if (!event.isCancelled()) {
                    processSpawnedEntities(player, event);
                }
            }
        }
    });
}
Also used : EntityItem(net.minecraft.entity.item.EntityItem) SpongeImpl(org.spongepowered.common.SpongeImpl) EventContextKeys(org.spongepowered.api.event.cause.EventContextKeys) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) Collection(java.util.Collection) Sponge(org.spongepowered.api.Sponge) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) UUID(java.util.UUID) Entity(org.spongepowered.api.entity.Entity) PrettyPrinter(org.spongepowered.asm.util.PrettyPrinter) Collectors(java.util.stream.Collectors) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) EntityUtil(org.spongepowered.common.entity.EntityUtil) SpawnTypes(org.spongepowered.api.event.cause.entity.spawn.SpawnTypes) List(java.util.List) TrackingUtil(org.spongepowered.common.event.tracking.TrackingUtil) Map(java.util.Map) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Entity(org.spongepowered.api.entity.Entity) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) PrettyPrinter(org.spongepowered.asm.util.PrettyPrinter) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Collection(java.util.Collection) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) UUID(java.util.UUID) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) Map(java.util.Map) EntityItem(net.minecraft.entity.item.EntityItem)

Example 5 with EntityUtil

use of org.spongepowered.common.entity.EntityUtil in project SpongeCommon by SpongePowered.

the class EntityTickPhaseState method unwind.

@SuppressWarnings("unchecked")
@Override
public void unwind(EntityTickContext phaseContext) {
    final Entity tickingEntity = phaseContext.getSource(Entity.class).orElseThrow(TrackingUtil.throwWithContext("Not ticking on an Entity!", phaseContext));
    final Optional<User> creator = phaseContext.getOwner();
    final Optional<User> notifier = phaseContext.getNotifier();
    final User entityCreator = notifier.orElseGet(() -> creator.orElse(null));
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(tickingEntity);
        phaseContext.addNotifierAndOwnerToCauseStack();
        phaseContext.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
            final List<Entity> experience = new ArrayList<Entity>(entities.size());
            final List<Entity> nonExp = new ArrayList<Entity>(entities.size());
            final List<Entity> breeding = new ArrayList<Entity>(entities.size());
            final List<Entity> projectile = new ArrayList<Entity>(entities.size());
            for (Entity entity : entities) {
                if (entity instanceof EntityXPOrb) {
                    experience.add(entity);
                } else if (tickingEntity instanceof Ageable && tickingEntity.getClass() == entity.getClass()) {
                    breeding.add(entity);
                } else if (entity instanceof Projectile) {
                    projectile.add(entity);
                } else {
                    nonExp.add(entity);
                }
            }
            if (!experience.isEmpty()) {
                Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.EXPERIENCE);
                if (EntityUtil.isEntityDead(tickingEntity)) {
                    if (tickingEntity instanceof EntityLivingBase) {
                        CombatEntry entry = ((EntityLivingBase) tickingEntity).getCombatTracker().getBestCombatEntry();
                        if (entry != null) {
                            if (entry.damageSrc != null) {
                                Sponge.getCauseStackManager().addContext(EventContextKeys.LAST_DAMAGE_SOURCE, (DamageSource) entry.damageSrc);
                            }
                        }
                    }
                }
                final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), experience);
                if (!SpongeImpl.postEvent(event)) {
                    for (Entity entity : event.getEntities()) {
                        if (entityCreator != null) {
                            EntityUtil.toMixin(entity).setCreator(entityCreator.getUniqueId());
                        }
                        EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                    }
                }
                Sponge.getCauseStackManager().removeContext(EventContextKeys.LAST_DAMAGE_SOURCE);
            }
            if (!breeding.isEmpty()) {
                Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.BREEDING);
                if (tickingEntity instanceof EntityAnimal) {
                    final EntityPlayer playerInLove = ((EntityAnimal) tickingEntity).getLoveCause();
                    if (playerInLove != null) {
                        Sponge.getCauseStackManager().addContext(EventContextKeys.PLAYER, (Player) playerInLove);
                    }
                }
                SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), breeding);
                if (!SpongeImpl.postEvent(event)) {
                    for (Entity entity : event.getEntities()) {
                        if (entityCreator != null) {
                            EntityUtil.toMixin(entity).setCreator(entityCreator.getUniqueId());
                        }
                        EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                    }
                }
                Sponge.getCauseStackManager().removeContext(EventContextKeys.PLAYER);
            }
            if (!projectile.isEmpty()) {
                Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PROJECTILE);
                final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), projectile);
                SpongeImpl.postEvent(event);
                if (!event.isCancelled()) {
                    for (Entity entity : event.getEntities()) {
                        if (entityCreator != null) {
                            entity.setCreator(entityCreator.getUniqueId());
                        }
                        EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                    }
                }
            }
            Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PASSIVE);
            final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), nonExp);
            SpongeImpl.postEvent(event);
            if (!event.isCancelled()) {
                for (Entity entity : event.getEntities()) {
                    if (entityCreator != null) {
                        entity.setCreator(entityCreator.getUniqueId());
                    }
                    EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                }
            }
        });
        phaseContext.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(entities -> {
            final ArrayList<Entity> capturedEntities = new ArrayList<>();
            for (EntityItem entity : entities) {
                capturedEntities.add(EntityUtil.fromNative(entity));
            }
            Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
            final DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), capturedEntities);
            SpongeImpl.postEvent(event);
            if (!event.isCancelled()) {
                for (Entity entity : event.getEntities()) {
                    if (entityCreator != null) {
                        EntityUtil.toMixin(entity).setCreator(entityCreator.getUniqueId());
                    }
                    EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                }
            }
        });
        phaseContext.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(blockSnapshots -> TrackingUtil.processBlockCaptures(blockSnapshots, this, phaseContext));
        phaseContext.getBlockItemDropSupplier().acceptIfNotEmpty(map -> {
            final List<BlockSnapshot> capturedBlocks = phaseContext.getCapturedBlocks();
            for (BlockSnapshot snapshot : capturedBlocks) {
                final BlockPos blockPos = ((IMixinLocation) (Object) snapshot.getLocation().get()).getBlockPos();
                final Collection<EntityItem> entityItems = map.get(blockPos);
                if (!entityItems.isEmpty()) {
                    Sponge.getCauseStackManager().pushCause(snapshot);
                    Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
                    final List<Entity> items = entityItems.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
                    final DropItemEvent.Destruct event = SpongeEventFactory.createDropItemEventDestruct(Sponge.getCauseStackManager().getCurrentCause(), items);
                    SpongeImpl.postEvent(event);
                    if (!event.isCancelled()) {
                        for (Entity entity : event.getEntities()) {
                            creator.ifPresent(user -> entity.setCreator(user.getUniqueId()));
                            EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                        }
                    }
                    Sponge.getCauseStackManager().popCause();
                }
            }
        });
        phaseContext.getCapturedItemStackSupplier().acceptAndClearIfNotEmpty(drops -> {
            final List<EntityItem> items = drops.stream().map(drop -> drop.create(EntityUtil.getMinecraftWorld(tickingEntity))).collect(Collectors.toList());
            Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
            final List<Entity> entities = (List<Entity>) (List<?>) items;
            if (!entities.isEmpty()) {
                DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
                SpongeImpl.postEvent(event);
                if (!event.isCancelled()) {
                    for (Entity droppedItem : event.getEntities()) {
                        EntityUtil.getMixinWorld(droppedItem).forceSpawnEntity(droppedItem);
                    }
                }
            }
        });
        this.fireMovementEvents(EntityUtil.toNative(tickingEntity));
    }
}
Also used : SpongeImpl(org.spongepowered.common.SpongeImpl) EntityItemFrame(net.minecraft.entity.item.EntityItemFrame) EventContextKeys(org.spongepowered.api.event.cause.EventContextKeys) ExplosionContext(org.spongepowered.common.event.tracking.phase.general.ExplosionContext) Vector3d(com.flowpowered.math.vector.Vector3d) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) DamageSource(org.spongepowered.api.event.cause.entity.damage.source.DamageSource) ArrayList(java.util.ArrayList) EntityXPOrb(net.minecraft.entity.item.EntityXPOrb) CombatEntry(net.minecraft.util.CombatEntry) TrackingUtil(org.spongepowered.common.event.tracking.TrackingUtil) Ageable(org.spongepowered.api.entity.living.Ageable) EntityHanging(net.minecraft.entity.EntityHanging) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Transaction(org.spongepowered.api.data.Transaction) Nullable(javax.annotation.Nullable) EntityItem(net.minecraft.entity.item.EntityItem) User(org.spongepowered.api.entity.living.player.User) IMixinLocation(org.spongepowered.common.interfaces.world.IMixinLocation) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) Collection(java.util.Collection) Sponge(org.spongepowered.api.Sponge) BlockPos(net.minecraft.util.math.BlockPos) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) IProjectile(net.minecraft.entity.IProjectile) InternalSpawnTypes(org.spongepowered.common.registry.type.event.InternalSpawnTypes) Entity(org.spongepowered.api.entity.Entity) Collectors(java.util.stream.Collectors) BlockChange(org.spongepowered.common.world.BlockChange) EntityUtil(org.spongepowered.common.entity.EntityUtil) EntityAnimal(net.minecraft.entity.passive.EntityAnimal) List(java.util.List) EntityLivingBase(net.minecraft.entity.EntityLivingBase) EntityPlayer(net.minecraft.entity.player.EntityPlayer) Transform(org.spongepowered.api.entity.Transform) World(org.spongepowered.api.world.World) VecHelper(org.spongepowered.common.util.VecHelper) Optional(java.util.Optional) Player(org.spongepowered.api.entity.living.player.Player) Projectile(org.spongepowered.api.entity.projectile.Projectile) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) Entity(org.spongepowered.api.entity.Entity) User(org.spongepowered.api.entity.living.player.User) ArrayList(java.util.ArrayList) CombatEntry(net.minecraft.util.CombatEntry) Ageable(org.spongepowered.api.entity.living.Ageable) CauseStackManager(org.spongepowered.api.event.CauseStackManager) BlockPos(net.minecraft.util.math.BlockPos) ArrayList(java.util.ArrayList) List(java.util.List) EntityAnimal(net.minecraft.entity.passive.EntityAnimal) EntityItem(net.minecraft.entity.item.EntityItem) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) IMixinLocation(org.spongepowered.common.interfaces.world.IMixinLocation) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) IProjectile(net.minecraft.entity.IProjectile) Projectile(org.spongepowered.api.entity.projectile.Projectile) EntityLivingBase(net.minecraft.entity.EntityLivingBase) EntityPlayer(net.minecraft.entity.player.EntityPlayer) EntityXPOrb(net.minecraft.entity.item.EntityXPOrb)

Aggregations

List (java.util.List)5 Collectors (java.util.stream.Collectors)5 EntityItem (net.minecraft.entity.item.EntityItem)5 Sponge (org.spongepowered.api.Sponge)5 Entity (org.spongepowered.api.entity.Entity)5 SpongeEventFactory (org.spongepowered.api.event.SpongeEventFactory)5 EventContextKeys (org.spongepowered.api.event.cause.EventContextKeys)5 DropItemEvent (org.spongepowered.api.event.item.inventory.DropItemEvent)5 SpongeImpl (org.spongepowered.common.SpongeImpl)5 EntityUtil (org.spongepowered.common.entity.EntityUtil)5 TrackingUtil (org.spongepowered.common.event.tracking.TrackingUtil)5 CauseStackManager (org.spongepowered.api.event.CauseStackManager)4 SpawnEntityEvent (org.spongepowered.api.event.entity.SpawnEntityEvent)4 Collection (java.util.Collection)3 EntityPlayerMP (net.minecraft.entity.player.EntityPlayerMP)3 ItemDropData (org.spongepowered.common.event.tracking.context.ItemDropData)3 InternalSpawnTypes (org.spongepowered.common.registry.type.event.InternalSpawnTypes)3 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 Optional (java.util.Optional)2