Jump to content

Recommended Posts

Posted

I'm trying to add a radiation to my mod and I need to store its value for each player. As I understand it, I should use capability for this.
The problem is that I don't understand well the new capability system in 1.17.
So, can I create a capability to store an integer value? What are the main components of capability in its present form?

Posted

Okay. The second link was really helpful to me. Thanks for it.
I managed to implement the capability I needed, but I'm not sure about the correctness of my approach to serialization.
Anyway, I post the resulting code here.
Thanks again for your help.

My interface:

 
Spoiler

 


public interface IRadiation extends INBTSerializable<CompoundTag>
{
    int getRadLevel();
    void setRadLevel(int value);
}

Its implementation:

Spoiler

public class RadiationCapability implements IRadiation
{
    public static final ResourceLocation ID = new ResourceLocation(MainClass.MODID, "radiation_level");
    private static final String NBT_KEY = "thrad.rad";

    @CapabilityInject(IRadiation.class)
    public static Capability<IRadiation> RADIATION_CAPABILITY = null;
    public static void register() { CapabilityManager.INSTANCE.register(IRadiation.class); }

    private int radLevel;

    public RadiationCapability() { this(Configuration.DEFAULT_RAD_LEVEL); }
    public RadiationCapability(int radLevel) { this.radLevel = radLevel; }

    @Override
    public int getRadLevel() { return radLevel; }

    @Override
    public void setRadLevel(int value) { radLevel = value; }

    @Override
    public CompoundTag serializeNBT()
    {
        CompoundTag nbt = new CompoundTag();
        nbt.putInt(NBT_KEY, getRadLevel());
        return nbt;
    }

    @Override
    public void deserializeNBT(CompoundTag nbt)
    {
        setRadLevel(nbt.getInt(NBT_KEY));
    }
}

 

And its provider:

Spoiler

public class RadiationCapProvider implements ICapabilitySerializable<CompoundTag>
{
    private final Capability<IRadiation> capability;
    private final LazyOptional<IRadiation> implementation;

    public RadiationCapProvider(Capability<IRadiation> cap, LazyOptional<IRadiation> impl)
    {
        capability = cap;
        implementation = impl;
    }

    public static RadiationCapProvider from(Capability<IRadiation> cap, NonNullSupplier<IRadiation> impl)
    {
        return new RadiationCapProvider(cap, LazyOptional.of(impl));
    }

    @Nonnull
    @Override
    public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side)
    {
        if(cap == capability) return implementation.cast();
        return LazyOptional.empty();
    }

    @Override
    public CompoundTag serializeNBT()
    {
        return implementation.isPresent() ? implementation.orElse(null).serializeNBT() : new CompoundTag();
    }

    @Override
    public void deserializeNBT(CompoundTag nbt)
    {
        if(implementation.isPresent()) implementation.orElse(null).deserializeNBT(nbt);
    }
}

 

 

Posted

Should I use an instance of my RadiationCapability for this?

Spoiler

public class RadiationCapProvider implements ICapabilitySerializable<CompoundTag>
{
    private final RadiationCapability instance;
    private final Capability<IRadiation> capability;
    private final LazyOptional<IRadiation> implementation;

    public RadiationCapProvider(Capability<IRadiation> cap, LazyOptional<IRadiation> impl)
    {
        capability = cap;
        implementation = impl;
        instance = (RadiationCapability) impl.orElse(null);
    }

    public static RadiationCapProvider from(Capability<IRadiation> cap, NonNullSupplier<IRadiation> impl)
    {
        return new RadiationCapProvider(cap, LazyOptional.of(impl));
    }

    @Nonnull
    @Override
    public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side)
    {
        if(cap == capability) return implementation.cast();
        return LazyOptional.empty();
    }

    @Override
    public CompoundTag serializeNBT()
    {
        return instance.serializeNBT();
    }

    @Override
    public void deserializeNBT(CompoundTag nbt)
    {
        instance.deserializeNBT(nbt);
    }
}

 

 

Posted

Okay. Now I think that I figured out my mistake and this is how my Provider looks now:

Spoiler

public class RadiationCapProvider implements ICapabilitySerializable<CompoundTag>
{
    private final Capability<IRadiation> capability = RadiationCapability.RADIATION_CAPABILITY;
    private final RadiationCapability instance = new RadiationCapability();

    @Nonnull
    @Override
    public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side)
    {
        if(cap == capability) return LazyOptional.of(()->instance).cast();
        return LazyOptional.empty();
    }

    @Override
    public CompoundTag serializeNBT() { return instance.serializeNBT(); }

    @Override
    public void deserializeNBT(CompoundTag nbt) { instance.deserializeNBT(nbt); }
}

 

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.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I tried do download the essential mod to my mod pack but i didnt work. I paly on 1.21 and it should work. I use neoforge for my modding. The weird things is my friend somehow added the mod to his modpack and many others that I somehow can´t. Is there anything i can do? 
    • Thanks, I've now installed a slightly newer version and the server is at least starting up now.
    • i have the same issue. Found 1 Create mod class dependency(ies) in createdeco-1.3.3-1.19.2.jar, which are missing from the current create-1.19.2-0.5.1.i.jar Found 11 Create mod class dependency(ies) in createaddition-fabric+1.19.2-20230723a.jar, which are missing from the current create-1.19.2-0.5.1.i.jar Detailed walkthrough of mods which rely on missing Create mod classes: Mod: createaddition-fabric+1.19.2-20230723a.jar Missing classes of create: com/simibubi/create/compat/jei/category/sequencedAssembly/JeiSequencedAssemblySubCategory com/simibubi/create/compat/recipeViewerCommon/SequencedAssemblySubCategoryType com/simibubi/create/compat/rei/CreateREI com/simibubi/create/compat/rei/EmptyBackground com/simibubi/create/compat/rei/ItemIcon com/simibubi/create/compat/rei/category/CreateRecipeCategory com/simibubi/create/compat/rei/category/WidgetUtil com/simibubi/create/compat/rei/category/animations/AnimatedBlazeBurner com/simibubi/create/compat/rei/category/animations/AnimatedKinetics com/simibubi/create/compat/rei/category/sequencedAssembly/ReiSequencedAssemblySubCategory com/simibubi/create/compat/rei/display/CreateDisplay Mod: createdeco-1.3.3-1.19.2.jar Missing classes of create: com/simibubi/create/content/kinetics/fan/SplashingRecipe
    • The crash points to moonlight lib - try other builds or make a test without this mod and the mods requiring it
    • Do you have shaders enabled? There is an issue with the mod simpleclouds - remove this mod or disable shaders, if enabled  
  • Topics

×
×
  • Create New...

Important Information

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