- 9
- 1
Пакеты:
Сам инвентарь кастомный:
Main:
Proxys:
Заранее спасибо.
Не могу понять почему не работает инвентарь.
Кто сможет помочь - буду благодарен.
package net.maslenok.inventory.packets;
import java.io.IOException;
import com.google.common.base.Throwables;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import cpw.mods.fml.relauncher.Side;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.main.Main;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.PacketBuffer;
public abstract class AbstractMessage<T extends AbstractMessage<T>> implements IMessage, IMessageHandler <T, IMessage> {
/**
* Some PacketBuffer methods throw IOException - default handling propagates the exception.
* if an IOException is expected but should not be fatal, handle it within this method.
*/
protected abstract void read(PacketBuffer buffer) throws IOException;
/**
* Some PacketBuffer methods throw IOException - default handling propagates the exception.
* if an IOException is expected but should not be fatal, handle it within this method.
*/
protected abstract void write(PacketBuffer buffer) throws IOException;
/**
* Called on whichever side the message is received;
* for bidirectional packets, be sure to check side
* If {@link #requiresMainThread()} returns true, this method is guaranteed
* to be called on the main Minecraft thread for this side.
*/
public abstract void process(EntityPlayer player, Side side);
/**
* If message is sent to the wrong side, an exception will be thrown during handling
* @return True if the message is allowed to be handled on the given side
*/
protected boolean isValidOnSide(Side side) {
return true; // default allows handling on both sides, i.e. a bidirectional packet
}
/**
* Whether this message requires the main thread to be processed (i.e. it
* requires that the world, player, and other objects are in a valid state).
*/
protected boolean requiresMainThread() {
return true;
}
@Override
public void fromBytes(ByteBuf buffer) {
try {
read(new PacketBuffer(buffer));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public void toBytes(ByteBuf buffer) {
try {
write(new PacketBuffer(buffer));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public final IMessage onMessage(T msg, MessageContext ctx) {
if (!msg.isValidOnSide(ctx.side)) {
throw new RuntimeException("Invalid side " + ctx.side.name() + " for " + msg.getClass().getSimpleName());
} else if (msg.requiresMainThread()) {
//*checkThreadAndEnqueue(msg, ctx);
} else {
msg.process(net.maslenok.inventory.main.Main.proxy.getPlayerEntity(ctx), ctx.side);
}
return null;
}
/**
* Messages that can only be sent from the server to the client should use this class
*/
public static abstract class AbstractClientMessage<T extends AbstractMessage<T>> extends AbstractMessage<T> {
@Override
protected final boolean isValidOnSide(Side side) {
return side.isClient();
}
}
/**
* Messages that can only be sent from the client to the server should use this class
*/
public static abstract class AbstractServerMessage<T extends AbstractMessage<T>> extends AbstractMessage<T> {
@Override
protected final boolean isValidOnSide(Side side) {
return side.isServer();
}
}
}
import java.io.IOException;
import com.google.common.base.Throwables;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import cpw.mods.fml.relauncher.Side;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.main.Main;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.PacketBuffer;
public abstract class AbstractMessage<T extends AbstractMessage<T>> implements IMessage, IMessageHandler <T, IMessage> {
/**
* Some PacketBuffer methods throw IOException - default handling propagates the exception.
* if an IOException is expected but should not be fatal, handle it within this method.
*/
protected abstract void read(PacketBuffer buffer) throws IOException;
/**
* Some PacketBuffer methods throw IOException - default handling propagates the exception.
* if an IOException is expected but should not be fatal, handle it within this method.
*/
protected abstract void write(PacketBuffer buffer) throws IOException;
/**
* Called on whichever side the message is received;
* for bidirectional packets, be sure to check side
* If {@link #requiresMainThread()} returns true, this method is guaranteed
* to be called on the main Minecraft thread for this side.
*/
public abstract void process(EntityPlayer player, Side side);
/**
* If message is sent to the wrong side, an exception will be thrown during handling
* @return True if the message is allowed to be handled on the given side
*/
protected boolean isValidOnSide(Side side) {
return true; // default allows handling on both sides, i.e. a bidirectional packet
}
/**
* Whether this message requires the main thread to be processed (i.e. it
* requires that the world, player, and other objects are in a valid state).
*/
protected boolean requiresMainThread() {
return true;
}
@Override
public void fromBytes(ByteBuf buffer) {
try {
read(new PacketBuffer(buffer));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public void toBytes(ByteBuf buffer) {
try {
write(new PacketBuffer(buffer));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public final IMessage onMessage(T msg, MessageContext ctx) {
if (!msg.isValidOnSide(ctx.side)) {
throw new RuntimeException("Invalid side " + ctx.side.name() + " for " + msg.getClass().getSimpleName());
} else if (msg.requiresMainThread()) {
//*checkThreadAndEnqueue(msg, ctx);
} else {
msg.process(net.maslenok.inventory.main.Main.proxy.getPlayerEntity(ctx), ctx.side);
}
return null;
}
/**
* Messages that can only be sent from the server to the client should use this class
*/
public static abstract class AbstractClientMessage<T extends AbstractMessage<T>> extends AbstractMessage<T> {
@Override
protected final boolean isValidOnSide(Side side) {
return side.isClient();
}
}
/**
* Messages that can only be sent from the client to the server should use this class
*/
public static abstract class AbstractServerMessage<T extends AbstractMessage<T>> extends AbstractMessage<T> {
@Override
protected final boolean isValidOnSide(Side side) {
return side.isServer();
}
}
}
package net.maslenok.inventory.packets;
import java.io.IOException;
import com.google.common.base.Throwables;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import cpw.mods.fml.relauncher.Side;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.main.Main;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.PacketBuffer;
public abstract class AbstractMessage<T extends AbstractMessage<T>> implements IMessage, IMessageHandler <T, IMessage> {
/**
* Some PacketBuffer methods throw IOException - default handling propagates the exception.
* if an IOException is expected but should not be fatal, handle it within this method.
*/
protected abstract void read(PacketBuffer buffer) throws IOException;
/**
* Some PacketBuffer methods throw IOException - default handling propagates the exception.
* if an IOException is expected but should not be fatal, handle it within this method.
*/
protected abstract void write(PacketBuffer buffer) throws IOException;
/**
* Called on whichever side the message is received;
* for bidirectional packets, be sure to check side
* If {@link #requiresMainThread()} returns true, this method is guaranteed
* to be called on the main Minecraft thread for this side.
*/
public abstract void process(EntityPlayer player, Side side);
/**
* If message is sent to the wrong side, an exception will be thrown during handling
* @return True if the message is allowed to be handled on the given side
*/
protected boolean isValidOnSide(Side side) {
return true; // default allows handling on both sides, i.e. a bidirectional packet
}
/**
* Whether this message requires the main thread to be processed (i.e. it
* requires that the world, player, and other objects are in a valid state).
*/
protected boolean requiresMainThread() {
return true;
}
@Override
public void fromBytes(ByteBuf buffer) {
try {
read(new PacketBuffer(buffer));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public void toBytes(ByteBuf buffer) {
try {
write(new PacketBuffer(buffer));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public final IMessage onMessage(T msg, MessageContext ctx) {
if (!msg.isValidOnSide(ctx.side)) {
throw new RuntimeException("Invalid side " + ctx.side.name() + " for " + msg.getClass().getSimpleName());
} else if (msg.requiresMainThread()) {
//*checkThreadAndEnqueue(msg, ctx);
} else {
msg.process(net.maslenok.inventory.main.Main.proxy.getPlayerEntity(ctx), ctx.side);
}
return null;
}
/**
* Messages that can only be sent from the server to the client should use this class
*/
public static abstract class AbstractClientMessage<T extends AbstractMessage<T>> extends AbstractMessage<T> {
@Override
protected final boolean isValidOnSide(Side side) {
return side.isClient();
}
}
/**
* Messages that can only be sent from the client to the server should use this class
*/
public static abstract class AbstractServerMessage<T extends AbstractMessage<T>> extends AbstractMessage<T> {
@Override
protected final boolean isValidOnSide(Side side) {
return side.isServer();
}
}
}
import java.io.IOException;
import com.google.common.base.Throwables;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import cpw.mods.fml.relauncher.Side;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.main.Main;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.PacketBuffer;
public abstract class AbstractMessage<T extends AbstractMessage<T>> implements IMessage, IMessageHandler <T, IMessage> {
/**
* Some PacketBuffer methods throw IOException - default handling propagates the exception.
* if an IOException is expected but should not be fatal, handle it within this method.
*/
protected abstract void read(PacketBuffer buffer) throws IOException;
/**
* Some PacketBuffer methods throw IOException - default handling propagates the exception.
* if an IOException is expected but should not be fatal, handle it within this method.
*/
protected abstract void write(PacketBuffer buffer) throws IOException;
/**
* Called on whichever side the message is received;
* for bidirectional packets, be sure to check side
* If {@link #requiresMainThread()} returns true, this method is guaranteed
* to be called on the main Minecraft thread for this side.
*/
public abstract void process(EntityPlayer player, Side side);
/**
* If message is sent to the wrong side, an exception will be thrown during handling
* @return True if the message is allowed to be handled on the given side
*/
protected boolean isValidOnSide(Side side) {
return true; // default allows handling on both sides, i.e. a bidirectional packet
}
/**
* Whether this message requires the main thread to be processed (i.e. it
* requires that the world, player, and other objects are in a valid state).
*/
protected boolean requiresMainThread() {
return true;
}
@Override
public void fromBytes(ByteBuf buffer) {
try {
read(new PacketBuffer(buffer));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public void toBytes(ByteBuf buffer) {
try {
write(new PacketBuffer(buffer));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public final IMessage onMessage(T msg, MessageContext ctx) {
if (!msg.isValidOnSide(ctx.side)) {
throw new RuntimeException("Invalid side " + ctx.side.name() + " for " + msg.getClass().getSimpleName());
} else if (msg.requiresMainThread()) {
//*checkThreadAndEnqueue(msg, ctx);
} else {
msg.process(net.maslenok.inventory.main.Main.proxy.getPlayerEntity(ctx), ctx.side);
}
return null;
}
/**
* Messages that can only be sent from the server to the client should use this class
*/
public static abstract class AbstractClientMessage<T extends AbstractMessage<T>> extends AbstractMessage<T> {
@Override
protected final boolean isValidOnSide(Side side) {
return side.isClient();
}
}
/**
* Messages that can only be sent from the client to the server should use this class
*/
public static abstract class AbstractServerMessage<T extends AbstractMessage<T>> extends AbstractMessage<T> {
@Override
protected final boolean isValidOnSide(Side side) {
return side.isServer();
}
}
}
package net.maslenok.inventory.packets;
import java.io.IOException;
import com.google.common.base.Throwables;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import cpw.mods.fml.relauncher.Side;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.main.Main;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.PacketBuffer;
public abstract class AbstractMessage<T extends AbstractMessage<T>> implements IMessage, IMessageHandler <T, IMessage> {
/**
* Some PacketBuffer methods throw IOException - default handling propagates the exception.
* if an IOException is expected but should not be fatal, handle it within this method.
*/
protected abstract void read(PacketBuffer buffer) throws IOException;
/**
* Some PacketBuffer methods throw IOException - default handling propagates the exception.
* if an IOException is expected but should not be fatal, handle it within this method.
*/
protected abstract void write(PacketBuffer buffer) throws IOException;
/**
* Called on whichever side the message is received;
* for bidirectional packets, be sure to check side
* If {@link #requiresMainThread()} returns true, this method is guaranteed
* to be called on the main Minecraft thread for this side.
*/
public abstract void process(EntityPlayer player, Side side);
/**
* If message is sent to the wrong side, an exception will be thrown during handling
* @return True if the message is allowed to be handled on the given side
*/
protected boolean isValidOnSide(Side side) {
return true; // default allows handling on both sides, i.e. a bidirectional packet
}
/**
* Whether this message requires the main thread to be processed (i.e. it
* requires that the world, player, and other objects are in a valid state).
*/
protected boolean requiresMainThread() {
return true;
}
@Override
public void fromBytes(ByteBuf buffer) {
try {
read(new PacketBuffer(buffer));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public void toBytes(ByteBuf buffer) {
try {
write(new PacketBuffer(buffer));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public final IMessage onMessage(T msg, MessageContext ctx) {
if (!msg.isValidOnSide(ctx.side)) {
throw new RuntimeException("Invalid side " + ctx.side.name() + " for " + msg.getClass().getSimpleName());
} else if (msg.requiresMainThread()) {
//*checkThreadAndEnqueue(msg, ctx);
} else {
msg.process(net.maslenok.inventory.main.Main.proxy.getPlayerEntity(ctx), ctx.side);
}
return null;
}
/**
* Messages that can only be sent from the server to the client should use this class
*/
public static abstract class AbstractClientMessage<T extends AbstractMessage<T>> extends AbstractMessage<T> {
@Override
protected final boolean isValidOnSide(Side side) {
return side.isClient();
}
}
/**
* Messages that can only be sent from the client to the server should use this class
*/
public static abstract class AbstractServerMessage<T extends AbstractMessage<T>> extends AbstractMessage<T> {
@Override
protected final boolean isValidOnSide(Side side) {
return side.isServer();
}
}
}
import java.io.IOException;
import com.google.common.base.Throwables;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import cpw.mods.fml.relauncher.Side;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.main.Main;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.PacketBuffer;
public abstract class AbstractMessage<T extends AbstractMessage<T>> implements IMessage, IMessageHandler <T, IMessage> {
/**
* Some PacketBuffer methods throw IOException - default handling propagates the exception.
* if an IOException is expected but should not be fatal, handle it within this method.
*/
protected abstract void read(PacketBuffer buffer) throws IOException;
/**
* Some PacketBuffer methods throw IOException - default handling propagates the exception.
* if an IOException is expected but should not be fatal, handle it within this method.
*/
protected abstract void write(PacketBuffer buffer) throws IOException;
/**
* Called on whichever side the message is received;
* for bidirectional packets, be sure to check side
* If {@link #requiresMainThread()} returns true, this method is guaranteed
* to be called on the main Minecraft thread for this side.
*/
public abstract void process(EntityPlayer player, Side side);
/**
* If message is sent to the wrong side, an exception will be thrown during handling
* @return True if the message is allowed to be handled on the given side
*/
protected boolean isValidOnSide(Side side) {
return true; // default allows handling on both sides, i.e. a bidirectional packet
}
/**
* Whether this message requires the main thread to be processed (i.e. it
* requires that the world, player, and other objects are in a valid state).
*/
protected boolean requiresMainThread() {
return true;
}
@Override
public void fromBytes(ByteBuf buffer) {
try {
read(new PacketBuffer(buffer));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public void toBytes(ByteBuf buffer) {
try {
write(new PacketBuffer(buffer));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public final IMessage onMessage(T msg, MessageContext ctx) {
if (!msg.isValidOnSide(ctx.side)) {
throw new RuntimeException("Invalid side " + ctx.side.name() + " for " + msg.getClass().getSimpleName());
} else if (msg.requiresMainThread()) {
//*checkThreadAndEnqueue(msg, ctx);
} else {
msg.process(net.maslenok.inventory.main.Main.proxy.getPlayerEntity(ctx), ctx.side);
}
return null;
}
/**
* Messages that can only be sent from the server to the client should use this class
*/
public static abstract class AbstractClientMessage<T extends AbstractMessage<T>> extends AbstractMessage<T> {
@Override
protected final boolean isValidOnSide(Side side) {
return side.isClient();
}
}
/**
* Messages that can only be sent from the client to the server should use this class
*/
public static abstract class AbstractServerMessage<T extends AbstractMessage<T>> extends AbstractMessage<T> {
@Override
protected final boolean isValidOnSide(Side side) {
return side.isServer();
}
}
}
package net.maslenok.inventory.packets;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import net.maslenok.inventory.main.Main;
import net.minecraft.entity.player.EntityPlayer;
public class OpenGuiPacket extends AbstractPacket {
// this will store the id of the gui to open
private int id;
// The basic, no-argument constructor MUST be included to use the new automated handling
public OpenGuiPacket() {}
// if there are any class fields, be sure to provide a constructor that allows
// for them to be initialized, and use that constructor when sending the packet
public OpenGuiPacket(int id) {
this.id = id;
}
@Override
public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
// basic Input/Output operations, very much like DataOutputStream
buffer.writeInt(id);
}
@Override
public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
// basic Input/Output operations, very much like DataInputStream
id = buffer.readInt();
}
@Override
public void handleClientSide(EntityPlayer player) {
// for opening a GUI, we don't need to do anything here
}
@Override
public void handleServerSide(EntityPlayer player) {
// because we sent the gui's id with the packet, we can handle all cases with one line:
player.openGui(Main.instance, id, player.worldObj, (int) player.posX, (int) player.posY, (int) player.posZ);
}
}
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import net.maslenok.inventory.main.Main;
import net.minecraft.entity.player.EntityPlayer;
public class OpenGuiPacket extends AbstractPacket {
// this will store the id of the gui to open
private int id;
// The basic, no-argument constructor MUST be included to use the new automated handling
public OpenGuiPacket() {}
// if there are any class fields, be sure to provide a constructor that allows
// for them to be initialized, and use that constructor when sending the packet
public OpenGuiPacket(int id) {
this.id = id;
}
@Override
public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
// basic Input/Output operations, very much like DataOutputStream
buffer.writeInt(id);
}
@Override
public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
// basic Input/Output operations, very much like DataInputStream
id = buffer.readInt();
}
@Override
public void handleClientSide(EntityPlayer player) {
// for opening a GUI, we don't need to do anything here
}
@Override
public void handleServerSide(EntityPlayer player) {
// because we sent the gui's id with the packet, we can handle all cases with one line:
player.openGui(Main.instance, id, player.worldObj, (int) player.posX, (int) player.posY, (int) player.posZ);
}
}
package net.maslenok.inventory.packets;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import cpw.mods.fml.relauncher.Side;
import net.minecraft.client.main.Main;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
public class PacketDispatcher {
private static byte packetId = 0;
private static final SimpleNetworkWrapper dispatcher = NetworkRegistry.INSTANCE.newSimpleChannel(net.maslenok.inventory.main.Main.MODID);
public static void registerPackets() {
//* Client
PacketDispatcher.registerMessage(net.maslenok.inventory.packets.OpenGuiPacket.class, net.maslenok.inventory.packets.OpenGuiPacket.class, Side.CLIENT);
//* Server
PacketDispatcher.registerMessage(net.maslenok.inventory.packets.SyncPlayerPropsPacket.class, net.maslenok.inventory.packets.SyncPlayerPropsPacket.class, Side.SERVER);
}
@SuppressWarnings("unchecked")
private static void registerMessage(Class handlerClass, Class messageClass, Side side) {
PacketDispatcher.dispatcher.registerMessage(handlerClass, messageClass, packetId++, side);
}
//Wrapper methods
public static void sendTo(IMessage message, EntityPlayerMP player) {
PacketDispatcher.dispatcher.sendTo(message, player);
}
public static void sendToAll(IMessage message) {
PacketDispatcher.dispatcher.sendToAll(message);
}
public static void sendToAllAround(IMessage message, NetworkRegistry.TargetPoint point) {
PacketDispatcher.dispatcher.sendToAllAround(message, point);
}
public static void sendToAllAround(IMessage message, int dimension, double x, double y, double z, double range) {
PacketDispatcher.dispatcher.sendToAllAround(message, new NetworkRegistry.TargetPoint(dimension, x, y, z, range));
}
public static void sendToAllAround(IMessage message, EntityPlayer player, double range) {
PacketDispatcher.sendToAllAround(message, player.worldObj.provider.dimensionId, player.posX, player.posY, player.posZ, range);
}
public static void sendToDimension(IMessage message, int dimensionId) {
PacketDispatcher.dispatcher.sendToDimension(message, dimensionId);
}
public static void sendToServer(IMessage message) {
PacketDispatcher.dispatcher.sendToServer(message);
}
}
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import cpw.mods.fml.relauncher.Side;
import net.minecraft.client.main.Main;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
public class PacketDispatcher {
private static byte packetId = 0;
private static final SimpleNetworkWrapper dispatcher = NetworkRegistry.INSTANCE.newSimpleChannel(net.maslenok.inventory.main.Main.MODID);
public static void registerPackets() {
//* Client
PacketDispatcher.registerMessage(net.maslenok.inventory.packets.OpenGuiPacket.class, net.maslenok.inventory.packets.OpenGuiPacket.class, Side.CLIENT);
//* Server
PacketDispatcher.registerMessage(net.maslenok.inventory.packets.SyncPlayerPropsPacket.class, net.maslenok.inventory.packets.SyncPlayerPropsPacket.class, Side.SERVER);
}
@SuppressWarnings("unchecked")
private static void registerMessage(Class handlerClass, Class messageClass, Side side) {
PacketDispatcher.dispatcher.registerMessage(handlerClass, messageClass, packetId++, side);
}
//Wrapper methods
public static void sendTo(IMessage message, EntityPlayerMP player) {
PacketDispatcher.dispatcher.sendTo(message, player);
}
public static void sendToAll(IMessage message) {
PacketDispatcher.dispatcher.sendToAll(message);
}
public static void sendToAllAround(IMessage message, NetworkRegistry.TargetPoint point) {
PacketDispatcher.dispatcher.sendToAllAround(message, point);
}
public static void sendToAllAround(IMessage message, int dimension, double x, double y, double z, double range) {
PacketDispatcher.dispatcher.sendToAllAround(message, new NetworkRegistry.TargetPoint(dimension, x, y, z, range));
}
public static void sendToAllAround(IMessage message, EntityPlayer player, double range) {
PacketDispatcher.sendToAllAround(message, player.worldObj.provider.dimensionId, player.posX, player.posY, player.posZ, range);
}
public static void sendToDimension(IMessage message, int dimensionId) {
PacketDispatcher.dispatcher.sendToDimension(message, dimensionId);
}
public static void sendToServer(IMessage message) {
PacketDispatcher.dispatcher.sendToServer(message);
}
}
package net.maslenok.inventory.packets;
import java.util.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.INetHandler;
import net.minecraft.network.NetHandlerPlayServer;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.FMLEmbeddedChannel;
import cpw.mods.fml.common.network.FMLOutboundHandler;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.internal.FMLProxyPacket;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@ChannelHandler.Sharable
public class PacketPipeline extends MessageToMessageCodec<FMLProxyPacket, AbstractPacket>{
private EnumMap<Side, FMLEmbeddedChannel> channels;
private LinkedList<Class<? extends AbstractPacket>> packets = new LinkedList<Class<? extends AbstractPacket>>();
private boolean isPostInitialised = false;
public boolean registerPacket(Class<? extends AbstractPacket> clazz) {
if(packets.size() > 256){
return false;
}
if(packets.contains(clazz)){
return false;
}
if(isPostInitialised){
return false;
}
packets.add(clazz);
return true;
}
//Кодирование пакета, в том числе настройки дискриминатора.
@Override
protected void encode(ChannelHandlerContext ctx, AbstractPacket msg, List<Object> out) throws Exception {
ByteBuf buffer = Unpooled.buffer();
Class<? extends AbstractPacket> clazz = msg.getClass();
if (!packets.contains(msg.getClass())) {
throw new NullPointerException("No Packet Registered for: " + msg.getClass().getCanonicalName());
}
byte discriminator = (byte) this.packets.indexOf(clazz);
buffer.writeByte(discriminator);
msg.encodeInto(ctx, buffer);
FMLProxyPacket proxyPacket = new FMLProxyPacket(buffer.copy(), ctx.channel().attr(NetworkRegistry.FML_CHANNEL).get());
out.add(proxyPacket);
}
//Декодирования и обработка пакета
@Override
protected void decode(ChannelHandlerContext ctx, FMLProxyPacket msg, List<Object> out) throws Exception {
ByteBuf payload = msg.payload();
byte discriminator = payload.readByte();
Class<? extends AbstractPacket> clazz = this.packets.get(discriminator);
if (clazz == null) {
throw new NullPointerException("No packet registered for discriminator: " + discriminator);
}
AbstractPacket pkt = clazz.newInstance();
pkt.decodeInto(ctx, payload.slice());
EntityPlayer player;
switch(FMLCommonHandler.instance().getEffectiveSide()){
case CLIENT:
player = this.getClientPlayer();
pkt.handleClientSide(player);
break;
case SERVER:
INetHandler netHandler = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get();
player = ((NetHandlerPlayServer) netHandler).playerEntity;
pkt.handleServerSide(player);
break;
default:
}
out.add(pkt);
}
public void initialise() {
channels = NetworkRegistry.INSTANCE.newChannel("InventoryPacket", this);
registerPackets();
}
public void registerPackets() {
registerPacket(OpenGuiPacket.class);
registerPacket(SyncPlayerPropsPacket.class);
}
public void postInitialise(){
if (isPostInitialised){
return;
}
isPostInitialised = true;
Collections.sort(packets, new Comparator<Class<? extends AbstractPacket>>(){
public int compare(Class<? extends AbstractPacket> clazz1, Class<? extends AbstractPacket> clazz2){
int com = String.CASE_INSENSITIVE_ORDER.compare(clazz1.getCanonicalName(), clazz2.getCanonicalName());
if (com == 0){
com = clazz1.getCanonicalName().compareTo(clazz2.getCanonicalName());
}
return com;
}
});
}
@SideOnly(Side.CLIENT)
private EntityPlayer getClientPlayer(){
return Minecraft.getMinecraft().thePlayer;
}
public void sendToAll(AbstractPacket message){
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL);
channels.get(Side.SERVER).writeAndFlush(message);
}
public void sendTo(AbstractPacket message, EntityPlayerMP player){
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER);
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(player);
channels.get(Side.SERVER).writeAndFlush(message);
}
public void sendToAllAround(AbstractPacket message, NetworkRegistry.TargetPoint point){
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT);
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point);
channels.get(Side.SERVER).writeAndFlush(message);
}
public void sendToDimension(AbstractPacket message, int dimensionId){
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.DIMENSION);
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(dimensionId);
channels.get(Side.SERVER).writeAndFlush(message);
}
public void sendToServer(AbstractPacket message){
channels.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER);
channels.get(Side.CLIENT).writeAndFlush(message);
}
}
import java.util.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.INetHandler;
import net.minecraft.network.NetHandlerPlayServer;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.FMLEmbeddedChannel;
import cpw.mods.fml.common.network.FMLOutboundHandler;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.internal.FMLProxyPacket;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@ChannelHandler.Sharable
public class PacketPipeline extends MessageToMessageCodec<FMLProxyPacket, AbstractPacket>{
private EnumMap<Side, FMLEmbeddedChannel> channels;
private LinkedList<Class<? extends AbstractPacket>> packets = new LinkedList<Class<? extends AbstractPacket>>();
private boolean isPostInitialised = false;
public boolean registerPacket(Class<? extends AbstractPacket> clazz) {
if(packets.size() > 256){
return false;
}
if(packets.contains(clazz)){
return false;
}
if(isPostInitialised){
return false;
}
packets.add(clazz);
return true;
}
//Кодирование пакета, в том числе настройки дискриминатора.
@Override
protected void encode(ChannelHandlerContext ctx, AbstractPacket msg, List<Object> out) throws Exception {
ByteBuf buffer = Unpooled.buffer();
Class<? extends AbstractPacket> clazz = msg.getClass();
if (!packets.contains(msg.getClass())) {
throw new NullPointerException("No Packet Registered for: " + msg.getClass().getCanonicalName());
}
byte discriminator = (byte) this.packets.indexOf(clazz);
buffer.writeByte(discriminator);
msg.encodeInto(ctx, buffer);
FMLProxyPacket proxyPacket = new FMLProxyPacket(buffer.copy(), ctx.channel().attr(NetworkRegistry.FML_CHANNEL).get());
out.add(proxyPacket);
}
//Декодирования и обработка пакета
@Override
protected void decode(ChannelHandlerContext ctx, FMLProxyPacket msg, List<Object> out) throws Exception {
ByteBuf payload = msg.payload();
byte discriminator = payload.readByte();
Class<? extends AbstractPacket> clazz = this.packets.get(discriminator);
if (clazz == null) {
throw new NullPointerException("No packet registered for discriminator: " + discriminator);
}
AbstractPacket pkt = clazz.newInstance();
pkt.decodeInto(ctx, payload.slice());
EntityPlayer player;
switch(FMLCommonHandler.instance().getEffectiveSide()){
case CLIENT:
player = this.getClientPlayer();
pkt.handleClientSide(player);
break;
case SERVER:
INetHandler netHandler = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get();
player = ((NetHandlerPlayServer) netHandler).playerEntity;
pkt.handleServerSide(player);
break;
default:
}
out.add(pkt);
}
public void initialise() {
channels = NetworkRegistry.INSTANCE.newChannel("InventoryPacket", this);
registerPackets();
}
public void registerPackets() {
registerPacket(OpenGuiPacket.class);
registerPacket(SyncPlayerPropsPacket.class);
}
public void postInitialise(){
if (isPostInitialised){
return;
}
isPostInitialised = true;
Collections.sort(packets, new Comparator<Class<? extends AbstractPacket>>(){
public int compare(Class<? extends AbstractPacket> clazz1, Class<? extends AbstractPacket> clazz2){
int com = String.CASE_INSENSITIVE_ORDER.compare(clazz1.getCanonicalName(), clazz2.getCanonicalName());
if (com == 0){
com = clazz1.getCanonicalName().compareTo(clazz2.getCanonicalName());
}
return com;
}
});
}
@SideOnly(Side.CLIENT)
private EntityPlayer getClientPlayer(){
return Minecraft.getMinecraft().thePlayer;
}
public void sendToAll(AbstractPacket message){
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL);
channels.get(Side.SERVER).writeAndFlush(message);
}
public void sendTo(AbstractPacket message, EntityPlayerMP player){
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER);
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(player);
channels.get(Side.SERVER).writeAndFlush(message);
}
public void sendToAllAround(AbstractPacket message, NetworkRegistry.TargetPoint point){
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT);
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point);
channels.get(Side.SERVER).writeAndFlush(message);
}
public void sendToDimension(AbstractPacket message, int dimensionId){
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.DIMENSION);
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(dimensionId);
channels.get(Side.SERVER).writeAndFlush(message);
}
public void sendToServer(AbstractPacket message){
channels.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER);
channels.get(Side.CLIENT).writeAndFlush(message);
}
}
package net.maslenok.inventory.packets;
import cpw.mods.fml.common.network.ByteBufUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import net.maslenok.inventory.proxy.common.CommonProxy;
import net.minecraft.client.main.Main;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
public class SyncPlayerPropsPacket extends AbstractPacket {
// Previously, we've been writing each field in our properties one at a time,
// but that is really annoying, and we've already done it in the save and load
// NBT methods anyway, so here's a slick way to efficiently send all of your
// extended data, and no matter how much you add or remove, you'll never have
// to change the packet / synchronization of your data.
// this will store our ExtendedPlayer data, allowing us to easily read and write
private NBTTagCompound data;
// The basic, no-argument constructor MUST be included to use the new automated handling
public SyncPlayerPropsPacket() {}
// We need to initialize our data, so provide a suitable constructor:
public SyncPlayerPropsPacket(EntityPlayer player) {
// create a new tag compound
data = new NBTTagCompound();
// and save our player's data into it
ExtendedPlayer.get(player).saveNBTData(data);
}
@Override
public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
// ByteBufUtils provides a convenient method for writing the compound
ByteBufUtils.writeTag(buffer, data);
}
@Override
public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
// luckily, ByteBufUtils provides an easy way to read the NBT
data = ByteBufUtils.readTag(buffer);
}
@Override
public void handleClientSide(EntityPlayer player) {
// now we can just load the NBTTagCompound data directly; one and done, folks
ExtendedPlayer.get(player).loadNBTData(data);
}
@Override
public void handleServerSide(EntityPlayer player) {
// we never send this packet to the server, so do nothing here
}
private static final String getSaveKey(EntityPlayer player) {
// no longer a username field, so use the command sender name instead:
return player.getCommandSenderName() + ":" + 1;
}
public static final void loadProxyData(EntityPlayer player) {
ExtendedPlayer playerData = ExtendedPlayer.get(player);
NBTTagCompound savedData = player.getEntityData();
if (savedData != null) { playerData.loadNBTData(savedData); }
net.maslenok.inventory.main.Main.packetPipeline.sendTo(new SyncPlayerPropsPacket(player), (EntityPlayerMP) player);
}
}
import cpw.mods.fml.common.network.ByteBufUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import net.maslenok.inventory.proxy.common.CommonProxy;
import net.minecraft.client.main.Main;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
public class SyncPlayerPropsPacket extends AbstractPacket {
// Previously, we've been writing each field in our properties one at a time,
// but that is really annoying, and we've already done it in the save and load
// NBT methods anyway, so here's a slick way to efficiently send all of your
// extended data, and no matter how much you add or remove, you'll never have
// to change the packet / synchronization of your data.
// this will store our ExtendedPlayer data, allowing us to easily read and write
private NBTTagCompound data;
// The basic, no-argument constructor MUST be included to use the new automated handling
public SyncPlayerPropsPacket() {}
// We need to initialize our data, so provide a suitable constructor:
public SyncPlayerPropsPacket(EntityPlayer player) {
// create a new tag compound
data = new NBTTagCompound();
// and save our player's data into it
ExtendedPlayer.get(player).saveNBTData(data);
}
@Override
public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
// ByteBufUtils provides a convenient method for writing the compound
ByteBufUtils.writeTag(buffer, data);
}
@Override
public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
// luckily, ByteBufUtils provides an easy way to read the NBT
data = ByteBufUtils.readTag(buffer);
}
@Override
public void handleClientSide(EntityPlayer player) {
// now we can just load the NBTTagCompound data directly; one and done, folks
ExtendedPlayer.get(player).loadNBTData(data);
}
@Override
public void handleServerSide(EntityPlayer player) {
// we never send this packet to the server, so do nothing here
}
private static final String getSaveKey(EntityPlayer player) {
// no longer a username field, so use the command sender name instead:
return player.getCommandSenderName() + ":" + 1;
}
public static final void loadProxyData(EntityPlayer player) {
ExtendedPlayer playerData = ExtendedPlayer.get(player);
NBTTagCompound savedData = player.getEntityData();
if (savedData != null) { playerData.loadNBTData(savedData); }
net.maslenok.inventory.main.Main.packetPipeline.sendTo(new SyncPlayerPropsPacket(player), (EntityPlayerMP) player);
}
}
Сам инвентарь кастомный:
package net.maslenok.inventory.iinventory;
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.ItemArmor;
import net.minecraft.item.ItemStack;
public class ContainerCustomPlayer extends Container {
/** Avoid magic numbers! This will greatly reduce the chance of you making errors in 'transferStackInSlot' method */
private static final int ARMOR_START = InventoryCustomPlayer.INV_SIZE, ARMOR_END = ARMOR_START+3,
INV_START = ARMOR_END+1, INV_END = INV_START+26, HOTBAR_START = INV_END+1,
HOTBAR_END = HOTBAR_START+8;
public ContainerCustomPlayer(EntityPlayer player, InventoryPlayer inventoryPlayer, InventoryCustomPlayer inventoryCustom)
{
int i;
// Add CUSTOM slots - we'll just add two for now, both of the same type.
// Make a new Slot class for each different item type you want to add
this.addSlotToContainer(new SlotCustom(inventoryCustom, 0, 80, 8));
this.addSlotToContainer(new SlotCustom(inventoryCustom, 1, 80, 26));
// Add ARMOR slots; note you need to make a public version of SlotArmor
// just copy and paste the vanilla code into a new class and change what you need
for (i = 0; i < 4; ++i)
{
this.addSlotToContainer(new SlotArmor(player, inventoryPlayer, inventoryPlayer.getSizeInventory() - 1 - i, 8, 8 + i * 18,
i));
}
// Add vanilla PLAYER INVENTORY - just copied/pasted from vanilla classes
for (i = 0; i < 3; ++i)
{
for (int j = 0; j < 9; ++j)
{
this.addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
this.addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 8 + j * 18, 104 + i * 18));
}
}
// Add ACTION BAR - just copied/pasted from vanilla classes
for (i = 0; i < 9; ++i)
{
this.addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, 142));
}
}
/**
* This should always return true, since custom inventory can be accessed from anywhere
*/
@Override
public boolean canInteractWith(EntityPlayer player)
{
return true;
}
/**
* Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that.
* Basically the same as every other container I make, since I define the same constant indices for all of them
*/
public ItemStack transferStackInSlot(EntityPlayer player, int par2)
{
ItemStack itemstack = null;
Slot slot = (Slot) this.inventorySlots.get(par2);
if (slot != null && slot.getHasStack())
{
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
// Either armor slot or custom item slot was clicked
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 either in custom or armor slots
else
{
// if item is our custom item
if (itemstack1.getItem() instanceof net.minecraft.item.ItemAxe)
{
if (!this.mergeItemStack(itemstack1, 0, InventoryCustomPlayer.INV_SIZE, false))
{
return null;
}
}
// if item is armor
else 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;
}
}
// item in player's inventory, but not in action bar
else if (par2 >= INV_START && par2 < HOTBAR_START)
{
// place in action bar
if (!this.mergeItemStack(itemstack1, HOTBAR_START, HOTBAR_START + 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(player, itemstack1);
}
return itemstack;
}
}
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.ItemArmor;
import net.minecraft.item.ItemStack;
public class ContainerCustomPlayer extends Container {
/** Avoid magic numbers! This will greatly reduce the chance of you making errors in 'transferStackInSlot' method */
private static final int ARMOR_START = InventoryCustomPlayer.INV_SIZE, ARMOR_END = ARMOR_START+3,
INV_START = ARMOR_END+1, INV_END = INV_START+26, HOTBAR_START = INV_END+1,
HOTBAR_END = HOTBAR_START+8;
public ContainerCustomPlayer(EntityPlayer player, InventoryPlayer inventoryPlayer, InventoryCustomPlayer inventoryCustom)
{
int i;
// Add CUSTOM slots - we'll just add two for now, both of the same type.
// Make a new Slot class for each different item type you want to add
this.addSlotToContainer(new SlotCustom(inventoryCustom, 0, 80, 8));
this.addSlotToContainer(new SlotCustom(inventoryCustom, 1, 80, 26));
// Add ARMOR slots; note you need to make a public version of SlotArmor
// just copy and paste the vanilla code into a new class and change what you need
for (i = 0; i < 4; ++i)
{
this.addSlotToContainer(new SlotArmor(player, inventoryPlayer, inventoryPlayer.getSizeInventory() - 1 - i, 8, 8 + i * 18,
i));
}
// Add vanilla PLAYER INVENTORY - just copied/pasted from vanilla classes
for (i = 0; i < 3; ++i)
{
for (int j = 0; j < 9; ++j)
{
this.addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
this.addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 8 + j * 18, 104 + i * 18));
}
}
// Add ACTION BAR - just copied/pasted from vanilla classes
for (i = 0; i < 9; ++i)
{
this.addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, 142));
}
}
/**
* This should always return true, since custom inventory can be accessed from anywhere
*/
@Override
public boolean canInteractWith(EntityPlayer player)
{
return true;
}
/**
* Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that.
* Basically the same as every other container I make, since I define the same constant indices for all of them
*/
public ItemStack transferStackInSlot(EntityPlayer player, int par2)
{
ItemStack itemstack = null;
Slot slot = (Slot) this.inventorySlots.get(par2);
if (slot != null && slot.getHasStack())
{
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
// Either armor slot or custom item slot was clicked
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 either in custom or armor slots
else
{
// if item is our custom item
if (itemstack1.getItem() instanceof net.minecraft.item.ItemAxe)
{
if (!this.mergeItemStack(itemstack1, 0, InventoryCustomPlayer.INV_SIZE, false))
{
return null;
}
}
// if item is armor
else 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;
}
}
// item in player's inventory, but not in action bar
else if (par2 >= INV_START && par2 < HOTBAR_START)
{
// place in action bar
if (!this.mergeItemStack(itemstack1, HOTBAR_START, HOTBAR_START + 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(player, itemstack1);
}
return itemstack;
}
}
package net.maslenok.inventory.iinventory;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;
public class GuiCustomPlayerInventory extends GuiContainer {
/** x size of the inventory window in pixels. Defined as float, passed as int */
private float xSize_lo;
/** y size of the inventory window in pixels. Defined as float, passed as int. */
private float ySize_lo;
/** Normally I use '(ModInfo.MOD_ID, "textures/...")', but it can be done this way as well */
private static final ResourceLocation iconLocation = new ResourceLocation("tutorial:textures/gui/custom_inventory.png");
/** Could use IInventory type to be more generic, but this way will save an import... */
private final InventoryCustomPlayer inventory;
public GuiCustomPlayerInventory(EntityPlayer player, InventoryPlayer inventoryPlayer, InventoryCustomPlayer
inventoryCustom)
{
super(new ContainerCustomPlayer(player, inventoryPlayer, inventoryCustom));
this.inventory = inventoryCustom;
// if you need the player for something later on, store it in a local variable here as well
}
/**
* Draws the screen and all the components in it.
*/
public void drawScreen(int mouseX, int mouseY, float f)
{
super.drawScreen(mouseX, mouseY, f);
xSize_lo = mouseX;
ySize_lo = mouseY;
}
/**
* Draw the foreground layer for the GuiContainer (everything in front of the items)
*/
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
{
// This method will simply draw inventory names on the screen - you could do without it entirely
// if that's not important to you, since we are overriding the default inventory rather than
// creating a specific type of inventory
String s = this.inventory.hasCustomInventoryName() ? this.inventory.getInventoryName() : I18n.format(this.inventory.getInventoryName());
// with the name "Custom Inventory", the 'Cu' will be drawn in the first slot
this.fontRendererObj.drawString(s, this.xSize - this.mc.fontRenderer.getStringWidth(s), 12, 4210752);
// this just adds "Inventory" above the player's inventory below
this.fontRendererObj.drawString(I18n.format("container.inventory"), 80, this.ySize - 96, 4210752);
}
/**
* Draw the background layer for the GuiContainer (everything behind the items)
*/
protected void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY)
{
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.getTextureManager().bindTexture(iconLocation);
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
drawPlayerModel(guiLeft + 51, guiTop + 75, 30, guiLeft + 51 - xSize_lo, guiTop + 25 - ySize_lo, mc.thePlayer);
}
/**
* Copied straight out of vanilla - renders the player model on screen
*/
public static void drawPlayerModel(int x, int y, int scale, float yaw, float pitch, EntityLivingBase entity) {
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
GL11.glPushMatrix();
GL11.glTranslatef(x, y, 50.0F);
GL11.glScalef(-scale, scale, scale);
GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
float f2 = entity.renderYawOffset;
float f3 = entity.rotationYaw;
float f4 = entity.rotationPitch;
float f5 = entity.prevRotationYawHead;
float f6 = entity.rotationYawHead;
GL11.glRotatef(135.0F, 0.0F, 1.0F, 0.0F);
RenderHelper.enableStandardItemLighting();
GL11.glRotatef(-135.0F, 0.0F, 1.0F, 0.0F);
GL11.glRotatef(-((float) Math.atan(pitch / 40.0F)) * 20.0F, 1.0F, 0.0F, 0.0F);
entity.renderYawOffset = (float) Math.atan(yaw / 40.0F) * 20.0F;
entity.rotationYaw = (float) Math.atan(yaw / 40.0F) * 40.0F;
entity.rotationPitch = -((float) Math.atan(pitch / 40.0F)) * 20.0F;
entity.rotationYawHead = entity.rotationYaw;
entity.prevRotationYawHead = entity.rotationYaw;
GL11.glTranslatef(0.0F, entity.yOffset, 0.0F);
RenderManager.instance.playerViewY = 180.0F;
RenderManager.instance.renderEntityWithPosYaw(entity, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F);
entity.renderYawOffset = f2;
entity.rotationYaw = f3;
entity.rotationPitch = f4;
entity.prevRotationYawHead = f5;
entity.rotationYawHead = f6;
GL11.glPopMatrix();
RenderHelper.disableStandardItemLighting();
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit);
GL11.glDisable(GL11.GL_TEXTURE_2D);
OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
}
}
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;
public class GuiCustomPlayerInventory extends GuiContainer {
/** x size of the inventory window in pixels. Defined as float, passed as int */
private float xSize_lo;
/** y size of the inventory window in pixels. Defined as float, passed as int. */
private float ySize_lo;
/** Normally I use '(ModInfo.MOD_ID, "textures/...")', but it can be done this way as well */
private static final ResourceLocation iconLocation = new ResourceLocation("tutorial:textures/gui/custom_inventory.png");
/** Could use IInventory type to be more generic, but this way will save an import... */
private final InventoryCustomPlayer inventory;
public GuiCustomPlayerInventory(EntityPlayer player, InventoryPlayer inventoryPlayer, InventoryCustomPlayer
inventoryCustom)
{
super(new ContainerCustomPlayer(player, inventoryPlayer, inventoryCustom));
this.inventory = inventoryCustom;
// if you need the player for something later on, store it in a local variable here as well
}
/**
* Draws the screen and all the components in it.
*/
public void drawScreen(int mouseX, int mouseY, float f)
{
super.drawScreen(mouseX, mouseY, f);
xSize_lo = mouseX;
ySize_lo = mouseY;
}
/**
* Draw the foreground layer for the GuiContainer (everything in front of the items)
*/
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
{
// This method will simply draw inventory names on the screen - you could do without it entirely
// if that's not important to you, since we are overriding the default inventory rather than
// creating a specific type of inventory
String s = this.inventory.hasCustomInventoryName() ? this.inventory.getInventoryName() : I18n.format(this.inventory.getInventoryName());
// with the name "Custom Inventory", the 'Cu' will be drawn in the first slot
this.fontRendererObj.drawString(s, this.xSize - this.mc.fontRenderer.getStringWidth(s), 12, 4210752);
// this just adds "Inventory" above the player's inventory below
this.fontRendererObj.drawString(I18n.format("container.inventory"), 80, this.ySize - 96, 4210752);
}
/**
* Draw the background layer for the GuiContainer (everything behind the items)
*/
protected void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY)
{
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.getTextureManager().bindTexture(iconLocation);
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
drawPlayerModel(guiLeft + 51, guiTop + 75, 30, guiLeft + 51 - xSize_lo, guiTop + 25 - ySize_lo, mc.thePlayer);
}
/**
* Copied straight out of vanilla - renders the player model on screen
*/
public static void drawPlayerModel(int x, int y, int scale, float yaw, float pitch, EntityLivingBase entity) {
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
GL11.glPushMatrix();
GL11.glTranslatef(x, y, 50.0F);
GL11.glScalef(-scale, scale, scale);
GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
float f2 = entity.renderYawOffset;
float f3 = entity.rotationYaw;
float f4 = entity.rotationPitch;
float f5 = entity.prevRotationYawHead;
float f6 = entity.rotationYawHead;
GL11.glRotatef(135.0F, 0.0F, 1.0F, 0.0F);
RenderHelper.enableStandardItemLighting();
GL11.glRotatef(-135.0F, 0.0F, 1.0F, 0.0F);
GL11.glRotatef(-((float) Math.atan(pitch / 40.0F)) * 20.0F, 1.0F, 0.0F, 0.0F);
entity.renderYawOffset = (float) Math.atan(yaw / 40.0F) * 20.0F;
entity.rotationYaw = (float) Math.atan(yaw / 40.0F) * 40.0F;
entity.rotationPitch = -((float) Math.atan(pitch / 40.0F)) * 20.0F;
entity.rotationYawHead = entity.rotationYaw;
entity.prevRotationYawHead = entity.rotationYaw;
GL11.glTranslatef(0.0F, entity.yOffset, 0.0F);
RenderManager.instance.playerViewY = 180.0F;
RenderManager.instance.renderEntityWithPosYaw(entity, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F);
entity.renderYawOffset = f2;
entity.rotationYaw = f3;
entity.rotationPitch = f4;
entity.prevRotationYawHead = f5;
entity.rotationYawHead = f6;
GL11.glPopMatrix();
RenderHelper.disableStandardItemLighting();
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit);
GL11.glDisable(GL11.GL_TEXTURE_2D);
OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
}
}
package net.maslenok.inventory.iinventory;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
public class InventoryCustomPlayer implements IInventory {
/** The name your custom inventory will display in the GUI, possibly just "Inventory" */
private final String name = "Custom Inventory";
/** The key used to store and retrieve the inventory from NBT */
private final String tagName = "CustomInvTag";
/** Define the inventory size here for easy reference */
// This is also the place to define which slot is which if you have different types,
// for example SLOT_SHIELD = 0, SLOT_AMULET = 1;
public static final int INV_SIZE = 2;
/** Inventory's size must be same as number of slots you add to the Container class */
private ItemStack[] inventory = new ItemStack[INV_SIZE];
public InventoryCustomPlayer()
{
// don't need anything here!
}
@Override
public int getSizeInventory()
{
return inventory.length;
}
@Override
public ItemStack getStackInSlot(int slot)
{
return inventory[slot];
}
@Override
public ItemStack decrStackSize(int slot, int amount)
{
ItemStack stack = getStackInSlot(slot);
if (stack != null)
{
if (stack.stackSize > amount)
{
stack = stack.splitStack(amount);
this.markDirty();
}
else
{
setInventorySlotContents(slot, null);
}
}
return stack;
}
@Override
public ItemStack getStackInSlotOnClosing(int slot)
{
ItemStack stack = getStackInSlot(slot);
setInventorySlotContents(slot, null);
return stack;
}
@Override
public void setInventorySlotContents(int slot, ItemStack itemstack)
{
this.inventory[slot] = itemstack;
if (itemstack != null && itemstack.stackSize > this.getInventoryStackLimit())
{
itemstack.stackSize = this.getInventoryStackLimit();
}
this.markDirty();
}
@Override
public String getInventoryName()
{
return name;
}
@Override
public boolean hasCustomInventoryName()
{
return name.length() > 0;
}
/**
* Our custom slots are similar to armor - only one item per slot
*/
@Override
public int getInventoryStackLimit()
{
return 1;
}
@Override
public void markDirty()
{
for (int i = 0; i < getSizeInventory(); ++i)
{
if (getStackInSlot(i) != null && getStackInSlot(i).stackSize == 0) {
inventory = null;
}
}
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
return true;
}
@Override
public void openInventory() {}
@Override
public void closeInventory() {}
/**
* This method doesn't seem to do what it claims to do, as
* items can still be left-clicked and placed in the inventory
* even when this returns false
*/
@Override
public boolean isItemValidForSlot(int slot, ItemStack itemstack)
{
// If you have different kinds of slots, then check them here:
// if (slot == SLOT_SHIELD && itemstack.getItem() instanceof ItemShield) return true;
// For now, only ItemUseMana items can be stored in these slots
return itemstack.getItem() instanceof net.minecraft.item.ItemAxe;
}
public void writeToNBT(NBTTagCompound compound)
{
NBTTagList items = new NBTTagList();
for (int i = 0; i < getSizeInventory(); ++i)
{
if (getStackInSlot(i) != null)
{
NBTTagCompound item = new NBTTagCompound();
item.setByte("Slot", (byte) i);
getStackInSlot(i).writeToNBT(item);
items.appendTag(item);
}
}
// We're storing our items in a custom tag list using our 'tagName' from above
// to prevent potential conflicts
compound.setTag(tagName, items);
}
public void readFromNBT(NBTTagCompound compound) {
// now you must include the NBTBase type ID when getting the list; NBTTagCompound's ID is 10
NBTTagList items = compound.getTagList(tagName, compound.getId());
for (int i = 0; i < items.tagCount(); ++i) {
// tagAt(int) has changed to getCompoundTagAt(int)
NBTTagCompound item = items.getCompoundTagAt(i);
byte slot = item.getByte("Slot");
if (slot >= 0 && slot < getSizeInventory()) {
inventory[slot] = ItemStack.loadItemStackFromNBT(item);
}
}
}
}
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
public class InventoryCustomPlayer implements IInventory {
/** The name your custom inventory will display in the GUI, possibly just "Inventory" */
private final String name = "Custom Inventory";
/** The key used to store and retrieve the inventory from NBT */
private final String tagName = "CustomInvTag";
/** Define the inventory size here for easy reference */
// This is also the place to define which slot is which if you have different types,
// for example SLOT_SHIELD = 0, SLOT_AMULET = 1;
public static final int INV_SIZE = 2;
/** Inventory's size must be same as number of slots you add to the Container class */
private ItemStack[] inventory = new ItemStack[INV_SIZE];
public InventoryCustomPlayer()
{
// don't need anything here!
}
@Override
public int getSizeInventory()
{
return inventory.length;
}
@Override
public ItemStack getStackInSlot(int slot)
{
return inventory[slot];
}
@Override
public ItemStack decrStackSize(int slot, int amount)
{
ItemStack stack = getStackInSlot(slot);
if (stack != null)
{
if (stack.stackSize > amount)
{
stack = stack.splitStack(amount);
this.markDirty();
}
else
{
setInventorySlotContents(slot, null);
}
}
return stack;
}
@Override
public ItemStack getStackInSlotOnClosing(int slot)
{
ItemStack stack = getStackInSlot(slot);
setInventorySlotContents(slot, null);
return stack;
}
@Override
public void setInventorySlotContents(int slot, ItemStack itemstack)
{
this.inventory[slot] = itemstack;
if (itemstack != null && itemstack.stackSize > this.getInventoryStackLimit())
{
itemstack.stackSize = this.getInventoryStackLimit();
}
this.markDirty();
}
@Override
public String getInventoryName()
{
return name;
}
@Override
public boolean hasCustomInventoryName()
{
return name.length() > 0;
}
/**
* Our custom slots are similar to armor - only one item per slot
*/
@Override
public int getInventoryStackLimit()
{
return 1;
}
@Override
public void markDirty()
{
for (int i = 0; i < getSizeInventory(); ++i)
{
if (getStackInSlot(i) != null && getStackInSlot(i).stackSize == 0) {
inventory = null;
}
}
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
return true;
}
@Override
public void openInventory() {}
@Override
public void closeInventory() {}
/**
* This method doesn't seem to do what it claims to do, as
* items can still be left-clicked and placed in the inventory
* even when this returns false
*/
@Override
public boolean isItemValidForSlot(int slot, ItemStack itemstack)
{
// If you have different kinds of slots, then check them here:
// if (slot == SLOT_SHIELD && itemstack.getItem() instanceof ItemShield) return true;
// For now, only ItemUseMana items can be stored in these slots
return itemstack.getItem() instanceof net.minecraft.item.ItemAxe;
}
public void writeToNBT(NBTTagCompound compound)
{
NBTTagList items = new NBTTagList();
for (int i = 0; i < getSizeInventory(); ++i)
{
if (getStackInSlot(i) != null)
{
NBTTagCompound item = new NBTTagCompound();
item.setByte("Slot", (byte) i);
getStackInSlot(i).writeToNBT(item);
items.appendTag(item);
}
}
// We're storing our items in a custom tag list using our 'tagName' from above
// to prevent potential conflicts
compound.setTag(tagName, items);
}
public void readFromNBT(NBTTagCompound compound) {
// now you must include the NBTBase type ID when getting the list; NBTTagCompound's ID is 10
NBTTagList items = compound.getTagList(tagName, compound.getId());
for (int i = 0; i < items.tagCount(); ++i) {
// tagAt(int) has changed to getCompoundTagAt(int)
NBTTagCompound item = items.getCompoundTagAt(i);
byte slot = item.getByte("Slot");
if (slot >= 0 && slot < getSizeInventory()) {
inventory[slot] = ItemStack.loadItemStackFromNBT(item);
}
}
}
}
package net.maslenok.inventory.iinventory;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
public class InventoryCustomPlayer implements IInventory {
/** The name your custom inventory will display in the GUI, possibly just "Inventory" */
private final String name = "Custom Inventory";
/** The key used to store and retrieve the inventory from NBT */
private final String tagName = "CustomInvTag";
/** Define the inventory size here for easy reference */
// This is also the place to define which slot is which if you have different types,
// for example SLOT_SHIELD = 0, SLOT_AMULET = 1;
public static final int INV_SIZE = 2;
/** Inventory's size must be same as number of slots you add to the Container class */
private ItemStack[] inventory = new ItemStack[INV_SIZE];
public InventoryCustomPlayer()
{
// don't need anything here!
}
@Override
public int getSizeInventory()
{
return inventory.length;
}
@Override
public ItemStack getStackInSlot(int slot)
{
return inventory[slot];
}
@Override
public ItemStack decrStackSize(int slot, int amount)
{
ItemStack stack = getStackInSlot(slot);
if (stack != null)
{
if (stack.stackSize > amount)
{
stack = stack.splitStack(amount);
this.markDirty();
}
else
{
setInventorySlotContents(slot, null);
}
}
return stack;
}
@Override
public ItemStack getStackInSlotOnClosing(int slot)
{
ItemStack stack = getStackInSlot(slot);
setInventorySlotContents(slot, null);
return stack;
}
@Override
public void setInventorySlotContents(int slot, ItemStack itemstack)
{
this.inventory[slot] = itemstack;
if (itemstack != null && itemstack.stackSize > this.getInventoryStackLimit())
{
itemstack.stackSize = this.getInventoryStackLimit();
}
this.markDirty();
}
@Override
public String getInventoryName()
{
return name;
}
@Override
public boolean hasCustomInventoryName()
{
return name.length() > 0;
}
/**
* Our custom slots are similar to armor - only one item per slot
*/
@Override
public int getInventoryStackLimit()
{
return 1;
}
@Override
public void markDirty()
{
for (int i = 0; i < getSizeInventory(); ++i)
{
if (getStackInSlot(i) != null && getStackInSlot(i).stackSize == 0) {
inventory = null;
}
}
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
return true;
}
@Override
public void openInventory() {}
@Override
public void closeInventory() {}
/**
* This method doesn't seem to do what it claims to do, as
* items can still be left-clicked and placed in the inventory
* even when this returns false
*/
@Override
public boolean isItemValidForSlot(int slot, ItemStack itemstack)
{
// If you have different kinds of slots, then check them here:
// if (slot == SLOT_SHIELD && itemstack.getItem() instanceof ItemShield) return true;
// For now, only ItemUseMana items can be stored in these slots
return itemstack.getItem() instanceof net.minecraft.item.ItemAxe;
}
public void writeToNBT(NBTTagCompound compound)
{
NBTTagList items = new NBTTagList();
for (int i = 0; i < getSizeInventory(); ++i)
{
if (getStackInSlot(i) != null)
{
NBTTagCompound item = new NBTTagCompound();
item.setByte("Slot", (byte) i);
getStackInSlot(i).writeToNBT(item);
items.appendTag(item);
}
}
// We're storing our items in a custom tag list using our 'tagName' from above
// to prevent potential conflicts
compound.setTag(tagName, items);
}
public void readFromNBT(NBTTagCompound compound) {
// now you must include the NBTBase type ID when getting the list; NBTTagCompound's ID is 10
NBTTagList items = compound.getTagList(tagName, compound.getId());
for (int i = 0; i < items.tagCount(); ++i) {
// tagAt(int) has changed to getCompoundTagAt(int)
NBTTagCompound item = items.getCompoundTagAt(i);
byte slot = item.getByte("Slot");
if (slot >= 0 && slot < getSizeInventory()) {
inventory[slot] = ItemStack.loadItemStackFromNBT(item);
}
}
}
}
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
public class InventoryCustomPlayer implements IInventory {
/** The name your custom inventory will display in the GUI, possibly just "Inventory" */
private final String name = "Custom Inventory";
/** The key used to store and retrieve the inventory from NBT */
private final String tagName = "CustomInvTag";
/** Define the inventory size here for easy reference */
// This is also the place to define which slot is which if you have different types,
// for example SLOT_SHIELD = 0, SLOT_AMULET = 1;
public static final int INV_SIZE = 2;
/** Inventory's size must be same as number of slots you add to the Container class */
private ItemStack[] inventory = new ItemStack[INV_SIZE];
public InventoryCustomPlayer()
{
// don't need anything here!
}
@Override
public int getSizeInventory()
{
return inventory.length;
}
@Override
public ItemStack getStackInSlot(int slot)
{
return inventory[slot];
}
@Override
public ItemStack decrStackSize(int slot, int amount)
{
ItemStack stack = getStackInSlot(slot);
if (stack != null)
{
if (stack.stackSize > amount)
{
stack = stack.splitStack(amount);
this.markDirty();
}
else
{
setInventorySlotContents(slot, null);
}
}
return stack;
}
@Override
public ItemStack getStackInSlotOnClosing(int slot)
{
ItemStack stack = getStackInSlot(slot);
setInventorySlotContents(slot, null);
return stack;
}
@Override
public void setInventorySlotContents(int slot, ItemStack itemstack)
{
this.inventory[slot] = itemstack;
if (itemstack != null && itemstack.stackSize > this.getInventoryStackLimit())
{
itemstack.stackSize = this.getInventoryStackLimit();
}
this.markDirty();
}
@Override
public String getInventoryName()
{
return name;
}
@Override
public boolean hasCustomInventoryName()
{
return name.length() > 0;
}
/**
* Our custom slots are similar to armor - only one item per slot
*/
@Override
public int getInventoryStackLimit()
{
return 1;
}
@Override
public void markDirty()
{
for (int i = 0; i < getSizeInventory(); ++i)
{
if (getStackInSlot(i) != null && getStackInSlot(i).stackSize == 0) {
inventory = null;
}
}
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
return true;
}
@Override
public void openInventory() {}
@Override
public void closeInventory() {}
/**
* This method doesn't seem to do what it claims to do, as
* items can still be left-clicked and placed in the inventory
* even when this returns false
*/
@Override
public boolean isItemValidForSlot(int slot, ItemStack itemstack)
{
// If you have different kinds of slots, then check them here:
// if (slot == SLOT_SHIELD && itemstack.getItem() instanceof ItemShield) return true;
// For now, only ItemUseMana items can be stored in these slots
return itemstack.getItem() instanceof net.minecraft.item.ItemAxe;
}
public void writeToNBT(NBTTagCompound compound)
{
NBTTagList items = new NBTTagList();
for (int i = 0; i < getSizeInventory(); ++i)
{
if (getStackInSlot(i) != null)
{
NBTTagCompound item = new NBTTagCompound();
item.setByte("Slot", (byte) i);
getStackInSlot(i).writeToNBT(item);
items.appendTag(item);
}
}
// We're storing our items in a custom tag list using our 'tagName' from above
// to prevent potential conflicts
compound.setTag(tagName, items);
}
public void readFromNBT(NBTTagCompound compound) {
// now you must include the NBTBase type ID when getting the list; NBTTagCompound's ID is 10
NBTTagList items = compound.getTagList(tagName, compound.getId());
for (int i = 0; i < items.tagCount(); ++i) {
// tagAt(int) has changed to getCompoundTagAt(int)
NBTTagCompound item = items.getCompoundTagAt(i);
byte slot = item.getByte("Slot");
if (slot >= 0 && slot < getSizeInventory()) {
inventory[slot] = ItemStack.loadItemStackFromNBT(item);
}
}
}
}
package net.maslenok.inventory.iinventory;
import javax.swing.Icon;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
public class SlotArmor extends Slot {
/** The armor type that can be placed on that slot, it uses the same values of armorType field on ItemArmor. */
final int armorType;
/** The parent class of this slot, ContainerPlayer, SlotArmor is a Anon inner class. */
final EntityPlayer player;
public SlotArmor(EntityPlayer player, IInventory inventory, int slotIndex, int x, int y, int armorType)
{
super(inventory, slotIndex, x, y);
this.player = player;
this.armorType = armorType;
}
/**
* Returns the maximum stack size for a given slot (usually the same as getInventoryStackLimit(), but 1 in the case
* of armor slots)
*/
public int getSlotStackLimit()
{
return 1;
}
/**
* Check if the stack is a valid item for this slot. Always true beside for the armor slots.
*/
public boolean isItemValid(ItemStack itemstack)
{
Item item = (itemstack == null ? null : itemstack.getItem());
return item != null && item.isValidArmor(itemstack, armorType, player);
}
/**
* Returns the icon index on items.png that is used as background image of the slot.
*/
@SideOnly(Side.CLIENT)
public IIcon getBackgroundIconIndex()
{
return ItemArmor.func_94602_b(this.armorType);
}
}
package net.maslenok.inventory.iinventory;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class SlotCustom extends Slot {
public SlotCustom(IInventory inventory, int slotIndex, int x, int y)
{
super(inventory, slotIndex, x, y);
}
/**
* Check if the stack is a valid item for this slot. Always true beside for the armor slots
* (and now also not always true for our custom inventory slots)
*/
@Override
public boolean isItemValid(ItemStack stack)
{
// We only want our custom item to be storable in this slot
return stack.getItem() instanceof net.minecraft.item.ItemAxe ;
}
}
import javax.swing.Icon;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
public class SlotArmor extends Slot {
/** The armor type that can be placed on that slot, it uses the same values of armorType field on ItemArmor. */
final int armorType;
/** The parent class of this slot, ContainerPlayer, SlotArmor is a Anon inner class. */
final EntityPlayer player;
public SlotArmor(EntityPlayer player, IInventory inventory, int slotIndex, int x, int y, int armorType)
{
super(inventory, slotIndex, x, y);
this.player = player;
this.armorType = armorType;
}
/**
* Returns the maximum stack size for a given slot (usually the same as getInventoryStackLimit(), but 1 in the case
* of armor slots)
*/
public int getSlotStackLimit()
{
return 1;
}
/**
* Check if the stack is a valid item for this slot. Always true beside for the armor slots.
*/
public boolean isItemValid(ItemStack itemstack)
{
Item item = (itemstack == null ? null : itemstack.getItem());
return item != null && item.isValidArmor(itemstack, armorType, player);
}
/**
* Returns the icon index on items.png that is used as background image of the slot.
*/
@SideOnly(Side.CLIENT)
public IIcon getBackgroundIconIndex()
{
return ItemArmor.func_94602_b(this.armorType);
}
}
package net.maslenok.inventory.iinventory;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class SlotCustom extends Slot {
public SlotCustom(IInventory inventory, int slotIndex, int x, int y)
{
super(inventory, slotIndex, x, y);
}
/**
* Check if the stack is a valid item for this slot. Always true beside for the armor slots
* (and now also not always true for our custom inventory slots)
*/
@Override
public boolean isItemValid(ItemStack stack)
{
// We only want our custom item to be storable in this slot
return stack.getItem() instanceof net.minecraft.item.ItemAxe ;
}
}
Main:
package net.maslenok.inventory.main;
import net.maslenok.inventory.packets.OpenGuiPacket;
import net.maslenok.inventory.packets.PacketPipeline;
import net.maslenok.inventory.proxy.common.CommonProxy;
import net.minecraft.init.Blocks;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import cpw.mods.fml.relauncher.Side;
@Mod(modid = Main.MODID, name = Main.NAME, version = Main.VERSION)
public class Main
{
public static final String MODID = "Corspes";
public static final String NAME = "Corspes";
public static final String VERSION = "Beta";
@SidedProxy(clientSide="net.maslenok.inventory.proxy.client.ClientProxy", serverSide="net.maslenok.inventory.proxy.common.CommonProxy")
public static CommonProxy proxy;
@Instance("Main")
public static Main instance;
public static final PacketPipeline packetPipeline = new PacketPipeline();
@EventHandler
public void initialise(FMLInitializationEvent event){
packetPipeline.initialise();
packetPipeline.registerPacket(OpenGuiPacket.class); // Пакет открытия инвентаря.
}
@EventHandler
public void postInitialise(FMLPostInitializationEvent eventt){
packetPipeline.postInitialise();
}
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event)
{
proxy.preInit(event);
System.out.println("Hello World! I'm Micky Mouse, xa-xa (preinit)");
}
@Mod.EventHandler
public void init(FMLInitializationEvent event)
{
proxy.init(event);
System.out.println("Hello World! I'm Micky Mouse, xa-xa (init)");
}
@Mod.EventHandler
public void postInit(FMLPostInitializationEvent event)
{
proxy.postInit(event);
System.out.println("Hello World! I'm Micky Mouse, xa-xa (postinit)");
}
}
import net.maslenok.inventory.packets.OpenGuiPacket;
import net.maslenok.inventory.packets.PacketPipeline;
import net.maslenok.inventory.proxy.common.CommonProxy;
import net.minecraft.init.Blocks;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import cpw.mods.fml.relauncher.Side;
@Mod(modid = Main.MODID, name = Main.NAME, version = Main.VERSION)
public class Main
{
public static final String MODID = "Corspes";
public static final String NAME = "Corspes";
public static final String VERSION = "Beta";
@SidedProxy(clientSide="net.maslenok.inventory.proxy.client.ClientProxy", serverSide="net.maslenok.inventory.proxy.common.CommonProxy")
public static CommonProxy proxy;
@Instance("Main")
public static Main instance;
public static final PacketPipeline packetPipeline = new PacketPipeline();
@EventHandler
public void initialise(FMLInitializationEvent event){
packetPipeline.initialise();
packetPipeline.registerPacket(OpenGuiPacket.class); // Пакет открытия инвентаря.
}
@EventHandler
public void postInitialise(FMLPostInitializationEvent eventt){
packetPipeline.postInitialise();
}
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event)
{
proxy.preInit(event);
System.out.println("Hello World! I'm Micky Mouse, xa-xa (preinit)");
}
@Mod.EventHandler
public void init(FMLInitializationEvent event)
{
proxy.init(event);
System.out.println("Hello World! I'm Micky Mouse, xa-xa (init)");
}
@Mod.EventHandler
public void postInit(FMLPostInitializationEvent event)
{
proxy.postInit(event);
System.out.println("Hello World! I'm Micky Mouse, xa-xa (postinit)");
}
}
Proxys:
package net.maslenok.inventory.proxy.client;
import org.lwjgl.input.Keyboard;
import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import net.maslenok.inventory.iinventory.KeyHandler;
import net.maslenok.inventory.proxy.common.CommonProxy;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.common.MinecraftForge;
public class ClientProxy extends CommonProxy {
public void preInit(FMLPreInitializationEvent event)
{
super.preInit(event);
}
public void init(FMLInitializationEvent event)
{
super.init(event);
FMLCommonHandler.instance().bus().register(new KeyHandler());
}
public void postInit(FMLPostInitializationEvent event)
{
super.postInit(event);
}
public EntityPlayer getPlayerEntity(MessageContext ctx)
{
return ctx.side.isClient() ? Minecraft.getMinecraft().thePlayer : super.getPlayerEntity(ctx);
}
}
import org.lwjgl.input.Keyboard;
import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import net.maslenok.inventory.iinventory.KeyHandler;
import net.maslenok.inventory.proxy.common.CommonProxy;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.common.MinecraftForge;
public class ClientProxy extends CommonProxy {
public void preInit(FMLPreInitializationEvent event)
{
super.preInit(event);
}
public void init(FMLInitializationEvent event)
{
super.init(event);
FMLCommonHandler.instance().bus().register(new KeyHandler());
}
public void postInit(FMLPostInitializationEvent event)
{
super.postInit(event);
}
public EntityPlayer getPlayerEntity(MessageContext ctx)
{
return ctx.side.isClient() ? Minecraft.getMinecraft().thePlayer : super.getPlayerEntity(ctx);
}
}
package net.maslenok.inventory.proxy.common;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import net.minecraft.entity.player.EntityPlayer;
public class CommonProxy
{
public void preInit(FMLPreInitializationEvent event)
{
}
public void init(FMLInitializationEvent event)
{
}
public void postInit(FMLPostInitializationEvent event) {}
public EntityPlayer getPlayerEntity(MessageContext ctx)
{
return ctx.getServerHandler().playerEntity;
}
}
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import net.minecraft.entity.player.EntityPlayer;
public class CommonProxy
{
public void preInit(FMLPreInitializationEvent event)
{
}
public void init(FMLInitializationEvent event)
{
}
public void postInit(FMLPostInitializationEvent event) {}
public EntityPlayer getPlayerEntity(MessageContext ctx)
{
return ctx.getServerHandler().playerEntity;
}
}
package net.maslenok.inventory.proxy.server;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import net.maslenok.inventory.proxy.common.CommonProxy;
public class ServerProxy extends CommonProxy {
public void preInit(FMLPreInitializationEvent event)
{
super.preInit(event);
}
public void init(FMLInitializationEvent event)
{
super.init(event);
}
public void postInit(FMLPostInitializationEvent event)
{
super.postInit(event);
}
}
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import net.maslenok.inventory.proxy.common.CommonProxy;
public class ServerProxy extends CommonProxy {
public void preInit(FMLPreInitializationEvent event)
{
super.preInit(event);
}
public void init(FMLInitializationEvent event)
{
super.init(event);
}
public void postInit(FMLPostInitializationEvent event)
{
super.postInit(event);
}
}
Заранее спасибо.
Не могу понять почему не работает инвентарь.
Кто сможет помочь - буду благодарен.
Последнее редактирование: