runtimeGuiCategories() {
+ return null;
+ }
+
+ @Override
+ public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement element) {
+ return null;
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/MCPacket.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/MCPacket.java
new file mode 100644
index 000000000..2da87aa23
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/MCPacket.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.network;
+
+import io.netty.buffer.ByteBuf;
+import net.minecraftforge.fml.common.network.ByteBufUtils;
+import nova.core.entity.component.Player;
+import nova.core.network.Packet;
+
+/**
+ * Wraps ByteBuf into a NOVA Packet.
+ * @author Calclavia
+ */
+public class MCPacket implements Packet {
+
+ public final ByteBuf buf;
+ public final Player player;
+ private int id = 0;
+
+ public MCPacket(ByteBuf buf) {
+ this.buf = buf;
+ player = null;
+ }
+
+ public MCPacket(ByteBuf buf, Player player) {
+ this.buf = buf;
+ this.player = player;
+ }
+
+ @Override
+ public Player player() {
+ if (player == null) {
+ throw new RuntimeException("Attempt to get player in packet when it does not exist!");
+ }
+
+ return player;
+ }
+
+ @Override
+ public int getID() {
+ return id;
+ }
+
+ @Override
+ public Packet setID(int id) {
+ this.id = id;
+ return this;
+ }
+
+ @Override
+ public Packet writeBoolean(boolean value) {
+ buf.writeBoolean(value);
+ return this;
+ }
+
+ @Override
+ public Packet writeByte(int value) {
+ buf.writeByte(value);
+ return this;
+ }
+
+ @Override
+ public Packet writeShort(int value) {
+ buf.writeShort(value);
+ return this;
+ }
+
+ @Override
+ public Packet writeInt(int value) {
+ buf.writeInt(value);
+ return this;
+ }
+
+ @Override
+ public Packet writeLong(long value) {
+ buf.writeLong(value);
+ return this;
+ }
+
+ @Override
+ public Packet writeChar(int value) {
+ buf.writeChar(value);
+ return this;
+ }
+
+ @Override
+ public Packet writeFloat(float value) {
+ buf.writeFloat(value);
+ return this;
+ }
+
+ @Override
+ public Packet writeDouble(double value) {
+ buf.writeDouble(value);
+ return this;
+ }
+
+ @Override
+ public Packet writeString(String value) {
+ ByteBufUtils.writeUTF8String(buf, value);
+ return this;
+ }
+
+ @Override
+ public Packet writeBytes(byte[] array) {
+ buf.writeBytes(array);
+ return this;
+ }
+
+ @Override
+ public byte[] readBytes(int length) {
+ byte[] array = new byte[length];
+ for (int i = 0; i < length; i++)
+ array[i] = buf.readByte();
+ return array;
+ }
+
+ @Override
+ public boolean readBoolean() {
+ return buf.readBoolean();
+ }
+
+ @Override
+ public byte readByte() {
+ return buf.readByte();
+ }
+
+ @Override
+ public short readUnsignedByte() {
+ return buf.readUnsignedByte();
+ }
+
+ @Override
+ public short readShort() {
+ return buf.readShort();
+ }
+
+ @Override
+ public int readInt() {
+ return buf.readInt();
+ }
+
+ @Override
+ public long readUnsignedInt() {
+ return buf.readUnsignedInt();
+ }
+
+ @Override
+ public long readLong() {
+ return buf.readLong();
+ }
+
+ @Override
+ public char readChar() {
+ return buf.readChar();
+ }
+
+ @Override
+ public float readFloat() {
+ return buf.readFloat();
+ }
+
+ @Override
+ public double readDouble() {
+ return buf.readDouble();
+ }
+
+ @Override
+ public String readString() {
+ return ByteBufUtils.readUTF8String(buf);
+ }
+
+ public void writeTo(ByteBuf other) {
+ other.writeBytes(buf);
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/discriminator/NovaPacket.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/discriminator/NovaPacket.java
new file mode 100644
index 000000000..61b04541d
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/discriminator/NovaPacket.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.network.discriminator;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import net.minecraft.entity.player.EntityPlayer;
+import nova.core.entity.Entity;
+import nova.core.entity.component.Player;
+import nova.core.network.handler.PacketHandler;
+import nova.core.wrapper.mc.forge.v1_11.network.MCPacket;
+import nova.core.wrapper.mc.forge.v1_11.network.netty.MCNetworkManager;
+import nova.internal.core.Game;
+
+/**
+ * NOVA Packet Structure:
+ *
+ * 1. Packet Type ID
+ * 2. Packet Sub ID
+ * 3. Data
+ * @author Calclavia
+ */
+public class NovaPacket extends PacketAbstract {
+
+ @Override
+ public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
+ buffer.writeBytes(data);
+ }
+
+ @Override
+ public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
+ data = buffer.slice();
+ }
+
+ @Override
+ public void handleClientSide(EntityPlayer player) {
+ handle(player);
+ }
+
+ @Override
+ public void handleServerSide(EntityPlayer player) {
+ handle(player);
+ }
+
+ public void handle(EntityPlayer player) {
+ try {
+ MCNetworkManager network = (MCNetworkManager) Game.network();
+ PacketHandler> packetHandler = network.getPacketType(data.readInt());
+ int subId = data.readInt();
+ MCPacket packet = new MCPacket(data.slice(), ((Entity) Game.natives().toNova(player)).components.get(Player.class));
+ //Set the ID of the packet
+ packet.setID(subId);
+ packetHandler.read(packet);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/discriminator/PacketAbstract.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/discriminator/PacketAbstract.java
new file mode 100644
index 000000000..3a866fc07
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/discriminator/PacketAbstract.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.network.discriminator;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import net.minecraft.entity.player.EntityPlayer;
+import nova.core.wrapper.mc.forge.v1_11.network.netty.MCNetworkManager;
+
+/**
+ * For custom packets extend this Class and register on Mod loading phase
+ *
+ * Without registering a NPE will be thrown as the {@link MCNetworkManager} won't know how to handle it
+ *
+ * To send this packet also look at {@link MCNetworkManager#sendToAll(PacketAbstract)}
+ * And other implementations there.
+ * @author tgame14, Calclavia
+ * @since 26/05/14
+ */
+public abstract class PacketAbstract {
+ public ByteBuf data = Unpooled.buffer();
+ EntityPlayer sender = null;
+
+ /**
+ * Encode the packet data into the ByteBuf stream. Complex data sets may need specific data handlers
+ * @param ctx channel context
+ * @param buffer the buffer to encode into
+ * @see net.minecraftforge.fml.common.network.ByteBufUtils
+ */
+ public abstract void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer);
+
+ /**
+ * Decode the packet data from the ByteBuf stream. Complex data sets may need specific data handlers
+ * @param ctx channel context
+ * @param buffer the buffer to decode from
+ * @see net.minecraftforge.fml.common.network.ByteBufUtils
+ */
+ public abstract void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer);
+
+ /**
+ * Handle a packet on the client side. Note this occurs after decoding has completed.
+ * @param player the player reference
+ */
+ public void handleClientSide(EntityPlayer player) {
+ throw new UnsupportedOperationException("Unsupported operation for Packet: " + getClass().getSimpleName());
+ }
+
+ /**
+ * Handle a packet on the server side. Note this occurs after decoding has completed.
+ * @param player the player reference
+ */
+ public void handleServerSide(EntityPlayer player) {
+ throw new UnsupportedOperationException("Unsupported operation for Packet: " + getClass().getSimpleName());
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/discriminator/PacketPlayerItem.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/discriminator/PacketPlayerItem.java
new file mode 100644
index 000000000..3d4f75858
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/discriminator/PacketPlayerItem.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.network.discriminator;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import nova.core.network.Syncable;
+import nova.core.wrapper.mc.forge.v1_11.network.MCPacket;
+
+/**
+ * A packet handler for players who are currently holding their item.
+ * @author Calclavia
+ */
+//TODO: Move to NOVA Core
+public class PacketPlayerItem extends PacketAbstract {
+ public int slotId;
+
+ public PacketPlayerItem() {
+
+ }
+
+ public PacketPlayerItem(int slotId) {
+ this.slotId = slotId;
+ }
+
+ public PacketPlayerItem(EntityPlayer player) {
+ this(player.inventory.currentItem);
+ }
+
+ @Override
+ public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
+ buffer.writeInt(slotId);
+ buffer.writeBytes(data);
+ }
+
+ @Override
+ public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
+ slotId = buffer.readInt();
+ data = buffer.slice();
+ }
+
+ @Override
+ public void handleClientSide(EntityPlayer player) {
+ ItemStack stack = player.inventory.getStackInSlot(this.slotId);
+
+ if (stack != null && stack.getItem() instanceof Syncable) {
+ MCPacket mcPacket = new MCPacket(data);
+ mcPacket.setID(data.readInt());
+ ((Syncable) stack.getItem()).read(mcPacket);
+ }
+ }
+
+ @Override
+ public void handleServerSide(EntityPlayer player) {
+ ItemStack stack = player.inventory.getStackInSlot(this.slotId);
+
+ if (stack != null && stack.getItem() instanceof Syncable) {
+ MCPacket mcPacket = new MCPacket(data);
+ mcPacket.setID(data.readInt());
+ ((Syncable) stack.getItem()).read(mcPacket);
+ }
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/netty/ChannelHandler.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/netty/ChannelHandler.java
new file mode 100644
index 000000000..d49859e0a
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/netty/ChannelHandler.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.network.netty;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec;
+import nova.core.wrapper.mc.forge.v1_11.network.discriminator.NovaPacket;
+import nova.core.wrapper.mc.forge.v1_11.network.discriminator.PacketAbstract;
+import nova.core.wrapper.mc.forge.v1_11.network.discriminator.PacketPlayerItem;
+
+/**
+ * Handles the channel and discriminators.
+ * @author Calclavia
+ */
+public class ChannelHandler extends FMLIndexedMessageToMessageCodec {
+ public ChannelHandler() {
+ addDiscriminator(0, NovaPacket.class);
+ addDiscriminator(1, PacketPlayerItem.class);
+ }
+
+ @Override
+ public void encodeInto(ChannelHandlerContext ctx, PacketAbstract packet, ByteBuf target) throws Exception {
+ packet.encodeInto(ctx, target);
+ }
+
+ @Override
+ public void decodeInto(ChannelHandlerContext ctx, ByteBuf source, PacketAbstract packet) {
+ packet.decodeInto(ctx, source);
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/netty/MCNetworkManager.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/netty/MCNetworkManager.java
new file mode 100644
index 000000000..05922cc1e
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/netty/MCNetworkManager.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.network.netty;
+
+import io.netty.buffer.Unpooled;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.network.INetHandler;
+import net.minecraft.network.Packet;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.text.TextComponentString;
+import net.minecraft.world.World;
+import net.minecraftforge.fml.common.FMLCommonHandler;
+import net.minecraftforge.fml.common.network.FMLEmbeddedChannel;
+import net.minecraftforge.fml.common.network.FMLOutboundHandler;
+import net.minecraftforge.fml.common.network.NetworkRegistry;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+import nova.core.entity.component.Player;
+import nova.core.network.NetworkManager;
+import nova.core.network.Syncable;
+import nova.core.wrapper.mc.forge.v1_11.launcher.NovaMinecraft;
+import nova.core.wrapper.mc.forge.v1_11.network.MCPacket;
+import nova.core.wrapper.mc.forge.v1_11.network.discriminator.NovaPacket;
+import nova.core.wrapper.mc.forge.v1_11.network.discriminator.PacketAbstract;
+import nova.core.wrapper.mc.forge.v1_11.wrapper.entity.backward.BWEntity;
+import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
+
+import java.util.EnumMap;
+
+/**
+ * The implementation of NetworkManager that will be injected.
+ * @author Calclavia
+ * @since 26/05/14
+ */
+public class MCNetworkManager extends NetworkManager {
+ public final String channel = NovaMinecraft.id;
+ public final EnumMap channelEnumMap = NetworkRegistry.INSTANCE.newChannel(channel, new ChannelHandler(), new MCPacketHandler());
+
+ public Packet> toMCPacket(PacketAbstract packet) {
+ return channelEnumMap.get(FMLCommonHandler.instance().getEffectiveSide()).generatePacketFrom(packet);
+ }
+
+ @Override
+ public nova.core.network.Packet newPacket() {
+ return new MCPacket(Unpooled.buffer());
+ }
+
+ @Override
+ public void sendPacket(nova.core.network.Packet packet) {
+ //Wrap the packet in NOVA's discriminator
+ PacketAbstract discriminator = new NovaPacket();
+ //Write packet
+ discriminator.data.writeBytes(((MCPacket) packet).buf);
+
+ if (isServer()) {
+ sendToAll(discriminator);
+ } else {
+ sendToServer(discriminator);
+ }
+ }
+
+ public PacketAbstract writePacket(int id, Syncable sender) {
+ PacketAbstract discriminator = new NovaPacket();
+ nova.core.network.Packet packet = newPacket();
+ packet.setID(id);
+
+ //Write packet
+ writePacket(sender, packet);
+ discriminator.data.writeBytes(((MCPacket) packet).buf);
+ return discriminator;
+ }
+
+ @Override
+ public void sendChat(Player player, String message) {
+ if (player instanceof BWEntity.MCPlayer) {
+ ((BWEntity.MCPlayer) player).entity.sendMessage(new TextComponentString(message));
+ }
+ }
+
+ @Override
+ public boolean isServer() {
+ return FMLCommonHandler.instance().getEffectiveSide().isServer();
+ }
+
+ /**
+ * @param packet the packet to send to the player
+ * @param player the player MP object
+ */
+ public void sendToPlayer(PacketAbstract packet, EntityPlayerMP player) {
+ this.channelEnumMap.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER);
+ this.channelEnumMap.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(player);
+ this.channelEnumMap.get(Side.SERVER).writeAndFlush(packet);
+ }
+
+ /**
+ * @param packet the packet to send to the players in the dimension
+ * @param dimId the dimension id to send to.
+ */
+ public void sendToAllInDimension(PacketAbstract packet, int dimId) {
+ this.channelEnumMap.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.DIMENSION);
+ this.channelEnumMap.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(dimId);
+ this.channelEnumMap.get(Side.SERVER).writeAndFlush(packet);
+ }
+
+ public void sendToAllInDimension(PacketAbstract packet, World world) {
+ sendToAllInDimension(packet, world.provider.getDimension());
+ }
+
+ /**
+ * sends to all clients connected to the server
+ * @param packet the packet to send.
+ */
+ public void sendToAll(PacketAbstract packet) {
+ this.channelEnumMap.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL);
+ this.channelEnumMap.get(Side.SERVER).writeAndFlush(packet);
+ }
+
+ public void sendToAllAround(PacketAbstract message, NetworkRegistry.TargetPoint point) {
+ this.channelEnumMap.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT);
+ this.channelEnumMap.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point);
+ this.channelEnumMap.get(Side.SERVER).writeAndFlush(message);
+ }
+
+ public void sendToAllAround(PacketAbstract message, World world, Vector3D point, double range) {
+ sendToAllAround(message, world, point.getX(), point.getY(), point.getZ(), range);
+ }
+
+ public void sendToAllAround(PacketAbstract message, TileEntity tile) {
+ sendToAllAround(message, tile, 64);
+ }
+
+ public void sendToAllAround(PacketAbstract message, TileEntity tile, double range) {
+ sendToAllAround(message, tile.getWorld(), tile.getPos().getX(), tile.getPos().getY(), tile.getPos().getZ(), range);
+ }
+
+ public void sendToAllAround(PacketAbstract message, World world, double x, double y, double z, double range) {
+ sendToAllAround(message, new NetworkRegistry.TargetPoint(world.provider.getDimension(), x, y, z, range));
+ }
+
+ @SideOnly(Side.CLIENT)
+ public void sendToServer(PacketAbstract packet) {
+ this.channelEnumMap.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER);
+ this.channelEnumMap.get(Side.CLIENT).writeAndFlush(packet);
+ }
+}
+
+
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/netty/MCPacketHandler.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/netty/MCPacketHandler.java
new file mode 100644
index 000000000..994303ffe
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/network/netty/MCPacketHandler.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.network.netty;
+
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import net.minecraft.network.INetHandler;
+import net.minecraft.network.NetHandlerPlayServer;
+import net.minecraftforge.fml.client.FMLClientHandler;
+import net.minecraftforge.fml.common.FMLCommonHandler;
+import net.minecraftforge.fml.common.network.NetworkRegistry;
+import nova.core.wrapper.mc.forge.v1_11.launcher.NovaMinecraft;
+import nova.core.wrapper.mc.forge.v1_11.network.discriminator.PacketAbstract;
+
+/**
+ * @author tgame14
+ * @since 31/05/14
+ */
+@ChannelHandler.Sharable
+public class MCPacketHandler extends SimpleChannelInboundHandler {
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, PacketAbstract packet) throws Exception {
+ INetHandler netHandler = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get();
+
+ switch (FMLCommonHandler.instance().getEffectiveSide()) {
+ case CLIENT:
+ FMLClientHandler.instance().getClient().addScheduledTask(() -> packet.handleClientSide(NovaMinecraft.proxy.getClientPlayer()));
+ break;
+ case SERVER:
+ FMLCommonHandler.instance().getMinecraftServerInstance().addScheduledTask(() -> packet.handleServerSide(((NetHandlerPlayServer) netHandler).playerEntity));
+ break;
+ default:
+ break;
+ }
+
+ }
+
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/MCCraftingGrid.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/MCCraftingGrid.java
new file mode 100644
index 000000000..0eafaf8b9
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/MCCraftingGrid.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.recipes;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.Container;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.InventoryCrafting;
+import net.minecraft.inventory.Slot;
+import net.minecraft.inventory.SlotCrafting;
+import net.minecraft.item.ItemStack;
+import nova.core.entity.component.Player;
+import nova.core.recipes.crafting.CraftingGrid;
+import nova.core.wrapper.mc.forge.v1_11.util.ReflectionUtil;
+import nova.core.wrapper.mc.forge.v1_11.util.WrapUtility;
+import nova.core.wrapper.mc.forge.v1_11.wrapper.item.ItemConverter;
+import nova.internal.core.Game;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Stan Hebben
+ */
+public class MCCraftingGrid implements CraftingGrid {
+ private static final ThreadLocal cache = new ThreadLocal();
+ private static final ThreadLocal cache2 = new ThreadLocal();
+ private final IInventory inventory;
+ private final Optional player;
+ private final EntityPlayer playerOrig;
+ private int width;
+ private int height;
+ private nova.core.item.Item[] stacks;
+ private ItemStack[] original;
+ private int numberOfStacks;
+
+ private MCCraftingGrid(InventoryCrafting inventory) {
+ this.inventory = inventory;
+ width = height = (int) Math.sqrt(inventory.getSizeInventory());
+ stacks = new nova.core.item.Item[width * height];
+ original = new ItemStack[stacks.length];
+ numberOfStacks = 0;
+ update();
+
+ Container container = ReflectionUtil.getCraftingContainer(inventory);
+ if (container != null) {
+ List slots = container.inventorySlots;
+ if (!slots.isEmpty() && slots.get(0) instanceof SlotCrafting) {
+ SlotCrafting slotCrafting = (SlotCrafting) slots.get(0);
+ playerOrig = ReflectionUtil.getCraftingSlotPlayer(slotCrafting);
+ player = WrapUtility.getNovaPlayer(playerOrig);
+ } else {
+ playerOrig = null;
+ player = null;
+ }
+ } else {
+ playerOrig = null;
+ player = null;
+ }
+ }
+
+ public MCCraftingGrid(IInventory inventory, EntityPlayer player) {
+ this.inventory = inventory;
+ width = height = (int) Math.sqrt(inventory.getSizeInventory());
+ stacks = new nova.core.item.Item[width * height];
+ original = new ItemStack[stacks.length];
+ numberOfStacks = 0;
+ update();
+
+ playerOrig = player;
+ this.player = WrapUtility.getNovaPlayer(player);
+ }
+
+ public static MCCraftingGrid get(InventoryCrafting inventory) {
+ if (cache.get() == null || cache.get().inventory != inventory) {
+ MCCraftingGrid result = new MCCraftingGrid(inventory);
+ cache.set(result);
+ return result;
+ } else {
+ MCCraftingGrid result = cache.get();
+ result.update();
+ return result;
+ }
+ }
+
+ public static MCCraftingGrid get(IInventory inventory, EntityPlayer player) {
+ if (cache2.get() == null || cache2.get().inventory != inventory || cache2.get().playerOrig != player) {
+ MCCraftingGrid result = new MCCraftingGrid(inventory, player);
+ cache2.set(result);
+ return result;
+ } else {
+ MCCraftingGrid result = cache2.get();
+ result.update();
+ return result;
+ }
+ }
+
+ private void update() {
+ if (inventory.getSizeInventory() != original.length) {
+ width = height = (int) Math.sqrt(inventory.getSizeInventory());
+ stacks = new nova.core.item.Item[inventory.getSizeInventory()];
+ original = new ItemStack[stacks.length];
+ numberOfStacks = 0;
+ }
+
+ for (int i = 0; i < inventory.getSizeInventory(); i++) {
+ if (changed(i)) {
+ //System.out.println("Slot " + i + " changed");
+ original[i] = inventory.getStackInSlot(i);
+ if (inventory.getStackInSlot(i) != null) {
+ if (stacks[i] == null) {
+ numberOfStacks++;
+ }
+
+ stacks[i] = Game.natives().toNova(original[i]);
+ } else {
+ if (stacks[i] != null) {
+ numberOfStacks--;
+ }
+
+ stacks[i] = null;
+ }
+ }
+ }
+ //System.out.println("Num stack count: " + numberOfStacks);
+ }
+
+ @Override
+ public Optional getPlayer() {
+ return player;
+ }
+
+ @Override
+ public int size() {
+ return width * height;
+ }
+
+ @Override
+ public int getWidth() {
+ return width;
+ }
+
+ @Override
+ public int getHeight() {
+ return height;
+ }
+
+ @Override
+ public int countFilledStacks() {
+ return numberOfStacks;
+ }
+
+ @Override
+ public Optional getStack(int i) {
+ return Optional.ofNullable(stacks[i]);
+ }
+
+ @Override
+ public Optional getStack(int x, int y) {
+ return Optional.ofNullable(stacks[y * width + x]);
+ }
+
+ @Override
+ public boolean setStack(int x, int y, Optional stack) {
+ //System.out.println("SetStack(" + x + ", " + y + ") " + stack);
+
+ int ix = y * width + x;
+ if (stack.isPresent()) {
+ if (!stack.get().equals(stacks[ix])) {
+ inventory.setInventorySlotContents(ix, Game.natives().toNative(stack.get()));
+
+ if (stacks[ix] == null) {
+ numberOfStacks++;
+ }
+
+ stacks[ix] = stack.get();
+ }
+ } else {
+ numberOfStacks--;
+ inventory.setInventorySlotContents(ix, null);
+ stacks[ix] = null;
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean setStack(int i, Optional stack) {
+ //System.out.println("SetStack(" + i + ") " + stack);
+
+ if (stack.isPresent()) {
+ if (stacks[i] == null) {
+ numberOfStacks++;
+ }
+
+ inventory.setInventorySlotContents(i, Game.natives().toNative(stack.get()));
+ stacks[i] = stack.get();
+ } else {
+ if (stacks[i] == null) {
+ return true;
+ }
+
+ numberOfStacks--;
+ inventory.setInventorySlotContents(i, null);
+ stacks[i] = null;
+ }
+
+ return true;
+ }
+
+ @Override
+ public void giveBack(nova.core.item.Item itemStack) {
+ playerOrig.inventory.addItemStackToInventory(ItemConverter.instance().toNative(itemStack));
+ }
+
+ @Override
+ public String getTopology() {
+ return CraftingGrid.topologySquare;
+ }
+
+ @Override
+ public String getType() {
+ return CraftingGrid.typeCrafting;
+ }
+
+ private boolean changed(int i) {
+ if (original[i] != inventory.getStackInSlot(i)) {
+ return true;
+ }
+
+ if (original[i] != null && stacks[i].count() != original[i].getCount()) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/MCCraftingRecipe.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/MCCraftingRecipe.java
new file mode 100644
index 000000000..8b3a53453
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/MCCraftingRecipe.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.recipes;
+
+import net.minecraft.item.crafting.IRecipe;
+import nova.core.item.Item;
+import nova.core.recipes.crafting.CraftingGrid;
+import nova.core.recipes.crafting.CraftingRecipe;
+import nova.internal.core.Game;
+
+import java.util.Optional;
+
+/**
+ * @author Stan Hebben
+ */
+public class MCCraftingRecipe implements CraftingRecipe {
+ private final IRecipe recipe;
+
+ public MCCraftingRecipe(IRecipe recipe) {
+ this.recipe = recipe;
+ }
+
+ @Override
+ public boolean matches(CraftingGrid craftingGrid) {
+ // TODO: supply world somehow?
+ return recipe.matches(new NovaCraftingGrid(craftingGrid), null);
+ }
+
+ @Override
+ public Optional- getCraftingResult(CraftingGrid craftingGrid) {
+ return Game.natives().toNova(recipe.getCraftingResult(new NovaCraftingGrid(craftingGrid)));
+ }
+
+ @Override
+ public void consumeItems(CraftingGrid craftingGrid) {
+ // not supported
+ }
+
+ @Override
+ public Optional
- getNominalOutput() {
+ return Game.natives().toNova(recipe.getRecipeOutput());
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/MinecraftItemIngredient.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/MinecraftItemIngredient.java
new file mode 100644
index 000000000..f430a58f0
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/MinecraftItemIngredient.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.recipes;
+
+import nova.core.item.Item;
+import nova.core.recipes.crafting.SpecificItemIngredient;
+import nova.internal.core.Game;
+
+/**
+ * @author Stan Hebben
+ */
+public class MinecraftItemIngredient extends SpecificItemIngredient {
+ public MinecraftItemIngredient(net.minecraft.item.ItemStack itemStack) {
+ super(((Item) Game.natives().toNova(itemStack)).getID());
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/MinecraftRecipeRegistry.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/MinecraftRecipeRegistry.java
new file mode 100644
index 000000000..af3f96b4a
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/MinecraftRecipeRegistry.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.recipes;
+
+import net.minecraft.item.crafting.CraftingManager;
+import net.minecraft.item.crafting.IRecipe;
+import net.minecraftforge.oredict.RecipeSorter;
+import net.minecraftforge.oredict.RecipeSorter.Category;
+import nova.core.event.RecipeEvent;
+import nova.core.recipes.RecipeManager;
+import nova.core.recipes.crafting.CraftingRecipe;
+import nova.core.wrapper.mc.forge.v1_11.util.ReflectionUtil;
+import nova.internal.core.Game;
+
+import java.util.AbstractList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+/**
+ * Created by Stan on 1/02/2015.
+ */
+public class MinecraftRecipeRegistry {
+ public static final MinecraftRecipeRegistry instance = new MinecraftRecipeRegistry();
+
+ private final Map forwardWrappers = new HashMap<>();
+ private final Map backwardWrappers = new HashMap<>();
+
+ private MinecraftRecipeRegistry() {
+ }
+
+ public void registerRecipes() {
+ long startTime = System.currentTimeMillis();
+
+ RecipeManager recipeManager = Game.recipes();
+
+ List recipes = CraftingManager.getInstance().getRecipeList();
+ for (IRecipe recipe : recipes) {
+ CraftingRecipe converted = convert(recipe);
+ if (converted != null) {
+ recipeManager.addRecipe(converted);
+ backwardWrappers.put(recipe, converted);
+ forwardWrappers.put(converted, recipe);
+ }
+ }
+
+ ReflectionUtil.setCraftingRecipeList(new RecipeListWrapper(recipes));
+
+ System.out.println("Initialized recipes in " + (System.currentTimeMillis() - startTime) + " ms");
+
+ RecipeSorter.register("nova:shaped", ShapedRecipeBasic.class, Category.SHAPED, "before:forge:shapedore");
+ RecipeSorter.register("nova:shaped.oredict", ShapedRecipeOre.class, Category.SHAPED, "after:nova:shaped after:minecraft:shaped before:minecraft:shapeless");
+
+ RecipeSorter.register("nova:shapeless", ShapelessRecipeBasic.class, Category.SHAPELESS, "after:minecraft:shapeless before:forge:shapelessore");
+ RecipeSorter.register("nova:shapeless.oredict", ShapelessRecipeOre.class, Category.SHAPELESS, "after:nova:shapeless after:minecraft:shapeless");
+
+ RecipeSorter.register("nova:unknown", NovaCraftingRecipe.class, Category.UNKNOWN, "");
+
+ recipeManager.whenRecipeAdded(CraftingRecipe.class, this::onNOVARecipeAdded);
+ recipeManager.whenRecipeRemoved(CraftingRecipe.class, this::onNOVARecipeRemoved);
+ }
+
+ private CraftingRecipe convert(IRecipe recipe) {
+ return RecipeConverter.toNova(recipe);
+ }
+
+ private IRecipe convert(CraftingRecipe recipe) {
+ return RecipeConverter.toMinecraft(recipe);
+ }
+
+ private void onNOVARecipeAdded(RecipeEvent.Add e) {
+ CraftingRecipe recipe = e.recipe;
+ if (forwardWrappers.containsKey(recipe)) {
+ return;
+ }
+
+ IRecipe minecraftRecipe = convert(recipe);
+
+ backwardWrappers.put(minecraftRecipe, recipe);
+ forwardWrappers.put(recipe, minecraftRecipe);
+
+ CraftingManager.getInstance().getRecipeList().add(minecraftRecipe);
+ }
+
+ private void onNOVARecipeRemoved(RecipeEvent.Remove e) {
+ IRecipe minecraftRecipe = forwardWrappers.get(e.recipe);
+
+ forwardWrappers.remove(e.recipe);
+ backwardWrappers.remove(minecraftRecipe);
+
+ CraftingManager.getInstance().getRecipeList().remove(minecraftRecipe);
+ }
+
+ private void onMinecraftRecipeAdded(IRecipe recipe) {
+ if (backwardWrappers.containsKey(recipe)) {
+ return;
+ }
+
+ CraftingRecipe novaRecipe = convert(recipe);
+
+ backwardWrappers.put(recipe, novaRecipe);
+ forwardWrappers.put(novaRecipe, recipe);
+
+ Game.recipes().addRecipe(novaRecipe);
+ }
+
+ private void onMinecraftRecipeRemoved(IRecipe recipe) {
+ CraftingRecipe novaRecipe = backwardWrappers.get(recipe);
+
+ forwardWrappers.remove(novaRecipe);
+ backwardWrappers.remove(recipe);
+
+ Game.recipes().removeRecipe(novaRecipe);
+ }
+
+ private class RecipeListWrapper extends AbstractList {
+ private final List original;
+
+ public RecipeListWrapper(List original) {
+ this.original = original;
+ }
+
+ @Override
+ public int size() {
+ return original.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return original.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return original.contains(o);
+ }
+
+ @Override
+ public Iterator iterator() {
+ return original.iterator();
+ }
+
+ @Override
+ public void forEach(Consumer super IRecipe> action) {
+ original.forEach(action);
+ }
+
+ @Override
+ public Object[] toArray() {
+ return original.toArray();
+ }
+
+ @Override
+ public T[] toArray(T[] a) {
+ return original.toArray(a);
+ }
+
+ @Override
+ public boolean add(IRecipe iRecipe) {
+ boolean result = original.add(iRecipe);
+ if (result && !backwardWrappers.containsKey(iRecipe)) {
+ onMinecraftRecipeAdded(iRecipe);
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ if (!backwardWrappers.containsKey(o)) {
+ return false;
+ }
+
+ boolean result = original.remove(o);
+ if (result) {
+ onMinecraftRecipeRemoved((IRecipe) o);
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean containsAll(Collection> c) {
+ return original.containsAll(c);
+ }
+
+ @Override
+ public boolean addAll(Collection extends IRecipe> c) {
+ boolean result = false;
+ for (IRecipe recipe : c) {
+ result |= add(recipe);
+ }
+ return result;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection extends IRecipe> c) {
+ for (IRecipe recipe : c) {
+ add(index, recipe);
+ index++;
+ }
+
+ return !c.isEmpty();
+ }
+
+ @Override
+ public boolean removeAll(Collection> c) {
+ boolean result = false;
+ for (Object o : c) {
+ result |= c.remove(o);
+ }
+ return result;
+ }
+
+ @Override
+ public boolean retainAll(Collection> c) {
+ return false;
+ }
+
+ @Override
+ public void sort(Comparator super IRecipe> c) {
+ original.sort(c);
+ }
+
+ @Override
+ public void clear() {
+ // one would have to be a mad scientist to use this operation... but ok
+
+ for (IRecipe recipe : original) {
+ onMinecraftRecipeRemoved(recipe);
+ }
+
+ original.clear();
+ }
+
+ @Override
+ public IRecipe get(int index) {
+ return original.get(index);
+ }
+
+ @Override
+ public IRecipe set(int index, IRecipe element) {
+ IRecipe current = original.get(index);
+ onMinecraftRecipeRemoved(current);
+
+ original.set(index, element);
+ onMinecraftRecipeAdded(element);
+
+ return current;
+ }
+
+ @Override
+ public void add(int index, IRecipe element) {
+ original.add(index, element);
+ onMinecraftRecipeAdded(element);
+ }
+
+ @Override
+ public IRecipe remove(int index) {
+ IRecipe current = original.remove(index);
+ onMinecraftRecipeRemoved(current);
+ return current;
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ return original.indexOf(o);
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ return original.lastIndexOf(o);
+ }
+
+ @Override
+ public ListIterator listIterator() {
+ return original.listIterator();
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ return original.listIterator(index);
+ }
+
+ @Override
+ public List subList(int fromIndex, int toIndex) {
+ return new RecipeListWrapper(original.subList(fromIndex, toIndex));
+ }
+
+ @Override
+ public Spliterator spliterator() {
+ return original.spliterator();
+ }
+
+ @Override
+ public Stream stream() {
+ return original.stream();
+ }
+
+ @Override
+ public Stream parallelStream() {
+ return original.parallelStream();
+ }
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/NovaCraftingGrid.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/NovaCraftingGrid.java
new file mode 100644
index 000000000..29d385bee
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/NovaCraftingGrid.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.recipes;
+
+import net.minecraft.inventory.InventoryCrafting;
+import nova.core.recipes.crafting.CraftingGrid;
+
+public class NovaCraftingGrid extends InventoryCrafting {
+ private final CraftingGrid craftingGrid;
+
+ public NovaCraftingGrid(CraftingGrid craftingGrid) {
+ super(new NovaCraftingGridContainer(craftingGrid), craftingGrid.getWidth(), craftingGrid.getHeight());
+ this.craftingGrid = craftingGrid;
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/NovaCraftingGridContainer.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/NovaCraftingGridContainer.java
new file mode 100644
index 000000000..2059423a5
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/NovaCraftingGridContainer.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.recipes;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.Container;
+import nova.core.recipes.crafting.CraftingGrid;
+
+/**
+ * TODO: complete this class. without it, modded recipes will not work when crafted from NOVA mods.
+ * @author Stan Hebben
+ */
+public class NovaCraftingGridContainer extends Container {
+ private final CraftingGrid craftingGrid;
+
+ public NovaCraftingGridContainer(CraftingGrid craftingGrid) {
+ this.craftingGrid = craftingGrid;
+ }
+
+ @Override
+ public boolean canInteractWith(EntityPlayer entityPlayer) {
+ return true;
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/NovaCraftingRecipe.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/NovaCraftingRecipe.java
new file mode 100644
index 000000000..c04a4c622
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/NovaCraftingRecipe.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.recipes;
+
+import net.minecraft.inventory.InventoryCrafting;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.crafting.IRecipe;
+import net.minecraft.util.NonNullList;
+import net.minecraft.world.World;
+import nova.core.item.Item;
+import nova.core.recipes.crafting.CraftingRecipe;
+import nova.internal.core.Game;
+
+import java.util.Optional;
+
+public class NovaCraftingRecipe implements IRecipe {
+ private final CraftingRecipe recipe;
+
+ public NovaCraftingRecipe(CraftingRecipe recipe) {
+ this.recipe = recipe;
+ }
+
+ @Override
+ public boolean matches(InventoryCrafting inventoryCrafting, World world) {
+ return recipe.matches(MCCraftingGrid.get(inventoryCrafting));
+ }
+
+ @Override
+ public ItemStack getCraftingResult(InventoryCrafting inventoryCrafting) {
+ Optional
- craftingResult = recipe.getCraftingResult(MCCraftingGrid.get(inventoryCrafting));
+ if (craftingResult.isPresent()) {
+ return Game.natives().toNative(craftingResult.get());
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public int getRecipeSize() {
+ return 1;
+ }
+
+ @Override
+ public ItemStack getRecipeOutput() {
+ Optional
- nominalOutput = recipe.getNominalOutput();
+ if (nominalOutput.isPresent()) {
+ return Game.natives().toNative(nominalOutput.get());
+ }
+ return null;
+ }
+
+ @Override
+ public NonNullList getRemainingItems(InventoryCrafting inv) {
+ return NonNullList.create();
+ }
+}
diff --git a/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/RecipeConverter.java b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/RecipeConverter.java
new file mode 100644
index 000000000..eb711986f
--- /dev/null
+++ b/minecraft/1.11/src/main/java/nova/core/wrapper/mc/forge/v1_11/recipes/RecipeConverter.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2015 NOVA, All rights reserved.
+ * This library is free software, licensed under GNU Lesser General Public License version 3
+ *
+ * This file is part of NOVA.
+ *
+ * NOVA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NOVA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NOVA. If not, see .
+ */
+
+package nova.core.wrapper.mc.forge.v1_11.recipes;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.crafting.IRecipe;
+import net.minecraft.item.crafting.ShapedRecipes;
+import net.minecraft.item.crafting.ShapelessRecipes;
+import net.minecraftforge.oredict.ShapedOreRecipe;
+import net.minecraftforge.oredict.ShapelessOreRecipe;
+import nova.core.item.Item;
+import nova.core.recipes.crafting.CraftingRecipe;
+import nova.core.recipes.crafting.ItemIngredient;
+import nova.core.recipes.crafting.OreItemIngredient;
+import nova.core.recipes.crafting.ShapedCraftingRecipe;
+import nova.core.recipes.crafting.ShapelessCraftingRecipe;
+import nova.core.recipes.crafting.SpecificItemIngredient;
+import nova.core.wrapper.mc.forge.v1_11.util.ReflectionUtil;
+import nova.internal.core.Game;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Wraps Minecraft crafting recipes to NOVA crafting recipes and vice versa.
+ *
+ * Although a naive implementation could wrap NOVA recipes into its own recipe class and forward that, mods like NEI
+ * won't be able to handle those recipes. Hence we wrap them into ShapedRecipes / ShapelessRecipes / ShapedOreRecipes and ShapelessOreRecipes
+ * as much as possible. Only when that is not possible (a rare case, in practice) the generic wrapper is used.
+ *
+ * The reverse is also done, such that mods listening to NOVA ShapedCraftingRecipes and ShapelessCraftingRecipes would be
+ * given the proper information and be informed of their registration, if desired.
+ * @author Stan Hebben
+ */
+public class RecipeConverter {
+ public static final int TYPE_ADVANCED = 0;
+ public static final int TYPE_ORE = 1;
+ public static final int TYPE_BASIC = 2;
+
+ private RecipeConverter() {
+ }
+
+ private static int getIngredientType(ItemIngredient ingredient) {
+ if (ingredient instanceof SpecificItemIngredient) {
+ return TYPE_BASIC;
+ } else if (ingredient instanceof OreItemIngredient) {
+ return TYPE_ORE;
+ } else {
+ return TYPE_ADVANCED;
+ }
+ }
+
+ private static Object getInternal(ItemIngredient ingredient) {
+ if (ingredient instanceof SpecificItemIngredient) {
+ return wrapSpecific((SpecificItemIngredient) ingredient);
+ } else if (ingredient instanceof OreItemIngredient) {
+ return ((OreItemIngredient) ingredient).getName();
+ }
+
+ return null;
+ }
+
+ private static ItemIngredient getIngredient(Object ingredient) {
+ if (ingredient == null) {
+ return null;
+ } else if (ingredient instanceof ItemStack) {
+ return ((ItemStack) ingredient).isEmpty() ? null : ItemIngredient.forItem(net.minecraft.item.Item.REGISTRY.getNameForObject(((ItemStack) ingredient).getItem()).toString());
+ } else if (ingredient instanceof String) {
+ return ItemIngredient.forDictionary((String) ingredient);
+ } else if (ingredient instanceof List) {
+ @SuppressWarnings("unchecked")
+ String oreDictEntry = findOreDictEntryFor((List) ingredient);
+ if (oreDictEntry == null) {
+ return null;
+ }
+
+ return new OreItemIngredient(oreDictEntry);
+ } else {
+ return null;
+ }
+ }
+
+ private static String findOreDictEntryFor(List ingredient) {
+ for (String key : net.minecraftforge.oredict.OreDictionary.getOreNames()) {
+ if (net.minecraftforge.oredict.OreDictionary.getOres(key).equals(ingredient)) {
+ return key;
+ }
+ }
+
+ return null;
+ }
+
+ private static ItemStack wrapSpecific(SpecificItemIngredient ingredient) {
+ for (Item item : ingredient.getExampleItems().get()) {
+ return Game.natives().toNative(item.getFactory().build());
+ }
+
+ throw new AssertionError("this can't be!");
+ }
+
+ private static int getRecipeType(ItemIngredient[] ingredients) {
+ int type = TYPE_BASIC;
+ for (ItemIngredient ingredient : ingredients) {
+ type = Math.min(type, getIngredientType(ingredient));
+ }
+ return type;
+ }
+
+ public static IRecipe toMinecraft(CraftingRecipe recipe) {
+ if (recipe instanceof ShapedCraftingRecipe) {
+ return convert((ShapedCraftingRecipe) recipe);
+ } else if (recipe instanceof ShapelessCraftingRecipe) {
+ return convert((ShapelessCraftingRecipe) recipe);
+ } else {
+ return new NovaCraftingRecipe(recipe);
+ }
+ }
+
+ public static IRecipe convert(ShapelessCraftingRecipe recipe) {
+ ItemIngredient[] ingredients = recipe.getIngredients();
+ int type = getRecipeType(ingredients);
+
+ switch (type) {
+ case TYPE_BASIC: {
+ ItemStack[] items = new ItemStack[ingredients.length];
+ for (int i = 0; i < ingredients.length; i++) {
+ items[i] = wrapSpecific((SpecificItemIngredient) ingredients[i]);
+ }
+ return new ShapelessRecipeBasic(items, recipe);
+ }
+ case TYPE_ORE: {
+ Object[] items = new Object[ingredients.length];
+ for (int i = 0; i < ingredients.length; i++) {
+ items[i] = getInternal(ingredients[i]);
+ }
+ return new ShapelessRecipeOre(items, recipe);
+ }
+ default:
+ return new NovaCraftingRecipe(recipe);
+ }
+ }
+
+ public static IRecipe convert(ShapedCraftingRecipe recipe) {
+ ItemIngredient[] ingredients = recipe.getIngredients();
+ int[] posx = recipe.getIngredientsX();
+ int[] posy = recipe.getIngredientsY();
+
+ // determine recipe type
+ int type = getRecipeType(ingredients);
+
+ // construct recipe
+ switch (type) {
+ case TYPE_BASIC: {
+ ItemStack[] basicIngredients = new ItemStack[recipe.getHeight() * recipe.getWidth()];
+ for (int i = 0; i < ingredients.length; i++) {
+ basicIngredients[posx[i] + posy[i] * recipe.getWidth()] = wrapSpecific((SpecificItemIngredient) ingredients[i]);
+ }
+
+ return new ShapedRecipeBasic(basicIngredients, recipe);
+ }
+ case TYPE_ORE: {
+ Object[] converted = new Object[recipe.getHeight() * recipe.getWidth()];
+ for (int i = 0; i < ingredients.length; i++) {
+ converted[posx[i] + posy[i] * recipe.getWidth()] = getInternal(ingredients[i]);
+ }
+
+ // arguments contents:
+ // 1) recipe patterns
+ // 2) characters + ingredients
+
+ int counter = 0;
+ String[] parts = new String[recipe.getHeight()];
+ ArrayList