How to create Item Entity

I’m trying to spawn an item entity into the world with a given item stack, location, and world.

I was reading this post here: [SOLVED] Creating an Item Entity

And I tried to follow it as best I could, but it seems things have changed a little bit since then. Here is the code I’ve written:

@Override
public void spawnItem( ItemStack itemStack, Location<World> spawnLocation, World world )
{
    Optional<Entity> itemEntity = world.createEntity( EntityTypes.ITEM, spawnLocation.getPosition() );

    if ( itemEntity.isPresent() )
    {
        Item items = (Item) itemEntity.get();
        Optional<RepresentedItemData> itemData = items.getItemData().fill( itemStack );

        if ( itemData.isPresent() )
        {
            items.offer( itemData.get() );

            world.spawnEntity(
                items, Cause.of( EntitySpawnCause.builder().entity( items ).type( SpawnTypes.PLUGIN ).build() ) );
        }
        else
        {
            logger.warn( "Unable to create item data for itemstack {}", itemStack );
        }
    }
    else
    {
        logger.warn( "Unable to spawn item for itemstack {}", itemStack );
    }
}

Whenever I run this I get:
“Unable to create item data for itemstack 1xtile.log@2”

Anyone have any ideas what I’m doing wrong?

Try just offering the entity the itemstack.

entity.offer(Keys.REPRESENTED_ITEM, itemStack)

Now I have:

@Override
public void spawnItem( ItemStack itemStack, Location<World> spawnLocation, World world )
{
    Optional<Entity> itemEntity = world.createEntity( EntityTypes.ITEM, spawnLocation.getPosition() );

    if ( itemEntity.isPresent() )
    {
        Item items = (Item) itemEntity.get();

        items.offer( Keys.REPRESENTED_ITEM, itemStack.createSnapshot() );

        world.spawnEntity(
            items, Cause.of( EntitySpawnCause.builder().entity( items ).type( SpawnTypes.PLUGIN ).build() ) );
    }
    else
    {
        logger.warn( "Unable to spawn item for itemstack {}", itemStack );
    }
}

It works until up to the part where it tries to spawn the entity, where I get the following exception:

Could not pass ChangeBlockEvent$Break$Impl to Plugin{id=treebreaker, name=Sodium labs’ Treebreaker, version=0.1}
java.lang.IllegalArgumentException: Could not find a Supplier for the provided class: org.spongepowered.api.event.cause.entity.spawn.EntitySpawnCause.Builder
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:125) ~[minecraft_server.1.8.jar:?]
at org.spongepowered.common.registry.SpongeGameRegistry.createBuilder(SpongeGameRegistry.java:249) ~[SpongeGameRegistry.class:1.8-3.0.0-BETA-129]
at org.spongepowered.api.event.cause.entity.spawn.EntitySpawnCause.builder(EntitySpawnCause.java:34) ~[EntitySpawnCause.class:1.8-3.0.0-BETA-129]

I was able to fix this by passing “this” into the cause.

world.spawnEntity( items, Cause.of( this ) );

But, I think this runs contrary to the docs here: https://docs.spongepowered.org/en/plugin/entities/spawning.html

Thanks for letting us know. Could I ask of you the Sponge Version you encountered this error with?

I will investigate whether the docs are at fault or it was a problem with the version you used. See the GitHub issue I created for updates / findings.

Updated the github issue

It’s an issue that the SpawnCauses have not been implemented and aren’t in use in any of the spawn events, this will be fixed sooner than later.