Jump to content

jabelar

Members
  • Posts

    3266
  • Joined

  • Last visited

  • Days Won

    39

Everything posted by jabelar

  1. A few things: I don't think you need the line with the clipRenderersByFrustum() because you're not actually trying to render and you've already got a frustum instance to check the bounding box again. Why is your arrow field of type EntityPig? Your code is basically looking for pigs, not arrows. Did you do that for debugging? Is it your intention to only detect pigs within 10 blocks of the camera? Or do you want everything in the full range of view to distance? Because your code would only detect pigs within 10 blocks. When you were testing the code were your pigs that close? If you want all pigs into the distance, I think you could just iterate through all the pigs in the world instead. None of that code will detect if obstacles are in the way. Why do you want to know if obstacles are in the way? Anyway, if you do, you'll want to do a "ray trace". There are methods in the world class for that -- you just specify the end points of the "ray" and it will return if any blocks are along that line. So I think you could take each pig and ray trace back to the frustum position.
  2. Is it happening at the point when you click on a slot? Then post the code for your container and/or slot (whole class please) that does the processing of the click. I usually make a custom slot for the output slots, as that can allow flexibility in behavior.
  3. You can follow the golem code, but the approach to animation is pretty simple. You just need to program the following: 1) Need a counter variable in your entity class to indicate how far into the animation you are. Most people make it a decrement counter, so if the total animation was 20 ticks (1 second) you'd set it to 20 at start of attack. 2) You need to sync the attack counter from Step #1 from server to client, using custom packets (or data watcher, or entity state) 3) In your entity model, in your render method you just need to set the rotation angles and positions based on the value of the attack counter from the entity passed into the method. 4) Don't forget to decrement the attack counter (either in entity update method or the model render method). That's it!
  4. Well, forgetting about it is what I mean by "tripping me up". Most old-school programming languages, like C, are true pass by value so you wouldn't have to make a copy since it would be made for you already. Java's way of doing it is definitely powerful/convenient, but you have to do more to not forget about it as it can cause security/scope issues, memory leaks, etc. if not handled properly.
  5. Java and its kooky pass by reference/value stuff always trips me up too. The idea that you can modify the original parameter passed in is obviously powerful, but can actually be a pain when what you want is a copy to modify. I'm sure I've got several of these mistakes lurking in my code...
  6. Cool. But that still supports my point -- that it is a new instance that needs to get stuff copied over from previous. I've seen a lot of posts in past couple days (like first response on this thread) where it is clear that some people don't realize that programmatically it is a new/clone instance.
  7. I would agree with your proposed approach. Basically I would have a text-based resource file that contains information about the blocks in your structure. There is actually a "schematic" format that many people use, but frankly I find it easier to just record the block name, metadata value and positions. I then read them into an array, and then cycle through the array and place the blocks (offset by starting position). I was originally tempted to just code the array directly into the class, but even for modest size structures (10 x 10 x 10) you quickly get into the thousands of lines and that is better put into an external text file. Lastly, I use block names instead of IDs, especially since that allows you to reference blocks from other mods confidently. Another key point when placing the blocks is that some blocks require other blocks to be placed first otherwise they won't place properly (like tripwire). I found that what works best is to place all the blocks with metadata = 0 first (except for some special blocks like tripwire), then place all the ones with metadata, then place a few special types of block.
  8. Fair enough, I usually am just extending them a bit (between 1 and 2).
  9. Actually, I don't think you can. Last time I tried I think I found that input events aren't fired when chat gui is open. I think your suggestion about using tick event is probably better.
  10. The tricky part is how to associate it to a player so it persists after you die or leave game. A lot of people don't realize it, but I'm pretty sure the EntityPlayer instance is made new every time you join the server. Its association to a username is temporary for the session. The server does save the extended properties, but from a programming point of view that information isn't loaded into same instance, but rather a fresh instance which doesn't check username before loading. So in CoolAlias' tutorial, he creates the extended properties such that it contains a hashmap of extended properties keyed to the username. In other words, the extended properties will first contain extended properties for the first username that plays, then it will add if/when other players play. Anyway, that's the part to pay attention to, and also the reason why just making extended entity properties for players is a bit complicated. Another note: you don't have to worry about the persistence of the extended properties if the properties are supposed to be used for temporary purposes within game. For example, if you had an extended property for "mana", you might decide it is easier to allow user to start every session with full mana bar instead of remembering it depending on your mod's gameplay concept.
  11. You can handle the NameFormat event and directly modify the event string. For example, for any of my friends who log in I usually add a funny title like "the Magnificent". Here is an example method: @SubscribeEvent(priority=EventPriority.NORMAL, receiveCanceled=true) public void onEvent(NameFormat event) { // DEBUG System.out.println("NameFormat event for username = "+event.username); if (event.username.equalsIgnoreCase("jnaejnae")) { event.displayname = event.username+" the Great and Powerful"; } else if (event.username.equalsIgnoreCase("MistMaestro")) { event.displayname = event.username+" the Wise"; } else if (event.username.equalsIgnoreCase("Taliaailat")) { event.displayname = event.username+" the Beautiful"; } else { event.displayname = event.username+" the Ugly"; } }
  12. The parameter that is passed in to an event often has additional fields that can be accessed. Look at the class for the events, and you'll see that it is possible to get the damage source which may be an entity.
  13. There is a LivingAttackEvent and a LivingHurtEvent, which both could probably be used depending on what you're interested in achieving. In my tutorial on events, I have tried to include a list of all the events I have found in the code. See: http://jabelarminecraft.blogspot.com/p/minecraft-forge-172-event-handling.html
  14. Sure you can. I've just been doing it with a tanning rack block in 1.8. But not horizontally. As you said, the chests and beds are actually multiple blocks.
  15. As far as I can see, your code looks pretty good. The EntityFX methods are not well documented, so I'm not sure how you figured out what the layers mean exactly -- it wasn't as clear to me, but I agree your list looks probably. The number 3 seems to be the layer rendered with the renderLitParticles() method. 0 and 1 are rendered in the renderParticles() method with 0 binding the particleTextures (vanilla particles) and 1 binding the texture map for blocks. Okay, so that's just to say I think you're correct about layer 3 being the one you want to use. The code in the renderWorld() method that calls both renderLitParticles() and renderParticles() looks like this: Which shows they are called close together and without any translation or movement between them. However, there is one area I'm suspicious about. The renderParticles() method itself includes some updates to the interpPosX, interpPosY, interpPosZ, whereas the renderLitParticles() does not. I'm not sure what the significance of that is, as I think the positions are still calculated separately in the renderParticle() method called by both methods. Anyway, I think you need to go back to debugging basics -- trace your code to see what the entity position is at the time it is being rendered. Put your IDE into debug mode and trace the behavior through the rendering.
  16. I think it is possible to replace the blocks as the chunk is initially populated with the PopulateChunkEvent. At leas I know you can do it with the main blocks in the world and don't see why it wouldn't work for the trees. I wrote a tutorial on it. Check out the section about replacing blocks on this page: http://jabelarminecraft.blogspot.com/p/minecraft-forge-172-modding-quick-tips.html
  17. The first thing you should do is make sure you have the latest SRG name mappings in your Forge setup. For some reason 1.8 is being distributed with an old mapping and actually many more of the functions now have names. To do this, you would edit your build.gradle file to have something like the following: minecraft { version = "1.8-11.14.1.1410" runDir = "../run/assets" mappings = "snapshot_20150518" } Where you see I've added a mapping. (The other parts for version and runDir you should update according to your setup and latest version). The numbers after the snapshot_ indicate the date and you can use anything up to the current date (like 20150604). If you do that and run gradlew setupDecompWorkspace and gradlew eclipse again on your workspace, you'll have many more names in the source code. In this case only one of the functions has new mapping, but that stil helps. The interface in my source code shows the following three functions: @SideOnly(Side.CLIENT) public interface GuiResponder { void func_175321_a(int p_175321_1_, boolean p_175321_2_); void onTick(int id, float value); void func_175319_a(int p_175319_1_, String p_175319_2_); } So at least you know one is the onTick function, so that should help. After that you might need to trace the call hierarchy of the other functions to see if you can figure them out. The first one seems to be related to mouse clicks. Lastly you might need to trace the code execution by adding console/logger statements or by using debug mode.
  18. Like all modding, it is best to find vanilla stuff that behaves close to what you want and check out in the source code how that works then adapt it to your use. So find a vanilla gui that uses gui slider and check it out. Basically the vanilla source code is great "tutorial" for a lot of stuff.
  19. Use your IDE (like Eclipse) and search Java for *redstone* constructor declarations. Regarding energy systems generally, the idea is that you need to have three types of blocks -- energy sources, energy conduits ("wires"), energy users (machines). In most cases you'll want these to have tile entities, as you need to remember some energy values and maybe do some complicated processing. The energy source just needs to keep a field that indicates the amount of energy it can provide. The energy conduit needs to look at neighboring blocks and adjust the amount of energy it has based on the energy sources and other conduits that are touching it. The energy users just need to look at neighboring blocks and check for energy sources or conduits with sufficient energy to operate the machine. That's the basic idea.
  20. I have a tutorial on making custom spawn eggs for custom entities here: http://jabelarminecraft.blogspot.com/p/minecraft-forge-1721710-creating-custom.html
  21. I don't think the ID used in the two methods (registerModEntity() and entityList.put()) are the same. The ID for the registerModEntity() is unique for each mod, and can start at 0 and increment. This registration method doesn't have to worry about ID of vanilla or other mods -- in other words there can be multiple mods that all use same ID in this registration. But I think the entityList.put() uses an "absolute" ID similar to the old global entity ID system. So maybe you need to get the global ID rather than just using the same mod ID. You can also just create your own spawn egg item, which is the way I tend to do it.
  22. Why does it need to be scrollable? Because you have lots of them? Anyway, the general idea is that you would create a class that extends GuiScreen. Then in the initGui() method you would create all the buttons. You would also have fields to remember the amount of scrolling. in the drawScreen() method you would then draw the buttons in a position based on the amount of scrolling. To control the scrolling you could look at other GUIs that have slider scrolling, or you could create "up" and "down" buttons. If you created buttons for the scrolling then you would handle the actionPerformed() method and adjust the scroll amount based on which button was pressed. In the updateScreen() method, for any button that is scrolled far enough to go off the screen, you would set visible to false. That's pretty much the idea -- just keep track of the scroll and draw the buttons locations according to the amount of scrolling.
  23. You might be able to figure out a way to fake it by using events. Basically, maybe you could use an event to cancel the 1.7.10 update code, and then go off and run the methods that call the AI. I haven't looked through the whole thing, so maybe there is something that would prevent this approach, but in the end the AI is just some code that is called each tick to check whether it should start or stop doing various things. ' Yet another approach would be to create a custom entity and replace the vanilla zombie pigman with the custom entity.
  24. Actually, adding the vectors works too. A Vec3 is really just an x, y, z coordinate. It is a "vector" if you consider it's origin to be relative, but it is an absolute position relative to the world origin. So the way he added the vectors would work as well. The final position would just be the xCoord, yCoord, zCoord of the resulting vector. But I did forget to discard the Y part of the vector. Good catch.
  25. I believe the easiest way to do it is to use vectors. Minecraft has a 3D vector class called Vec3 which basically just contains an x, y, z but also includes methods for adding, normailizing, etc. Anyway, there is a thing called the "look vector" which Minecraft maintains that indicates a normailzed (length of 1) vector in the direction the entity is facing. So if you want to find a position in front of an entity, the math is pretty simple: 1) Make a new Vec3 using the player position. 2) Get the player look vector multiplied by the distance you want it to be in front of the player. 3) Add the two vectors from step #1 and #2 together -- the x, y, z will be a position in front of the player. Note that in 1.7.10 to create a new Vec3 you have to use the vector helper method, but in 1.8 you can just construct them directly.
×
×
  • Create New...

Important Information

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