Guidebook

Guidebook

6M Downloads

Give player a book onWorldJoin event as a modder

Nightenom opened this issue ยท 8 comments

commented

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?

commented

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.

commented

Nice one, thank you

commented

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

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
commented

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)

commented

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

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.

commented

Yeah, you can add this to the main mod class where are fml init events or also you can make a new file with only that function. Don't forget to add @Mod.EventBusSubscriber in front of the class, as noted in the example book.