I'm creating a mod for minecraft and created a metadata item, it has three variants (default, 1 and 2).
when im trying to give it to my player with item:0 or nothing i get this item, and its id is just item without :number, but when i give item:1, the given item adds to stack to item:0. When i throw item:0 from inventory, item:1 successfully gives with it custom texture, but its id is item, not item:1
Here's my item with variants code:
public Trowel(String name, CreativeTabs tab) {
super(name, tab);
this.tab = tab;
}
public void getSubItems(Item item, CreativeTabs tabs, List<ItemStack> list) {
for(int i = 0; i < EnumTrowel.count(); i++) {
list.add(new ItemStack(item, 1, i));
}
}
#Override
public String getUnlocalizedName(ItemStack stack) {
for(int i = 0; i < EnumTrowel.count(); i++) {
if(stack.getItemDamage() == i) {
return this.getUnlocalizedName() + "_" + EnumTrowel.values()[i].getName();
} else {
continue;
}
}
return this.getUnlocalizedName() + "_" + EnumTrowel.CLEAR.getName();
}
This is my Main class preInit()
public static void preInit(FMLPreInitializationEvent event) {
proxy.registerModelBakeryStuff();
RegistryHandler.registerCustomMeshesAndStates();
RegistryHandler.registerFluid(concrete);
for(int i = 0; i < EnumTrowel.count(); i++) {
ModItems.registerRender(ModItems.TROWEL, i, "trowel_" + EnumTrowel.values()[i].getName());
}
}
And here's my ClientProxy register method
#Override
public void registerModelBakeryStuff() {
ModelBakery.registerItemVariants(ModItems.TROWEL, new ResourceLocation(Reference.MOD_ID, "trowel_clear"), new ResourceLocation(Reference.MOD_ID, "trowel_plaster"), new ResourceLocation(Reference.MOD_ID, "trowel_gypsum"));
}
item:0 = trowel_clear (default variant)
item:1 = trowel_plaster (1 variant)
item:2 = trowel_gypsum (2 variant)
There's no any errors in console.
I'm not actually sure what's going wrong, as you've hidden a few things behind other mehods that aren't really in places where they should be (why does ModItems have a registerRender method?)
Anyway, if I dissect my own code1 regarding items with variants I notice two things:
I don't see anything equivalent to variantName + "=" + variant.getByOrdinal(stack.getMetadata())); in your code. This string is what actually maps the metadata to a different model. My variants were all enum specified and hard mapped metadata <-> enum ordinal.
I don't see a call to ModelLoader.setCustomModelResourceLocation() which is what tells the game how to go find a resource for that string.
Its possible that your code does contain those things, but you haven't included it in the question, making it very difficult to figure out where things are going wrong.
Note that the class I've linked here is one half of a system that I custom built to handle the RegistryEvent systems in a way that was more friendly to having transitioned from 1.7.10's GameRegistry system. There's some odd redirections involved shoving data into arrays only to read them back out again later that's not actually necessary if you just construct items in the relevant event (which is the more widely accepted standard). I do all the same things, just at a different point.
Related
I'm having a bit of trouble in my head trying to solve this:
I'm working on a "rankList", an arrayList made of "Score". Score it's the object that has the following atributes: name,wins,loses,draws. My class Ranking has an ArrayList of Score objects. To create a new Score object I just use the name (and set the rest to 0 since it's new). However I'm trying to check if the player's name it's already in rankList I don't have to create new but sum a win or lose or draw.
I have been reading arround that I have to override equals then others say I have to override contains... It's getting a big mess in my head. My fastest solution would be to write an "for" that goes arround the arrayList and use the getName().equals("name"); however this is getting too messi in my code. I have checkPlayer (if the palyer is in the list):
public boolean checkPlayer(String playerName) {
for (int i = 0; i < this.rankList.size(); i++) {
if (this.rankList.get(i).getName().equals(playerName)) {
return true;
}
}
return false;
}
then if I want to incrase the wins i have this :
public void incraseWins(String playerName) {
if (checkPlayer(playerName)) {
for (int i = 0; i < this.rankList.size(); i++) {
if (this.rankList.get(i).getName().equals(playerName)) {
this.rankList.get(i).setWins(this.rankList.get(i).getWins() + 1);
break;
}
}
} else {
createPlayer(playerName);
//more for to get to the player i'm looking for...
for (int i = 0; i < this.rankList.size(); i++) {
if (this.rankList.get(i).getName().equals(playerName)) {
this.rankList.get(i).setWins(this.rankList.get(i).getWins() + 1);
break;
}
}
}
So i guess there is a better way to do this... :/
ArrayList is not the right data structure here. To check if an element exists in the array you are searching the entire arraylist. Which means it's O(N).
To keep an array list is sorted order and do a binary search on it would definitely be faster as suggested in the comments. But that wouldn't solve all your problems either because insert into the middle would be slow. Please see this Q&A: When to use LinkedList over ArrayList?
One suggestion is to use a Map. You would then be storing player name, player object pairs. This would give you very quick look ups. Worst case is O(log N) i believe.
It's also worth mentioning that you would probably need to make a permanent record of these scores eventually. If so an indexed RDBMS would give you much better performance and make your code a lot simpler.
Try using a hashtable with a key, it would be much more efficient!
e..Why not using map<>.
a binary search is good idea if you must use List,code like this
List<Method> a= new ArrayList<>();
//some method data add...
int index = Collections.binarySearch(a, m);
Method f = a.get(index);
and class method is impl of Comparable,then override compareTo() method
public class Method implements Comparable<Method>{
........
#Override
public int compareTo(Method o) {
return this.methodName.compareTo(o.getMethodName());
}
if you don't want use binsearch,CollectionUtils in commons can help you
CollectionUtils.find(a, new Predicate() {
#Override
public boolean evaluate(Object object) {
return ((Method)object).getMethodName().equals("aaa");
}
});
in fact CollectionUtils.find is also a 'for'
for (Iterator iter = collection.iterator(); iter.hasNext();) {
Object item = iter.next();
if (predicate.evaluate(item)) {
return item;
}
}
I'm making a minecraft mod menu (That sounds even worse on here) and Im trying to make the string variables appear from most lengthy to least lengthy
I.e:
"Chest Stealer"
"Player ESP"
"Flight"
"Speed"
"box" etc.
Here is my current code:
for(Module m : myClient.getModules())
{
if(m.isToggled() && m.getName() != "Click GUI" )
{
modules.add(m.getName());
for(int i = 0; i < modules.size();i++)
{
int currentModule = i;
for(int j = 0; j < modules.size();j++)
{
if(modules.get(currentModule).length() > modules.get(j).length())
{
int currentPos;
currentPos = modules.indexOf(i);
modules.set(modules.indexOf(j), modules.get(i));
modules.set(currentPos, modules.get(j));
}
}
Every time I try and tackle this problem I end up forgetting what I wanted to do mid-coding or it just doesnt work. Current, while
1 mod is active: Draws the mods name, no problem
2 mods are active: Leaves the mod that was activated first on top and draws the second mod's name twice below.
3+ mods are active: crashes.
Any feedback will be greatly appreciate, Thanks everyone
Here is a solution using streams:
List<String> modules = myClient.getModules().stream()
.filter(m -> m.isToggled() && !"Click GUI".equals(m.getName()))
.map(Module::getName)
.sorted(Comparator.comparing(String::length).reversed())
.collect(Collectors.toList());
This assumes getModules return some collection that can be streamed.
You need to write a module comparator by implemening java.util.Comparator interface and write your sorting logic in it, like:
import java.util.Comparator;
public class ModuleSorter implements Comparator<Module> {
#Override
public int compare(Module module1, Module module2) {
return Integer.valueOf(module2.getName().length()).compareTo(module1.getName().length());
}
}
I am assuming that myClient.getModules() returns an implementation of java.util.List. The sorting now would be as simple as:
final List<Module> moduleList = myClient.getModules();
moduleList.sort(new ModuleSorter());
The modules inside moduleList are sorted as per your requirement.
What should be my return at the end of my for loop? I'm trying to display the added results of all three parties numDemocrat, numRepulican and numIndepent by
calculating and then printing the number of democrats (party is "D"),
republicans (party is "R"), and independents (party is anything else).
I'm currently looping over the MemberOfCongress ArrayList returned by parseMembersOfCongress and counting up how many of each party type there are.
Also in my loop I need to check which party the current member belongs to and increment the proper variable. After the loop completes I then print the totals.
public void printPartyBreakdownInSenate()
{
CongressDataFetcher.fetchSenateData(congressNum);
}
{
ArrayList<MemberOfCongress> parseMembersOfCongress; String jsonString;
}
{
System.out.println("Number of Members of the Senate of the " + "&congressNum=" + "?chamber=");
}
public String[]
{
int numDemocrats = 0;
int numRepblican = 0;
int numIndepent = 0;
ArrayList<MemberOfCongress> members;
for (MemberOfCongress memberParty : members) {
if (memberParty.getParty() == "D" ) {
numDemocrats++;
}
else if (memberParty.getParty() == "R" ){
numRepblican++;
}
else if (memberParty.getParty() == "null"){
numIndepent++;
}
}
return ???;
}
Firstly i'm 99% positive you cannot return multiple values, unless your return either an array, an array list or a map.
But what you could do as a work around is one of the following.
1). Return a String array of party members.
2). Return a 2D array mapping name to age or something similar.
3). Return a hashmap of the data with a custom class of information mapped to a name.
4). Use getters to get different pieces of the data at time or all at once.
Java (like the majority of programmming languages) allows only a single return value from a method. There are lots of good reasons for this.
If you need to return multiple values then you will need a separate class for which your method can return a reference to an instance.
For example, in your case:
public enum Party {
REPUBLICAN, DEMOCRAT, OTHER;
}
public Map<Party, Integer> senatorsByParty(List<MemberOfCongress> senators) {
return senators.stream()
.collect(Collectors.groupingBy(MemberOfCongress::getParty, Collectors.counting()));
}
Apologies if you are not aware of the Java 8 syntax here. The stream functions are really just saying 'take all the senators, group them by party and then count them'. The key point is that you are returning a map from parties to integers representing the count of senators.
I've been working at this for a couple hours now and I feel (I hope) I'm right on the verge of figuring it out. This program reads in a bunch of values from an external file and places them in an array of objects which seems to be working just fine.
The Objects properties are:
Bank Account #
Customer Name
Bank Account Balance
1. I can output them in order of Account # (That's how their read in from the file, no sorting is necessary)
2. I've setup a method from implementing Comparable to sort by Bank Account Balance and it's working fine.
3. I need a second sort method, to sort by Customer Name.
- The problem I'm having with this is based on the research I've done and what I've tried I've come to the conclusion that the only way to make this work will be to build my own Comparable Objects (sorry if my terminology is skewed.) I've attempted this as well multiple times with both Java Doc and some similar questions on SE.
When all is said and done I'm going to throw some Listeners into my checkbox group to allow the user to toggle the different sort methods.
Here's the chunks i'm working on:
public class bankAccounts implements Comparable<bankAccounts> {
/* PRIVATE FIELDS HERE, FOLLOWED BY TYPICAL GET AND SET METHODS */
/*SORTS BY ACCOUNT BALANCE WORKING GREAT*/
public int compareTo(bankAccounts b) {
if (accountBalance < b.accountBalance)
{
return -1;
}
if (accountBalance > b.accountBalance) {
return 1;
}
return 0;
}
/* BEGIN SNIPPET OF MAIN CLASS */
/*METHOD I CALL FROM MAIN CLASS, SORTS BY BALANCE ^^ AS SEEN ABOVE */
Arrays.sort(retrievedAccounts);
for (int i=0; i<retrievedAccounts.length; i++) {
String resultFull = Integer.toString(retrievedAccounts[i].getAccountNumber()) + retrievedAccounts[i].getAccountLastName() + Double.toString(retrievedAccounts[i].getAccountBalance());
box.append(resultFull + "\n");
}
/* NORMAL METHOD WHICH OUTPUTS IN ORDER OF ACCOUNT NUMBER, NO SORTING HAPPENING HERE */
for(int x = 0; x < retrievedAccounts.length; ++x)
{
String resultFull=Integer.toString(retrievedAccounts[x].getAccountNumber()) + retrievedAccounts[x].getAccountLastName() + Double.toString(retrievedAccounts[x].getAccountBalance());
box.append("\n\n\n" + resultFull + "\n\n");
}
I'm hoping someone will have some insight towards a next step which might allow me to finish this up. If you have suggestions to take this a completely different direction I'm open to that as well.
This is an idea haven't tested.
Create a another private method to store compareType
public class bankAccounts implements Comparable<bankAccounts> {
private int compareType = 0; // 0 - compare by balance 1-compare by name
In your compare method
public int compareTo(bankAccounts b) {
if(this.compareType == 0){
if (accountBalance < b.accountBalance)
{
return -1;
}
if (accountBalance > b.accountBalance) {
return 1;
}
return 0;
}else{
return customerName.compareTo(b.customerName)
}
Use an implementation of Comparator<bankAccounts> that compares the names of your objects and pass that into the Arrays.sort() method.
Use an anonymous class like this:
Arrays.sort(retrievedAccounts, new Comparator<bankAccounts>() {
public int compare(bankAccounts a, bankAccounts b) {
return a.getName().compareTo(b.getName());
}
});
This code assumes you have a getter method on bankAccounts for customer name called getName()
You would do well to follow java naming conventions:
class names start with a capital letter
class names are singular, not plurals
I know someone will give me a hard time for this, but here goes. I am trying to convert some C code to Java and am still learning java as I go. I am having a very difficult time figuring out how to do this conversion and learning java for that matter. Any help or pointers on where to go would be greatly appreciated.
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
/* Jump to the selected adapter */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
A conversion offering:
public class Item {
private String name;
private String description;
public Item(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return this.name;
}
public String getDescription() {
return this.description;
}
}
(defined elsewhere)
List<Item> items;
And now the code
int index = 1;
for (Item item: items) {
System.out.print(index + ". " + item.getName());
if (item.getDescription() != null) {
System.out.println(" (" + item.getDescription() + ")");
} else {
System.out.println"( (No Description Available)");
}
index++;
}
List<NetworkInterface> nets = Collections.list(NetworkInterface.getNetworkInterfaces());
if (nets.size() == 0) {
System.out.println();
System.out.println("No interfaces found! Make sure WinPcap is installed.");
return;
}
System.out.print("Enter the interface number(1-" + nets.size() + "):");
Byte[] input = new byte[100];
System.in.read(input);
String inString = new String(input);
int interfaceIndex = Integer.getInteger(inString);
if (interfaceIndex < 1 || interfaceindex > nets.size()) {
System.out.println();
System.out.println("Interface number out of range.");
// freeing items is done by dereferencing
nets = null;
return;
}
// jump to the selected adapter
NetworkInterface selectedInterface = nets.get(interfaceIndex);
Note that you will have to do the "real" conversion of the rest of the program; that is writing a PCap solution in Java, or writing a JNI (Java) interface to call the PCap library routines.
WinPcap will always require native coding. You could use JNI to get some of that code (e.g. the select interface part) to java, but you'll never be able to fully convert it. (You can't directly call native dll's from java)
I can't really give you examples on JNI, but there is enough out there to find when searching JNI and Tutorial or the like :).
Java does not have pointers, so a construct like "d->next" won't map 1:1 in Java.
You'll have to figure out how to create a Java object that corresponds to whatever your "d" is. The rest looks like simple iteration and calls to System.out.
What do you mean by conversion?Are you trying to write an equivalent C program to Java?Is it an existing project or you wrote a program in C first and now you want to write the same program in Java?In any case you should get a good grip with both languages because they differ in the way you write programs that is C is a imperative/procedural language whereas Java is an object-oriented one. This alone means programming 'style' varies differently due to language semantics (and programming patterns, while language-agnostic, are applied differently too).
P.S.: I assume you are a beginner which, if I am correct, does not justify your votes down.