Jump to content

Recommended Posts

Posted (edited)

Hi,

 

So I'm relatively new to Game Design as a whole so this concept is something I understand but I can't work out how to do it in Forge specifically. I'm sure there is a relatively simple way of doing it. I want to be able to allow players to add items ( ItemStack or Item ) to a player specific Blacklist and from there have my Server sided code Read that from the event.player ( EntityPlayer ) on the TickEvent.PlayerTickEvent.

 

I've thought about using NBT but I feel like that would start to get out of hand so I've been looking into Capability's but I'm not 100% sure on how I would go about storing ItemStacks or just Items. I feel like there is a simple way to do this but I'm missing it.

Any help is greatly appreciated. Thanks in advance :D

 

TickEvent

Spoiler

public class ClientTick {
    @SubscribeEvent
    public void tickEvent( TickEvent.PlayerTickEvent event ) {
        EntityPlayer player = event.player;
        NBTTagCompound tag = player.getEntityData();
        if (!tag.getBoolean("jam_toggle_on"))
            return;
      // This is where I need to find which items the player has blacklisted. 

 

Everything Below that is just how the mod handles it's working stuff.

 

Capability's Attempt, unfinished due to not knowing how to handle item stacks

Spoiler

BlacklistCapability


public class BlacklistCapability implements IStorage<IBlacklist> {

    private String blacklistPrefix = "blacklist_";

    @Nullable
    @Override
    public NBTBase writeNBT(Capability<IBlacklist> capability, IBlacklist instance, EnumFacing side) {
        NBTTagList tagList = new NBTTagList();
        int iteration = 0;
        for (String item : instance.getItems()) {
            NBTTagCompound tag = new NBTTagCompound();
            tag.setString(blacklistPrefix+iteration, item);
            tagList.appendTag(tag);
            iteration ++;
        }

        return tagList;
    }

    @Override
    public void readNBT(Capability<IBlacklist> capability, IBlacklist instance, EnumFacing side, NBTBase nbt) {
        if( instance == null )
            return;

        if( nbt != null && nbt instanceof NBTTagList ) {
            NBTTagList list = (NBTTagList) nbt;
            int iteration = 0;
            while( list.iterator().hasNext() ) {
                instance.addItem( list.get(0).toString() );
                iteration ++;
            }
        }
    }
}

 

DefaultBlacklistCapability


public class DefaultBlacklistCapability implements IBlacklist {

    private List<ItemStack> blacklist = new ArrayList<>();

    public DefaultBlacklistCapability() {
    }

    @Override
    public void addItem(ItemStack item) {
        blacklist.add( item );
    }

    @Override
    public void removeItem(ItemStack item) {
        blacklist.remove( item );
    }

    @Override
    public List<ItemStack> getItems() {
        return blacklist;
    }
}

 

IBlacklist


public interface IBlacklist {

    public void addItem(ItemStack item);
    public void removeItem(ItemStack item);

    public List<ItemStack> getItems();

}

 

Hope some of that helps understand my issue. Virtually every tutorial or topic I've seen about this has had the parms of ReadNBT and WriteNBT have been NBTCompound nbt instead of what I've got from mine.

Edited by Tarista
Posted
19 minutes ago, diesieben07 said:
  • You are correct, getEntityData (i.e. "using NBT") is an old and outdated approach, which quickly gets out of hand. Capabilities are the way to go.
  • You most likely want to check TickEvent::phase, otherwise your code runs twice every tick.
  • Why is your class called ClientTick?
  • You can't just remove and add item stacks to a list like that, since ItemStack does not implement equals and hashCode. You need to manually check if the stack is in the list already when adding and removing.
  • When saving a list to NBT, why not use NBTTagList?
  • To save an ItemStack to NBT use ItemStack::writeToNBT and the ItemStack(NBTTagCompound) constructor.

 

I'm glad I was right about the NBT data. I thought it might be wrong.

  • I'll check the tick Phase Thanks :D
  • ClientTick, because I was being lazy, the class used to do something else and I'm yet to have refactored the name.
  • Yeah, I've got plans on changing the way the Capabilies are set up but I wanted to be able to write to it before I sorted out everything else.

Right, I think I've sorted out the writing of the data but I don't know how I'd then read it.

Spoiler

    @Nullable
    @Override
    public NBTBase writeNBT(Capability<IBlacklist> capability, IBlacklist instance, EnumFacing side) {
        NBTTagList tagList = new NBTTagList();

        for (ItemStack item : instance.getItems()) {
            NBTTagCompound tag = new NBTTagCompound();
            tag = item.writeToNBT(tag);
                    
            tagList.appendTag(tag);
        }

        return tagList;
    }

I feel like this is all wrong


    @Override
    public void readNBT(Capability<IBlacklist> capability, IBlacklist instance, EnumFacing side, NBTBase nbt) {
        if( instance == null )
            return;

      	// This is where it all starts to go wrong. I don't know how I'm suposed to be getting the
      	// data from?
        if( nbt != null && nbt instanceof NBTTagList ) {
            NBTTagList list = (NBTTagList) nbt;
            int iteration = 0;
            while( list.iterator().hasNext() ) {
                instance.addItem( list.get(0).toString() );
                iteration ++;
            }
        }
    }

 

 

Posted
4 minutes ago, diesieben07 said:

To read the stacks call the ItemStack(NBTTagCompound) constructor. The NBTTagCompound instances are the elements in the list.

Sorry to sound like an idiot but I've got no clue how I'd do that. The NBTBase nbt part of the readNBT is throwing me. Could you possibly show me what you mean? Thanks for the help so far :D

Posted
    @Nullable
    @Override
    public NBTBase writeNBT(Capability<IBlacklist> capability, IBlacklist instance, EnumFacing side) {
        NBTTagList tagList = new NBTTagList();
        int iteration = 0;
        for (String item : instance.getItems()) {
            NBTTagCompound tag = new NBTTagCompound();
            tag.setString(blacklistPrefix+iteration, item);
            tagList.appendTag(tag);
            iteration ++;
        }

        return tagList;
    }

    @Override
    public void readNBT(Capability<IBlacklist> capability, IBlacklist instance, EnumFacing side, NBTBase nbt) {
        if( instance == null )
            return;

        if( nbt != null && nbt instanceof NBTTagList ) {
            NBTTagList list = (NBTTagList) nbt;
            int iteration = 0;
            while( list.iterator().hasNext() ) {
                instance.addItem( list.get(0).toString() );
                iteration ++;
            }
        }
    }

what on earth is this, go and learn java first

Posted
3 minutes ago, loordgek said:

 

what on earth is this, go and learn java first

It's a mess of prototyping code that was half finished at the point of asking for help with a component that I've not had experience with nor have I had to do before. I'm a C++, C# Developer primarily. I've been learning Java for a little while. Your comment is wholesomely unneed and completely stupid to have put on a literal help topic. I wasn't asking for help with my Java skills, I was asking for help with a component I've not used before in any of my mods. I've been looking through other peoples mods with little avail so I though I'd ask the community. Forge isn't normal Java, Nor is Minecraft, the moment you hit Game Design you'll find a lot of things that don't function the way you would have originally thought they they'd work. For me, this is one of them.

Posted
    @Override
    public void readNBT(Capability capability, Object instance, EnumFacing side, NBTBase nbt) {
        NBTTagList list = (NBTTagList)nbt;
        for (int i = 0; i < list.tagCount(); i++) {
            new ItemStack(list.getCompoundTagAt(i));
        }
    }

this is what you want

  • Like 1
Posted
1 minute ago, loordgek said:

    @Override
    public void readNBT(Capability capability, Object instance, EnumFacing side, NBTBase nbt) {
        NBTTagList list = (NBTTagList)nbt;
        for (int i = 0; i < list.tagCount(); i++) {
            new ItemStack(list.getCompoundTagAt(i));
        }
    }

this is what you want

Thats perfect, Thank you :D I completely missed the tagCount function. I should have spotted that when reading the NBTTagList Class

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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