Posted December 7, 20177 yr Took me a while to get a working capability but now i don't see how i'm supposed to save them to disk. Here is my capability file, it's all registered and it works, just doesn't save public class Entity_Data { @CapabilityInject(DataInterface.class) public static final Capability<DataInterface> Data = null; public interface DataInterface { void setLevel(int value); int getLevel(); } public static class EventHandler { @SubscribeEvent public void onEntityConstruct(AttachCapabilitiesEvent evt) { evt.addCapability(new ResourceLocation(Ref.MODID, "Data"), new ICapabilitySerializable<NBTTagCompound>() { DataInterface inst = Data.getDefaultInstance(); @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { return capability == Data; } @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { return capability == Data ? Data.<T>cast(inst) : null; } @Override public NBTTagCompound serializeNBT() { return (NBTTagCompound)Data.getStorage().writeNBT(Data, inst, null); } @Override public void deserializeNBT(NBTTagCompound nbt) { Data.getStorage().readNBT(Data, inst, null, nbt); } }); } } public static class Storage implements IStorage<DataInterface> { @Override public NBTBase writeNBT(Capability<DataInterface> capability, DataInterface instance, EnumFacing side) { NBTTagCompound nbt = new NBTTagCompound(); nbt.setInteger("level", instance.getLevel()); return nbt; } @Override public void readNBT(Capability<DataInterface> capability, DataInterface instance, EnumFacing side, NBTBase nbt) { NBTTagCompound tag = (NBTTagCompound) nbt; instance.setLevel(tag.getInteger("level")); } } public static class DefaultImpl implements DataInterface { private int level = 1; @Override public int getLevel() { return level; } @Override public void setLevel(int value) { this.level = value; } } Also i followed a tutorial on how to make player data persist through death but it doesn't work even though the chat message is sent as a confirmation the code ran @SubscribeEvent public void onPlayerClone(PlayerEvent.Clone event){ if (!event.getEntityPlayer().world.isRemote) { event.getEntityPlayer().sendMessage(new TextComponentString("clone")); EntityPlayer player = event.getEntityPlayer(); DataInterface data = player.getCapability(Entity_Data.Data, null); DataInterface oldData = event.getOriginal().getCapability(Entity_Data.Data, null); data.setLevel(oldData.getLevel()); } } Thanks for any help! Edited December 7, 20177 yr by robertx555
December 7, 20177 yr Author 2 minutes ago, diesieben07 said: Don't subscribe to the bare AttachCapabilitiesEvent. In this case you want AttachCapabilitiesEvent<Entity> and check that the entity is a player. Where is the data value read/written outside the nbt serialization? Which behavior makes you think it is not persisted? I made a small test for it in servertickevent if (MAIN.player.hasCapability(Entity_Data.Data, null)) { DataInterface data = MAIN.player.getCapability(Entity_Data.Data, null); data.setLevel(data.getLevel() +1); MAIN.player.sendMessage( new TextComponentString(data.getLevel()+ " ")); Basically an increment every few ticks. I keep seeing increasing numbers.. until i leave game or die. It goes like 1,2,3,4 "i die" 1, 2 ,3 you get the idea. So either i have to save the data somehow or i messed something up with the compatibility
December 7, 20177 yr Author Just now, diesieben07 said: What on earth is MAIN.player supposed to be? MAIN.player = Minecraft.getMinecraft().player; I can post my whole mod on github in a sec but it contains a lot of shitty code that i'll have to revamp when i figure out how everything works
December 7, 20177 yr Author 26 minutes ago, diesieben07 said: That is the client player. The client does not save any data. If you want to modify the data, you must do it on the server. The fact that you are accessing this from the server thread only makes things worse, since you are now reaching across logical sides, which causes even more issues. You can't just store a static reference to the player like that. The player object will change when you switch worlds, etc. Just use Minecraft::player directly if you need the client player. How would i set the player data on the server? btw i uploaded to github in case it helps https://github.com/RobertSkalko/Minecraft-Forge-Singleplayer-MMORPG-like-mod
December 7, 20177 yr Author Whoa i think i solved it! Thanks! @SubscribeEvent public void onTickCalcStats(TickEvent.PlayerTickEvent event) { if (event.phase == Phase.END ) { tick++; if (tick > 100 && event.player != null && event.side.isServer()) { MAIN.player = event.player; EntityPlayer player = event.player; getStats(); if (player.hasCapability(Entity_Data.Data, null)) { DataInterface data = player.getCapability(Entity_Data.Data, null); data.setLevel(data.getLevel() +1); player.sendMessage( new TextComponentString(data.getLevel()+ " ")); } IAttributeInstance health = player.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH); health.setBaseValue(20); tick = 0; } } } You said i'm supposed to get player from event.. well servertickevent has no player but TickEvent.PlayerTickEvent does! I changed it and it suddenly magically worked! It saves on death and on quitting game! That answered another question, seems i don't have to call any other saving methods I'm gonna go and remove MAIN.player and update all the stuff.. Edited December 7, 20177 yr by robertx555
December 7, 20177 yr Author my bad i'll first check for server side, um getstats is for calculating player stats that i made. I put the whole thing on github if you want to get eye damage Gonna take me a while to fix stuff after removing MAIN.player
December 7, 20177 yr Author i'm making it for singleplayer only for now I'll try rework the getstats so it saves on capabilities, now that i have a working capability i can actually start the work sorry i just put the main files because the file is 200mb and my net is pretty slow
December 7, 20177 yr Author My tastes are niche so i wouldn't expect many to like the mod.. If i can easily make it multiplayer then sure Eclipse folder is 100 mb and build folder is 70 mb
December 7, 20177 yr Author i know but things are easier to balance if i only care about 1 player.. for example say i want to spawn random mobs around a player. It becomes more difficult to balance when multiple players are around. 1 player is lvl 100 the other is lvl 1, i would have to make it so both players can play somehow.. which would mean many changes didn't learn that yet, i'll try gitignore, kept hearing about it but now i see why it's useful
December 7, 20177 yr Author I know that at least. Btw managed to gitignore build and eclipse folders so here's the new one https://github.com/RobertSkalko/MMORPG-Mod Now i'm gonna see if i can use capabilities to save NBTTagCompound, i have like 20 stats so having 20 getter and setter functions seem like a disaster. Anyway it's nearly midnight so i'll do it tomorrow Thanks for the help! I won't need help anymore soon, got a lot of things to work on now!
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.