jabelar
Members-
Posts
3266 -
Joined
-
Last visited
-
Days Won
39
Everything posted by jabelar
-
Of course you can code such a system. But the original poster seemed to be hoping for some built-in method to easily create it, and the thread seemed to be leading to the idea that you can use the setSize() method to change this, but you can't. But like I said, it isn't too hard for an intermediate coder. I personally would still use the vanilla hitbox to be big enough to register any hit, and then when there is a hit, just check for whether the arrow was within a hitbox AABB. Note though that people who have done some work with multiple hitboxes before mention that you don't want to make critical hitboxes that are too small because the hitting in Minecraft really isn't that precise, especially if you encounter network lag.
-
First of all, there is only one built-in bounding box per entity and I think it is also used for path-finding collisions. In other words, the bounding box always tries to touch the ground. So I think that if you make the bounding box to just be the head, then I think you'll have problems with movement -- for example I think the zombie would sink into the ground so only the head was showing. So I think the best way to look for headshots is to leave the regular bounding box and get the height of the arrow entity at the point when it collides with your entity and compare heights. Anyway, the coordinates in the Techne model are "pixels" and I think you'll find that the origin is 24 pixels high which is therefore 1.5 blocks high (there are 16 pixels per block). Therefore, if you really wanted to have the bounding box be the head, I think you would have to check for collisions with an AABB that is positioned at 1.5F higher than the zombie's position.
-
I was just going through this thought process myself. I'm making a bunch of entities that look different (different textures and slightly different models) but otherwise mostly act the same. You basically have two different approaches that I can think of to handle this: 1) create one "super" renderer class, and one "super" model class. For each of these you make a constructor that takes in all the things that would make an entity different. For example, your constructor to the renderer can have different textures, your constructor to the model could have an enum to indicate whether your car should be a minivan, truck, etc. Then the code for each of these classes would take that information and change behavior accordingly. So creating different instances would be as easy as just passing different textures and other parameters when you register the renderer with the model in your proxy. 2) Create a renderer and/or model class for every different case. While this sounds like a bit of work, it actually only takes a couple seconds to copy a class in Eclipse. My only tip is to make sure you get the original class working well before copying it a bunch of times, otherwise each time you have to fix a bug it will require editing more classes. But anyway, it really isn't that much work to copy classes and edit to your liking. In your case of customizing the vehicles based on a txt file resource, I would suggest the first approach. You can simply make your renderer and model classes to have constructors that take the info from the txt file.
-
Performance optimization suggestions or tutorial?
jabelar replied to Purplicious_Cow's topic in Modder Support
You can actually time the various parts of the code that you suspect using something like this: final long startTime = System.currentTimeMillis(); for (int i = 0; i < length; i++) { // Do something } final long endTime = System.currentTimeMillis(); System.out.println("Total execution time: " + (endTime - startTime) ); A Minecraft tick is 1/20th of a second which is 50 milliseconds, and usually the code should finish before that (otherwise you'll see lag). So anything over 1 millisecond can start to be considered significant. You can get more precision us9ing System.nanoTime() but in some cases it might have trouble on multi-threaded situations. Anyway, with such an approach you can actually time your code and determine what is taking significant time and furthermore prove to yourself that your attempts to fix it are working. -
[1.7.10] Custom Entity Won't Spawn Naturally
jabelar replied to zanda268_1's topic in Modder Support
Hmmm, it should work I think. But the code is a bit convoluted. As far as I can tell, there is a list for each enum type such as spawnableMonsterList, spawnableCreatureList, spawnableWaterCreatureList and spawnableCaveCreatureList (for ambient type). The BiomeGenBase class has the getSpawnableList() method which returns each of those lists based on the enum type. The addSpawn() method seems to add onto the list as provided by the getSpawnableList() method. So if you add spawn with EnumEntityType.creature it should get added to the spawnableCreatureList. The spawning of EnumEntityType.creature is done with the performWorldGenSpawning() method in the SpawnerAnimals class. This is called by the ChunkProvider class' populate() method, depending on what the TerrainGen.populate() method allows. Any terrain that allows ANIMALS should populate creature entity type. Sorry, I don't know what else is wrong. Are you getting any other console errors? Sometimes my entities don't spawn if they have some constructor or reflection error during creation. -
[1.7.10] Custom Entity Won't Spawn Naturally
jabelar replied to zanda268_1's topic in Modder Support
I think you can put any EnumCreatureType you want in the addSpawn method. The options are creature, ambient, monster and waterCreature. I'm not sure where the finer controls are specifically, but you could probably just hook into the events that generate the world and do your own spawning code instead. -
Actually, you shouldn't feel bad. Often in programming you come to a point where you realize you have to do an extensive re-write of code. Think of the Minecraft authors who completely re-wrote the block state stuff. The main thing is that you become a stronger programmer the more approaches you explore. So for example after this experience you will have a better understanding on when a TESR may be needed.
-
For debugging you should learn to use console statements. Just add System.out.println() type statements at each point in your code to print out stuff that helps you see what it is actually doing. So I would suggest printing out the positions in the loop that creates the parts. It might also be helpful to have print statements inside the parts' code. Instead of using the built-in EntityDragonPart class, maybe copy that to your own class. Then you can do things like override methods and add print statements, or you can have it print out the position in the onUpdate() method, etc. You'll have more control with your own class. Anyway, if you print out information that shows what your code is doing, you should be able to quickly figure out what is going wrong.
-
Acces the src directory from java code?
jabelar replied to ItsAMysteriousYT's topic in Modder Support
I don't think you understood what the OP wants to do. First of all, this isn't a "fake" resource pack; it is a real resource pack that you create during initialization. He does plan to use JSON, he's not saying he wouldn't. -
Okay, so you can see that Entity Dragon pretty much takes the approach I mentioned -- when you construct the parent part, it creates an array of child parts which get the parent part passed to them. A few comments: - I don't think you need all those fields for each part. You already have an array of parts, so you shouldn't need a field for tendrilBase1, tendrilBase2, etc. I know that Ender Dragon does do that, but it isn't really needed -- you can reference tendrilBase3 with tendrilBase[3] and there is a string which can give the part a nice name if you need it. - When you construct the parts, you have them all set the same size (hitbox size). Is that what you want? Your picture makes it look like they'll get smaller and smaller. In Ender Dragon, it set's the hitboxes later but you can set them right when you construct them in the array of parts. Anyway, I think the main problem I see though is: where do you set the position of the parts? When you create them they'll be at 0, 0, 0 so you need to set their position. The Ender Dragon does this in the onLivingUpdate() method where you can see it has a for loop that goes through all the parts and updates their position. Regarding using onUpdate() or onLivingUpdate(), there are lots of methods that are called every tick and that is the main thing that matters. onLivingUpdate() makes good logical sense, so use that. By the way, you probably already know, but by pressing F3+B you can see all the entity bounding boxes. This would be useful while testing a multi-part entity.
-
It is better to post or at least explain what you've tried when you're asking for help. But here is some advice. First off, the models for an entity are already multi-part (like it has head and body and legs and arms). So when someone asks about making a multi-part entity, what they mean is that they want a complex hitbox. Because as you probably know, the hitboxes for a single entity are quite limited. The hitbox for a single entity must be a rectangular box and the X and Z dimensions have to be the same and the hitbox size is limited by pathfinding algorithms. So I'll assume that what you want to do is have a complex multi-part hitbox for your entity. Anyway, the way I would do it is actually make the "entity" made up of multiple actual entities. One part (like the body) could be considered the parent entity and could have the full entity model, and the rest of the entities would be invisible and will follow along. This means that whenever you construct the parent entity part, it will additionally create the other parts (in the correct relative positions). To create the parent/child relationship between the entities, you'll need a list in the parent entity that keeps track of the instances of the child entities, and each child entity should have a field that contains the parent entity. Then you'll have information in each part about the other parts, which you'll need for your logic of movement and damage. Then, all you need to do is: 1) move everything together. You'd do this by moving the parent entity part and the onUpdate() method for that entity should also automatically update the other parts' positions (and maybe rotations). 2) decide how you want to handle damage. You might just want to have the damage in the parent entity reduced when any child entity is hit. Or depending on the mob, maybe you want each part to get damaged separately. In the first case, you'll have to handle the case when the child parts are hit and instead inflict the damage on the associated parent. 3) if parent part dies, make sure to kill of the child parts. The only other tricky thing is pathfinding. There is a reason that the Ender Dragon is flying and also destroys blocks -- if it did not then the path finding would be very difficult -- imagine a complex entity trying to move around in a cave or forest. To make multi-part entity work with pathfinding is a tough coding challenge, so it is best if you can "cheat" -- like maybe allow it to move anywhere the parent part can go -- i.e. only do pathfinding on the parent part and don't worry if the rest of the parts overlap into blocks. That's pretty much it! Hope it helps.
-
As CoolAlias says, your crash isn't really about plants but rather about how blocks in 1.8 work. You need to have a block property that represents growth stage and you need to convert that to and from metadata by overriding the appropriate methods. In terms of plants generally, I have a tutorial but it is currently for 1.7.10 so you have to convert the block stuff to 1.8. I'll try to update the tutorial sometime, but it might at least give you some concepts that help you understand how to fully implement a plant: http://jabelarminecraft.blogspot.com/p/minecraft-forge-172-creating-custom.html
-
ModelRenderer .addBox To use Floats in all 6 values
jabelar replied to American2050's topic in Modder Support
This is just basic Java. You simply need to make your own method called something like createModelRendererFloat() with the parameters you want. In that method you would convert the parameters (floats to int) and then return a new ModelRenderer. To convert float to int, you simply have to round the float and then cast it to int. -
[1.7.10] switching a mobs ai. [SOLVED] 100%
jabelar replied to BoonieQuafter-CrAfTeR's topic in Modder Support
Did you read my tutorial on AI that I linked above. It explains how the AI works in detail. Briefly, there are two types of AI. The original AI which called a couple methods to update the state of the entity, and all the code for the AI ran there. But the newer AI is much more complex and is enabled if the isAIEnabled() method of your entity returns true. In that case, it cycles through a number of AI class instances (that you add to a list in your entity constructor) based on a priority you set. It checks if the AI should start executing, or if it is already executing it checks to see if it should continue executing. So there are methods for each of those that you override and put in the condition you want. So in your case, if you want to switch between ranged and melee, your entity just needs a field to "remember" what it used in the last attack. Then you can have both types of attack in your AI list, but in the shouldExecute() method of each you would check what the last attack was and only return true if the last attack was the opposite type. The rest of the AI would just be copied from the melee and ranged attack AI. -
To other points: 1) They're called SRG names I think. 2) It is important to update the mappings in your build.gradle file to grab the latest mappings. For some reason 1.8 is being distributed with a mapping from back in November and several of the names have been made more readable since then. To do this, put something like this in your build.gradle: minecraft { version = "1.8-11.14.2.1439" runDir = "../run/assets" mappings = "snapshot_20150712" } Of course the version and run directory may be different in your case, I'm just saying to add the mappings line. The snapshot is just a date, and it is best to just put the current date which today is 20150712.
-
[1.7.10] switching a mobs ai. [SOLVED] 100%
jabelar replied to BoonieQuafter-CrAfTeR's topic in Modder Support
Making your own AI class is actually pretty easy. Just copy the code from a vanilla AI class that is close to what you want and then modify to your liking. Then build up your own fresh AI task list for the entity (clear the list and then add back all the AI you want). -
As mentioned you should use git and github. In fact, to make that easier, I suggest using SourceTree which has an easy graphical interface and built-in git so you don't have to muck with your overall computer's file system and git command lines. I have a tutorial to set this up here: http://jabelarminecraft.blogspot.com/p/minecraft-forge-publishing-to-github.html With git you CAN edit the same file at the same time. What happens is that you merge the changes later, where one of you (whoever is more experienced) should decide which edits to keep. The whole process of updating and syncing is really fast, so you can do it in real time. Like if you were chatting with the other person you could make an edit, commit it and have them pull it all within about 30 seconds. I suggest using SourceTree even if you're just coding by yourself. It provides revision control and backup safety. Also, you can use multiple different computers to work on the same project.
-
If someone is not strong enough in Java to understand how to count ticks, I don't think it is good to suggest they try multi-threading. You shouldn't need to use multi-threading for delays anyway, since there is no need. All you need is to either hook into a method that is called every tick, or one of the tick events. For things like entities, there is even a field already called ticksExisted that automatically increments, and there is also a world time that counts ticks as well.
-
For AI, I have some tutorials: http://jabelarminecraft.blogspot.com/p/minecraft-forge-1721710-custom-entity-ai.html For attacking attributes, I have this tutorial: http://jabelarminecraft.blogspot.com/p/minecraft-forge-1721710-apply.html For giant mobs, one of the main difficulties is the hit box, I think there are some limits to the size, at least in the height. This is due, I think, to the pathfinding -- it is hard for Minecraft to figure out how large hitboxes can move through terrain. In the giant entity I made, I think the maximum size I found that worked was setSize(1.0F, 4.5F).
-
[1.7.10] switching a mobs ai. [SOLVED] 100%
jabelar replied to BoonieQuafter-CrAfTeR's topic in Modder Support
Please post the crash report as well. However, you're also not really using the AI right. You're not supposed to keep adding tasks to the task list. Instead you should have all the tasks on the list already and you "switch" by changing the conditions that trigger in the shouldExecute() method. It is important to note that the number (in your case "4") is NOT an index, but rather just a priority level. You can have multiple tasks with the same number. So when you're adding tasks in your code, your list is just getting longer and longer -- possibly that is the cause of your crash. Anyway, the adding of the tasks should be something you just do once during initialization, not during every tick of the AI logic. -
1.8 - Need help - How to improve/shorten item registering code
jabelar replied to SuperGeniusZeb's topic in Modder Support
While it may seem clever or interesting to do such things in an algorithmic, compressed way, there is nothing wrong with cutting and pasting same code multiple times. You need to ask yourself why you were doing this, and I expect you'd say you thought it would save time. Yet, obviously you've already spent more time trying to save time than you would have saved and you're not even done yet! So what's the point? I'd also propose that the simpler your code is logically, the less likely it is to have bugs. So it is better to cut and paste 14 sections of code that you know work than to try some sort of iteration through a map and such. Of course if you're a high-level programmer, then you can get the map right on the first try and might as well do that. But there is no shame at all in simply having cut and paste code. -
Are you sure that that method is called when you have AI enabled? My understanding was that if the isAIEnabled() returns true then it doesn't run the old AI methods.
-
I have a tutorial for crops here: http://jabelarminecraft.blogspot.com/p/minecraft-forge-172-creating-custom.html It is 1.7.10 tutorial so you'll have to do some conversion, but it explains the major concepts and important methods.
-
I'm not sure specifically, but perhaps there is another type of gui opened at that time. You might want to check for any GuiScreen at all and print that to console. It should tell you what GUI is open at that time, and then you could check for that instead. By the way, changing the main menus with a mod is frowned upon. Imagine if everyone tried to get cute by adding things to the main menus -- it would be a mess and probably lots of compatibility issues as well.
-
Trying to spawn particles on the server side.
jabelar replied to kitsushadow's topic in Modder Support
No, you don't. World#spawnParticle calls IWorldAccess#spawnParticle, and the server implementation (in WorldManager) literally does nothing. If you try to spawn them on the server, nothing will happen. You either send a packet or spawn them directly on the client side, depending on the situation. You misunderstood my statement. I said you "initiate" the spawn. That does not mean you use any world spawn method. I mean you use your own code to send a packet to all the clients. This is the confusion -- the impetus for spawning particles should be on the server. The actual instance of the particles is only created on the clients. The problem is the terminology "spawn". Spawn doesn't mean create an instance, it means to start the process to create something (whatever that means for the case involved). For example, you could say that placing a block is "spawning" a block -- even though no new instance is created at all. In the case of actual entities, you actually instantiate them on the server. In the case of particles you initiate the spawn on server but instantiate on the clients, and in case of blocks you initiate the spawn on the server and it is never instantiated in the Java sense. All of that is spawning, and all of those cases start on the server.