Jump to content

coolAlias

Members
  • Posts

    2805
  • Joined

  • Last visited

Posts posted by coolAlias

  1. Logs require 4* metadata values per type, so you can only have a maximum of 4 log types per block instance, which is basically the same as per unique block class (though you could "get around it" by passing in the types array to the constructor and making a separate instance of the same class).

     

    So yes, you do need to split them up.

     

    * More technically: meta 0-3 (bits 1 and 2) are used for the wood type, and then bits 3 (i.e. meta = 4) and 4 (i.e. meta = 8 ) are used for block rotation, so there is no room left for other variants in a 4-bit space. E.g. type 0 also has values at 4, 8, and 12; a total of 4 states per type.

  2. I imagine there already exist some really nice utility classes that can do this if you can find the right library... or you can even use the built-in Minecraft code:

    String text = "Your text\nAnother line of text.";
    String[] temp = text.split("\\\\n"); // split the text on new-lines
    List<String> desc = new ArrayList<String>(); // this will store the resulting wrapped text
    for (String s : temp) {
        desc.addAll(fontRendererObj.listFormattedStringToWidth(s, 101)); // whatever line length you want, here I use 101
        desc.add(""); // this will be an empty line, simulating a paragraph break or new-line
    }
    

    I use that in combination with a scroll bar for lengthy texts and it works great, taking into account things like individual character width. It's still not exactly what you want if you really want 'justified' text like you'd find in a text editor, as it doesn't pad characters to fit shorter strings to the width, but you can view the code and perhaps use that as a starting point.

  3. In your case, since you have camera shake that should only occur presumably in 1st person, the answer is actually simpler: move the player, not the camera.

     

    What I mean by that is, you can rotate the player's head yaw and pitch, and their view perspective will change accordingly, effectively simulating camera movement without moving the camera.

     

    That's how I made the Z-targeting in my Zelda mod, though I had originally framed the problem in the same way that you had and made no progress on it for over a day until I rephrased the question.

  4. See here for a tutorial that explains both methods (IEEP and ItemStack NBT).

     

    As others have said, don't worry about performance. Neither implementation will cause any sort of performance issue at all; just choose the one that makes sense for your project.

     

    I.e., if you want the inventory tied to the player, like an extra armor slot, use IEEP; if you want an item that stores an inventory, such as a backpack, use ItemStack NBT. That is the only way to design - worry about performance only after you implement it in a logical fashion and notice issues.

  5. You can specify an external directory from which your workspace will run, so that you can test multiple mods while using the same default run directory - hence the aptly named 'runDir'. It is the directory where the vanilla assets are stored, world saves, etc.

     

    You can also specify the run directory to be that of your project, so each project has its own separate run directory. There are advantages to both methods, and you can choose which one based on the project, so some projects can share while other projects don't.

     

    The assetsDir I haven't seen used in some time - I'm not sure if it's deprecated or something, but it was basically the same thing, though it may have only applied to where the vanilla assets are located. I don't really recall and didn't try to look it up, but it's something like that. :P

  6. Oh, you don't want the original arm to render either? I thought you were rendering a 2nd arm in addition to the first, in which case you wouldn't cancel any of the events at all, just render your extra model at that time and leave everything else as is.

     

    You can still render Java models the same as before, btw - that's how Entities are rendered, even in 1.8. I have yet to do so within the same context as an Item being rendered, but I don't imagine there would be any technical reason preventing one from doing so, though you may have to deal with unexpected GL states depending on when you do it.

     

    Hopefully someone else more knowledgeable with OpenGL / rendering in Minecraft can help out - it's not exactly my strong suit :P

  7. You're getting a NPE on this line:

    NBTTagCompound properties = (NBTTagCompound)compound.getTag(EXT_PROP_NAME);
    

    The only thing that can be null in that line is the 'compound' parameter given to the method from your message handling, and the reason that's null is because of this:

    @Override
        @SideOnly(Side.CLIENT)
        public void handleClientSide(MessageSyncPlayerProps message, EntityPlayer player)
        {
            ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer).loadNBTData(data);
        }
    

    Do you see that there is a 'message' parameter in there? That's the message that was received, but you are sending 'this.data', where 'this' is now the message handler, not the message. The handler doesn't know anything about what was sent or received, and that's one of the reasons that it can be confusing putting handling methods within the message class - you expect class fields to be available, but none of them are initialized to anything.

     

    You can fix your problem now by using 'message.data' as the argument to loadNBTData, but I recommend you redesign your message handling so it's more intuitive to use.

     

    Something like this, where the handling calls a method on the message instance itself, rather than passing the message instance to the method, let's you use code like you originally wanted to use.

  8. You should probably render the arm model using RenderPlayerEvent or RenderHandEvent rather than trying to jam it on to the item model, but you should still be able to use the technique I showed in my link above if you really want to do them 'together'. Basically, you would render the arm model separately anyway, irrespective of whatever model you will return for the actual gun.

     

    While I'm sure there is probably a way to do what you set out to do (merge 2 separate models with 2 separate transformation matrices together into 1), it's very likely far more technically challenging than it would be worth. Is there any particular reason you can't render the 2 models separately?

  9. Off topic, sort of, but I still don't see why you even need IPerspectiveAwareModel if all you are going to do is apply the vanilla transformations... that would be done for you with a standard model.

     

    Anyway, to your problem: the only way I can think of to have 2 models with different transformations is to actually have 2 models, each with its own JSON defining its transformations for each perspective, and probably to render them separately so that the different transformations don't interfere with each other.

     

    Note that you can actually render other models independently, though I don't know how recommended this is... there is very likely a better way, but this is what I hacked together for my mod when I wanted to render different arrow items dynamically into a bow while it is in use.

     

    I'm sure you'll get better ideas soon, but that might get you started towards something that at least works in the meantime. ;)

  10. For 2 & 3, you can create a subclass of LayerRenderer and do whatever transforms (e.g. scale) and translations you want to do from there. Here is an example which I use for any generic biped entity (based on the vanilla LayerHeldItem code which you should be able to use if your entity model sets isChild to true...).

     

    Not too sure about #1 - it should change the position based on the shooting entity's height / eye height as you described. You may want to try playing around with the numbers and putting a break point in that EntityArrow constructor to see what, exactly, is getting passed in for your entity's eye height. You never know - it might not be what you think it is, and at the very least you will know one way or another if that truly is the issue.

  11. Just an FYI: since you commented out the read/writeNBT methods entirely, you are not actually overriding them to do nothing, but instead allowing the super class version of those methods to be called.

     

    Now I don't recommend doing this, as some parts of the game engine probably rely on the entity being able to write to and read from NBT, but to actually prevent the method from doing anything, you'd need to do this:

    @Override
    public void writeEntityToNBT(NBTTagCompound tag) {
      // leave this completely empty
    }
    
    @Override
    public void readEntityFromNBT(NBTTagCompound tag) {
      // leave this completely empty
    }
    

    Again, I don't recommend that, but you should know that your code isn't doing quite what you seem to think it is, nor does it need to. Killing the entity when the owner is null is perfectly effective at preventing it from remaining in the game.

  12. Is this method better than checking the tickLife?

    As I said in my last reply, they are basically identical, though this one technically should have better performance than a modulo operation (since in the worst case modulo takes more work to calculate as ticksExisted increases toward infinity, but most implementations aren't that bad).

     

    Anyway: pre-mature optimization. Use whichever one you want - you won't notice the difference, and neither will the computer.

  13. Both methods Draco mentions work great, with one caveat: they only tick while the item is in the inventory (for onUpdate) or equipped (for onArmorTickUpdate), meaning that if you want anything to happen when an item is no longer equipped / in the inventory, such as ending an effect, it won't work.

     

    Since you are only adding potion effects at this time, you can get away with it by simply giving the potion effect a low duration, such as 4-5 ticks, and applying it every 4 ticks or so (e.g.  if (world.getWorldTime() % 4 == 0) { apply potion }).

     

    If you want to be able to fly or some other effect that must end when the item(s) are no longer available to tick, you have to implement your own solution, generally using the PlayerTick event in combination with IExtendedEntityProperties for storing the last item(s) used. When the last item is not null but the current slot for it is null, you know to remove the effect.

     

    EDIT: Adding potion effects / checking a few conditionals every tick doesn't really impact performance that much. Though it's good to think about these kinds of things it's really pre-optimization. Not to mention that even if you could intercept the packets, how would you remove the potion effect? What if the player had that potion effect from something else, too? Every option has pros / cons ;)

  14. Interesting way to do that. I didn't know you were able to measure how long the tick has existed for. However, inquiry, would it be more effective to write a loop into that method that increases an integer, and once the integer reaches a certain amount it reduces the player level and then the integer resets back to 0?

    No no no - definitely DO NOT write a loop.

    public void onUpdate() { // executes each tick
    for (int i = 0; i < 80; i++) {
      // now you are looping 80 times every tick...
    }
    

    Unless you meant have a class field for the counter, and increment that counter ONCE each tick during onUpdate until it reaches 80, at which point you subtract XP and reset the counter to 0 - THAT would be okay, and probably more efficient than using the modulo operator all the time, but not in a performance-telling sort of way.

  15. The nice thing about streaming sounds like records is that you don't have to track individual instances yourself to stop them from playing, just the coordinates. That said, the TickingSound is much more ideal for loops and it's not much more effort to use those, as Draco showed, so it's probably better for your purpose.

     

    Note that whichever method you use, you are still going to have to send some data to the other players if you want them to hear your sound, either via the block notifying client players of its current state if you use that to track when sound is playing (which would happen automatically when you change state, so you, personally, wouldn't technically have to do anything), or by actually sending packets each time a player clicks the block.

  16. Simplest way is to use records instead of sound effects - you can stop a record playing at a given position by passing null as the argument:

    player.worldObj.playRecord(blockpos, null);
    

    Note that that code only works on the client side, so if your sound is playing for all nearby players, you will need to send a packet to each of them so they can call that code.

  17. First you check if the current player is an instance of EntityPlayerMP, which they will be if the code is executing on the server, and then cast it. You want to use #transferPlayerToDimension with a custom Teleporter that overrides makePortal to do nothing:

    ((EntityPlayerMP) player).mcServer.getConfigurationManager().transferPlayerToDimension((EntityPlayerMP) player, 0, new TeleporterNoPortal((WorldServer) player.worldObj));
    

    Be sure to adjust the player's posY afterwards or risk falling through the void. I think this may have to do with the chunk not being properly loaded until getBlock is called, which I don't do until adjusting the Y whereas the original has to build the portal... anyway, it works pretty well for my uses.

  18. That's what I was doing, but the problem is the level of the enchantments are still completely random (still the case with the earlier suggestion too).  I'm trying to make it so that three different bags have three different general levels of enchanted books, but that's not happening yet.

    Oh right, the 30 is hard-coded in there, and you can't generate an enchanted stack to add to the loot list initially because then only that ONE enchanted book will ever be in the loot list...

     

    Well, the only viable option I can think of at the moment is to make a dummy item that extends ItemEnchantedBook and overrides the getChestGenBase method to use different values for the enchantment level based on some custom field, so you would need 3 instances of this item for the different loot levels. Obviously you would pass the regular Items.book in as the ItemStack, just like I showed in my first reply.

     

    It's not very elegant, but it should work.

  19. You shouldn't need to calculate it every tick, only when the entity actually attacks. If you copied / mimicked EntityWolf, then your Entity should have a method like #getOwner that returns the player who owns it. You can use that method at any time, such as when your entity is attacking, to get the owner and thereby any information about the owner that you want.

     

    Roughly:

    @Override
    public boolean attackEntityAsMob(Entity entity) {
    // get the base damage from your entity's attributes, if you added that attribute
    // if not, just start with a base of 2.0F or something
    float damage = (float) getEntityAttribute(SharedMonsterAttributes.attackDamage).getAttributeValue();
    EntityLivingBase owner = this.getOwner();
    if (owner instanceof EntityPlayer) {
      EntityPlayer player = (EntityPlayer) owner;
      // now you've got the player owner - go to town modifying the damage
    }
    // finally, attack the target entity with the adjusted damage amount
    

    Never calculate something every tick if you can get away with calculating it only when it needs to be used ;)

  20. Ah, I see. You don't need to specify an actual enchantment for books when adding to ChestGenHooks - instead, add a regular Items.enchanted_book. When you generate your loot bag's loot, call ChestGenHooks#getItems, which in turn calls Item#getChestGenBase on each item.

     

    Enchanted books override this method to add random enchantments, otherwise vanilla loot charts would have to add every single enchantment combination as a possibility in their loot lists. This way they can just add the enchanted book, and if one is generated, determine what it is at that time.

     

    You won't need a new Random any more at that point in your code, but if you did, there's nothing wrong with making a new Random instance into a class field and using that. Usually you can get an instance of Random from the World object. Items and I think Blocks also have a Random class field, as well as some other classes and many methods.

×
×
  • Create New...

Important Information

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