How to remove the distance restriction when looking into other players inventories:

Discussion in 'Resources' started by vildaberper, May 13, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    vildaberper

    DCInventoryPlayer:
    Show Spoiler
    Code:
    public class DCInventoryPlayer extends InventoryPlayer implements IInventory{
        public DCInventoryPlayer(String name, EntityHuman entityhuman){
            super(entityhuman);
            this.name = name;
            this.a = entityhuman.inventory.getContents();
            this.b = entityhuman.inventory.getArmorContents();
            this.d = entityhuman;
        }
    
        public ItemStack[] a = new ItemStack[36];
        public ItemStack[] b = new ItemStack[4];
        public int c = 0;
        public EntityHuman d;
        public boolean e = false;
        public String name = "";
    
        @Override
        public ItemStack a(int i, int j){
            ItemStack[] aitemstack = this.a;
    
            if(i >= this.a.length){
                aitemstack = this.b;
                i -= this.a.length;
            }
            if(aitemstack[i] != null){
                ItemStack itemstack;
    
                if(aitemstack[i].count <= j){
                    itemstack = aitemstack[i];
                    aitemstack[i] = null;
                    return itemstack;
                }else{
                    itemstack = aitemstack[i].a(j);
                    if(aitemstack[i].count == 0){
                        aitemstack[i] = null;
                    }
                    return itemstack;
                }
            }else{
                return null;
            }
        }
    
        @Override
        public boolean a_(EntityHuman arg0){
            update();
            return true;
        }
    
        @Override
        public ItemStack[] getContents(){
            return a;
        }
    
        @Override
        public ItemStack getItem(int arg0){
            return a[arg0];
        }
    
        @Override
        public int getMaxStackSize(){
            return 64;
        }
    
        @Override
        public String getName(){
            return name;
        }
    
        @Override
        public int getSize(){
            return 43;
        }
    
        @Override
        public void setItem(int arg0, ItemStack arg1){
            a[arg0] = arg1;
            this.d.inventory.items[arg0] = arg1;
        }
    
        @Override
        public void update(){
            this.d.inventory.items = this.a;
            this.d.inventory.armor = this.b;
        }
    }


    And how to use it:
    Code:
    Player viewer, target;
    String caption;
    
    DCInventoryPlayer dcip = new DCInventoryPlayer(caption, (net.minecraft.server.EntityHuman) ((CraftPlayer) target).getHandle());
    ((CraftPlayer) viewer).getHandle().a(dcip);
    The hotbar will show up at the top!
     
  2. Offline

    Celtic Minstrel

    Or even better!
    Code:
    public class DCInventoryPlayer extends InventoryPlayer {
        public DCInventoryPlayer(String name, EntityHuman entityhuman){
            super(entityhuman);
        }
    
        @Override
        public boolean a_(EntityHuman arg0){
            return true;
        }
    }
    
    This much smaller class should have the exact same effect, without the broken updating that will almost certainly result from overriding update() to do nothing at all. (I say it does nothing at all because the lines it does contain are the equivalent of "a = a".)
     
  3. Offline

    vildaberper

    Or even better yet!
    I added a boolean for update, if youre looking at an inventory where d (the entity) is null.
    Show Spoiler

    Code:
    public class DCInventoryPlayer extends InventoryPlayer implements IInventory{
        public DCInventoryPlayer(String name, EntityHuman entityhuman){
            super(entityhuman);
            this.name = name;
            this.a = entityhuman.inventory.getContents();
            this.b = entityhuman.inventory.getArmorContents();
            this.d = entityhuman;
        }
    
        public DCInventoryPlayer(String name){
            super(null);
            this.name = name;
            this.a = new ItemStack[43];
            this.b = new ItemStack[4];
            this.d = null;
        }
    
        public DCInventoryPlayer(String name, ItemStack[] itemstack){
            super(null);
            this.name = name;
            this.a = itemstack;
            this.b = new ItemStack[4];
            this.d = null;
        }
    
        public DCInventoryPlayer(String name, org.bukkit.inventory.ItemStack[] itemstack){
            super(null);
            this.name = name;
            this.a = Misc.getItemStack(itemstack); // Changes the itemstack to net.minecraft.server...
            this.b = new ItemStack[4];
            this.d = null;
        }
    
        public ItemStack[] a = new ItemStack[36];
        public ItemStack[] b = new ItemStack[4];
        public int c = 0;
        public EntityHuman d;
        public boolean e = false, update = true;
        public String name = "";
    
        @Override
        public ItemStack a(int i, int j){
            ItemStack[] aitemstack = this.a;
    
            if(i >= this.a.length){
                aitemstack = this.b;
                i -= this.a.length;
            }
            if(aitemstack[i] != null){
                ItemStack itemstack;
    
                if(aitemstack[i].count <= j){
                    itemstack = aitemstack[i];
                    aitemstack[i] = null;
                    return itemstack;
                }else{
                    itemstack = aitemstack[i].a(j);
                    if(aitemstack[i].count == 0){
                        aitemstack[i] = null;
                    }
                    return itemstack;
                }
            }else{
                return null;
            }
        }
    
        @Override
        public boolean a_(EntityHuman arg0){
            update();
            return true;
        }
    
        @Override
        public ItemStack[] getContents(){
            return a;
        }
    
        @Override
        public ItemStack getItem(int arg0){
            return a[arg0];
        }
    
        @Override
        public int getMaxStackSize(){
            return 64;
        }
    
        @Override
        public String getName(){
            return name;
        }
    
        @Override
        public int getSize(){
            return 36;
        }
    
        @Override
        public void setItem(int arg0, ItemStack arg1){
            a[arg0] = arg1;
            if(this.d != null && update){
                this.d.inventory.items[arg0] = arg1;
            }
        }
    
        @Override
        public void update(){
            if(this.d != null && update){
                this.d.inventory.items = this.a;
                this.d.inventory.armor = this.b;
            }
        }
    }
     
  4. Offline

    Celtic Minstrel

    ...I don't believe you quite understand what is going on there.

    1. "this.d.inventory.items" and "this.a" refer to the exact same object. A change to one of them will automatically be reflected in the other. The same applies to "this.d.inventory.armor" and "this.b". Thus your update() method never does anything, which means that when the game decides the inventory needs to be updated, it won't work.
    2. Your setItem does nearly the exact same thing as InventoryPlayer.setItem, but worse – it does not set an armour slot if you pass 36-39 as the slot number. The same applies to your getItem.
    3. Your getSize returns the wrong value (it should return 40, thus including the armour slots). However, InventoryPlayer.getSize already does this, so there is no need for you to override it.
    4. Your getMaxStackSize is redundant because it does the exact same thing as InventoryPlayer.getMaxStackSize. The same is true of your getContents and your ItemStack a(int,int).
    5. Your boolean a_(EntityHuman) is calling update(), which is unnecessary; update() is meant to be called when the inventory changes, not when the game needs to know if it's in range.
    6. You have duplicated all the data in InventoryPlayer. Every instance variable you have in the class already exists in InventoryPlayer, which means that it exists in your class. Your a variable is InventoryPlayer.items; b is InventoryPlayer.armor; c is InventoryPlayer.itemInHandIndex; d is InventoryPlayer.d; e is unused in your class, but already exists as InventoryPlayer.e, and then you added update to do the exact same thing; and name ... well, okay, you have one useful variable there, but it's the only variable you need.
    7. All the constructors except for the first don't make sense. This is meant to wrap an existing player inventory, isn't it? So why do you have constructors that do not take an EntityHuman as an argument? Logically, you should have one that takes an EntityHuman and sets name to the player's name, and another that takes an EntityHuman and a String.
    8. The "implements IInventory" is redundant since InventoryPlayer already implements IInventory.

    Long story short: You're trying too hard. At least half of that class is unnecessary, and a few details are actually harmful. All you need is two constructors, the name variable, the getName method, and the a_ method. Everything else is already done for you by InventoryPlayer, which you are extending. You don't need to do it again.

    I'll admit that I missed some details in my shorter class that I posted above; I hadn't noticed that you also included a way to customize the window title. But taking that small class and tacking on the name stuff would be much more effective than your massive class that won't even work quite right.
     
  5. Offline

    vildaberper

    My class allows the opening of any ItemStack, setting the entityhuman to the player opening it. And if update is set to false, it would look like two different inventories. So no, update isnt useless, since this.d.inventory.items is not the same this as this.a, if its set to false. If its set to true, the entityhuman whos opening the itemstack would get it in his inventory, but not if its set to false.

    Its only meant to view inventories, not armor slots.

    Same with the size, 36 is the size of the players inventory.

    I tested it, and it meant a faster update of the player's inventory youre viewing.

    The constructors is for when looking at an ItemStack and not an entityhuman, which is extremely useful. I use it in my plugin DefaultCommands. It makes it possible to edit offline players inventories. :)
     
  6. Offline

    Celtic Minstrel

    I think the real problem then is that you're trying to create one class where really you should have two separate classes — one for wrapping an EntityHuman to remove the distance restriction, and one for viewing an inventory window with arbitrary contents passed in as an ItemStack[]. The latter should not extend InventoryPlayer, because there is no associated player, and having an associated player is an integral part of InventoryPlayer.

    I'll accept that some of my points were not valid (forgot about context when complaining that the size should be 40, for example), but there are still at least two that are. First, you really don't need those instance variables (the a, b, c, d, e ones). Second, this.d.inventory.items is the same as this.a in every situation where the update() function actually enters the if statement, so your update() never does anything.
     
  7. Offline

    vildaberper

    There is no other easy way of opening an itemstack and edit in real-time, without making it an inventoryplayer. And without the entityhuman, the client crash.

    It does, without it my inventory will be the same as the ItemStack Im viewing. Tested and confirmed, just now. :)
     
Thread Status:
Not open for further replies.

Share This Page