I have created a custom spider mob that has a small percent chance to replace a normal spider when one is spawned. To do this I have subscribed to the EntityJoinWorldEvent. I check that the event is going to spawn a spider, then cancel the event and spawn my own spider instead.
Like this:
@SubscribeEvent
public void onEntityJoinWorld( EntityJoinWorldEvent event )
{
World world = event.world;
Entity entity = event.entity;
if( entity instanceof EntitySpider && Math.random() < 0.25 )
{
event.setCanceled( true );
if( !world.isRemote )
{
EntityBigSpider bigSpider = new EntityBigSpider( world );
bigSpider.setLocationAndAngles(entity.posX, entity.posY, entity.posZ, 0.0F, 0.0F);
world.spawnEntityInWorld( bigSpider );
}
}
}
So far this works fine, my spiders are spawned as expected. The problem comes when I close the game and start it back up. When the game starts respawning all entities as the chunk is reloaded, the EntityJoinWorldEvent event is triggered and I get a ConcurrentModificationException crash.
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(Unknown Source)
at java.util.HashMap$KeyIterator.next(Unknown Source)
at com.google.common.collect.AbstractMapBasedMultimap$WrappedCollection$WrappedIterator.next(AbstractMapBasedMultimap.java:486)
at net.minecraft.util.ClassInheritanceMultiMap$2.computeNext(Unknown Source)
at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143)
at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138)
at net.minecraft.world.World.loadEntities(Unknown Source)
at net.minecraft.world.chunk.Chunk.onChunkLoad(Unknown Source)
at net.minecraftforge.common.chunkio.ChunkIOProvider.callStage2(Unknown Source)
at net.minecraftforge.common.chunkio.ChunkIOProvider.callStage2(Unknown Source)
at net.minecraftforge.common.util.AsynchronousExecutor.skipQueue(Unknown Source)
at net.minecraftforge.common.util.AsynchronousExecutor.getSkipQueue(Unknown Source)
at net.minecraftforge.common.chunkio.ChunkIOExecutor.syncChunkLoad(Unknown Source)
at net.minecraft.world.gen.ChunkProviderServer.loadChunk(Unknown Source)
at net.minecraft.world.gen.ChunkProviderServer.loadChunk(Unknown Source)
at net.minecraft.server.MinecraftServer.initialWorldChunkLoad(Unknown Source)
at net.minecraft.server.integrated.IntegratedServer.loadAllWorlds(Unknown Source)
at net.minecraft.server.integrated.IntegratedServer.startServer(Unknown Source)
at net.minecraft.server.MinecraftServer.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I need to find a way to prevent my code from running until the world has finished with its loadEntities method. Is there maybe some indicator I can check to make sure its safe to start spawning my own entities? Event better would be if I can test if an entity is being spawned for the first time and not being respawned as the chunk is being reloaded.
Also, I tried to use the code button but it doesn't seem to do anything. Does it not work in chrome maybe?