Jump to content

coolAlias

Members
  • Posts

    2805
  • Joined

  • Last visited

Posts posted by coolAlias

  1. I wouldn't nest those classes and methods inside of an Item class - just make one giant class that contains all of your Item references and you should be fine.

     

    The advantage of using Reflection vs. a simpler solution such as @EverythingGames proposed is that you can do other things with your Items at the time of registration, such as making calls based on implemented interfaces or whatever else. Pretty handy, but you may not need it.

     

    It's much more difficult to provide a similar system for Blocks because Block registration is far more complicated than Item registration. You may have to provide custom ItemBlocks for each block, and those may take custom arguments, plus the registerBlock method might require additional arguments, not to mention registering TileEntities if needed.

     

    Unless you really just have cookie-cutter blocks, I wouldn't advise a similar system.

  2. Put this?

     

    if (pos == null)

    {

        return false;

    }

    I said the BLOCK at that position can be anything, though it will not be null, and the BlockPos certainly will not be null.

     

    The problem is you are getting the block at the position BELOW your block, and then assuming that it is also your block, which clearly it usually won't be.

     

    You need to check what the actual blockstate is at each position you check before trying to access any specific properties.

  3. You are registering your packet again on the key press, instead of sending it - this is waaaaaay wrong. Only ever register your packet ONCE.

     

    To send it, you need to use your simple network wrapper instance:

    // this sends to the server, obviously
    SummonCraft.network.sendToServer(new YourMessageClass(...));
    

  4. Part of the problem is surely that you have the following line of code in YOUR TileEntity:

    BlockFurnace.setState(this.isBurning(), this.worldObj, this.pos);
    

    That places a VANILLA furnace block, completely destroying your custom block.

  5. also you said before that I was getting the crash report because the game thinks this.getattacktarget cant equal null? how can I let the game know that it can be null?

    No, I said it CAN be null, but you are treating it like it could never possibly be null, which is not true:

    Object o = null;
    if (o.someMethod()) { // crashes because object is null
    

    You can't call methods or access fields on null.

  6. The issue is that you are treating an air block like it was your block:

    java.lang.IllegalArgumentException: Cannot get property PropertyEnum{...} as it does not exist in BlockState{block=minecraft:air, properties=[]}
    
    at stevekung.mods.moreplanets.planets.fronos.blocks.BlockFronosTallGrass.canBlockStay(BlockFronosTallGrass.java:125)
    
    at stevekung.mods.moreplanets.common.blocks.BlockFlowerMP.canReplace(BlockFlowerMP.java:62)
    

    Here in your code:

    @Override
    public boolean canBlockStay(World world, BlockPos pos, IBlockState state)
    {
    	Block block = world.getBlockState(pos.down()).getBlock();
    	BlockType type = (BlockType)state.getValue(VARIANT);
    

    The block you get at the given BlockPos can be ANYTHING, not just your block. You need to check first.

  7. That doesn't look like the full crash log, but based on the line you say it's pointing to, it's a NullPointerException: the attack target can be NULL.

     

    As to your other issue, you should be able to remove tasks from the list, though the best way to do that is with an Iterator to avoid potential ConcurrentModificationExceptions.

     

    Another option is to add both tasks, but in the respective attack methods add some extra checks to make sure it can't attack using both within a certain time of the other.

  8. This is the resolution that you get passed in the RenderGameOverlayEvent:

    new ScaledResolution(mc, mc.displayWidth, mc.displayHeight)
    

    Thus, you can't store the ScaledResolution - your GUI is created ONCE, but the ScaledResolution is a new instance every time.

     

    Use the ScaledResolution given to you by the event.

  9. I put the .setContainerItem(A) in C's class, but that didn't do anything. How would I set up the #doesContainerItemLeaveCraftingGrid?

    Override it in your Item class and return false. If you don't know what that means, Google it.

     

    C.setContainerItem(A) should have worked - are both A and C your items (i.e. not vanilla)? If so, then it's possible that you didn't initialize A before C, in which case when you initialize C the container item is simply set to null:

    public static Item A, B, C; // these are all null right now
    @EventHandler
    public void preInit(FMLPreInitializationEvent event) {
    C = new ItemC(); // C is initialized first, but right now A is still null!!! uh oh!
    A = new ItemA(); // now A is initialized, but it's too late - C has already been initialized with a null container item
    B = new ItemB();
    }
    

    Obviously, switching the order of initialization should fix your problem.

  10. It has nothing to do with sounds, at least not directly - ConcurrentModificationException happens when a single object is being modified from more than one place at the same time. This can happen especially easily with Collections (e.g. List), for example, even something as simple as the following might throw a CoMod:

    List<String> list = new ArrayList<String>();
    list.add("One");
    list.add("Two");
    for (String s : list) {
    list.remove(s);
    }
    

    It only gets more likely if you have the same object being manipulated from more places, especially if you start involving other threads, and the same strategies apply for dealing with it.

     

    In your particular case, your crash log pointed to #actionPerformed in your GUI class, instigated by a mouse click: com.fredtargaryen.floocraft.client.gui.GuiTeleport.actionPerformed(GuiTeleport.java:119)

     

    I would look through all of the code that you call before and after that section, as well as if you have any other code operating on these (e.g. a tick handler) to see if you are modifying Collections somewhere, as that is probably the most common cause of CoMod exceptions.

  11. You need to set the container item for the OTHER item, so if you craft A + B = C and B is consumed, then you need to set C's container item to A. You don't set A's container item to A, nor C's to C, which it looks like you are doing with your knife.

     

    Also, if you want to force the container item to remain in the crafting grid rather than getting added to the player's inventory, you can override Item#doesContainerItemLeaveCraftingGrid to return false (in item C).

  12. Wait... Why are you returning null??? You have to return the itemstack provided (I'm pretty sure). I think that's why if it is a null pointer. Problem solved.

    No, you can return null to set the current item to nothing. EDIT: I stand corrected :P

     

    @OP Your problem is you are using the NBT tag directly without checking if it exists - ItemStacks generally do not have an NBT tag until you give them one.

    if (!itemstack.hasTagCompound()) {
       itemstack.setTagCompound(new NBTTagCompound());
    }
    

  13. I've never run in to this problem with my NBT for items. I don't think you'll need packets because I believe the item NBT gets updated on the client from the server by default, but you can try. Look into SimpleNetworkWrapper - there are a couple tutorials on it in the Tutorials Section.

     

    Even though it probably works, I wouldn't advise setting the integer while checking if the NBT is null. At first glance I though you were setting a new NBTTagCompound every time. Try this instead:

    if(stack.getTagCompound() == null)
    {
        stack.setTagCompound(new NBTTagCompound());
    }
    else
    {
        //Do your setting and getting here
    }
    

    The reply right above yours already mentioned that ItemStack NBT is automatically synced from server -> client, but that is not going to help the OP - he's trying to change the NBT from a GUI, so he definitely needs packets. No getting around that.

  14. I don't have access to the server...

    How can you not have access to the server side from your mod? Are you trying to make some kind of client hack?

     

    Server side is when the world object is not remote, i.e.:

    if (!worldObj.isRemote) {
      // you are on the server side right now
    }
    

  15. When you have a lot of items that are exactly the same, use item subtypes and handle that in your Item class directly.

     

    Don't store meta information such as colorSets outside of the class that uses it - encapsulation is your friend. If you find you are storing a lot of 'meta' type information, you should probably reevaluate your design.

     

    If you want to simplify registration, you can easily do so with Reflection.

     

    // call this method AFTER you have initialized all items
    private static void registerItems() {
    try {
    	for (Field f : YourItems.class.getFields()) { // get all declared fields in your Items class
    		if (Item.class.isAssignableFrom(f.getType())) { // if a field is an item, fetch it and register it
    			Item item = (Item) f.get(null);
    			if (item != null) {
    				// while the unlocalized name is not intended for this purpose and some may object to its use
    				// like this, I see no harm in it as it is a convenient way to automate registration
    				String name = item.getUnlocalizedName();
    				GameRegistry.registerItem(item, name.substring(name.lastIndexOf(".") + 1));
    			}
    		}
    	}
    } catch(Exception e) {
    	// catch so you don't crash, but log so you can still find and fix the issue
    	e.printStackTrace();
    }
    }
    

     

    While you do still have to initialize every item individually, if you use item subtypes correctly you will have far fewer to register, and, using a few custom interfaces, you can set up a similar system to automate registration of item variants and model resource locations.

     

    That said, Jabelar's point still stands: if you are not strong in Java, the time you spend trying to automate things will far outweigh the time it would have taken you to just get it working, so it's probably not worth trying until you have more experience.

  16. To clarify, ItemStack NBT needs to be set on the server, but once set it syncs automatically to the client side so your GUI will know about it.

     

    Your issue is that you are trying to set the NBT from within the GUI, but that is client side, so you need to send a packet from the GUI saying "player wants to do X", then handle that packet on the server, check if the player is allowed to make those changes, and adjust the NBT accordingly.

×
×
  • Create New...

Important Information

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