Jump to content

shieldbug1

Forge Modder
  • Posts

    404
  • Joined

  • Last visited

Everything posted by shieldbug1

  1. I've been testing using the /kill command to see if it works. That should trigger the Clone event, shouldn't it? Edit: Changed to player TickEvent, still not syncing properly. Edit 2: Okay, this is really weird. The ClientProxy is definitely receiving the right values, and it's definitely setting them right. However in the PlayerTickEvent, the stats aren't right, even if I do this: if(event.side.isClient()) { PlayerStats client = PlayerStats.get(cpw.mods.fml.client.FMLClientHandler.instance().getClientPlayerEntity()); System.out.println("Client Stats: level: " + client.getLevel() + ", exp: " + client.getEXP()); } That and the entity being used to sync in the client in the proxy are gotten through identical methods (FMLClientHandler.instance().getClientPlayerEntity()).
  2. I am testing this on Single Player, so it couldn't be other players. When I print out the level and the exp fields in the event method, along with FMLCommonHandler.instance().getEffectiveSide(), the Server one is right, and the client one is never updated from the original Level 1, Exp 0. The handle method for the packet is definitely being called, too (if I print out the stats from there, they're right).
  3. Read the EAQ.
  4. You can use IExtendedEntityProperties. ItemStack#writeToNBT() and ItemStack.loadItemStackFromNBT() are what you're looking for.
  5. I've been working a bit on some Server > Client IExtendedEntityProperties syncing stuff, and I'm just a little confused about one thing. When handling the message on the Client side, the only instance of EntityPlayer I can get is Minecraft.getMinecraft().thePlayer (or alternatively FMLClientHandler.instance().getClientPlayerEntity()), right? However, when I use certain events that occur on both Client and Server side (LivingEvent.LivingUpdateEvent, for example), the client instance of EntityPlayer doesn't seem to be the same as the instance of EntityPlayer from Minecraft#thePlayer. Am I doing things the right way, or is there a better way to do this? This is all the relevant code: PlayerStats (IExtendedEntityProperties): public final class PlayerStats implements IExtendedEntityProperties { private static final String PLAYER_STATS = Reference.MOD_ID + "PlayerStat"; private static int maxLevel = 100, maxEXP = 1000000, minEXP = 100; private static final ImmutableMap<Integer, Integer> XP_TO_LEVEL_UP_MAP = ImmutableMap.copyOf(initLevelMap()); private final EntityPlayer player; private int level, exp; private PlayerStats(EntityPlayer player) { this.player = player; this.level = 1; this.exp = 0; } @Override public void saveNBTData(NBTTagCompound compound) { compound.setInteger(LEVEL, this.level); compound.setInteger(EXP, this.exp); } @Override public void loadNBTData(NBTTagCompound compound) { this.level = compound.getInteger(LEVEL); this.exp = compound.getInteger(EXP); } public void copy(PlayerStats oldStats) { this.level = oldStats.level; this.exp = oldStats.exp; } public void copy(PlayerStatSync message) { this.level = message.level; this.exp = message.exp; } public static final void register(EntityPlayer player) { if(player.getExtendedProperties(PLAYER_STATS) == null) { player.registerExtendedProperties(PLAYER_STATS, new PlayerStats(player)); } else { LogHelper.warn("Tried to register PlayerStats to a player twice."); } } public static PlayerStats get(EntityPlayer player) { if(player.getExtendedProperties(PLAYER_STATS) == null) { register(player); } return (PlayerStats) player.getExtendedProperties(PLAYER_STATS); } } PlayerStatHandler: @SubscribeEvent public void onPlayerTick(LivingEvent.LivingUpdateEvent event) { if(event.entityLiving instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer) event.entityLiving; PlayerStats stats = PlayerStats.get(player); System.out.println(String.format("Level: %s, Experience: %s, Side:%s", stats.getLevel(), stats.getEXP(), RPGMod.getSide())); } } @SubscribeEvent public void onPlayerClone(PlayerEvent.Clone event) { if(event.wasDeath) { PlayerStats.get(event.entityPlayer).copy(PlayerStats.get(event.original)); PacketHandler.sendPlayerStatSyncToPlayer(event.entityPlayer); } } PacketHandler: public final class PacketHandler { private PacketHandler(){} private static final SimpleNetworkWrapper NETWORK = new SimpleNetworkWrapper(Reference.MOD_ID); public static void init() { int discriminator = 0; NETWORK.registerMessage(PlayerStatSync.Handler.class, PlayerStatSync.class, discriminator++, Side.CLIENT); } public static void sendPlayerStatSyncToPlayer(EntityPlayer player) { if(RPGMod.isServer()) { PlayerStatSync packet = new PlayerStatSync(PlayerStats.get(player)); LogHelper.packetSent(packet); NETWORK.sendTo(packet, (EntityPlayerMP) player); } else { LogHelper.error("PacketHandler attempted to send a PlayerStatSync packet from the client!" + Reference.LINE_SEPERATOR + " This is bad, report it to the mod author with the latest log!"); LogHelper.printStackTrace(); } } } Client Proxy: public final class ClientProxy extends CommonProxy { @Override public void handlePlayerStatSync(PlayerStatSync message, MessageContext ctx) { PlayerStats stats = PlayerStats.get(FMLClientHandler.instance().getClientPlayerEntity()); stats.copy(message); } } Message Class, and Message Handler Class: public final class PlayerStatSync implements IMessage { public int level, exp; public PlayerStatSync(){} public PlayerStatSync(PlayerStats stats) { this.level = stats.getLevel(); this.exp = stats.getEXP(); } @Override public void fromBytes(ByteBuf buf) { this.level = buf.readInt(); this.exp = buf.readInt(); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(this.level); buf.writeInt(this.exp); } @Override public String toString() { return String.format( "PlayerStatSync - Level: %s, EXP: %s", this.level, this.exp); } public static final class Handler implements IMessageHandler<PlayerStatSync, IMessage> { @Override public IMessage onMessage(PlayerStatSync message, MessageContext ctx) { LogHelper.packetRecieved(message); RPGMod.proxy.handlePlayerStatSync(message, ctx); return null; } } }
  6. Either override getIconItemStack and return your own ItemStack, or override getTabIconItem for the Item and func_151243_f for the metadata of the item. Both are identical, as only getIconItemStack gets called GuiContainerCreative, and the default 'implementation' of getIconItemStack returns a new ItemStack of getTabIconItem, stackSize of one and metadata of func_151243_f.
  7. Search it up on google, it will tell you. This message tells you EXACTLY what's wrong. This is not a Java Support forum, please go learn basic java elsewhere.
  8. Are you saying that the logs folder is completely empty?
  9. Have you tried READING THE EAQ?
  10. We can't help without the logs. "It doesn't work" or "it's broken" doesn't help us.
  11. Read up on what static means, and fix the problem yourself. This is not a Java support forum.
  12. It's just update 20. I'm relatively certain it's being worked on by the forge team, but for now Java 1.8_20 and Forge are not compatible.
  13. I don't think there is one with EntityLivingBase, but there is onBlockHarvested with an EntityPlayer instance. There is also onBlockPreDestroyed, but it doesn't have an EntityPlayer field. Lastly, you have the BlockEvent.BreakEvent you can use, with getPlayer().
  14. It's not hard to check. PlayerTickEvent or LivingUpdateEvent, with a flag set to true. It would look something like this: private boolean flag = true; @SubscribeEvent public void onPlayerTick(TickEvent.PlayerTickEvent event) { if(event.phase == TickEvent.Phase.START && event.side == Side.SERVER) { if(flag) { if(event.player.inventory.armorInventory[0] == MyItem) { flag = false; // DO STUFF } } else { if(event.player.inventory.armorInventory[0] == null) { flag = true; } } } } This is a very minimal amount of processing required to be done every tick, I doubt it would ever interfere with performance.
  15. The EAQ tells you EXACTLY what is causing it, and how to fix it.
  16. Read the EAQ!
  17. In the LivingHurtEvent just check it was the player that was hit last, and if the damage source was caused by something extending EntityLivingBase (so you don't get stuff like fall damage, fire, etc.), and if so, map it somewhere. Maybe a map with the Player's UUID > Entity which attacked, or something like that.
  18. You can use World#getCurrentWorldTime() % 20 == 0 to make it run 1 a second (since there's twenty ticks in a second)
  19. First of all you can compare Items simply by using == without IDs. if(item == YourItem) would work as there is only one instance of the Item. Secondly ItemStack#getItem() results in an Item. IDs are no longer used in 1.7+
  20. I think what OP means is a way to get the 'translated' names of Blocks, Items, and Liquids that he didn't create. To do so, it simply requires like I said to use StatCollector.translateToLocal(unlocalisedName). This will not only get the user readable name, but it will also translate it to the appropriate language that the user is currently using (I believe).
×
×
  • Create New...

Important Information

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