Jedispencer21 Posted April 18, 2016 Posted April 18, 2016 So I have never tried to make a gun before, so what I am wondering is, what would be the best way to make the gun, such as bullets, making guns have a fire and reload speed, being able to customize the guns with different parts, and such. Also with the customizing, each part would supposedly change the look of the gun's model, how would I go about making the model based on what parts are on the gun? Quote
Asweez Posted April 18, 2016 Posted April 18, 2016 There are several tutorials for this, namely one on the minecraft forge wiki. This tutorial deals with the gun and bullets. To extend reload time, fire rate, etc, use NBT timers stored on your item that count up or down every tick, and when the user fires, the gun checks to see if the timer has reached the max time, then it will proceed to shoot, otherwise it will do nothing. Quote Creator of the MyFit, MagiCraft, Tesseract gun, and Papa's Wingeria mod.
maestro1184 Posted April 19, 2016 Posted April 19, 2016 I found this tutorial really helpful for the gun I'm working on: https://emxtutorials.wordpress.com/creating-a-gun/ I actually adjusted it a little to make it more like a hunting rifle. It's still a work in progress but I might be able to answer some questions if you have them. Quote
UberAffe Posted April 19, 2016 Posted April 19, 2016 don't forget that you have two options for "bullets" you can actually make an entity that travels through the world like the arrow does or you can just look at what is currently at the target location and damage it. Quote Current Project: Armerger Planned mods: Light Drafter | Ore Swords Looking for help getting a mod off the ground? Coding | Textures
Jedispencer21 Posted April 20, 2016 Author Posted April 20, 2016 All right, so now I am wondering, is how could I make it so that I have a custom gun crafting bench that I am able to add gun parts to, to create customized guns that add different stats based on the part. Quote
perromercenary00 Posted April 20, 2016 Posted April 20, 2016 just make all the posible guns results as metadata and cxreate the recipes to mach thath Quote
Jedispencer21 Posted April 20, 2016 Author Posted April 20, 2016 The only thing is, is that its not an actual crafting table, more like a table with slots that you add the pieces to, and you can remove those pieces as well, and it results with a gun with those parts. Quote
Choonster Posted April 20, 2016 Posted April 20, 2016 The only thing is, is that its not an actual crafting table, more like a table with slots that you add the pieces to, and you can remove those pieces as well, and it results with a gun with those parts. Give the gun an inventory using the Capability system and have the table use it. Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
AnZaNaMa Posted April 20, 2016 Posted April 20, 2016 Hmm... this sounds very similar to the way IE revolvers work... Quote - Just because things are the way they are doesn't mean they can't be the way you want them to be. Unless they're aspen trees. You can tell they're aspens 'cause the way they are.
Jedispencer21 Posted April 20, 2016 Author Posted April 20, 2016 If you wouldn't mind, could you give a bit of an explanation as to how I would give the gun an inventory, and allow the table to access it. I have read the document, but still don't fully understand as to how I would do it. Quote
Choonster Posted April 21, 2016 Posted April 21, 2016 Create an implementation of ICapabilitySerializable that provides an IItemHandler instance (probably an ItemStackHandler ). Override Item#initCapabilities to return a new instance of the provider. This gives your item an IItemHandler inventory that's stored in memory with the ItemStack and not written to NBT until it needs to be (unlike the old way of giving items inventories, which was using an IInventory read from and written to NBT every time it was accessed). To get this inventory from an ItemStack of your Item , use the ICapabilityProvider#getCapability method inherited by ItemStack . I don't have any examples of this exact use case, but I do have several of my own capabilities in my mod. You can see their APIs here and implementations here. ItemSlingshot and ItemLastUseTimeModel attach the ILastUseTime capability to themselves to track their last use time. The IMaxHealth capability is attached to all living entities in CapabilityMaxHealth.EventHandler to provide bonus max health and used by ItemMaxHealth{Getter/Setter} , BlockMaxHealth{Getter/Setter} and CommandMaxHealth{Add/Base/Get/Set} . The IPigSpawner capability is attached to ItemPigSpawner by itself and to Items.CLAY_BALL in CapabilityPigSpawner.EventHandler to allow them to spawn pigs and used by BlockPigSpawnerRefiller . Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
Jedispencer21 Posted April 21, 2016 Author Posted April 21, 2016 Lets see if I fully understand. What I have to do is create a new class that implements ICapabilitySerializable? And what do you mean provide an IItemHandler instance, would I create a new instance or what? Then in the item class for the gun in the initCapabilities method I return the instance? Quote
Choonster Posted April 22, 2016 Posted April 22, 2016 What I have to do is create a new class that implements ICapabilitySerializable? Yes. This provides your IItemHandler instance from ItemStack#getCapability and reads from/writes to NBT. And what do you mean provide an IItemHandler instance, would I create a new instance or what? Yes, either of ItemStackHandler or your own IItemHandler implementation. You need to create a new instance of this for every instance of your provider ( ICapabilitySerializable ) class. Then in the item class for the gun in the initCapabilities method I return the instance? Return a new instance of your provider class every time the Item#initCapabilities method is called. Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
Jedispencer21 Posted April 22, 2016 Author Posted April 22, 2016 Alright, so I have this: public class ItemGun extends Item { public ItemGun() { this.setMaxStackSize(1); } public ICapabilityProvider initCapabilities(ItemStack stack, NBTTagCompound nbt) { return new CapabilitiesGunParts.ProviderGunParts(); } } public class CapabilitiesGunParts { @CapabilityInject(IItemHandler.class) public static final Capability<IItemHandler> GUN_PART_CAPABILITY = null; public static void register() { CapabilityManager.INSTANCE.register(IItemHandler.class, new Capability.IStorage<IItemHandler>() { public NBTBase writeNBT(Capability<IItemHandler> capability, IItemHandler instance, EnumFacing side) { return null; } public void readNBT(Capability<IItemHandler> capability, IItemHandler instance, EnumFacing side, NBTBase nbt) { } }, ItemStackHandler.class); } public static class ProviderGunParts implements ICapabilitySerializable<NBTTagCompound> { public static final ItemStackHandler stackHandler = new ItemStackHandler(10); // 10 For the amount of slots. public boolean hasCapability(Capability<?> capability, EnumFacing facing) { return capability == GUN_PART_CAPABILITY; } public <T> T getCapability(Capability<T> capability, EnumFacing facing) { if (capability == GUN_PART_CAPABILITY) { return (T) stackHandler; } return null; } public NBTTagCompound serializeNBT() { return (NBTTagCompound) GUN_PART_CAPABILITY.getStorage().writeNBT(GUN_PART_CAPABILITY, stackHandler, (EnumFacing) null); } public void deserializeNBT(NBTTagCompound nbt) { GUN_PART_CAPABILITY.getStorage().readNBT(GUN_PART_CAPABILITY, stackHandler, (EnumFacing) null, nbt); } } } public class CapabilityEvents { public void attachCap(AttachCapabilitiesEvent.Item event) { if (event.getItem() == CGItems.base_gun) { event.addCapability(new ResourceLocation(References.MOD_NAME + ":GunParts"), new CapabilitiesGunParts.ProviderGunParts()); } } } Firstly, is this correct, and secondly, what would I put in the write/read methods? Quote
Choonster Posted April 23, 2016 Posted April 23, 2016 Do not register a Capability for IItemHandler , Forge already does that. Do not use AttachCapabilitiesEvent for your own objects, it's only for external objects. Do not store the IItemHandler in a static field, each instance of the provider must have its own instance of IItemHandler . The CapabilitiesGunParts.GUN_PART_CAPABILITY will be populated with the IItemHandler Capability , but there's no real reason to have the field since you can just use CapabilityItemHandler.ITEM_HANDLER_CAPABILITY . Always use the @Override annotation on override methods. Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
Jedispencer21 Posted April 23, 2016 Author Posted April 23, 2016 So instead of creating my own capability, I could instead just use CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, and just replace GUN_PART_CAPABILITY like this: public class ProviderGunParts implements ICapabilitySerializable<NBTTagCompound> { public ItemStackHandler stackHandler = new ItemStackHandler(10); public boolean hasCapability(Capability<?> capability, EnumFacing facing) { return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY; } public <T> T getCapability(Capability<T> capability, EnumFacing facing) { if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return (T) this.stackHandler; } return null; } public NBTTagCompound serializeNBT() { return (NBTTagCompound) CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.getStorage(). writeNBT(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY,this.stackHandler, (EnumFacing) null); } public void deserializeNBT(NBTTagCompound nbt) { CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.getStorage().readNBT(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, this.stackHandler, (EnumFacing) null, nbt); } } and I do not need to use the AttachCapabilityEvent.Item, I just use the Item#initCapabilities method Quote
Choonster Posted April 23, 2016 Posted April 23, 2016 That code looks correct, yes. I'd personally make the stackHandler field private final IItemHandler rather than public ItemStackHandler just to ensure that external code can't replace it, but it's not strictly necessary. You can optionally add a public getter method for it. There's no reason to cast null to any type except in very specific circumstances, you only see that in Minecraft's code because the compiler automatically inserts it. Use Item#initCapabilities instead of AttachCapabilitiesEvent.Item for your own items, yes. Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
Jedispencer21 Posted April 23, 2016 Author Posted April 23, 2016 Ok, so now for the work bench, it will have a tile entity, what would be a means of getting the inventory from the tile entity? Also, how would I go about making the model of the item based on the parts that the gun has attached. Quote
Choonster Posted April 23, 2016 Posted April 23, 2016 Give your TileEntity an IItemHandler field for its own inventory. If you want things like hoppers and pipes to interact with it, override the ICapabilityProvider methods inherited by TileEntity . Make sure you call the super methods if the Capability isn't CapabilityItemHandler.ITEM_HANDLER_CAPABILITY so capabilities attached from AttachCapabilitiesEvent.TileEntity still work. To get the item's inventory, use the ICapabilityProvider methods inherited by ItemStack . The model will probably require an IModel , an ICustomModelLoader and an ItemOverrideList . I don't know much about the model system myself, I suggest you look at Forge's ModelDynBucket or Tinkers' Construct's tool models. Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
Jedispencer21 Posted April 25, 2016 Author Posted April 25, 2016 Firstly, how would I go about creating an IItemHandler for the inventory. Also hoppers, pipes, ect. will not be able to interact with this. Secondly, what I want to do with the bench is have, sorta different pages inside of it. Like have a page for editing the gun, and a page for private storage, like and ender chest. So what exactly would I need in terms of the TileEntity, Gui, and Container, for this? Also, aside from the bench, each player should have materials, not actual inventory items, that will be dropped by enemies, and be picked up and added to the materials for the player. Is there a way to make different drops for each player? Quote
Choonster Posted April 26, 2016 Posted April 26, 2016 Firstly, how would I go about creating an IItemHandler for the inventory. Also hoppers, pipes, ect. will not be able to interact with this. Create an ItemStackHandler field and initialise it with a new instance. Read it from and write it to NBT like any other field of your TileEntity using the INBTSerializable methods. If you don't want hopper and pipes to interact with it, don't expose it as a capability. Instead, create a regular getter method so your GUI code can access it. Secondly, what I want to do with the bench is have, sorta different pages inside of it. Like have a page for editing the gun, and a page for private storage, like and ender chest. So what exactly would I need in terms of the TileEntity, Gui, and Container, for this? I'm not that familiar with the GUI system myself, so I can only provide basic advice. You'll probably need to implement each page as a separate GUI and have buttons/tabs to switch between them. When the player clicks one of these, send a packet to the server to open the new page's GUI. Tinkers' Construct's tinker table GUIs have similar functionality to this (though each tab is for a separate block), consider looking at how that's implemented. Also, aside from the bench, each player should have materials, not actual inventory items, that will be dropped by enemies, and be picked up and added to the materials for the player. Is there a way to make different drops for each player? You'll want to create your own capability to store the materials and attach it to players using AttachCapabilitiesEvent.Entity . I'm not sure exactly how you plan for these materials to be dropped, but you should have access to the player that most recently attacked the entity. Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
Recommended Posts
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.