Jump to content

Implement IFuelHandler as a method rather than a class


boredherobrine13

Recommended Posts

Warning: My java knowledge level is intermediate but I am still learning.

 

Hi, my mod, More Fuels Mod, which is a total rehaul of the Minecraft fuel timings to generally be more realistic as well as adding certain items, needed to be configurable. In order to have a config flag for each of over 100 custom timings formerly in one class that implemented IFuelHandler, I ended up having to move each fuel to its own class. I hate this, but I have been thus far unable to find a way to individually call one if(fuel.getItem == Item.ITEM) statement from within the main method of a class implementing IFuelHandler. I recognize this is probably due to those methods not working with IFuelHandler even if they are just used to call each if statement individually from one class rather than having one class for each if statement. I am unsure if it is at all possible to implement IFuelHandler as a method rather than a class or using an Interface, and if so how. Any ideas how? Or am I missing some obvious other easy methods to containerize all these if statements in one class and still be able to individually enable and disable them using config flags. Sorry If I am missing something obvious due to my intermediate java knowledge.

 

Example of the rough gist of what I'd like to be able to do if at all possible (this code doesn't work)

public class TestFuelSystem implements IFuelHandler{

	@Override
	public int getBurnTime(ItemStack fuel) {
		public static int AppleFuelSwitch{
		if(fuel.getItem() == Items.APPLE)
			return 100;
		}
		public static int ArrowFuelSwitch{
		if(fuel.getItem() == Items.ARROW)
			return 200;
		}
		return 0;
	}
	
}

 

The theoretical methods AppleFuelSwitch and ArrowFuelSwitch could then be used to individually enable or disable the fuels then from my main class, rather than lumping them all in one class and having no ability to config which ones are on, or putting each if statement in its OWN class implementing IFuelHandler and making way too many classes...

Link to comment
Share on other sites

I don't understand your fuel-switches at all. What's a "theoretical method"? What syntax is that? I pasted it into Eclipse, and it's all underlined in red. I've simply deleted everything that had no meaning, and this is what I came up with, which has a chance of working:
 

import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.IFuelHandler;

public class TestFuelSystem implements IFuelHandler {

  @Override
  public int getBurnTime(ItemStack fuel) {
    if (fuel.getItem () == Items.APPLE) return 100;
    if (fuel.getItem () == Items.ARROW) return 200;
    return 0;
  }

}

 

If you wanted more than that, please explain (and show more context).

 

Have you thought about using a map (mapping fuel item to burn time)? You could take your time during map creation to figure out what each should be, and if someone changes a config setting, then you could edit a value for a key in your map.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

  • 2 weeks later...
On 5/27/2017 at 10:54 AM, diesieben07 said:

If I understand you correctly you basically want many fuel handlers without the overhead of having a class for every one of them.

Thankfully IFuelHandler is a functional interface and as such can be implemented using a lambda.

Hi, I will admit that I wasn't fully aware of how Lamba expressions work. I spent some time advancing my java knowledge and now I have code that ALMOST checks out. This is probably a dumb java mistake, but would you mind pointing out to me why the third part of the lambda expression (code executed) doesn't work. Specifically why I can't use fuel.getItem and what I should use instead. Here is the current code:

 

package com.bored.morefuelsmod.newfuelsystem;

import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.IFuelHandler;
import net.minecraftforge.fml.common.Optional.Interface;

public class TestFuelSystem{
	IFuelHandler test = (getBurnTime) -> {
		if(fuel.getItem == Items.ARROW)
			return 100;
	};
	IFuelHandler testtwo = (getBurnTime) -> {
		if(fuel.getiItem == Items.APPLE)
			return 100;
	};
}

 

Link to comment
Share on other sites

(Hint: that value would be 0)

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

What even are you doing?!? Based solely on what you are doing, you should be doing something along the lines of:

GameRegistry.registerFuelHandler(s -> {
  if(s.getItem() == Items.APPLE){
    return 200;
  }else{
    return 0;
  }
});
/////////or/////////////
IFuelHandler fuelHandler = s -> {
  if(s.getItem() == Items.ARROW){
    return 100;
  }
};
GameRegistry.registerFuelHandler(fuelHandler);
////////or as jeffryfisher suggested (you could also do a .contains if statement then get a value if true, but what have you)//////
final Map<Item, Integer> fuelMap = new HashMap();
fuelMap.put(Items.APPLE, 200);
GameRegistry.registerFuelHandler(s -> {
  final Integer i = fuelMap.get(s.getItem());
  if(i != null){
    return i;
  }else{
    return 0;
  }
});

Any of these ways should work. But, you seem to just be bull-crapping you way through this. Learn the language first, then try to solve the problem at hand. 

Edited by draganz
Link to comment
Share on other sites

20 minutes ago, diesieben07 said:
20 minutes ago, diesieben07 said:

You still have to return something in the lambda even if the if-statement's condition does not evaluate to true.

 

14 minutes ago, Draco18s said:

(Hint: that value would be 0)

You still have to return something in the lambda even if the if-statement's condition does not evaluate to true.

1

If I use an else and return 0, it still gives me an error in the actual statement. The big issue here is that I cannot use "fuel".getItem because it does not know what fuel is. This code does not work. However based on some other comments I may investigate maps instead, as they seem simpler than all this.

	IFuelHandler test = (getBurnTime) -> {
		if(fuel.getItem == Items.ARROW)
			return 100;
		else
			return 0;
	};

 

Link to comment
Share on other sites

17 minutes ago, draganz said:

What even are you doing?!? Based solely on what you are doing, you should be doing something along the lines of:


GameRegistry.registerFuelHandler(s -> {
  if(s.getItem() == Items.APPLE){
    return 200;
  }else{
    return 0;
  }
});
/////////or/////////////
IFuelHandler fuelHandler = s -> {
  if(s.getItem() == Items.ARROW){
    return 100;
  }
};
GameRegistry.registerFuelHandler(fuelHandler);
////////or as jeffryfisher suggested (you could also do a .contains if statement then get a value if true, but what have you)//////
private static final Map<Item, Integer> fuelMap = new HashMap();
fuelMap.put(Items.APPLE, 200);
GameRegistry.registerFuelHandler(s -> {
  final Integer i = fuelMap.get(s.getItem());
  if(i != null){
    return i;
  }else{
    return 0;
  }
});

Any of these ways should work. But, you seem to just be bull-crapping you way through this. Learn the language first, then try to solve the problem at hand. 

I am learning the language. This is basically my practice as I learn more. I admit I need to learn more about maps and some other concepts. I do have one question though. Assuming I go with a HashMap, I would need to edit how my config system works. At present, I have an (absolutely atrocious system, made by me when I had almost no java knowledge) where each fuel has its own class and the config switch is required to register the FuelHandler. If I use a Map, what would be the best way to edit the map and change values to 0 from the main class in accordance with my config stuff. 

 

Edit: I also see how my previous lambda statements were severely flawed. For some reason, I thought I needed to use getBurnTime, rather than just assign the int I wanted to return a name. *facepalm*

Edited by boredherobrine13
Link to comment
Share on other sites

10 minutes ago, diesieben07 said:

Well, there is no parameter "fuel" in the lambda. You called the parameter "getBurnTime". Why you did that is beyond me, but you did.

I'm not sure why, but I figured since you were using the Interface IFuelHandler, and it had a fuel parameter, I wouldn't need to name one for the lambda expression. I admit my java knowledge is still expanding, but on the bright side this was a good experience and has helped me to understand lambda expressions as a whole better than I previously did.

Link to comment
Share on other sites

why don't you just load values from the config file. Assuming you have a "common" config file (present on both server and client), then the values can be loaded from the file. Just have the file contain (say item unlocalized names) and corresponding integer values for the burn time. Then get the item from the name (Item class has a static method, I believe it is for the unlocalized name) and then save the item and value to your map. 

Link to comment
Share on other sites

1 minute ago, draganz said:

why don't you just load values from the config file. Assuming you have a "common" config file (present on both server and client), then the values can be loaded from the file. Just have the file contain (say item unlocalized names) and corresponding integer values for the burn time. Then get the item from the name (Item class has a static method, I believe it is for the unlocalized name) and then save the item and value to your map. 

I don't necessarily want the mod to be that user-tweakable just yet. IE, it's partly designed as an experience, and if those values are messed with it would unbalance other parts of the mod. So they can either totally enable or disable, but it would balance the delicate weighting of some other things in the mod if users could just change the values to whatever they want. Not so much like it would break the code, but it would make a very unbalanced experience for players.

Link to comment
Share on other sites

22 minutes ago, draganz said:

Then use a boolean

That's what I already do. Here's what I'm using RN.

		boolean enableTest1 = config.get(Configuration.CATEGORY_GENERAL, "fuelenableTestExperiment1", true).getBoolean(true);
			if(enableTest1)
				GameRegistry.registerFuelHandler(TestFuelSystem.arrow);

Which is moderately concerning because it doesn't really work ATM, And I'm not sure how to register a lambda expression as a fuel handler rather than a class. In fact, the fuel doesn't work at all regardless of what the config flag is after the mod is compiled. That's a problem. Previously each fuel had its own class and they were configured like this for example: 

boolean enableDeadbush = config.get(Configuration.CATEGORY_GENERAL, "fuelenableDeadbush", true).getBoolean(true);
		if(enableDeadbush)
			GameRegistry.registerFuelHandler(new Deadbush());

 

Link to comment
Share on other sites

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

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

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