diff --git a/minecraft/1.11.2/build.gradle b/minecraft/1.11.2/build.gradle index f1c424824..7501b09ce 100644 --- a/minecraft/1.11.2/build.gradle +++ b/minecraft/1.11.2/build.gradle @@ -56,7 +56,7 @@ task fatJar(type: Jar) { attributes 'FMLAT': 'nova_at.cfg' } classifier = 'fat' - + doLast { reobfFatJar.execute() } @@ -107,7 +107,7 @@ apply plugin: 'net.minecraftforge.gradle.forge' minecraft { version = property("minecraft.version") + "-" + property("forge.version") - mappings = 'snapshot_20170227' + mappings = 'snapshot_20170313' runDir = "run" } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/util/WrapperEvent.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/util/WrapperEvent.java index 0deef379b..27400a5f9 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/util/WrapperEvent.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/util/WrapperEvent.java @@ -29,12 +29,12 @@ import nova.core.item.Item; import nova.core.util.Direction; import nova.core.world.World; -import nova.core.wrapper.mc.forge.v1_11_2.wrapper.capability.forward.FWCapabilityProvider; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.backward.BWBlock; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.forward.FWTile; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.entity.backward.BWEntity; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.entity.forward.FWEntity; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.backward.BWItem; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.forward.FWItemCapabilityProvider; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import java.util.Optional; @@ -116,9 +116,9 @@ public BWEntityCreate(BWEntity novaEntity, net.minecraft.entity.Entity mcEntity) public static class FWItemInitCapabilities extends Event { public final Item novaItem; - public final FWCapabilityProvider capabilityProvider; + public final FWItemCapabilityProvider capabilityProvider; - public FWItemInitCapabilities(Item novaItem, FWCapabilityProvider capabilityProvider) { + public FWItemInitCapabilities(Item novaItem, FWItemCapabilityProvider capabilityProvider) { this.novaItem = novaItem; this.capabilityProvider = capabilityProvider; } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWTile.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWTile.java index 3ac182b4b..ce50bc993 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWTile.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWTile.java @@ -35,32 +35,36 @@ import nova.core.network.Syncable; import nova.core.retention.Data; import nova.core.retention.Storable; +import nova.core.util.Direction; import nova.core.util.EnumSelector; import nova.core.wrapper.mc.forge.v1_11_2.network.netty.MCNetworkManager; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.capability.forward.NovaCapabilityProvider; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import java.io.IOException; +import java.util.EnumMap; import java.util.HashMap; import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; /** * A Minecraft TileEntity to Nova block wrapper * @author Calclavia */ -public class FWTile extends TileEntity { +public class FWTile extends TileEntity implements NovaCapabilityProvider { - private final Map, Object> capabilities = new HashMap<>(); - private final Map, Object>> sidedCapabilities = new HashMap<>(); + private final EnumMap, Object>> capabilities = new EnumMap<>(Direction.class); { + for (Direction facing : Direction.values()) + capabilities.put(facing, new ConcurrentHashMap<>()); + } protected String blockID; protected Block block; protected Data cacheData = null; - public FWTile() { - for (EnumFacing facing : EnumFacing.VALUES) - sidedCapabilities.put(facing, new HashMap<>()); - } + public FWTile() {} public FWTile(String blockID) { this.blockID = blockID; @@ -127,36 +131,48 @@ public void readFromNBT(NBTTagCompound nbt) { cacheData = Game.natives().toNova(nbt.getCompoundTag("nova")); } - public T addCapability(Capability capability, T capabilityInstance, EnumSelector facing) { - if (facing == null || facing.allowsAll()) { - if (capabilities.containsKey(capability)) + @Override + public boolean hasCapabilities() { + return capabilities.values().parallelStream().map(map -> map.keySet().parallelStream()).count() > 0; + } + + @Override + public T addCapability(Capability capability, T capabilityInstance, EnumSelector facing) { + if (facing.allowsAll()) { + if (capabilities.get(Direction.UNKNOWN).containsKey(capability)) throw new IllegalArgumentException("Already has capability " + capabilityInstance.getClass()); - capabilities.put(capability, capabilityInstance); + capabilities.get(Direction.UNKNOWN).put(capability, capabilityInstance); } else { facing.forEach(enumFacing -> { - Map, Object> capabilities = sidedCapabilities.get(enumFacing); + Map, Object> caps = capabilities.get(enumFacing); - if (capabilities.containsKey(capability)) + if (caps.containsKey(capability)) throw new IllegalArgumentException("Already has capability " + capabilityInstance.getClass()); - capabilities.put(capability, capabilityInstance); + caps.put(capability, capabilityInstance); }); } return capabilityInstance; } @Override - public boolean hasCapability(Capability capability, EnumFacing facing) { - return (facing != null ? sidedCapabilities.get(facing).containsValue(capability) : capabilities.containsValue(capability)) - || super.hasCapability(capability, facing); + public boolean hasCapability(Capability capability, Direction direction) { + return Optional.of(direction) + .filter(d -> d != Direction.UNKNOWN) + .map(capabilities::get) + .map(caps -> caps.containsValue(capability)) + .orElseGet(() -> capabilities.get(Direction.UNKNOWN).containsValue(capability)); } @Override - public T getCapability(Capability capability, EnumFacing facing) { - if (!hasCapability(capability, facing)) return null; - T capabilityInstance = (T) (facing != null ? sidedCapabilities.get(facing).get(capability) : capabilities.get(capability)); - return capabilityInstance != null ? capabilityInstance : super.getCapability(capability, facing); + @SuppressWarnings("unchecked") + public T getCapability(Capability capability, Direction direction) { + return (T) Optional.of(direction) + .filter(d -> d != Direction.UNKNOWN) + .map(capabilities::get) + .map(caps -> caps.get(capability)) + .orElseGet(() -> capabilities.get(Direction.UNKNOWN).get(capability)); } @Override diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/capability/forward/FWCapabilityProvider.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/capability/forward/FWCapabilityProvider.java index 4b3420423..a34f9a664 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/capability/forward/FWCapabilityProvider.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/capability/forward/FWCapabilityProvider.java @@ -5,60 +5,69 @@ */ package nova.core.wrapper.mc.forge.v1_11_2.wrapper.capability.forward; -import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.ICapabilityProvider; +import nova.core.util.Direction; import nova.core.util.EnumSelector; -import java.util.HashMap; +import java.util.EnumMap; import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; /** * * @author ExE Boss */ -public class FWCapabilityProvider implements ICapabilityProvider { +public class FWCapabilityProvider implements NovaCapabilityProvider { - private final Map, Object> capabilities = new HashMap<>(); - private final Map, Object>> sidedCapabilities = new HashMap<>(); + private final EnumMap, Object>> capabilities = new EnumMap<>(Direction.class); public FWCapabilityProvider() { - for (EnumFacing facing : EnumFacing.VALUES) - sidedCapabilities.put(facing, new HashMap<>()); + for (Direction facing : Direction.values()) + capabilities.put(facing, new ConcurrentHashMap<>()); } + @Override public boolean hasCapabilities() { - return !capabilities.isEmpty() || sidedCapabilities.values().stream().flatMap(map -> map.keySet().stream()).count() > 0; + return capabilities.values().parallelStream().map(map -> map.keySet().parallelStream()).count() > 0; } - public T addCapability(Capability capability, T capabilityInstance, EnumSelector facing) { - if (facing == null || facing.allowsAll()) { - if (capabilities.containsKey(capability)) + @Override + public T addCapability(Capability capability, T capabilityInstance, EnumSelector facing) { + if (facing.allowsAll()) { + if (capabilities.get(Direction.UNKNOWN).containsKey(capability)) throw new IllegalArgumentException("Already has capability " + capabilityInstance.getClass()); - capabilities.put(capability, capabilityInstance); + capabilities.get(Direction.UNKNOWN).put(capability, capabilityInstance); } else { facing.forEach(enumFacing -> { - Map, Object> capabilities = sidedCapabilities.get(enumFacing); + Map, Object> caps = capabilities.get(enumFacing); - if (capabilities.containsKey(capability)) + if (caps.containsKey(capability)) throw new IllegalArgumentException("Already has capability " + capabilityInstance.getClass()); - capabilities.put(capability, capabilityInstance); + caps.put(capability, capabilityInstance); }); } return capabilityInstance; } @Override - public boolean hasCapability(Capability capability, EnumFacing facing) { - return (facing != null ? sidedCapabilities.get(facing).containsValue(capability) : capabilities.containsValue(capability)); + public boolean hasCapability(Capability capability, Direction direction) { + return Optional.of(direction) + .filter(d -> d != Direction.UNKNOWN) + .map(capabilities::get) + .map(caps -> caps.containsValue(capability)) + .orElseGet(() -> capabilities.get(Direction.UNKNOWN).containsValue(capability)); } @Override @SuppressWarnings("unchecked") - public T getCapability(Capability capability, EnumFacing facing) { - if (!hasCapability(capability, facing)) return null; - return (T) (facing != null ? sidedCapabilities.get(facing).get(capability) : capabilities.get(capability)); + public T getCapability(Capability capability, Direction direction) { + return (T) Optional.of(direction) + .filter(d -> d != Direction.UNKNOWN) + .map(capabilities::get) + .map(caps -> caps.get(capability)) + .orElseGet(() -> capabilities.get(Direction.UNKNOWN).get(capability)); } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/capability/forward/NovaCapabilityProvider.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/capability/forward/NovaCapabilityProvider.java new file mode 100644 index 000000000..c97b3000a --- /dev/null +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/capability/forward/NovaCapabilityProvider.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017 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_2.wrapper.capability.forward; + +import net.minecraft.util.EnumFacing; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import nova.core.util.Direction; +import nova.core.util.EnumSelector; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.DirectionConverter; + +import javax.annotation.Nullable; + +/** + * @author ExE Boss + */ +public interface NovaCapabilityProvider extends ICapabilityProvider { + + boolean hasCapabilities(); + + default T addCapability(Capability capability, T instance, Direction... directions) { + return addCapability(capability, instance, EnumSelector.of(Direction.class).blockAll().apart(directions).lock()); + } + + + default T addCapability(Capability capability, T instance, Direction direction) { + return addCapability(capability, instance, direction == Direction.UNKNOWN ? + EnumSelector.of(Direction.class).allowAll().lock() : + EnumSelector.of(Direction.class).blockAll().apart(direction).lock()); + } + + + T addCapability(Capability capability, T instance, EnumSelector directions); + + boolean hasCapability(Capability capability, Direction direction); + + @Override + default boolean hasCapability(Capability capability, @Nullable EnumFacing facing) { + return hasCapability(capability, DirectionConverter.instance().toNova(facing)); + } + + @Nullable + T getCapability(Capability capability, Direction direction); + + @Override + @Nullable + default T getCapability(Capability capability, @Nullable EnumFacing facing) { + return getCapability(capability, DirectionConverter.instance().toNova(facing)); + } +} diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/forward/FWEntity.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/forward/FWEntity.java index 971e65d27..985334f68 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/forward/FWEntity.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/forward/FWEntity.java @@ -34,23 +34,29 @@ import nova.core.entity.EntityFactory; import nova.core.retention.Data; import nova.core.retention.Storable; +import nova.core.util.Direction; import nova.core.util.EnumSelector; import nova.core.util.shape.Cuboid; import nova.core.wrapper.mc.forge.v1_11_2.util.WrapperEvent; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.capability.forward.NovaCapabilityProvider; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.data.DataConverter; import nova.internal.core.Game; -import java.util.HashMap; +import java.util.EnumMap; import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; /** * Entity wrapper * @author Calclavia */ -public class FWEntity extends net.minecraft.entity.Entity implements IEntityAdditionalSpawnData { +public class FWEntity extends net.minecraft.entity.Entity implements IEntityAdditionalSpawnData, NovaCapabilityProvider { - private final Map, Object> capabilities = new HashMap<>(); - private final Map, Object>> sidedCapabilities = new HashMap<>(); + private final EnumMap, Object>> capabilities = new EnumMap<>(Direction.class); { + for (Direction facing : Direction.values()) + capabilities.put(facing, new ConcurrentHashMap<>()); + } protected final EntityTransform transform; protected Entity wrapped; @@ -226,35 +232,47 @@ public void setDead() { super.setDead(); } - public T addCapability(Capability capability, T capabilityInstance, EnumSelector facing) { - if (facing == null || facing.allowsAll()) { - if (capabilities.containsKey(capability)) + @Override + public boolean hasCapabilities() { + return capabilities.values().parallelStream().map(map -> map.keySet().parallelStream()).count() > 0; + } + + @Override + public T addCapability(Capability capability, T capabilityInstance, EnumSelector facing) { + if (facing.allowsAll()) { + if (capabilities.get(Direction.UNKNOWN).containsKey(capability)) throw new IllegalArgumentException("Already has capability " + capabilityInstance.getClass()); - capabilities.put(capability, capabilityInstance); + capabilities.get(Direction.UNKNOWN).put(capability, capabilityInstance); } else { facing.forEach(enumFacing -> { - Map, Object> capabilities = sidedCapabilities.get(enumFacing); + Map, Object> caps = capabilities.get(enumFacing); - if (capabilities.containsKey(capability)) + if (caps.containsKey(capability)) throw new IllegalArgumentException("Already has capability " + capabilityInstance.getClass()); - capabilities.put(capability, capabilityInstance); + caps.put(capability, capabilityInstance); }); } return capabilityInstance; } @Override - public boolean hasCapability(Capability capability, EnumFacing facing) { - return (facing != null ? sidedCapabilities.get(facing).containsValue(capability) : capabilities.containsValue(capability)) - || super.hasCapability(capability, facing); + public boolean hasCapability(Capability capability, Direction direction) { + return Optional.of(direction) + .filter(d -> d != Direction.UNKNOWN) + .map(capabilities::get) + .map(caps -> caps.containsValue(capability)) + .orElseGet(() -> capabilities.get(Direction.UNKNOWN).containsValue(capability)); } @Override - public T getCapability(Capability capability, EnumFacing facing) { - if (!hasCapability(capability, facing)) return null; - T capabilityInstance = (T) (facing != null ? sidedCapabilities.get(facing).get(capability) : capabilities.get(capability)); - return capabilityInstance != null ? capabilityInstance : super.getCapability(capability, facing); + @SuppressWarnings("unchecked") + public T getCapability(Capability capability, Direction direction) { + return (T) Optional.of(direction) + .filter(d -> d != Direction.UNKNOWN) + .map(capabilities::get) + .map(caps -> caps.get(capability)) + .orElseGet(() -> capabilities.get(Direction.UNKNOWN).get(capability)); } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/forward/FWEntityRenderer.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/forward/FWEntityRenderer.java index 6e567e421..111fced59 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/forward/FWEntityRenderer.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/forward/FWEntityRenderer.java @@ -72,8 +72,8 @@ public static void render(FWParticle wrapper, nova.core.entity.Entity entity, do GL11.glBlendFunc(model.blendSFactor, model.blendDFactor); } - Tessellator.getInstance().getBuffer().begin(GL_QUADS, DefaultVertexFormats.BLOCK); - model.render(Optional.of(Minecraft.getMinecraft().getRenderManager())); + Tessellator.getInstance().getBuffer().begin(GL_QUADS, DefaultVertexFormats.ITEM); + model.render(Minecraft.getMinecraft().getRenderManager()); Tessellator.getInstance().draw(); if (model.blendSFactor > 0 && model.blendDFactor > 0) { @@ -102,8 +102,8 @@ public static void render(FWEntity wrapper, nova.core.entity.Entity entity, doub GL11.glBlendFunc(model.blendSFactor, model.blendDFactor); } - Tessellator.getInstance().getBuffer().begin(GL_QUADS, DefaultVertexFormats.BLOCK); - model.render(Optional.of(Minecraft.getMinecraft().getRenderManager())); + Tessellator.getInstance().getBuffer().begin(GL_QUADS, DefaultVertexFormats.ITEM); + model.render(Minecraft.getMinecraft().getRenderManager()); Tessellator.getInstance().draw(); if (model.blendSFactor > 0 && model.blendDFactor > 0) { diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/ItemConverter.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/ItemConverter.java index 6dca71931..52702c886 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/ItemConverter.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/ItemConverter.java @@ -23,6 +23,7 @@ import com.google.common.collect.HashBiMap; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.registry.GameRegistry; @@ -41,10 +42,12 @@ import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.backward.BWItem; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.backward.BWItemFactory; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.forward.FWItem; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.forward.FWItemCapabilityProvider; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.forward.FWNBTTagCompound; import nova.internal.core.Game; import nova.internal.core.launch.InitializationException; +import java.lang.reflect.Field; import java.util.Objects; import java.util.Set; @@ -74,24 +77,30 @@ public Class getNativeSide() { } @Override - public Item toNova(ItemStack itemStack) { - return getNovaItem(itemStack).setCount(itemStack.getCount()); + public Item toNova(ItemStack stack) { + return getNovaItem(stack).setCount(stack.getCount()); } - public Item getNovaItem(ItemStack itemStack) { - if (itemStack.getItemDamage() == net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE) { + public Item getNovaItem(ItemStack stack) { + if (stack.getItemDamage() == net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE) { // TODO: Deal withPriority wildcard meta values - important for the ore dictionary - return getNovaItem(new ItemStack(itemStack.getItem(), 1, 0)); + return getNovaItem(new ItemStack(stack.getItem(), 1, 0)); } - if (itemStack.getTagCompound() != null && itemStack.getTagCompound() instanceof FWNBTTagCompound) { - return Objects.requireNonNull((FWNBTTagCompound) itemStack.getTagCompound()).getItem(); + ICapabilityProvider stackCapabilities = getStackCapabilities(stack); + + if (stack.getTagCompound() instanceof FWNBTTagCompound) { + return ((FWNBTTagCompound) stack.getTagCompound()).getItem(); +// } else if (stack.getCapabilites() instanceof FWItemCapabilityProvider) { +// return ((FWItemCapabilityProvider)stack.getCapabilites()).item; + } else if (stackCapabilities instanceof FWItemCapabilityProvider) { + return ((FWItemCapabilityProvider) stackCapabilities).item; } else { - ItemFactory itemFactory = registerMinecraftMapping(itemStack.getItem(), itemStack.getItemDamage()); + ItemFactory itemFactory = registerMinecraftMapping(stack.getItem(), stack.getItemDamage()); - Data data = itemStack.getTagCompound() != null ? Game.natives().toNova(itemStack.getTagCompound()) : new Data(); - if (!itemStack.getHasSubtypes() && itemStack.getItemDamage() > 0) { - data.put("damage", itemStack.getItemDamage()); + Data data = stack.getTagCompound() != null ? Game.natives().toNova(stack.getTagCompound()) : new Data(); + if (!stack.getHasSubtypes() && stack.getItemDamage() > 0) { + data.put("damage", stack.getItemDamage()); } return itemFactory.build(data); @@ -332,4 +341,17 @@ public String toString() { } } } + + private ICapabilityProvider getStackCapabilities(ItemStack stack) { + try { + Field capabilities = ItemStack.class.getDeclaredField("capabilities"); + capabilities.setAccessible(true); + @SuppressWarnings("unchecked") + ICapabilityProvider provider = (ICapabilityProvider) capabilities.get(stack); + capabilities.setAccessible(false); + return provider; + } catch (ReflectiveOperationException ex) { + return null; + } + } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/FWItem.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/FWItem.java index 540e75daf..357c0445a 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/FWItem.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/FWItem.java @@ -29,12 +29,11 @@ import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.common.capabilities.ICapabilityProvider; import nova.core.item.Item; import nova.core.item.ItemFactory; import nova.core.wrapper.mc.forge.v1_11_2.util.WrapperEvent; -import nova.core.wrapper.mc.forge.v1_11_2.wrapper.capability.forward.FWCapabilityProvider; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.ItemConverter; +import nova.internal.core.Game; import java.util.List; import javax.annotation.Nullable; @@ -54,9 +53,10 @@ public FWItem(ItemFactory item) { @Override @Nullable - public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable NBTTagCompound nbt) { + public FWItemCapabilityProvider initCapabilities(ItemStack stack, @Nullable NBTTagCompound nbt) { Item item = ItemConverter.instance().toNova(stack); - WrapperEvent.FWItemInitCapabilities event = new WrapperEvent.FWItemInitCapabilities(item, new FWCapabilityProvider()); + WrapperEvent.FWItemInitCapabilities event = new WrapperEvent.FWItemInitCapabilities(item, new FWItemCapabilityProvider(item)); + Game.events().publish(event); return event.capabilityProvider.hasCapabilities() ? event.capabilityProvider : null; } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/FWItemBlock.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/FWItemBlock.java index b6f67c454..bfd26d288 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/FWItemBlock.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/FWItemBlock.java @@ -29,16 +29,15 @@ import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.common.capabilities.ICapabilityProvider; import nova.core.item.Item; import nova.core.item.ItemFactory; import nova.core.wrapper.mc.forge.v1_11_2.util.WrapperEvent; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.forward.FWBlock; -import nova.core.wrapper.mc.forge.v1_11_2.wrapper.capability.forward.FWCapabilityProvider; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.ItemConverter; import nova.internal.core.Game; import java.util.List; +import javax.annotation.Nullable; /** * @author Calclavia @@ -50,9 +49,11 @@ public FWItemBlock(FWBlock block) { } @Override - public ICapabilityProvider initCapabilities(ItemStack stack, NBTTagCompound nbt) { - Item item = Game.natives().toNova(stack); - WrapperEvent.FWItemInitCapabilities event = new WrapperEvent.FWItemInitCapabilities(item, new FWCapabilityProvider()); + @Nullable + public FWItemCapabilityProvider initCapabilities(ItemStack stack, NBTTagCompound nbt) { + Item item = ItemConverter.instance().toNova(stack); + WrapperEvent.FWItemInitCapabilities event = new WrapperEvent.FWItemInitCapabilities(item, new FWItemCapabilityProvider(item)); + Game.events().publish(event); return event.capabilityProvider.hasCapabilities() ? event.capabilityProvider : null; } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/FWItemCapabilityProvider.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/FWItemCapabilityProvider.java new file mode 100644 index 000000000..936ee63ae --- /dev/null +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/FWItemCapabilityProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 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_2.wrapper.item.forward; + +import nova.core.item.Item; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.capability.forward.FWCapabilityProvider; + +/** + * @author ExE Boss + */ +public class FWItemCapabilityProvider extends FWCapabilityProvider { + + public final Item item; + + public FWItemCapabilityProvider(Item item) { + this.item = item; + } +} diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/backward/BWModel.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/backward/BWModel.java index b85657b67..c5a46cf6c 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/backward/BWModel.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/backward/BWModel.java @@ -20,27 +20,27 @@ package nova.core.wrapper.mc.forge.v1_11_2.wrapper.render.backward; -import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import nova.core.render.model.CustomModel; import nova.core.render.model.MeshModel; +import nova.core.render.model.Vertex; import nova.core.render.texture.EntityTexture; -import nova.core.render.texture.Texture; import nova.core.util.math.Vector3DUtil; import nova.core.wrapper.mc.forge.v1_11_2.render.RenderUtility; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.VectorConverter; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.assets.AssetConverter; -import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; -import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; +import org.lwjgl.opengl.GL11; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import javax.annotation.Nonnull; @@ -52,15 +52,15 @@ public class BWModel extends MeshModel { public void render() { - render(Optional.empty()); + render(Optional.empty(), Optional.empty()); } public void render(@Nonnull IBlockAccess access) { render(Optional.of(access), Optional.empty()); } - public void render(Optional entityRenderManager) { - render(Optional.empty(), entityRenderManager); + public void render(@Nonnull RenderManager entityRenderManager) { + render(Optional.ofNullable(entityRenderManager.world), Optional.of(entityRenderManager)); } public void render(Optional access, Optional entityRenderManager) { @@ -81,7 +81,29 @@ public void render(Optional access, Optional entity entityRenderManager.get().renderEngine.bindTexture(AssetConverter.instance().toNative(face.texture.get())); } - face.vertices.forEach(v -> { + final List vertices; + switch (worldRenderer.getDrawMode()) { + case GL11.GL_TRIANGLES: + vertices = new ArrayList<>(3); + vertices.add(face.vertices.get(0)); + vertices.add(face.vertices.get(1)); + vertices.add(face.vertices.get(2)); + break; + case GL11.GL_QUADS: + vertices = new ArrayList<>(4); + vertices.add(face.vertices.get(0)); + vertices.add(face.vertices.get(1)); + vertices.add(face.vertices.get(2)); + if (face.vertices.size() >= 4) + vertices.add(face.vertices.get(3)); + else + vertices.add(face.vertices.get(2)); + break; + default: + vertices = new ArrayList<>(face.vertices); + break; + } + vertices.forEach(v -> { worldRenderer.getVertexFormat().getElements().forEach(vfe -> { switch (vfe.getUsage()) { case POSITION: { @@ -105,24 +127,21 @@ public void render(Optional access, Optional entity worldRenderer.tex(tex.getInterpolatedU(16 * v.uv.getX()), tex.getInterpolatedV(16 * v.uv.getY())); } } else if (vfe.getIndex() == 1) { - // TODO: Lightmap if (face.getBrightness() >= 0) { worldRenderer.lightmap((int)(face.getBrightness() * 15), (int)(face.getBrightness() * 11)); } else if(access.isPresent()) { // Determine nearest adjacent block. Vector3D nearestPos = Vector3DUtil.floor(face.getCenter().add(face.normal.scalarMultiply(0.05))); - BlockPos blockPos = Game.natives().toNative(nearestPos); + BlockPos blockPos = VectorConverter.instance().toNative(nearestPos); IBlockState state = access.get().getBlockState(blockPos); - Block block = state.getBlock(); - @SuppressWarnings("deprecation") - int brightness = block.getPackedLightmapCoords(state, access.get(), blockPos); + int brightness = state.getPackedLightmapCoords(access.get(), blockPos); // TODO: Add Ambient Occlusion /* - int aoBrightnessXYNN = block.getPackedLightmapCoords(state, access.get(), blockPos.east()); - int aoBrightnessYZNN = block.getPackedLightmapCoords(state, access.get(), blockPos.north()); - int aoBrightnessYZNP = block.getPackedLightmapCoords(state, access.get(), blockPos.south()); - int aoBrightnessXYPN = block.getPackedLightmapCoords(state, access.get(), blockPos.west()); + int aoBrightnessXYNN = state.getPackedLightmapCoords(access.get(), blockPos.east()); + int aoBrightnessYZNN = state.getPackedLightmapCoords(access.get(), blockPos.north()); + int aoBrightnessYZNP = state.getPackedLightmapCoords(access.get(), blockPos.south()); + int aoBrightnessXYPN = state.getPackedLightmapCoords(access.get(), blockPos.west()); int brightnessTopLeft = getAoBrightness(aoBrightnessXYZNNP, aoBrightnessXYNN, aoBrightnessYZNP, i1); int brightnessTopRight = getAoBrightness(aoBrightnessYZNP, aoBrightnessXYZPNP, aoBrightnessXYPN, i1); diff --git a/src/main/java/nova/core/util/EnumSelector.java b/src/main/java/nova/core/util/EnumSelector.java index 0eaf14157..c6982fd1c 100644 --- a/src/main/java/nova/core/util/EnumSelector.java +++ b/src/main/java/nova/core/util/EnumSelector.java @@ -21,9 +21,11 @@ package nova.core.util; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.Iterator; +import java.util.Objects; import java.util.Set; import java.util.Spliterator; import java.util.Spliterators; @@ -53,7 +55,7 @@ private EnumSelector(Class enumClass) { * @return an instance of EnumSelector for the given type. */ public static > EnumSelector of(Class enumClass) { - return new EnumSelector(enumClass); + return new EnumSelector<>(enumClass); } private void checkWritable() { @@ -111,7 +113,7 @@ public EnumSelector blockAll() { * @see #blockAll() * @param value The given {@code enum} value that should have behavior opposite of the default. * @return this - * @throws IllegalStateException If the EnumSelector has not been {@link #lock() locked}. + * @throws IllegalStateException If the EnumSelector has been {@link #lock() locked}. */ public EnumSelector apart(T value) { checkWritable(); @@ -124,15 +126,67 @@ public EnumSelector apart(T value) { * * @see #allowAll() * @see #blockAll() - * @param first The given {@code enum} value that should have behavior opposite of the default. - * @param rest The given {@code enum} values that should have behavior opposite of the default. + * @param first The first {@code enum} value that should have behavior opposite of the default. + * @param second The second {@code enum} value that should have behavior opposite of the default. * @return this - * @throws IllegalStateException If the EnumSelector has not been {@link #lock() locked}. + * @throws IllegalStateException If the EnumSelector has been {@link #lock() locked}. */ - public EnumSelector apart(T first, T... rest) { + public EnumSelector apart(T first, T second) { checkWritable(); exceptions.add(first); - exceptions.addAll(Arrays.asList(rest)); + exceptions.add(second); + return this; + } + + /** + * Specify which {@code enum} values should have behavior opposite of the default + * + * @see #allowAll() + * @see #blockAll() + * @param values The given {@code enum} values that should have behavior opposite of the default. + * @return this + * @throws IllegalStateException If the EnumSelector has been {@link #lock() locked}. + */ + @SuppressWarnings("unchecked") + public EnumSelector apart(T... values) { + checkWritable(); + exceptions.addAll(Arrays.asList(values)); + return this; + } + + /** + * Specify which {@code enum} values should have behavior opposite of the default + * + * @see #allowAll() + * @see #blockAll() + * @param values The given {@code enum} values that should have behavior opposite of the default. + * @return this + * @throws IllegalStateException If the EnumSelector has been {@link #lock() locked}, + * or if the {@code values} parameter is an EnumSelector instance which has + * not been {@link #lock() locked}. + */ + @SuppressWarnings("unchecked") + public EnumSelector apart(Iterable values) { + checkWritable(); + if (values instanceof EnumSelector) { + EnumSelector other = (EnumSelector) values; + try { + other.checkReadable(); + } catch (IllegalStateException e) { + throw new IllegalArgumentException(e); + } + if (!defaultAllow && !defaultBlock) + throw new IllegalStateException("Cannot call EnumSelector.apart(EnumSelector) without specifying default behaviour."); + if ((defaultAllow && other.defaultBlock) || (defaultBlock && other.defaultBlock)) { + this.exceptions.addAll(other.exceptions); + } else { + this.exceptions.addAll(EnumSet.complementOf(other.exceptions)); + } + } else if (values instanceof Collection) { + exceptions.addAll((Collection)values); + } else { + values.forEach(exceptions::add); + } return this; } @@ -183,7 +237,7 @@ public boolean allows(T value) { */ public boolean allowsAll() { checkReadable(); - return defaultAllow && exceptions.isEmpty(); + return (defaultAllow && exceptions.isEmpty()) || (defaultBlock && EnumSet.complementOf(exceptions).isEmpty()); } /** @@ -206,7 +260,7 @@ public boolean blocks(T value) { */ public boolean blocksAll() { checkReadable(); - return defaultBlock && exceptions.isEmpty(); + return (defaultBlock && exceptions.isEmpty()) || (defaultAllow && EnumSet.complementOf(exceptions).isEmpty()); } /** @@ -266,4 +320,46 @@ public Set toSet() { checkReadable(); return Collections.unmodifiableSet(defaultBlock ? exceptions : EnumSet.complementOf(exceptions)); } + + /** + * {@inheritDoc} + * + * @see EnumSet#toString() + * @return The same result as calling {@link #toSet()}.{@link EnumSet#toString() toString()}. + * @throws IllegalStateException If the EnumSelector has not been {@link #lock() locked}. + */ + @Override + public String toString() { + return toSet().toString(); + } + + /** + * {@inheritDoc} + * + * @see EnumSet#hashCode() + * @return The hash calculated from {@link #toSet()}.{@link EnumSet#hashCode() hashCode()}. + * @throws IllegalStateException If the EnumSelector has not been {@link #lock() locked}. + */ + @Override + public int hashCode() { + checkReadable(); + int hash = 5; + hash = 79 * hash + Objects.hashCode(this.toSet()); + return hash; + } + + /** + * {@inheritDoc} + * + * @see EnumSet#equals(Object) + * @return true if this EnumSelector allows the exact same values as the other EnumSelector + * @throws IllegalStateException If the EnumSelector has not been {@link #lock() locked}. + */ + @Override + public boolean equals(Object other) { + checkReadable(); + if (this == other) return true; + if (other == null || getClass() != other.getClass()) return false; + return this.toSet().equals(((EnumSelector)other).toSet()); + } } diff --git a/src/test/java/nova/core/util/EnumSelectorTest.java b/src/test/java/nova/core/util/EnumSelectorTest.java index d7d851111..f62b13928 100644 --- a/src/test/java/nova/core/util/EnumSelectorTest.java +++ b/src/test/java/nova/core/util/EnumSelectorTest.java @@ -20,12 +20,14 @@ package nova.core.util; +import org.hamcrest.CoreMatchers; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import static nova.testutils.NovaAssertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; /** * @author ExE Boss @@ -55,6 +57,35 @@ public void setUp() { enumSelectorExample4 = EnumSelector.of(EnumExample.class).blockAll().lock(); } + @Test + public void testAdditionalMethods() { + EnumSelector ex1a = EnumSelector.of(EnumExample.class).blockAll().apart(enumSelectorExample1).lock(); + EnumSelector ex1b = EnumSelector.of(EnumExample.class).allowAll().apart(enumSelectorExample1).lock(); + EnumSelector ex1c = EnumSelector.of(EnumExample.class).blockAll().apart(enumSelectorExample1.toSet()).lock(); + EnumSelector ex1d = EnumSelector.of(EnumExample.class).allowAll().apart(enumSelectorExample1.toSet()).lock(); + + EnumSelector ex2a = EnumSelector.of(EnumExample.class).blockAll().apart(enumSelectorExample2).lock(); + EnumSelector ex2b = EnumSelector.of(EnumExample.class).allowAll().apart(enumSelectorExample2).lock(); + EnumSelector ex2c = EnumSelector.of(EnumExample.class).blockAll().apart(enumSelectorExample2::iterator).lock(); + EnumSelector ex2d = EnumSelector.of(EnumExample.class).allowAll().apart(enumSelectorExample2::iterator).lock(); + + EnumSelector ex3a = EnumSelector.of(EnumExample.class).blockAll().apart(EnumExample.values()).lock(); + EnumSelector ex3b = EnumSelector.of(EnumExample.class).allowAll().apart(EnumExample.values()).lock(); + + assertThat(ex1a.allows(EnumExample.EXAMPLE_42)).isTrue(); + assertThat(ex1b.allows(EnumExample.EXAMPLE_42)).isFalse(); + assertThat(ex1c.allows(EnumExample.EXAMPLE_42)).isTrue(); + assertThat(ex1d.allows(EnumExample.EXAMPLE_42)).isFalse(); + + assertThat(ex2a.allows(EnumExample.EXAMPLE_42)).isFalse(); + assertThat(ex2b.allows(EnumExample.EXAMPLE_42)).isTrue(); + assertThat(ex2c.allows(EnumExample.EXAMPLE_42)).isFalse(); + assertThat(ex2d.allows(EnumExample.EXAMPLE_42)).isTrue(); + + assertThat(ex3a.allowsAll()).isTrue(); + assertThat(ex3b.blocksAll()).isTrue(); + } + @Test public void testAllLocked() { assertThat(enumSelectorExample1.locked()).isEqualTo(true); @@ -173,4 +204,39 @@ public void testCannotAllowBlocking() { thrown.expectMessage("You can't allow all enum values when you are already blocking them."); enumSelectorExample.allowAll(); } + + @Test + public void testApartIteratorException() { + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Cannot call EnumSelector.apart(EnumSelector) without specifying default behaviour."); + EnumSelector enumSelectorExample = EnumSelector.of(EnumExample.class).apart(enumSelectorExample1); + } + + @Test + public void testApartEnumExampleException() { + thrown.expect(IllegalArgumentException.class); + thrown.expectCause(CoreMatchers.instanceOf(IllegalStateException.class)); + EnumSelector enumSelectorExample = EnumSelector.of(EnumExample.class).allowAll().apart(EnumSelector.of(EnumExample.class)); + } + + @Test + public void testToString() { + assertThat(enumSelectorExample1.toString()).isEqualTo('[' + String.join(", ", EnumExample.EXAMPLE_24.toString(), EnumExample.EXAMPLE_42.toString()) + ']'); + assertThat(enumSelectorExample4.toString()).isEqualTo("[]"); + } + + @Test + public void testHashCode() { + assertThat(enumSelectorExample3.hashCode()).isEqualTo(EnumSelector.of(EnumExample.class).allowAll().lock().hashCode()); + assertThat(enumSelectorExample4.hashCode()).isEqualTo(EnumSelector.of(EnumExample.class).blockAll().lock().hashCode()); + } + + @Test + public void testEquals() { + assertThat(enumSelectorExample1).isEqualTo(enumSelectorExample1); + assertThat(enumSelectorExample2).isNotEqualTo(null); + assertThat(enumSelectorExample2).isNotEqualTo(this); + assertThat(enumSelectorExample2).isNotEqualTo(enumSelectorExample3); + assertThat(enumSelectorExample4).isEqualTo(EnumSelector.of(EnumExample.class).blockAll().lock()); + } }