Jump to content

Having problem with world capability


OneHotEncoder

Recommended Posts

I'm trying to use world capabilities to keep track of all portal locations for my custom dimension (know that PointOfInterest exists but PointOfInterestType constructor is private).

 

The problem is that the AttachCapabilitiesEvent is fired each time the player is transported to my dimension (but not when the player is transported to the overworld from my dimension). It almost seems like a new ServerWorld instance is created each time? So the portal locations in my dimension are lost. Below is the code which registers the capability.

@Mod.EventBusSubscriber(MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public class CapabilityEvents {
  
  @SubscribeEvent
  public static void onAttachWorldCapabilities(final AttachCapabilitiesEvent<World> event) {
    if (event.getObject() instanceof ServerWorld) {
      final ResourceLocation resourceLocation = new ResourceLocation(MOD_ID, "portal_locations");
      event.addCapability(resourceLocation, new PortalLocations());
    }
  }
}

 

I've tried to check if the world already has the capability attached by prepending the following code to the method, but it doesn't work.

if (event.getObject().getCapability(ModCapabilityManager.PORTAL_LOCATIONS).isPresent()) {
  return;
}

 

What can I do to make sure that the capability doesn't "reset" each time I transport the player to my dimension? The code used to transport the player is a slightly modified version of ServerPlayerEntity#changeDimension

Link to comment
Share on other sites

12 minutes ago, OneHotEncoder said:

It almost seems like a new ServerWorld instance is created each time?

That seems likely.

 

I assume you are using Forge 1.15.2? Please clarify :) 

 

How are the portals stored and how do they work? If it is a Portal Block, then could you have whatever is teleporting the player in check for nearby Portal Blocks, like Minecraft does with the Nether? 

Similar with entities.

How to ask a good coding question: https://stackoverflow.com/help/how-to-ask

Give logs, code, desired effects, and actual effects. Be thorough or we can't help you. Don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy.

 

My own mod, Magiks Most Evile: GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki)

Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/

Link to comment
Share on other sites

6 minutes ago, GenElectrovise said:

That seems likely.

 

I assume you are using Forge 1.15.2? Please clarify :) 

 

How are the portals stored and how do they work? If it is a Portal Block, then could you have whatever is teleporting the player in check for nearby Portal Blocks, like Minecraft does with the Nether? 

Similar with entities.

Yes I'm using Forge 1.15.2

 

Each portal location is stored as a BlockPos which can correspond to any one of the portal blocks that make up the portal. Do you mean that each time the player is teleported I should scan all nearby blocks and see if there is a portal block among them? That would certainly work but kinda seems like a cheap solution, I'd prefer to actually store the locations if it doesn't turn out to be way harder than imagined.

Link to comment
Share on other sites

Random thought, I have no idea if this is relevant or helpful:

public interface IForgeDimension
{
    default Dimension getDimension()
    {
        return (Dimension) this;
    }

    World getWorld();

    /**
     * Called from {@link World#initCapabilities()}, to gather capabilities for this
     * world. It's safe to access world here since this is called after world is
     * registered.
     *
     * On server, called directly after mapStorage and world data such as Scoreboard
     * and VillageCollection are initialized. On client, called when world is
     * constructed, just before world load event is called. Note that this method is
     * always called before the world load event.
     *
     * @return initial holder for capabilities on the world
     */
    default net.minecraftforge.common.capabilities.ICapabilityProvider initCapabilities()
    {
        return null;
    }

 

But apart from that-

Are you sure that you are loading/saving your capability to NBT correctly?

 

Eg for ItemStacks which have an attached capability, they are also created fresh each time (initCapability is called at every ItemStack construction) but the capability is immediately loaded from NBT.  Perhaps your capability is not doing that correctly.  Eg look at CapabilityItemHandler and serializeNBT(), WorldCapabilityData

 

-TGG

Edited by TheGreyGhost
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.