Posted September 22, 20196 yr I have some information, just strings and ints, that I need to store to the world save. I looked into WorldSavedData, but I'm not sure whether or not this is what I am supposed to use? I am also very confused about WorldSavedData and how to use it. I'd just like to know what the best way to store this data would be and how I go about do so (beginner here). Thanks! Edited September 22, 20196 yr by TeryWells typo
September 23, 20196 yr Author I was speaking to some people on a discord server who suggested storing a separate file in the world folder. I'd probably do json. In 1.12 there's DimensionManager#getCurrentSaveRootDirectory, is there an equivalent of this in 1.14?
September 23, 20196 yr Author Well I'll only actually set these on world creation and this way the user can go in and customize the values if they so please. But I'll take your word that that is not a good idea haha. I've been playing around with WorldCapabilityData and I'm just thoroughly confused at this point. Like I said I'm very much beginner, I imagine everything I'm doing is incorrect but here's whats going on: public class ModData extends WorldCapabilityData { private final String key = Epicity.modid; public CompoundNBT data; public ModData(String name) { super(name); } public CompoundNBT get() { data.putInt("color", (int) Math.floor(Math.random() * 16777215)); markDirty(); return data; } @Override public void read(CompoundNBT compound) { this.data = compound.getCompound(key); } @Override public CompoundNBT write(CompoundNBT compound) { compound.put(key, data); return compound; } } and then public static ModData mapData; ... private void clientRegistries(final FMLClientSetupEvent event) { Minecraft.getInstance().getBlockColors().register((state, worldIn, pos, tintIndex) -> mapData.get().getInt("color"), ModBlocks.blockity); Minecraft.getInstance().getItemColors().register((stack, tintIndex) -> mapData.get().getInt("color"), ModItems.blockity); } I don't even know if its actually saving because I get NullPointerException when I load up a world and look at the block.
September 23, 20196 yr Author Okay I have switched it over to WorldSavedData and removed using nbt. I tried using the WorldEvent.Load event to get the world, but I'm not sure to go from here. Most people previously seem to do things with MapStorage however that doesn't exist in 1.14 apparently. Thanks Edited September 23, 20196 yr by TeryWells
September 26, 20196 yr Author Took me a little while to better understand capabilities but I think I'm understanding them better now. I've written up the basics, however it doesn't seem to actually be working when I try to get and set the color integer. Spoiler Blockity public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) { if (!worldIn.isRemote()) { IModData x = ModDataUtil.getModData(worldIn); if (x.getColor() == 0) { x.setColor((int) Math.ceil(Math.random() * 16777)); } placer.sendMessage(new StringTextComponent("Color: " + x.getColor())); } } ModDataUtil public final class ModDataUtil { public static IModData getModData(ICapabilityProvider world) { return world.getCapability(ModDataCapability.INSTANCE) .orElseGet(ModDataCapability::new); } } Spoiler ModDataCapacity public class ModDataCapability implements IModData, ICapabilitySerializable<CompoundNBT> { @CapabilityInject(IModData.class) public static Capability<IModData> INSTANCE; public static ResourceLocation NAME = new ResourceLocation(Epicity.modid, "mod_data"); private final LazyOptional<IModData> holder = LazyOptional.of(() -> this); private int color; @Override public int getColor() { return this.color; } @Override public void setColor(int color) { this.color = color; } @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) { return INSTANCE.orEmpty(cap, holder); } @Override public CompoundNBT serializeNBT() { CompoundNBT nbt = new CompoundNBT(); nbt.putInt("color", this.color); return nbt; } @Override public void deserializeNBT(CompoundNBT nbt) { this.color = nbt.getInt("color"); } public static boolean canAttachTo(ICapabilityProvider obj) { try { if (obj.getCapability(INSTANCE).isPresent()) { return false; } } catch (NullPointerException ex) { // Forge seems to be screwing up somewhere? Epicity.logger.error("Failed to get capabilities from {}", obj); return false; } return obj instanceof World; } public static void register() { CapabilityManager.INSTANCE.register(IModData.class, new Storage(), ModDataCapability::new); } private static class Storage implements Capability.IStorage<IModData> { @Nullable @Override public INBT writeNBT(Capability<IModData> capability, IModData instance, Direction side) { if (instance instanceof ModDataCapability) { return ((ModDataCapability) instance).serializeNBT(); } return new CompoundNBT(); } @Override public void readNBT(Capability<IModData> capability, IModData instance, Direction side, INBT nbt) { if (instance instanceof ModDataCapability) { ((ModDataCapability) instance).deserializeNBT((CompoundNBT) nbt); } } } } I largely used this to write my own capability if I removed .orElseGet(ModDataCapability::new), world.getCapability(ModDataCapability.INSTANCE) gives the error Incompatible types. Required IModData but 'getCapability' was inferred to LazyOptional<T>: Not instances of type variables T exist so LazyOptional<T> conforms to IModData
September 26, 20196 yr Author Okay so I have a function to set the color to a random number if the color is equal to 0, and then get the color and print it. This is in blockity#onBlockPlacedBy. Now in the game it will print it out, but even after placing the block, which should mean color is no longer equal to 0, it still continues to randomize the value of color even though it is no longer equal to 1. public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) { if (!worldIn.isRemote()) { IModData x = ModDataUtil.getModData(worldIn); if (x.getColor() == 0) { x.setColor((int) Math.ceil(Math.random() * 16777)); } placer.sendMessage(new StringTextComponent("Color: " + x.getColor())); } } Here is the getModData function: public static IModData getModData(ICapabilityProvider world) { return world.getCapability(ModDataCapability.INSTANCE) .orElseGet(ModDataCapability::new); } I think the above is the issue but I don't know what I'm doing wrong here? Edited September 26, 20196 yr by TeryWells
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.