Give player a book onWorldJoin event as a modder
Nightenom opened this issue ยท 8 comments
How does a modder add a guidebook to player's inventory (first time player joined a world) so it works in Java? Can it be done by argument (true/false) while registering the book?
I generally don't like when mods add random books to the inventory on first join, so I don't really want to have such a feature. However if you want to do that, the way I implement it when configured in the guidebook config file, is this: https://github.com/gigaherz/Guidebook/blob/master/src/main/java/gigaherz/guidebook/GuidebookMod.java#L85,L101
You could use a similar thing in your mod.
This works great except that the book is without texture. It can be opened and has content, just texture missing. What am I doing wrong?
@SubscribeEvent
public static void checkGbookGiven(EntityJoinWorldEvent event)
{
final Entity entity = event.getEntity();
final String bookPlayerTag = Constants.MOD_ID + ":gbookGiven";
final ItemGuidebook gbook = new ItemGuidebook("guidebook");
if (entity instanceof EntityPlayer && !entity.getEntityWorld().isRemote && !entity.getTags().contains(bookPlayerTag))
{
ItemHandlerHelper.giveItemToPlayer((EntityPlayer) entity, gbook.of(bookLocation));
entity.addTag(bookPlayerTag);
}
}
This is an error it throws when throwing the gbook without texture and it is really helpful
[23:45:07] [Server thread/FATAL] [net.minecraft.server.MinecraftServer]: Error executing task
java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[?:1.8.0_172]
at java.util.concurrent.FutureTask.get(FutureTask.java:192) ~[?:1.8.0_172]
at net.minecraft.util.Util.runTask(Util.java:54) [Util.class:?]
at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:796) [MinecraftServer.class:?]
at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:741) [MinecraftServer.class:?]
at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192) [IntegratedServer.class:?]
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:590) [MinecraftServer.class:?]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_172]
Caused by: java.lang.ArrayIndexOutOfBoundsException: -1
at net.minecraft.stats.StatList.getDroppedObjectStats(StatList.java:129) ~[StatList.class:?]
at net.minecraft.entity.player.EntityPlayer.dropItem(EntityPlayer.java:839) ~[EntityPlayer.class:?]
at net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(ForgeHooks.java:686) ~[ForgeHooks.class:?]
at net.minecraft.entity.player.EntityPlayer.dropItem(EntityPlayer.java:780) ~[EntityPlayer.class:?]
at net.minecraft.network.NetHandlerPlayServer.processPlayerDigging(NetHandlerPlayServer.java:679) ~[NetHandlerPlayServer.class:?]
at net.minecraft.network.play.client.CPacketPlayerDigging.processPacket(CPacketPlayerDigging.java:56) ~[CPacketPlayerDigging.class:?]
at net.minecraft.network.play.client.CPacketPlayerDigging.processPacket(CPacketPlayerDigging.java:12) ~[CPacketPlayerDigging.class:?]
at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:21) ~[PacketThreadUtil$1.class:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_172]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_172]
at net.minecraft.util.Util.runTask(Util.java:53) ~[Util.class:?]
... 5 more
Found a working solution for the mod I contribute to, might work well for you too:
I found out that you need to call item from ModItems (or similar place where it's registered from) instead of creating new Item()
player.addItemStackToInventory(new ItemStack(ModItems.guideBook));
For your mod ModItems probably equals to registerItems() in GuidebookMod, to this you should refer from guidebook.of(ResourceLocation)
Obviously, gigaherz proved it was my bad. The solution for modders who want to add their gbook for players onFirstJoin is:
@GameRegistry.ItemStackHolder(value = "gbook:guidebook", nbt = "{Book:\"" + MOD_ID + ":pathToTheBook.xml\"}")
public static ItemStack gbookStack;
// Give one gbook per player on first join
@SubscribeEvent
@Optional.Method(modid = "gbook")
public static void checkGbookGiven(EntityJoinWorldEvent event)
{
final Entity entity = event.getEntity();
final String bookPlayerTag = MOD_ID + ":someTagLikeGbookGiven";
if (entity instanceof EntityPlayer && !entity.getEntityWorld().isRemote && !entity.getTags().contains(bookPlayerTag))
{
ItemHandlerHelper.giveItemToPlayer((EntityPlayer) entity, gbookStack.copy());
entity.addTag(bookPlayerTag);
}
}
Where did you put this code, @Nightenom? I am adding my guidebook through a mod, but until this point I didn't need to add any code because of Guidebook's auto-detect. I am just putting it in my "modid" class, but it isn't working. No errors given.