Posted November 6, 201510 yr Hi ! I overhauled the standard FoodStats system and increased the maximum hunger beyond 20. Unfortunately, the GUI still only shows the last 20 points. So I have to remake the Hunger bar so it changes the way hunger level are displayed. But : 1. The original code looks very obfuscated, do you know any working example of something that sounds a bit like what I'm trying to do ? 2. I can disable the original with RenderGameOverlayEvent, but I don't see how to create the new GUI from here. There's no access to the player or the world. 3. I suspect my code to be functional for only one player. Here is the code replacing the FoodStats class : http://hastebin.com/awopohuzef.java Am I right ? Anybody ever played with those things ? EDIT : I will use a PlayerTickEvent to show the GUI, but that doesn't answer all my questions.
November 6, 201510 yr Author You only need to draw a few rectangles, based on the number of food bars you want to display. I suggest you look at GuIngameForge, which is basically a cleaned up version of GuiIngame + the event firing code. GUIs are client side only. The client only ever has one player and one world: Minecraft#thePlayer and Minecraft#theWorld . No, that is not the correct event to "show the GUI". You need to use RenderGameOverlayEvent, as you already mentioned earlier. Okay, I wasn't aware of GuiIngameForge. I should have looked where the event was fired. I added an other question in my OP regarding the way I replace the food handling class (which I think I should take the multiplayer in account since there are individual food counters in there, but I'm not sure I do since I think the data get stored in only one place which sounds awefully wrong). PS : I know I'm unleashing incompatibility and bad things by starting to use reflection but I had no choice, Forge just doesn't allow to safely modify much about Food and other real game mechanics.
November 6, 201510 yr Author I improved my code to look only once through fields to find the right one. I'm not sure how player related variables can be made yet : (hashmap maybe ? Or an event is triggered at the "character creation" ?) but I will find out as it's probably something people always ask.
November 6, 201510 yr Author I still need some way to create a new instance for each player, but not each time it appears in the world like I would in my current code.
November 7, 201510 yr Author It seems my condition if(!(player.getFoodStats() instanceof HardFoodStats)) is always true and so, at each relogging the foodStats is a new instance. That makes absolutely no sense. Here is my most recent code : http://hastebin.com/idasoyimiq.java
November 7, 201510 yr Author That makes absolutely no sense. How so? Well, HardFoodStats extends FoodStats. Therefore my logic is HardFoodStats instanceof FoodStats == true,, FoodStats instanceof FoodStats == true, HardFoodStats instanceof HardFoodStats == true but FoodStats instanceof HardFoodStats == false. So if the part of my code under !(getFoodStats instanceof HardFoodStats) is loaded each time (each logging, for the same player) that means each time I log in my player.getFoodStats is NOT the HardFoodStats instance I previously assigned.
November 7, 201510 yr Author But the instance can't be "renewed". Even in Vanilla. I mean, there is the foodLevel in there. When you renew it, it gets back to max (initial value). Let's assume a new foodStats instance is automatically created at each EntityJoinWorld, and it seems to be the case, how does vanilla save its food level value ?
November 7, 201510 yr Author So I will search when and how these methods are called and mimic the vanilla system. Thanks. EDIT : Called in the EntityPlayer class. I need a way to use NBTTagCompound, something like a getNBTfromEntity()... Very interesting.
November 7, 201510 yr Author That's already what I did. Initially I was using the vanilla "foodLevel" NBT tag so I thought it was the problem. Made a custom one, no changes. That's really strange. I will look if there is some kind of NBT viewer out there. EDIT : I found one and after a few experiments it seems the writing works well but the reading doesn't work. In my method public void readNBT(NBTTagCompound p_75112_1_) { System.out.println("Started reading NBT tags..."); if (p_75112_1_.hasKey("foodLevel")) { System.out.println("NBT Tag found !"); this.foodLevel = p_75112_1_.getInteger("foodLevel"); this.foodTimer = p_75112_1_.getInteger("foodTickTimer"); this.foodSaturationLevel = p_75112_1_.getFloat("foodSaturationLevel"); this.foodExhaustionLevel = p_75112_1_.getFloat("foodExhaustionLevel"); } } "Started reading..." is printed but not "NBT Tag found !" so .hasKey("foodLevel") never worked. I don't get it because NBTExplorer clearly show the value exist in the save.
November 8, 201510 yr Author My actual problem is that during the EntityJoinWorld event, player.getEntityData() returns an empty NBTTagCompound. Does this make sense ? How can I read from it then ? The readNBT isn't called magically, and all the information on the web is about TileEntities.. Note I have to call readNBT somewhere myself, because at the time getFoodStats().readNBT(compound) is originally called in EntityPlayer, it still has the old class. I did a workaround by getting values from the vanilla class. But I can't keep it, as not all values have public getters..
November 8, 201510 yr The compound tag returned by Entity#getEntityData is added by Forge and only used for custom entity data, it's never written to by Minecraft. Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
November 8, 201510 yr Author Then I have two solutions : Read from the Minecraft compound tag; Read&Write on a Forge compound tag. But I don't know how to access any of these compound tags if this method doesn't work. EDIT : Fixed. I now write on the EntityPlayer.getEntityData() compound at logout with an event.
November 8, 201510 yr You should be able to call FoodStats#writeNBT on the vanilla object to get all of its values, then call HardFoodStats#readNBT to read those values into your own object before you replace the vanilla one. If HardFoodStats has values in addition to the vanilla ones, you may need to store them in the player's persisted NBT data or an IExtendedEntityProperties object. Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
November 8, 201510 yr Author The saving now works perfectly, thank you. Back to the GUI displaying, my little method which should hide the original hunger bar and display mine just hide the original. Currently, my custom hunger bar is the vanilla one (I will tweak it once it works). http://hastebin.com/umiwedupic.java Maybe I should play with Pre and Post events ? I tried to cancel in Pre and display in Post but it was still the same problem.
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.