Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

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.

  • 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.

  • 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.

  • 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.

  • 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

 

  • 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.

  • 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 ?

  • 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.

  • 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.

  • 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..

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.

  • 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.

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.

  • 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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.