Jump to content

MrCaracal

Members
  • Posts

    80
  • Joined

  • Last visited

Posts posted by MrCaracal

  1. A chunk is 16x16 blocks, so if you multiply the chunk coordinates by 32 before passing them to your generate[dimensionName] methods, you'll actually be generating very far away from the intended chunks.

     

    Consider the following line-by-line walkthrough:

     

    At L17 your method has been called; suppose it receives chunk coordinates (2,2). On L21 the method multiplies these values by 32 and pass them to the individual dimension methods. The values are now (64,64). At L56 the method then adds a random integer between 0 and 32 to each of them. Worst case scenario, the values are now (96,96). This is somewhat far away from the coordinates of Chunk (2,2), which should have coordinates between 32 and 48 for the X and Z (I can't recall whether they're positive or negative, sorry).

     

    You can imagine how this issue is magnified the farther out from chunk (0,0) you travel - very soon you'll be generating in chunks that are a massive distance away, which is a significant resource demand. If you didn't travel to the Nether from or near chunk coordinates (0,0) you will immediately be generating in distant chunks, which is what causes the memory issue.

     

    TL;DR - Change those 32s to 16s, a chunk is 16x16 blocks and not 32x32.

  2. The if statement in your class will never run, since you are using a bitwise "and" instead of a logical "and". I'm assuming it's just a typo.

     

    if ( age >= 7 & R > 8 ) // Will always be false in this context, should have two ampersands: ((age >= 7) && (R > )
            {
            ret.add(new ItemStack(this.getSeed(), 1, 0));
            }
    

     

    Also as Jabelar said, you are retrieving the drops list from the superclass which probably isn't what you want at all. It looks like you just copy pasted the method from BlockCrops. I think you'd be better off writing a new method that does exactly what you want, since what you want is very simple:

     

    • Make a new List containing only one ItemStack of your seed
    • Perform your 20% chance check
    • If the check passes, add another seed ItemStack to the list
    • Return that List.

     

    Also, I had a question regarding your post, Jabelar: You say "world instance of World" will always return true, but won't it only return true server side?

  3. And why would you NOT save those variables to NBT?  Do you want them to get reset when you save and exit?

    Yes, they absolutely should be written to NBT - I'm only commenting on Trekkie's onUpdate method as it currently exists in the top post. (Did you look at it?) I had no way of knowing whether the mod had some kind of external custom packet handler for synching these values not shown in the original post, hence my wording.

     

    To recap, for Trekkie's benefit:

    - Only side-local fields are being modified

    - The TE's NBT isn't being notified of this, (hence the builtin handling Draco mentioned isn't being used)

    - There is no custom packet handling synching the values, hence the block has the appearance of "not working" client side

    - Therefore you need some kind of packet handling to notify each side of changes.

  4. I get the sense that you're getting into modding in order to learn how to code, and I think that's wonderful, but the forums here are very much not a Java school so I suggest you look elsewhere for those kinds of tips.

     

    To answer your question by adding to what's already been said: there is a way to define an ItemStack to have a particular item, a particular size, and a particular metadata value. If you set the metadata value of an ItemStack to OreDictionary.WILDCARD_VALUE (which is actually equal to INT_MAX, behind the scenes), the ItemStack when used to define a recipe will produce a recipe ignore the damage value of the item.

     

    ItemStack someItemStack = new ItemStack(yourItem, quantity, metadata)
    

     

    Except the above code isn't copy-paste ready: you will want to pass the OreDictionary.WILDCARD_VALUE as the metadata of the item.

  5. I think the change made your TileEntity have the appearance of not working, since unless you have a packet handler notifying the client of changes, the client is going to be unaware of any of the changes made to the TileEntity serverside.

     

    Effectively, your updateEntity logic doesn't happen on the client, and unless you have a packet handler to let the client know about these state changes, it will look (from the client perspective) like it isn't working anymore.

  6. The biggest stumbling block in updating to 1.8 for me was ensuring that the model .jsons had the correct name.

     

    My advice is to break down your registerRender method and set a breakpoint at the end of it so that you can see exactly what name the mesher is expecting. The method adjusted for debug might look something like this:

     

    public static void registerRender(Block block) {
         Item item = Item.getItemFromBlock(block);
         String modelName = ref.uid + ":" +  block.getUnlocalizedName().substring(5);
         ModelResourceLocation resLocation = new ModelResourceLocation(modelName, "inventory")
         Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0, resLocation);
    
         /* Setting your breakpoint at the above line will allow you to easily see all the values of the variables within this method 
    when debugging. You may find that the value of modelName differs from the name of your model file. */
    }
    

     

    The name registered to the mesher must match the name of the blockstates and model file precisely, including capitalization!

  7. I am an enormous fan of DF. The music and the entity models you have shown off so far are quite beautifully done, I am impressed.

     

    Your project has certainly piqued my interest, but I am wary of recruiting-type posts such as these. I'm not saying this is the case here, but I have found that projects presented in this way often have a deficit of programmers on the team and a surfeit of idea-persons and/or artists. I have nothing against idea-persons or artists but my interest would be in the experience of mutual collaboration with a team of fellow programmers and not being simply "the programmer" who is told to implement other persons' ideas, so please forgive my caution and allow me to ask a few questions regarding your project:

     

    - How much coding has been accomplished so far?

    - How many coders are there on the team?

    - What kind of expectations would you have of a team member?

    - I noticed your Alpaca demonstration video is about nine months old, how active is development of this project currently?

     

    Again, I am not trying to disparage your project.

     

    Now, regarding my potential contribution: By some twist of fate, I happen to have a working set of Dwarf-Fortress "dwarven" crops that I developed as a personal project for 1.7.10 but never released publicly. Implemented are all the "classic" crops, Cave Wheat, Plump Helmets, Pigtails, Sweetpods, Dimple Cups, and Quarry Bushes. The sprites and code are original, and a few screenshots can be found in the following imgur album:

  8. Such a thing is perfectly possible!

     

    Here are your ingredients:

    Anywhere you are given a World as a parameter, you can call getEntitesWithinAABB(Class passedClass, AxisAlignedBB passedAABB), which will return an ArrayList of entities of the passed class type within the passed bounding box.

    Dropped items are objects of type EntityItem; and EntityItems have a method called getEntityItem which returns the ItemStack they "contain".

  9. You are correct in that this issue is caused by rendering classes being "client-side" only - meaning that the rendering classes don't exist at all on a dedicated server.

     

    What you need is a way to ensure that your rendering stuff is only called upon by the Minecraft client. The way this is accomplished is by the use of a proxy class, like Ernio said. You will create two classes with identical method signatures: one that will be loaded for the client, one that will be loaded for the server. If you make your client proxy class inherit from your common proxy class and override the common proxy's methods, you will be able to call methods in your common proxy instance and have them execute one way on the "client" and one way on the "server."

     

    This is useful for separating your rendering stuff between "sides". If your rendering stuff is only registered in your client proxy, it will only ever load that stuff on a client. Here's the wiki tutorial on how to write a proxy class -> http://www.minecraftforge.net/wiki/Proxies

     

    Attempting to use the @ClientSideOnly or @SideOnly annotations was logical given their names, but not quite what those are meant to be used for. Those annotations simply mean "the following field or method should only exist to the specified side". They can cause problems if one side is expecting that field or method and it is tagged to only "exist" on the other, so they should be used sparingly and only on fields and methods that you know will only be used on one side; one example being IIcon fields and related methods.

  10. Do you mean you can't "view" the base codes? Because you certainly should not be editing them, it is deliberate that you cannot. If you can't view the code, it might be a workspace issue; you might try carefully stepping through the setup process again.

     

    As far as your random crashes, ConcurrentModificationExceptions are typically caused by modifying an iterable collection while still traversing it. Is there any place where you're editing some form of Collection at the same time as you (or some other vanilla code) is iterating through it?

  11. I'm trying to read between the lines here, but as I understand it: you have a block or structure of blocks that generates in the spawn chunk in your custom dimension. At some point track the placement of this block needs to be tracked as you need to know a coordinate to teleport the player to; and so you need to know the Y-position of your block/structure, which obviously won't exist until after the block has been placed. The solution you're proposing is to load the entire spawn chunk once so you can get the Y coordinate of your block for later use in your teleport system, so you're asking how to force-load a chunk just once. Is that right?

     

    One-time force-loading chunks is a bit unusual. Perhaps there's a better way of accomplishing the functionality you seek, would you mind sharing a bit of context?

     

    Also: have you peeked at how Nether Portals work in the vanilla code? I think that would be a fine case example of generating a structure at a teleport destination; the only difference being the placement of your structure would have different rules (since I think you only want it in the spawn chunk, yes?).

  12. To expand on that, the "normal" recipe class you're using doesn't care about the size of an ItemStack when checking the validity of a recipe. Otherwise, it would only recognize a recipe of a specific ItemStack size, or it would have to check for all possible stack sizes. Imagine how inconvenient that would be!

     

    Your options, I believe are to either create a new item that is equal in "material worth" to a stack of 64 torches and use that item in your recipe, or to create and register a custom recipe handler class that does care about the ItemStack size and register your recipe using that.

  13. Well, if the solution works as well as you need it to, I won't rain on your parade any further, but I will advise you to put it on your to-do list for things to take another look at in the future.

     

    As for the other thing you just mentioned, isDead only returns true on the tick before the entity is to be destroyed. It's not exactly a "dead" flag in the way we'd think of a dead pig, i.e. one with zero hearts remaining. If you want your model to halt the breathing animation some time before that, I think you'll need to come up with a different trigger.

  14. You're extending BlockContainer, and BlockContainer already extends Block, so that's your Block class.

     

    Since you're using a TESR and not a ISBRH, you should register your renderer with ClientRegistry.bindTileEntitySpecialRenderer, as the tutorial suggests. This is typically done somewhere in the main mod file, during Init. I'm sorry if I was unclear, those directions were written under the assumption that you'd be using ISBRH.

     

    You're using a TESR, so you don't need to worry about Render IDs. FYI though, A Render ID is basically a number (integer) that Minecraft uses to correlate a block with a renderer. When it comes time to render the world, the Minecraft client polls the getRenderType method on each block and calls the renderer corresponding to the number it receives. You may have noticed that (among others) there are two other accessible methods in RenderingRegistry, a registerBlockHandler that accepts an integer and a handler, and getNetAvailableRenderID. That's what these two are for.

     

    TL;DR - Use ClientRegistry.bindTileEntitySpecialRenderer like the tutorial said, since you're using a TESR.

  15. EDIT: I only just saw your PS. The first thing I think you should do is move your rendering stuff to a proxy class so that it doesn't load on a dedicated server, which does not have any of the rendering functions. Minecraft.getMinecraft(), for instance, is client-side only and will crash a dedicated server. I like your gumption but I advise you to start at the beginning of the tutorials on the wiki because you're missing some very necessary boilerplate.

     

    It certainly is possible! Have you perused the wiki? -> http://www.minecraftforge.net/wiki/Using_wavefront_model

     

    I know you asked for an "up-to-date" tutorial but as far as I am aware the process is the same now as it was then, except you can use ISimpleBlockRenderingHandler instead of TESR.

     

    I don't think you need to make a Container or a Tile Entity class if all you want is a simple block with a fancy render, because unless you tell it to the renderer doesn't care what logic the actual Block implementation has.

     

    The process is basically:

     

    1) Write your rendering handler that implements either ISimpleBLockRenderingHandler or TileEntitySpecialRenderer. (Unless you're doing something extra-fancy, ISBRH is just fine. You'll know if and when you need it, otherwise, just use ISRBH)

    2) Register your rendering handler with RenderingRegistry.registerBlockHandler.

    3) Make getRenderType method in your block class return the render ID corresponding to your rendering handler.

  16. May I ask for a clarification?

     

    Are you saying that you would like to implement your own .obj model loader, or that you have an .obj that you'd like to use as a model for a block?

     

    I ask because Forge already includes such a model loader. To answer either of the above potential questions I recommend you peek at WavefrontObject.class, and ObjModelLoader.class in the net.minecraftforge.client.model.obj package.

  17. I see your solution, but I don't know that I would recommend it.

     

    You've employed a workaround to the fact that every time you call rand.nextFloat() you receive a different value. You don't need a new random value every time render() is called on your model, and you certainly don't need to be polling a HashMap every time render() is called to make sure the random number you got this time is the same one you got the first time. I doubt that this will scale very nicely with a large number of entities.

     

    A random number generator simply isn't what you need for this application, I think... especially given you've gone to some length to ensure that the number you're getting is not random per render() call, but constant.

×
×
  • Create New...

Important Information

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