static is NOT the friend that you think it is. You need a real instance of your inventory that belongs to the player, not one for everybody.
You don't need a container at all to display an inventory in a Gui, though that is usually the most convenient. All the container does is make sure that the client version of the inventory has the same items inside of it as the server does, but since your gui is an overlay, I don't think you can use the typical container stuff.
Instead, you should be sending packets to update the client version when loading and whenever anything changes, but that goes well beyond this tutorial.
public class ContainerSkill extends Container
{
/** The Item Inventory for this Container */
final InventoryAbilityItem inventory;
/** Using these will make transferStackInSlot easier to understand and implement
* INV_START is the index of the first slot in the Player's Inventory, so our
* InventoryItem's number of slots (e.g. 5 slots is array indices 0-4, so start at 5)
* Notice how we don't have to remember how many slots we made? We can just use
* InventoryItem.INV_SIZE and if we ever change it, the Container updates automatically. */
private static final int INV_START = InventoryAbilityItem.INV_SIZE, INV_END = INV_START+26,
HOTBAR_START = INV_END+1, HOTBAR_END = HOTBAR_START+8;
// If you're planning to add armor slots, put those first like this:
// ARMOR_START = InventoryItem.INV_SIZE, ARMOR_END = ARMOR_START+3,
// INV_START = ARMOR_END+1, and then carry on like above.
// ITEM INVENTORY - you'll need to adjust the slot locations to match your texture file
// I have them set vertically in columns of 4 to the right of the player model
for (i = 0; i < InventoryAbilityItem.INV_SIZE; ++i)
{
// You can make a custom Slot if you need different behavior,
// such as only certain item types can be put into this slot
// We made a custom slot to prevent our inventory-storing item
// from being stored within itself, but if you want to allow that and
// you followed my advice at the end of the above step, then you
// could get away with using the vanilla Slot class
this.addSlotToContainer(new SlotItemInv(this.inventory, i, 80 + (18 * (int)(i/4)), 8 + (18*(i%4))));
}
// If you want, you can add ARMOR SLOTS here as well, but you need to
// make a public version of SlotArmor. I won't be doing that in this tutorial.
/*
for (i = 0; i < 4; ++i)
{
// These are the standard positions for survival inventory layout
this.addSlotToContainer(new SlotArmor(this.player, inventoryPlayer, inventoryPlayer.getSizeInventory() - 1 - i, 8, 8 + i * 18, i));
}
*/
// PLAYER INVENTORY - uses default locations for standard inventory texture file
for (i = 0; i < 3; ++i)
{
for (int j = 0; j < 9; ++j)
{
this.addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 18*2 + j * 18+2, 18*6 + i * 18+2));
}
}
// PLAYER ACTION BAR - uses default locations for standard action bar texture file
for (i = 0; i < 9; ++i)
{
this.addSlotToContainer(new Slot(inventoryPlayer, i, 18*2 + i * 18+2, 150+18));
}
}
@Override
public boolean canInteractWith(EntityPlayer player) {
// be sure to return the inventory's isUseableByPlayer method
// if you defined special behavior there:
return inventory.isUseableByPlayer(player);
}
/**
* Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that.
* Only real change we make to this is to set needsUpdate to true at the end
*/
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2)
{
ItemStack itemstack = null;
Slot slot = (Slot) this.inventorySlots.get(par2);
// If item is in our custom Inventory or armor slot
if (par2 < INV_START)
{
// try to place in player inventory / action bar
if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, true))
{
return null;
}
slot.onSlotChange(itemstack1, itemstack);
}
// Item is in inventory / hotbar, try to place in custom inventory or armor slots
else
{
/* If your inventory only stores certain instances of Items,
* you can implement shift-clicking to your inventory like this:
// Check that the item is the right type
if (itemstack1.getItem() instanceof ItemCustom)
{
// Try to merge into your custom inventory slots
// We use 'InventoryItem.INV_SIZE' instead of INV_START just in case
// you also add armor or other custom slots
if (!this.mergeItemStack(itemstack1, 0, InventoryItem.INV_SIZE, false))
{
return null;
}
}
// If you added armor slots, check them here as well:
// Item being shift-clicked is armor - try to put in armor slot
if (itemstack1.getItem() instanceof ItemArmor)
{
int type = ((ItemArmor) itemstack1.getItem()).armorType;
if (!this.mergeItemStack(itemstack1, ARMOR_START + type, ARMOR_START + type + 1, false))
{
return null;
}
}
* Otherwise, you have basically 2 choices:
* 1. shift-clicking between action bar and inventory
* 2. shift-clicking between player inventory and custom inventory
* I've implemented number 1:
*/
// item is in player's inventory, but not in action bar
if (par2 >= INV_START && par2 < HOTBAR_START)
{
// place in action bar
if (!this.mergeItemStack(itemstack1, HOTBAR_START, HOTBAR_END + 1, false))
{
return null;
}
}
// item in action bar - place in player inventory
else if (par2 >= HOTBAR_START && par2 < HOTBAR_END + 1)
{
if (!this.mergeItemStack(itemstack1, INV_START, INV_END + 1, false))
{
return null;
}
}
}
return itemstack;
}
// NOTE: The following is necessary if you want to prevent the player from moving the item while the
// inventory is open; if you don't and the player moves the item, the inventory will not be able to save properly
@Override
public ItemStack slotClick(int slot, int button, int flag, EntityPlayer player) {
// this will prevent the player from interacting with the item that opened the inventory:
return super.slotClick(slot, button, flag, player);
}
}
Hello. When I click on the item in the hotbar (in my custom inventory) it drops down from the inventory. It started after I changed inventory postition. Where it can be fixed? Thanks.
Hi coolAlias,
can you put into main post a clean and full "custom inventory player" section for MC 1.8?
I having serious problems to do it ....
thank you so much
There is a full demo mod if you need to make comparisons between your code, but the tutorial itself isn't meant to have full sections of copy/paste code.
Since I successfully implemented your ExtendedPlayer and PacketDispatcher classes into my mod I ran into this issue:
- SSP all works absolutely fine.
- SMP (dedicated server) when I run the server (with forge 1303) MC 1.8 crash with follow error:
[10:24:24] [Server thread/INFO]: Starting minecraft server version 1.8
[10:24:24] [Server thread/INFO] [MinecraftForge]: Attempting early MinecraftForge initialization
[10:24:24] [Server thread/INFO] [FML]: MinecraftForge v11.14.1.1303 Initialized
[10:24:25] [Server thread/INFO] [FML]: Replaced 204 ore recipies
[10:24:25] [Server thread/INFO] [MinecraftForge]: Completed early MinecraftForge initialization
[10:24:25] [Server thread/INFO] [FML]: Searching C:\Users\7ed\Desktop\Forge 1.8d\eclipse\mods for mods
[10:24:51] [Server thread/INFO] [FML]: Forge Mod Loader has identified 4 mods to load
[10:24:53] [Server thread/INFO] [FML]: Attempting connection with missing mods [mcp, FML, Forge, mymod] at CLIENT
[10:24:53] [Server thread/INFO] [FML]: Attempting connection with missing mods [mcp, FML, Forge, mymod] at SERVER
[10:24:56] [Server thread/ERROR]: Encountered an unexpected exception
java.lang.NoClassDefFoundError: net/minecraft/client/entity/EntityPlayerSP
at java.lang.Class.forName0(Native Method) ~[?:1.7.0_75]
at java.lang.Class.forName(Class.java:274) ~[?:1.7.0_75]
at net.minecraftforge.fml.common.ProxyInjector.inject(ProxyInjector.java:60) ~[ProxyInjector.class:?]
at net.minecraftforge.fml.common.FMLModContainer.constructMod(FMLModContainer.java:494) ~[FMLModContainer.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_75]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[?:1.7.0_75]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.7.0_75]
at java.lang.reflect.Method.invoke(Method.java:606) ~[?:1.7.0_75]
at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) ~[guava-17.0.jar:?]
at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) ~[guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) ~[guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) ~[guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.post(EventBus.java:275) ~[guava-17.0.jar:?]
at net.minecraftforge.fml.common.LoadController.sendEventToModContainer(LoadController.java:208) ~[LoadController.class:?]
at net.minecraftforge.fml.common.LoadController.propogateStateMessage(LoadController.java:187) ~[LoadController.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_75]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[?:1.7.0_75]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.7.0_75]
at java.lang.reflect.Method.invoke(Method.java:606) ~[?:1.7.0_75]
at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) ~[guava-17.0.jar:?]
at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) ~[guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) ~[guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) ~[guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.post(EventBus.java:275) ~[guava-17.0.jar:?]
at net.minecraftforge.fml.common.LoadController.distributeStateMessage(LoadController.java:118) ~[LoadController.class:?]
at net.minecraftforge.fml.common.Loader.loadMods(Loader.java:493) ~[Loader.class:?]
at net.minecraftforge.fml.server.FMLServerHandler.beginServerLoading(FMLServerHandler.java:87) ~[FMLServerHandler.class:?]
at net.minecraftforge.fml.common.FMLCommonHandler.onServerStart(FMLCommonHandler.java:322) ~[FMLCommonHandler.class:?]
at net.minecraft.server.dedicated.DedicatedServer.startServer(DedicatedServer.java:117) ~[DedicatedServer.class:?]
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:438) [MinecraftServer.class:?]
at java.lang.Thread.run(Thread.java:745) [?:1.7.0_75]
Caused by: java.lang.ClassNotFoundException: net.minecraft.client.entity.EntityPlayerSP
at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:191) ~[launchwrapper-1.11.jar:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:425) ~[?:1.7.0_75]
at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ~[?:1.7.0_75]
... 31 more
Caused by: java.lang.RuntimeException: Attempted to load class net/minecraft/client/entity/EntityPlayerSP for invalid side SERVER
at net.minecraftforge.fml.common.asm.transformers.SideTransformer.transform(SideTransformer.java:49) ~[forgeSrc-1.8-11.14.1.1303.jar:?]
at net.minecraft.launchwrapper.LaunchClassLoader.runTransformers(LaunchClassLoader.java:279) ~[launchwrapper-1.11.jar:?]
at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:176) ~[launchwrapper-1.11.jar:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:425) ~[?:1.7.0_75]
at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ~[?:1.7.0_75]
... 31 more
...and seems caused by EntityPlayerSP class that I never used in all my code.
Please Help and thank you....
If you follow the tutorials exactly, it works on a server perfectly fine.
The problem you encountered appears to be a class-loading issue, caused by the Java compiler attempting to load one of your imported @SideOnly(Side.CLIENT) classes (such as Minecraft.getMinecraft()) on the server.
That happens when you don't use your Proxy classes to retrieve the player / IThreadListener when dealing with packets.
Please read the tutorials carefully, including the related network tutorial, and look through ALL of the demo code - taking just one piece of the puzzle (e.g. PacketDispatcher) will not a working mod make.
IThreadListener was added in 1.8 because 1.8 added multithreading; 1.7 does not use multiple threads, so you don't need that at all (and it doesn't exist).
Read the error again - it tells you exactly what is wrong, namely that the registerMessage method expects an IMessageHandler as the first argument, where you gave it an IMessage.
@keomate88 That's because you are setting the tag data on the stack sent in the packet, but you want the one in the player's inventory.
Other points of note:
1. If the itemstack in question is the one the player is holding, then you don't need to send the stack in the packet - you already know that player.getHeldItem() will give you the one you want.
2. If the itemstack in question is NOT the held item, you still don't need to send it - send instead the inventory slot index, which is a single integer.
3. If you only need to set a single integer in the tag compound, send that integer in the packet rather than the entire NBT tag.
Hi, thanks for your tutorial, but I'm blocked between the tutos: (i'm french, sorry for my english) I don't know how make the IExtendedEntityProperties! Please could you give me all the classes or help me saying all what i have to do? I'm coding in 1.7.10. Or maybe i can send you my src folder and you fix my mistakes ?
For the IExtendedEntityProperties, you don't need any of the mana stuff, just a field to store and retrieve your inventory. If you follow the Custom Inventory tutorial, it should be pretty clear. If you can't figure it out, there is already a demo on Github.
@keomate88 Change the value of MANA_WATCHER to something else, like 21.
That's the problem with DataWatcher - it only has 32 slots available, a fair number of which are already taken by vanilla (not 20, though), and many more of which are used by other mods, especially when it comes to EntityPlayer.
Really, DataWatcher is not very suitable to use in IExtendedEntityProperties for that last fact alone, but it is quite useful in custom Entity classes that don't need to worry about such conflicts.
@keomate88 Did you read my last post? DataWatcher ONLY has 32 slots TOTAL to share amongst ALL mods. If you are using 7 of those indexes in your IEEP, you are almost guaranteed to have conflicts.
The ONLY way NOT to conflict is to not use DataWatcher - send your own packets instead (which is all DataWatcher does in the background anyway - it is not special).
Yes I did, but If I want to save permanently the player's "mana" value where i should send the packet?
... Packets should have nothing to do with saving data - that is handled on the server. The point of packets as far as IEEP is concerned is usually to convey the existing data to the client so that the client can display it. The client should never be telling the server what that data is.
sorry if bother you again, I successfully delete&replaced all my Datawachers ... now I ran into a strange NPE using this code:
[code] [code]new itemStack(Item.getItemFromBlock(Block.getBlockFromName("tile.extrautils:cobblestone_compressed")), 1, 0)<br>[/code]
[/code] In sum I need to create an instance of outer mod installed block ("ExtraUtils").
And I can't find the right func/method/param to make it.
Yes, I know this doesn't regards this thread but I hope you can help me however ...
thank you so much.
These types of questions belong in the Modification Development section of the forums. Thanks.
Your above code all looks correct. Can you show me the code where you open the GUI? You need to make sure to open Container-based GUIs on the server side, not the client.
Don't change the position of an inventory. Items drop when you click outside of the inventory, so if you move the GUI, you won't move the positions you have to click outside to drop items. Change the xSize in your inventory GUI to something bigger than 176 (which is the default).
Don't change the position of an inventory. Items drop when you click outside of the inventory, so if you move the GUI, you won't move the positions you have to click outside to drop items. Change the xSize in your inventory GUI to something bigger than 176 (which is the default).
Is this directed at me???
Anyway, you can make your inventory whatever size you want and place it wherever you like on the screen so long as you place your slots accordingly in the Container class, but yes, items do drop if you click outside of whatever space you defined for the GUI.
Um, your PlayerInv class has 256 + 4 slots?! I thought you were adding 2.
Please describe in full details what exactly is not working, how you get it to not work, and which classes are involved so I don't have to go digging around all your code. Lately my time has become extremely limited :\
And you're getting the NPE on getServerGuiElement, or getClientGuiElement? Again, this is ONLY in multiplayer that you get this issue? That's very bizarre.
Oh, I know why: you must have added @SideOnly(Side.CLIENT) to one of your Container or Inventory classes - this will work in single player, but not multiplayer because the integrated server counts as the 'client' side - it's a legacy from when Minecraft used to have two separate .jar files for the server and client.
Looking at your code, I see at least one case in your customGuiContainer class - check for more and remove them all.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumYou don't need a container at all to display an inventory in a Gui, though that is usually the most convenient. All the container does is make sure that the client version of the inventory has the same items inside of it as the server does, but since your gui is an overlay, I don't think you can use the typical container stuff.
Instead, you should be sending packets to update the client version when loading and whenever anything changes, but that goes well beyond this tutorial.
ContainerSkill.class
package a_mod28.client.gui;
import a_mod28.SlotItemInv;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class ContainerSkill extends Container
{
/** The Item Inventory for this Container */
final InventoryAbilityItem inventory;
/** Using these will make transferStackInSlot easier to understand and implement
* INV_START is the index of the first slot in the Player's Inventory, so our
* InventoryItem's number of slots (e.g. 5 slots is array indices 0-4, so start at 5)
* Notice how we don't have to remember how many slots we made? We can just use
* InventoryItem.INV_SIZE and if we ever change it, the Container updates automatically. */
private static final int INV_START = InventoryAbilityItem.INV_SIZE, INV_END = INV_START+26,
HOTBAR_START = INV_END+1, HOTBAR_END = HOTBAR_START+8;
// If you're planning to add armor slots, put those first like this:
// ARMOR_START = InventoryItem.INV_SIZE, ARMOR_END = ARMOR_START+3,
// INV_START = ARMOR_END+1, and then carry on like above.
public ContainerSkill(EntityPlayer par1Player, InventoryPlayer inventoryPlayer, InventoryAbilityItem inventoryItem)
{
this.inventory = inventoryItem;
int i;
// ITEM INVENTORY - you'll need to adjust the slot locations to match your texture file
// I have them set vertically in columns of 4 to the right of the player model
for (i = 0; i < InventoryAbilityItem.INV_SIZE; ++i)
{
// You can make a custom Slot if you need different behavior,
// such as only certain item types can be put into this slot
// We made a custom slot to prevent our inventory-storing item
// from being stored within itself, but if you want to allow that and
// you followed my advice at the end of the above step, then you
// could get away with using the vanilla Slot class
this.addSlotToContainer(new SlotItemInv(this.inventory, i, 80 + (18 * (int)(i/4)), 8 + (18*(i%4))));
}
// If you want, you can add ARMOR SLOTS here as well, but you need to
// make a public version of SlotArmor. I won't be doing that in this tutorial.
/*
for (i = 0; i < 4; ++i)
{
// These are the standard positions for survival inventory layout
this.addSlotToContainer(new SlotArmor(this.player, inventoryPlayer, inventoryPlayer.getSizeInventory() - 1 - i, 8, 8 + i * 18, i));
}
*/
// PLAYER INVENTORY - uses default locations for standard inventory texture file
for (i = 0; i < 3; ++i)
{
for (int j = 0; j < 9; ++j)
{
this.addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 18*2 + j * 18+2, 18*6 + i * 18+2));
}
}
// PLAYER ACTION BAR - uses default locations for standard action bar texture file
for (i = 0; i < 9; ++i)
{
this.addSlotToContainer(new Slot(inventoryPlayer, i, 18*2 + i * 18+2, 150+18));
}
}
@Override
public boolean canInteractWith(EntityPlayer player) {
// be sure to return the inventory's isUseableByPlayer method
// if you defined special behavior there:
return inventory.isUseableByPlayer(player);
}
/**
* Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that.
* Only real change we make to this is to set needsUpdate to true at the end
*/
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2)
{
ItemStack itemstack = null;
Slot slot = (Slot) this.inventorySlots.get(par2);
if (slot != null && slot.getHasStack())
{
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
// If item is in our custom Inventory or armor slot
if (par2 < INV_START)
{
// try to place in player inventory / action bar
if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, true))
{
return null;
}
slot.onSlotChange(itemstack1, itemstack);
}
// Item is in inventory / hotbar, try to place in custom inventory or armor slots
else
{
/* If your inventory only stores certain instances of Items,
* you can implement shift-clicking to your inventory like this:
// Check that the item is the right type
if (itemstack1.getItem() instanceof ItemCustom)
{
// Try to merge into your custom inventory slots
// We use 'InventoryItem.INV_SIZE' instead of INV_START just in case
// you also add armor or other custom slots
if (!this.mergeItemStack(itemstack1, 0, InventoryItem.INV_SIZE, false))
{
return null;
}
}
// If you added armor slots, check them here as well:
// Item being shift-clicked is armor - try to put in armor slot
if (itemstack1.getItem() instanceof ItemArmor)
{
int type = ((ItemArmor) itemstack1.getItem()).armorType;
if (!this.mergeItemStack(itemstack1, ARMOR_START + type, ARMOR_START + type + 1, false))
{
return null;
}
}
* Otherwise, you have basically 2 choices:
* 1. shift-clicking between action bar and inventory
* 2. shift-clicking between player inventory and custom inventory
* I've implemented number 1:
*/
// item is in player's inventory, but not in action bar
if (par2 >= INV_START && par2 < HOTBAR_START)
{
// place in action bar
if (!this.mergeItemStack(itemstack1, HOTBAR_START, HOTBAR_END + 1, false))
{
return null;
}
}
// item in action bar - place in player inventory
else if (par2 >= HOTBAR_START && par2 < HOTBAR_END + 1)
{
if (!this.mergeItemStack(itemstack1, INV_START, INV_END + 1, false))
{
return null;
}
}
}
if (itemstack1.stackSize == 0)
{
slot.putStack((ItemStack) null);
}
else
{
slot.onSlotChanged();
}
if (itemstack1.stackSize == itemstack.stackSize)
{
return null;
}
slot.onPickupFromSlot(par1EntityPlayer, itemstack1);
}
return itemstack;
}
// NOTE: The following is necessary if you want to prevent the player from moving the item while the
// inventory is open; if you don't and the player moves the item, the inventory will not be able to save properly
@Override
public ItemStack slotClick(int slot, int button, int flag, EntityPlayer player) {
// this will prevent the player from interacting with the item that opened the inventory:
return super.slotClick(slot, button, flag, player);
}
}
but if i click items in this slots
items be drop
i think drop area is not match
like this
how set position and set size of drop area?
(bad english sorry)
i thought container problem
but it was gui problem
(xSize, ySize)
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumThere is a full demo mod if you need to make comparisons between your code, but the tutorial itself isn't meant to have full sections of copy/paste code.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumIf you follow the tutorials exactly, it works on a server perfectly fine.
The problem you encountered appears to be a class-loading issue, caused by the Java compiler attempting to load one of your imported @SideOnly(Side.CLIENT) classes (such as Minecraft.getMinecraft()) on the server.
That happens when you don't use your Proxy classes to retrieve the player / IThreadListener when dealing with packets.
Please read the tutorials carefully, including the related network tutorial, and look through ALL of the demo code - taking just one piece of the puzzle (e.g. PacketDispatcher) will not a working mod make.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumLook at the 1.7.10 branch of the demo mod.
-
View User Profile
-
View Posts
-
Send Message
Curse Premium-
View User Profile
-
View Posts
-
Send Message
Curse PremiumOther points of note:
1. If the itemstack in question is the one the player is holding, then you don't need to send the stack in the packet - you already know that player.getHeldItem() will give you the one you want.
2. If the itemstack in question is NOT the held item, you still don't need to send it - send instead the inventory slot index, which is a single integer.
3. If you only need to set a single integer in the tag compound, send that integer in the packet rather than the entire NBT tag.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumFor the IExtendedEntityProperties, you don't need any of the mana stuff, just a field to store and retrieve your inventory. If you follow the Custom Inventory tutorial, it should be pretty clear. If you can't figure it out, there is already a demo on Github.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumThat's the problem with DataWatcher - it only has 32 slots available, a fair number of which are already taken by vanilla (not 20, though), and many more of which are used by other mods, especially when it comes to EntityPlayer.
Really, DataWatcher is not very suitable to use in IExtendedEntityProperties for that last fact alone, but it is quite useful in custom Entity classes that don't need to worry about such conflicts.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumThe ONLY way NOT to conflict is to not use DataWatcher - send your own packets instead (which is all DataWatcher does in the background anyway - it is not special).
-
View User Profile
-
View Posts
-
Send Message
Curse Premium... Packets should have nothing to do with saving data - that is handled on the server. The point of packets as far as IEEP is concerned is usually to convey the existing data to the client so that the client can display it. The client should never be telling the server what that data is.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumThese types of questions belong in the Modification Development section of the forums. Thanks.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumYour above code all looks correct. Can you show me the code where you open the GUI? You need to make sure to open Container-based GUIs on the server side, not the client.
Don't change the position of an inventory. Items drop when you click outside of the inventory, so if you move the GUI, you won't move the positions you have to click outside to drop items. Change the xSize in your inventory GUI to something bigger than 176 (which is the default).
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumSo your inventory works fine in single player, but not multiplayer? That's bizarre.
Do you have a Github repository, by any chance? That would make it much easier to help you.
Is this directed at me???
Anyway, you can make your inventory whatever size you want and place it wherever you like on the screen so long as you place your slots accordingly in the Container class, but yes, items do drop if you click outside of whatever space you defined for the GUI.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumUm, your PlayerInv class has 256 + 4 slots?! I thought you were adding 2.
Please describe in full details what exactly is not working, how you get it to not work, and which classes are involved so I don't have to go digging around all your code. Lately my time has become extremely limited :\
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumAnd you're getting the NPE on getServerGuiElement, or getClientGuiElement? Again, this is ONLY in multiplayer that you get this issue? That's very bizarre.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumOh, I know why: you must have added @SideOnly(Side.CLIENT) to one of your Container or Inventory classes - this will work in single player, but not multiplayer because the integrated server counts as the 'client' side - it's a legacy from when Minecraft used to have two separate .jar files for the server and client.
Looking at your code, I see at least one case in your customGuiContainer class - check for more and remove them all.