Jump to content

coolAlias

Members
  • Posts

    2805
  • Joined

  • Last visited

Posts posted by coolAlias

  1. Anyone can call that method at anytime, and it does exactly what it says it does: it sets the slot contents to the stack provided. If you have 3 stone and want to add 3, you create a stack of 6 stone and use that as the argument to this method. That's how this method has always worked.

     

    As for the stack comparison and return, I would guess that is to avoid needlessly calling #onContentsChanged, a presumably potentially expensive operation - probably ends up forcing a write to disk down the line somewhere.

  2. Not sure which version you are using, but in 1.8 and earlier there was a method like the following:

    worldObj.playSoundEffect(x, y, z, sound_name, volume, pitch);
    

    If you call that on the server, it will notify and play the sound for all nearby client players. If one player dies, the others will still be able to hear the sound for as long as it lasts, and the sound should fade if they walk away.

     

    If that doesn't work for you, you can try playing the sound as a record instead - remember to change the sound category to 'record' in your sounds.json file before you do so.

  3. For now you'll just have to handle it within the event itself.

     

    The code sample you wrote should work for determining if the player already has the achievement, in which case you can ignore the rest of the event as irrelevant.

     

    If the player doesn't yet have the achievement, then they will have it after the event unless you do something to prevent it, i.e. they are in the process of earning the achievement.

     

    So yes, you will be having lots of false events being fired that you will be ignoring before doing the rest of your processing:

    Achievement a= event.getAchievement();
    if (event.getEntity()instanceof EntityPlayer && ((EntityPlayer) event.getEntity()).hasAchievement(a)) {
      return; // player already has achievement - ignore this event
    }
    // player is earning the achievement right now, depending on what you do
    // proceed with your extra steps to determine if they are allowed to earn it
    

  4. Achievements are 'added' every single time, but if you already have it, nothing happens. So every time the inventory is opened, the inventory achievement is given to the player and the event triggers, even if that achievement has already been activated.

     

    That's the way vanilla works, and I guess the Forge event hook writer didn't consider it necessary to filter out already achieved achievements before posting the event; I wonder if it would be worth making a pull request?

  5. In 1.8 and earlier, interacting with a block via right-click fired an event on both sides, so you should be okay unless it's changed as Draco suggests it may have.

     

    In either case, you want to only change inventory items on the server, so removing a 'sugar,' adding a 'swift_item', and damaging a stack (which I don't see you trying to do anywhere?) need to all happen when the world object is NOT remote.

     

    ItemStack should have a method e.g. #damageItem that is used to increment the amount of damage done on the stack:

    ItemStack stack = whateverStackYouWantToDamage;
    stack.damageItem(1, player); // this is pre-1.8.9 code; may have changed
    

  6. You need to use the offset functions when determining block positions. Check out the way vanilla villages and such actually place blocks - I don't have access to the code right now, but in 1.8 and previously each coordinate would be run through functions similar to these ones that I wrote.

     

    I'm pretty sure vanilla has methods you can use already, including one(s) that will handle blockstate/metadata, so use those if you can rather than writing your own. I just happened to have some on hand from previous work, so it was faster to use them at the time rather than figure out both that vanilla had what I needed and how to use it.

  7. That's only 342 iterations, and while 200 / 342 may seem skewed, it is also entirely within the realm of possibility for an RNG. If you want to see a more even distribution, you'd probably have to run 1000s of iterations.

     

    What kinds of values does 'chances' have? Why not check the chance before you loop to avoid the loop entirely if the chance != 1? And if chance == 1, why not get more random numbers for the axis? E.g.

    int chance = Stuff.randInt(1, chances);
    if (chance == 1) {
        int xAxis = Stuff.randInt(1, 3) - 2; // gives value between -1 and 1, inclusive
        int zAxis = Stuff.randInt(1, 3) - 2; // gives value between -1 and 1, inclusive
        // now iterate over the yAxis as you like using xAxis and zAxis
        return EnumActionResult.SUCCESS;
    }
    

    That way you only have one single loop all on its own instead of nested inside of 2 other loops, and far fewer random number generations, all with effectively the same result.

  8. Recursion wouldn't be a bad place to start given the approach you have described. Lots of resources available online for both recursion and procedural generation, all of which you should be able to apply pretty directly to Minecraft.

     

    One thing to keep in mind, though, is that not all chunks will be loaded when your generation starts, so if your algorithm can proceed from any arbitrary point that would be best (as in chunk 1 generates with your entrance but the algorithm doesn't require chunks 2-8 to also load immediately - they can load independently at any time and still continue potentially generating your dungeon).

     

    Very simple in theory, much more difficult in practice. Good luck!

  9. You shouldn't need packets for this... unless things have changed very considerably. ITickable#update should be called on both sides automatically, but you should only update your TileEntity data on the server (i.e. when the world is NOT remote, as I mentioned).

     

    If you open the GUI, the Container sends the current inventory data to the client so it can be viewed, and you should use the various Container methods such as #detectAndSendChanges (or whatever that has become in whatever version of Minecraft you are coding for) to handle progress bars such as burn time. Check out the vanilla ContainerFurnace class for an example of that.

  10. If you are standing inside the barrel's reach, it can't hit you, so it makes sense to start the ray trace from the end of the barrel rather than the middle of the block, but yes, it becomes trickier if you have 360-degree rotation (and possibly pitch as well) instead of just 4 (or 6) facings.

     

    The simplest method may be the one you have already suggested - traversing a vector along the target trajectory until you both a. exit the end of the barrel and b. collide with something. Either that or write your own ray-trace function that ignores the originating block, as I don't believe the vanilla method has any parameter to do so.

  11. You have a lot of funky stuff in there...

    // this is the worst way to decrement stack size that I have ever seen:
    inventory[0] = new ItemStack(inventory[0].getItem(), --inventory[0].stackSize);
    
    // this does absolutely nothing:
    inventory[0].stackSize = inventory[0].stackSize;
    

     

    Anyway, it sounds like your output slot either has a stack size of 0 (which you should be able to see in the GUI) or only exists on the client side, so when you pick it up it doesn't actually register as a real stack. Try adding the following to the beginning of your #update method:

    if (this.worldObj.isRemote) {
        return; // don't do anything on client
    }
    

    I'd also recommend taking a closer look at the vanilla furnace's TileEntity code - there is lots of information there that is applicable to your situation.

  12. You also need to update your build.gradle to use the new Minecraft/Forge version, otherwise your mod will be building for 1.9 still.

     

    If that doesn't do the trick, I would try cleaning the gradle cache and re-doing the setup process for the 1.10 Forge workspace with your chosen IDE.

     

    If you plan to continue programming, either as a hobby, a career, or both, you would do well to NEVER promise anything will be done at any time until it is already done and tested and even then, be cautious. It is ALWAYS better to under-promise and over-deliver ;)

  13. EntityArrow does some special-casing on its spawn packet, so whenever you extend it you need to implement IEntityAdditionalSpawnData and perform the same special casing to your own arrow:

    @Override
    public void writeSpawnData(ByteArrayDataOutput buffer) {
    buffer.writeInt(this.shootingEntity != null ? this.shootingEntity.entityId : -1);
    }
    
    @Override
    public void readSpawnData(ByteArrayDataInput buffer) {
    // Replicate EntityArrow's special spawn packet handling from NetClientHandler#handleVehicleSpawn:
    Entity shooter = worldObj.getEntityByID(buffer.readInt());
    if (shooter instanceof EntityLivingBase) {
    	this.shootingEntity = (EntityLivingBase) shooter;
    }
    }
    

    Strangely enough, that fixed the crooked arrow issue for me.

  14. If you're trying to track a single custom Item type then it might be possible, but certainly not globally for ALL item types.

     

    Which item(s) do you want to track?

     

    Why do you want to track the total number of items? In other words, what exactly are you trying to accomplish by doing so?

×
×
  • Create New...

Important Information

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