Titanium237458 Posted June 20, 2015 Posted June 20, 2015 I am working on a flower which should save the player that makes a shift-right click on it, but I can't figure out how to save the player entity. I know how NBT works, and I try to save the player's username in that block and then get the EntityPlayer from the username again, but it doesn't seem to work. This is the flower code (Note that my mod should be a Botania Addon): package titanium.sanguisnaturae.block.subtile.functional; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.server.MinecraftServer; import net.minecraft.util.ChatComponentText; import net.minecraft.util.IIcon; import net.minecraft.world.World; import titanium.sanguisnaturae.constants.BlockNames; import titanium.sanguisnaturae.lexicon.SNLexiconEntries; import vazkii.botania.api.BotaniaAPI; import vazkii.botania.api.lexicon.LexiconEntry; import vazkii.botania.api.subtile.SubTileFunctional; public class SubtileTransmeed extends SubTileFunctional{ private final String TAG_PLAYER = "TRANSMEED_PLAYER"; private final String TAG_SECONDS = "TRANSMEED_SECONDS"; private EntityPlayer player; private int MANA_COST = 10; private int seconds = 0; public EntityPlayer getPlayer() { if (mana >= MANA_COST && player != null) { mana -= MANA_COST; return player; } return null; } @Override public void onUpdate() { super.onUpdate(); if(ticksExisted % 20 == 0) seconds++; } @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { if(player.isSneaking()) this.player = player; //Testing stuff player.addChatComponentMessage(new ChatComponentText("Bound Player: " + ((this.player == null) ? "null" : player.getCommandSenderName()))); player.addChatComponentMessage(new ChatComponentText("Seconds Existed: " + seconds)); //the second counting works return super.onBlockActivated(world, x, y, z, player, side, hitX, hitY, hitZ); } //Here comes the part I'm asking about @Override public void writeToPacketNBT(NBTTagCompound cmp) { super.writeToPacketNBT(cmp); if(player == null){ cmp.setString(TAG_PLAYER, ""); } else { cmp.setString(TAG_PLAYER, player.getCommandSenderName()); } cmp.setInteger(TAG_SECONDS, seconds); } @Override public void readFromPacketNBT(NBTTagCompound cmp) { super.readFromPacketNBT(cmp); String str = cmp.getString(TAG_PLAYER); if(str == null || str.equals("")){ player = null; } else { player = MinecraftServer.getServer().getConfigurationManager().func_152612_a(str); } seconds = cmp.getInteger(TAG_SECONDS); } @Override public int getMaxMana() { return 1000; } @Override public int getColor() { return 0xFF0000; } @Override public IIcon getIcon() { return BotaniaAPI.getSignatureForName(BlockNames.TRANSMEED).getIconForStack(null); } @Override public LexiconEntry getEntry() { return SNLexiconEntries.entryTransmeed; } } EDIT: I fixed it now. I no longer use EntityPlayer but the GameProfile and made some other adjustments to the NBT saving / loading, took out the debug stuff with the second saving etc. For anyone interested, here's what the code now looks like: package titanium.sanguisnaturae.block.subtile.functional; import com.mojang.authlib.GameProfile; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTUtil; import net.minecraft.server.MinecraftServer; import net.minecraft.util.ChatComponentText; import net.minecraft.util.IIcon; import net.minecraft.world.World; import titanium.sanguisnaturae.constants.BlockNames; import titanium.sanguisnaturae.lexicon.SNLexiconEntries; import vazkii.botania.api.BotaniaAPI; import vazkii.botania.api.lexicon.LexiconEntry; import vazkii.botania.api.subtile.SubTileFunctional; public class SubtileTransmeed extends SubTileFunctional{ private final String TAG_PLAYER = "TRANSMEED_PLAYER"; private GameProfile player; private int MANA_COST = 1; public EntityPlayer getPlayer() { if (mana >= MANA_COST && player != null) { mana -= MANA_COST; return MinecraftServer.getServer().getConfigurationManager().func_152612_a(player.getName()); } return null; } @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { if(!world.isRemote){ if(player.isSneaking()){ this.player = player.getGameProfile(); } else { player.addChatComponentMessage(new ChatComponentText("Bound Player: " + ((this.player == null) ? "null" : player.getCommandSenderName()))); } } return super.onBlockActivated(world, x, y, z, player, side, hitX, hitY, hitZ); } @Override public void writeToPacketNBT(NBTTagCompound cmp) { super.writeToPacketNBT(cmp); if (this.player != null) { NBTTagCompound nbt = new NBTTagCompound(); NBTUtil.func_152460_a(nbt, player); cmp.setTag(TAG_PLAYER, nbt); } } @Override public void readFromPacketNBT(NBTTagCompound cmp) { super.readFromPacketNBT(cmp); if(cmp.hasKey(TAG_PLAYER)) player = NBTUtil.func_152459_a(cmp.getCompoundTag(TAG_PLAYER)); } @Override public int getMaxMana() { return 20; } @Override public int getColor() { return 0xFF0000; } @Override public IIcon getIcon() { return BotaniaAPI.getSignatureForName(BlockNames.TRANSMEED).getIconForStack(null); } @Override public LexiconEntry getEntry() { return SNLexiconEntries.entryTransmeed; } } Thank you for your help anyway Quote
Failender Posted June 20, 2015 Posted June 20, 2015 Define "doenst seem to work" When are you triing to access the information and how Quote
tiffit Posted June 20, 2015 Posted June 20, 2015 You need to mark dirty when the player is set, or else it will not save Quote
Titanium237458 Posted June 20, 2015 Author Posted June 20, 2015 Define "doenst seem to work" When are you triing to access the information and how In "onBlockActivated" it will print out the Bound Player and the seconds the tile existed. When I shift right click it will bind myself to it and then everytime I right click it it will print my username and the time the tile existed. When I log out and log in, and right click the tile, it will print "null", as in no player is bound to it, so it didn't save properly. You need to mark dirty when the player is set, or else it will not save I don't think this is the case because it saves the seconds the tile existed properly, but I will try in a bit Quote
sham1 Posted June 20, 2015 Posted June 20, 2015 Have you tried to save player's UUID instead? Because when you have the UUID you can just look up the player whose UUID it is. Quote If my post helped you, please press that "Thank You"-button to show your appreciation. Also if you don't know Java, I would suggest you read the official tutorials by Oracle to get an idea of how to do this. Thanks, and good modding! Also if you haven't, set up a Git repo for your mod not only for convinience but also to make it easier to help you.
Titanium237458 Posted June 20, 2015 Author Posted June 20, 2015 You need to mark dirty when the player is set, or else it will not save Still same result Have you tried to save player's UUID instead? Because when you have the UUID you can just look up the player whose UUID it is. You mean like this? @Override public void writeToPacketNBT(NBTTagCompound cmp) { super.writeToPacketNBT(cmp); if(player == null){ cmp.setString(TAG_PLAYER, ""); } else { cmp.setString(TAG_PLAYER, player.getPersistentID().toString()); } cmp.setInteger(TAG_SECONDS, seconds); } @Override public void readFromPacketNBT(NBTTagCompound cmp) { super.readFromPacketNBT(cmp); String str = cmp.getString(TAG_PLAYER); if(str != null && !str.equals("")){ UUID uuid = UUID.fromString(str); if(uuid == null){ player = null; } else { String playerName = MinecraftServer.getServer().func_152358_ax().func_152652_a(uuid).getName(); player = MinecraftServer.getServer().getConfigurationManager().func_152612_a(playerName); } } seconds = cmp.getInteger(TAG_SECONDS); } When I reload the world the flower transforms into "Botania Flower", which you only get when something went wrong. So that doesn't work either, or am I using it wrong? Quote
Failender Posted June 20, 2015 Posted June 20, 2015 You should check for !isRemote on the worldObj in your onBlockActivated, so it gets only processed on server side and the server sends all needed informations to the client. Quote
Recommended Posts
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.