diff --git a/minecraft/1.11.2/gradle.properties b/minecraft/1.11.2/gradle.properties index dfff6bc70..4d6000c88 100644 --- a/minecraft/1.11.2/gradle.properties +++ b/minecraft/1.11.2/gradle.properties @@ -6,5 +6,5 @@ forgeGradleVersion = 2.2-SNAPSHOT packaging = jar info.inceptionYear = 2016 -info.description = The wrapper of the Nova API to the MinecraftForge 1.11 modding system. +info.description = The wrapper of the Nova API to the MinecraftForge 1.11.2 modding system. info.organization.name = NOVA diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/NovaMinecraftPreloader.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/NovaMinecraftPreloader.java index cc675dcfb..6f5a04399 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/NovaMinecraftPreloader.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/NovaMinecraftPreloader.java @@ -1,13 +1,13 @@ /* * Copyright (c) 2015 NOVA, All rights reserved. - * This library is free software, licensed under GNU Lesser General Public License version 3 + * 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. + * 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 @@ -43,6 +43,7 @@ import nova.core.wrapper.mc.forge.v1_11_2.wrapper.assets.NovaFileResourcePack; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.assets.NovaFolderResourcePack; import nova.core.wrapper.mc.forge.v1_11_2.util.ReflectionUtil; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.assets.NovaResourcePack; import java.io.File; import java.io.IOException; @@ -52,8 +53,10 @@ import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; @@ -62,20 +65,22 @@ import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; + import javax.json.Json; import javax.json.stream.JsonGenerator; public class NovaMinecraftPreloader extends DummyModContainer { - public static final String version = "0.0.1"; + public static final String VERSION = "0.0.1"; private static final ModMetadata md; public static Set> modClasses; public static Map, File> modClassToFile; + public static List> novaResourcePacks = Collections.emptyList(); static { md = new ModMetadata(); md.modId = "novapreloader"; md.name = "NOVA Preloader"; - md.version = version; + md.version = VERSION; } public NovaMinecraftPreloader() { @@ -293,6 +298,7 @@ public void registerResourcePacks() { List packs = (List) resourcePackField.get(FMLClientHandler.instance()); Set addedPacks = new HashSet<>(); + List> novaPacks = new LinkedList<>(); classesMap.keySet().forEach(novaMod -> { Class c = classesMap.get(novaMod); @@ -312,13 +318,15 @@ public void registerResourcePacks() { if (!addedPacks.contains(fn)) { addedPacks.add(fn); - packs.add(new NovaFileResourcePack(file, novaMod.id(), novaMod.domains())); + NovaFileResourcePack pack = new NovaFileResourcePack(file, novaMod.id(), novaMod.domains()); + packs.add(pack); + novaPacks.add(pack); System.out.println("Registered NOVA jar resource pack: " + fn); } } else { //Add folder resource pack location. The folderLocation is the root of the project, including the packages of classes, and an assets folder inside. String folderLocation = c.getProtectionDomain().getCodeSource().getLocation().getPath(); - String classPath = c.getCanonicalName().replaceAll("\\.", "/"); + String classPath = c.getCanonicalName().replace('.', '/'); folderLocation = folderLocation.replaceFirst("file:", "").replace(classPath, "").replace("/.class", "").replaceAll("%20", " "); File folderFile = new File(folderLocation); if (!new File(folderFile, "assets").isDirectory()) { @@ -329,11 +337,14 @@ public void registerResourcePacks() { modClassToFile.put(c, folderFile); addedPacks.add(folderLocation); - packs.add(new NovaFolderResourcePack(folderFile, novaMod.id(), novaMod.domains())); + NovaFolderResourcePack pack = new NovaFolderResourcePack(folderFile, novaMod.id(), novaMod.domains()); + packs.add(pack); + novaPacks.add(pack); System.out.println("Registered NOVA folder resource pack: " + folderFile.getAbsolutePath()); } }); resourcePackField.set(FMLClientHandler.instance(), packs); + novaResourcePacks = new ArrayList<>(novaPacks); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/launcher/ClientProxy.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/launcher/ClientProxy.java index 363665787..29402dc19 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/launcher/ClientProxy.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/launcher/ClientProxy.java @@ -1,13 +1,13 @@ /* * Copyright (c) 2015 NOVA, All rights reserved. - * This library is free software, licensed under GNU Lesser General Public License version 3 + * 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. + * 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 @@ -24,29 +24,38 @@ import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.particle.Particle; import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.client.resources.IResource; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.client.registry.RenderingRegistry; +import net.minecraftforge.fml.common.ProgressManager; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import nova.core.entity.Entity; import nova.core.entity.EntityFactory; +import nova.core.language.LanguageManager; +import nova.core.wrapper.mc.forge.v1_11_2.NovaMinecraftPreloader; import nova.core.wrapper.mc.forge.v1_11_2.render.RenderUtility; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.forward.FWBlock; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.forward.FWTile; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.forward.FWTileRenderer; -import nova.core.wrapper.mc.forge.v1_11_2.wrapper.particle.backward.BWParticle; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.entity.forward.FWEntity; -import nova.core.wrapper.mc.forge.v1_11_2.wrapper.particle.forward.FWParticle; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.entity.forward.FWEntityRenderer; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.forward.FWItem; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.particle.backward.BWParticle; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.particle.forward.FWParticle; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + /** * @author Calclavia */ @@ -65,6 +74,49 @@ public void init(FMLInitializationEvent evt) { RenderingRegistry.registerEntityRenderingHandler(FWEntity.class, FWEntityRenderer.instance); } + @Override + public void loadLanguage(LanguageManager languageManager) { + super.loadLanguage(languageManager); + ProgressManager.ProgressBar progressBar = ProgressManager.push("Loading NOVA language files", + NovaMinecraftPreloader.novaResourcePacks.size() + 1); + FMLProgressBar fmlProgressBar = new FMLProgressBar(progressBar); + fmlProgressBar.step("nova"); + Minecraft.getMinecraft().getLanguageManager().getLanguages() + .stream() + .map(lang -> lang.getLanguageCode().replace('_', '-')) + .forEach(langName -> { + ResourceLocation location = new ResourceLocation("nova", langName + ".lang"); + try { + Minecraft.getMinecraft().getResourceManager().getAllResources(location).forEach(resource -> + loadLanguage(languageManager, location, langName, resource.getInputStream())); + } catch (IOException ex) { + } + }); + NovaMinecraftPreloader.novaResourcePacks.forEach(pack -> { + fmlProgressBar.step(pack.getID()); + pack.getLanguageFiles().stream().forEach(location -> { + String resourcePath = location.getResourcePath(); + String langName = resourcePath.substring(5, resourcePath.length() - 5); + try { + Minecraft.getMinecraft().getResourceManager().getAllResources(location).forEach(resource -> + loadLanguage(languageManager, location, langName, resource.getInputStream())); + } catch (IOException ex) { + } + }); + }); + fmlProgressBar.finish(); + ProgressManager.pop(progressBar); + } + + private void loadLanguage(LanguageManager languageManager, ResourceLocation location, String langName, InputStream stream) { + try { + Properties p = new Properties(); + p.load(stream); + p.entrySet().stream().forEach(e -> languageManager.register(langName, e.getKey().toString(), e.getValue().toString())); + } catch (IOException ex) { + } + } + @Override public void registerItem(FWItem item) { super.registerItem(item); diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/launcher/CommonProxy.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/launcher/CommonProxy.java index cf312880e..d019ba281 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/launcher/CommonProxy.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/launcher/CommonProxy.java @@ -27,6 +27,7 @@ import net.minecraftforge.fml.common.registry.GameRegistry; import nova.core.entity.Entity; import nova.core.entity.EntityFactory; +import nova.core.language.LanguageManager; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.forward.FWBlock; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.forward.FWTile; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.forward.FWTileUpdater; @@ -46,6 +47,8 @@ public void preInit(FMLPreInitializationEvent evt) { EntityRegistry.registerModEntity(new ResourceLocation("nova", "novaEntity"), FWEntity.class, "novaEntity", 1, NovaMinecraft.instance, 64, 20, true); } + public void loadLanguage(LanguageManager languageManager) {} + public void registerResourcePacks(Set> modClasses) { } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/launcher/NovaMinecraft.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/launcher/NovaMinecraft.java index 233a0abad..26ac85b80 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/launcher/NovaMinecraft.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/launcher/NovaMinecraft.java @@ -1,14 +1,14 @@ /* * Copyright (c) 2015 NOVA, All rights reserved. - * This library is free software, licensed under GNU Lesser General Public License version 3 + * 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. + * 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 @@ -53,7 +53,7 @@ import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.BlockConverter; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.world.WorldConverter; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.cuboid.CuboidConverter; -import nova.core.wrapper.mc.forge.v1_11_2.wrapper.data.DataWrapper; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.data.DataConverter; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.entity.EntityConverter; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.inventory.InventoryConverter; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.ItemConverter; @@ -73,19 +73,19 @@ * The main Nova Minecraft Wrapper loader, using Minecraft Forge. * @author Calclavia */ -@Mod(modid = NovaMinecraft.id, name = NovaMinecraft.name, version = NovaMinecraftPreloader.version, acceptableRemoteVersions = "*") +@Mod(modid = NovaMinecraft.MOD_ID, name = NovaMinecraft.NAME, version = NovaMinecraftPreloader.VERSION, acceptableRemoteVersions = "*") public class NovaMinecraft { - public static final String id = "nova"; - public static final String name = "NOVA"; - public static final String mcId = "minecraft"; + public static final String MOD_ID = "nova"; + public static final String NAME = "NOVA"; + public static final String GAME_ID = "minecraft"; @SidedProxy(clientSide = "nova.core.wrapper.mc.forge.v1_11_2.launcher.ClientProxy", serverSide = "nova.core.wrapper.mc.forge.v1_11_2.launcher.CommonProxy") public static CommonProxy proxy; - @Mod.Instance(id) + @Mod.Instance(MOD_ID) public static NovaMinecraft instance; private static NovaLauncher launcher; - @Mod.Metadata(id) + @Mod.Metadata(MOD_ID) private static ModMetadata modMetadata; private static Set nativeConverters; @@ -129,7 +129,7 @@ public void preInit(FMLPreInitializationEvent evt) { /** * Register native converters */ - Game.natives().registerConverter(new DataWrapper()); + Game.natives().registerConverter(new DataConverter()); Game.natives().registerConverter(new EntityConverter()); Game.natives().registerConverter(new BlockConverter()); Game.natives().registerConverter(new ItemConverter()); @@ -176,10 +176,11 @@ public void preInit(FMLPreInitializationEvent evt) { // Initiate config system TODO: Storables // launcher.getLoadedModMap().forEach((mod, loader) -> { - // Configuration config = new Configuration(new File(evt.getModConfigurationDirectory(), mod.name())); + // Configuration config = new Configuration(new File(evt.getModConfigurationDirectory(), mod.NAME())); // ConfigManager.instance.sync(config, loader.getClass().getPackage().getName()); // }); + proxy.loadLanguage(Game.language()); Game.language().init(); Game.render().init(); Game.blocks().init(); @@ -209,7 +210,7 @@ public void preInit(FMLPreInitializationEvent evt) { * Register event handlers */ MinecraftForge.EVENT_BUS.register(new ForgeEventHandler()); - FMLCommonHandler.instance().bus().register(new FMLEventHandler()); + MinecraftForge.EVENT_BUS.register(new FMLEventHandler()); MinecraftForge.EVENT_BUS.register(Game.retention()); } catch (Exception e) { System.out.println("Error during preInit"); diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/network/netty/MCNetworkManager.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/network/netty/MCNetworkManager.java index f8d8d6a13..14da12f25 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/network/netty/MCNetworkManager.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/network/netty/MCNetworkManager.java @@ -51,7 +51,7 @@ * @since 26/05/14 */ public class MCNetworkManager extends NetworkManager { - public final String channel = NovaMinecraft.id; + public final String channel = NovaMinecraft.MOD_ID; public final EnumMap channelEnumMap = NetworkRegistry.INSTANCE.newChannel(channel, new ChannelHandler(), new MCPacketHandler()); public Packet toMCPacket(PacketAbstract packet) { @@ -112,7 +112,7 @@ public void sendToPlayer(PacketAbstract packet, EntityPlayerMP player) { /** * @param packet the packet to send to the players in the dimension - * @param dimId the dimension id to send to. + * @param dimId the dimension MOD_ID to send to. */ public void sendToAllInDimension(PacketAbstract packet, int dimId) { this.channelEnumMap.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.DIMENSION); diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/recipes/RecipeConverter.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/recipes/RecipeConverter.java index 9175a75d4..fd0cd08e2 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/recipes/RecipeConverter.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/recipes/RecipeConverter.java @@ -39,6 +39,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.Optional; /** @@ -84,7 +85,7 @@ 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()); + return ((ItemStack) ingredient).isEmpty() ? null : ItemIngredient.forItem(Objects.toString(net.minecraft.item.Item.REGISTRY.getNameForObject(((ItemStack) ingredient).getItem()))); } else if (ingredient instanceof String) { return ItemIngredient.forDictionary((String) ingredient); } else if (ingredient instanceof List) { @@ -237,6 +238,7 @@ public static CraftingRecipe toNova(IRecipe recipe) { } else if (recipe instanceof ShapedRecipes) { ShapedRecipes shaped = (ShapedRecipes) recipe; + @SuppressWarnings({"unchecked", "rawtypes"}) Optional[][] ingredients = new Optional[shaped.recipeHeight][shaped.recipeWidth]; for (int i = 0; i < shaped.recipeHeight; i++) { for (int j = 0; j < shaped.recipeWidth; j++) { @@ -251,6 +253,7 @@ public static CraftingRecipe toNova(IRecipe recipe) { int width = ReflectionUtil.getShapedOreRecipeWidth(shaped); int height = recipe.getRecipeSize() / width; + @SuppressWarnings({"unchecked", "rawtypes"}) Optional[][] recipeIngredients = new Optional[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/render/RenderUtility.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/render/RenderUtility.java index ec2de699c..0a086975e 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/render/RenderUtility.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/render/RenderUtility.java @@ -23,9 +23,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.RenderHelper; -import net.minecraft.client.renderer.block.model.FaceBakery; -import net.minecraft.client.renderer.block.model.ItemModelGenerator; -import net.minecraft.client.renderer.block.model.ModelBlock; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.IResource; @@ -40,11 +37,13 @@ import net.minecraftforge.fml.relauncher.SideOnly; import nova.core.component.renderer.Renderer; import nova.core.component.renderer.StaticRenderer; +import nova.core.item.ItemFactory; import nova.core.render.texture.Texture; import nova.core.wrapper.mc.forge.v1_11_2.launcher.ForgeLoadable; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.assets.AssetConverter; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.forward.FWBlock; 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.IFWItem; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.render.forward.FWEmptyModel; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.render.forward.FWSmartBlockModel; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.render.forward.FWSmartItemModel; @@ -55,7 +54,6 @@ import java.io.IOException; import java.lang.reflect.Field; import java.util.HashMap; -import java.util.Optional; import static org.lwjgl.opengl.GL11.GL_BLEND; import static org.lwjgl.opengl.GL11.GL_FLAT; @@ -78,37 +76,6 @@ public class RenderUtility implements ForgeLoadable { public static final ResourceLocation particleResource = new ResourceLocation("textures/particle/particles.png"); public static final RenderUtility instance = new RenderUtility(); - // Cruft needed to generate default item models - protected static final ItemModelGenerator ITEM_MODEL_GENERATOR = new ItemModelGenerator(); - protected static final FaceBakery FACE_BAKERY = new FaceBakery(); - // Ugly D: - protected static final ModelBlock MODEL_GENERATED = ModelBlock.deserialize( - "{" + - " \"elements\":[{\n" + - " \"from\": [0, 0, 0],\n" + - " \"to\": [16, 16, 16],\n" + - " \"faces\": {\n" + - " \"down\": {\"uv\": [0, 0, 16, 16], \"texture\":\"\"}\n" + - " }\n" + - " }],\n" + - " \"display\": {\n" + - " \"thirdperson_righthand\": {\n" + - " \"rotation\": [ -90, 0, 0 ],\n" + - " \"translation\": [ 0, 1, -3 ],\n" + - " \"scale\": [ 0.55, 0.55, 0.55 ]\n" + - " },\n" + - " \"firstperson_righthand\": {\n" + - " \"rotation\": [ 0, -90, 25 ],\n" + - " \"translation\": [ 0, 3.75, 2.3125 ],\n" + - " \"scale\": [ 0.6, 0.6, 0.6 ]\n" + - " },\n" + - " \"firstperson_lefthand\": {\n" + - " \"rotation\": [ 0, 90, -25 ],\n" + - " \"translation\": [ 0, 3.75, 2.3125 ],\n" + - " \"scale\": [ 0.6, 0.6, 0.6 ]\n" + - " }\n" + - " }\n" + - "}"); //NOVA Texture to MC TextureAtlasSprite private final HashMap textureMap = new HashMap<>(); @@ -155,12 +122,6 @@ public static void enableLightmap() { OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); } - public TextureAtlasSprite getTexture(Optional texture) { - if (!texture.isPresent()) - return Minecraft.getMinecraft().getTextureMapBlocks().getMissingSprite(); - return getTexture(texture.get()); - } - public TextureAtlasSprite getTexture(Texture texture) { if (textureMap.containsKey(texture)) { return textureMap.get(texture); @@ -179,7 +140,6 @@ public void preTextureHook(TextureStitchEvent.Pre event) { if (event.getMap() == Minecraft.getMinecraft().getTextureMapBlocks()) { Game.render().blockTextures.forEach(t -> registerIcon(t, event)); Game.render().itemTextures.forEach(t -> registerIcon(t, event)); - //TODO: This is HACKS. We should create custom sprite sheets for entities. Game.render().entityTextures.forEach(t -> registerIcon(t, event)); } } @@ -195,7 +155,15 @@ public void textureHook(TextureStitchEvent.Post event) { Game.render().entityTextures.forEach(this::updateTexureDimensions); } + /** + * Update the texture dimensions for the given texture. + * @param texture The texture to update. + * @throws RuntimeException If the texture update fails. + * @see PR review + */ private void updateTexureDimensions(Texture texture) { + // NOTE: This is the only way to update the `dimension` field without breaking anything. + // https://github.com/NOVA-Team/NOVA-Core/pull/265#discussion_r103739268 try { Field dimension = Texture.class.getDeclaredField("dimension"); dimension.setAccessible(true); @@ -219,12 +187,14 @@ public void onModelBakeEvent(ModelBakeEvent event) { ResourceLocation itemRL = Item.REGISTRY.getNameForObject(itemFromBlock); ModelResourceLocation blockLocation = new ModelResourceLocation(blockRL, "normal"); ModelResourceLocation itemLocation = new ModelResourceLocation(itemRL, "inventory"); + ItemFactory itemFactory = ((IFWItem)itemFromBlock).getItemFactory(); + nova.core.item.Item dummy = itemFactory.build(); if (block.dummy.components.has(StaticRenderer.class)) { - event.getModelRegistry().putObject(blockLocation, new FWSmartBlockModel(block.dummy, true)); + event.getModelRegistry().putObject(blockLocation, new FWSmartBlockModel(block.dummy)); } else { event.getModelRegistry().putObject(blockLocation, new FWEmptyModel()); } - event.getModelRegistry().putObject(itemLocation, new FWSmartBlockModel(block.dummy, true)); + event.getModelRegistry().putObject(itemLocation, new FWSmartBlockModel(block.dummy, dummy)); } }); diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/util/MCLanguageManager.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/util/MCLanguageManager.java index 527d58f62..12e36ea68 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/util/MCLanguageManager.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/util/MCLanguageManager.java @@ -20,7 +20,6 @@ package nova.core.wrapper.mc.forge.v1_11_2.util; -import net.minecraft.util.text.translation.I18n; import net.minecraftforge.fml.common.FMLCommonHandler; import nova.core.language.LanguageManager; import nova.core.wrapper.mc.forge.v1_11_2.launcher.ForgeLoadable; @@ -40,16 +39,12 @@ public String getCurrentLanguage() { return FMLCommonHandler.instance().getCurrentLanguage().replace('_', '-'); } - /** - * {@inheritDoc} - * @deprecated Removed in Forge 1.9 - */ @Override - @Deprecated + @SuppressWarnings("deprecation") public String translate(String key) { String value = super.translate(key); if (value.equals(key)) - value = I18n.translateToLocal(key); + value = net.minecraft.util.text.translation.I18n.translateToLocal(key); return value; } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/CategoryConverter.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/CategoryConverter.java index ae0b20b91..bb01a118e 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/CategoryConverter.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/CategoryConverter.java @@ -40,7 +40,7 @@ public class CategoryConverter implements NativeConverter{ public static CategoryConverter instance() { - return (CategoryConverter) Game.natives().getNative(Category.class, CreativeTabs.class); + return Game.natives().getNative(Category.class, CreativeTabs.class); } @Override diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/DirectionConverter.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/DirectionConverter.java index c6bd88bc8..fb6d208bd 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/DirectionConverter.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/DirectionConverter.java @@ -8,6 +8,10 @@ import net.minecraft.util.EnumFacing; import nova.core.nativewrapper.NativeConverter; import nova.core.util.Direction; +import nova.internal.core.Game; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; /** * @@ -15,6 +19,10 @@ */ public class DirectionConverter implements NativeConverter { + public static DirectionConverter instance() { + return Game.natives().getNative(Direction.class, EnumFacing.class); + } + @Override public Class getNovaSide() { return Direction.class; @@ -26,7 +34,7 @@ public Class getNativeSide() { } @Override - public Direction toNova(EnumFacing nativeObj) { + public Direction toNova(@Nullable EnumFacing nativeObj) { if (null == nativeObj) return Direction.UNKNOWN; else switch (nativeObj) { @@ -41,6 +49,7 @@ else switch (nativeObj) { } @Override + @Nullable public EnumFacing toNative(Direction novaObj) { switch (novaObj) { case DOWN: return EnumFacing.DOWN; @@ -49,7 +58,7 @@ public EnumFacing toNative(Direction novaObj) { case SOUTH: return EnumFacing.SOUTH; case WEST: return EnumFacing.WEST; case EAST: return EnumFacing.EAST; - default: return (EnumFacing) null; + default: return null; } } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/VectorConverter.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/VectorConverter.java index 5d336b43a..44880c8dc 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/VectorConverter.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/VectorConverter.java @@ -22,9 +22,15 @@ import net.minecraft.util.math.BlockPos; import nova.core.nativewrapper.NativeConverter; +import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; public class VectorConverter implements NativeConverter { + + public static VectorConverter instance() { + return Game.natives().getNative(Vector3D.class, BlockPos.class); + } + @Override public Class getNovaSide() { return Vector3D.class; diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/AssetConverter.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/AssetConverter.java index ccd2260c9..6c6b3f057 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/AssetConverter.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/AssetConverter.java @@ -32,7 +32,7 @@ public final class AssetConverter implements NativeConverter { public static AssetConverter instance() { - return (AssetConverter) Game.natives().getNative(Asset.class, ResourceLocation.class); + return Game.natives().getNative(Asset.class, ResourceLocation.class); } @Override diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/NovaFileResourcePack.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/NovaFileResourcePack.java index c5fd41dd8..67e6ed296 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/NovaFileResourcePack.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/NovaFileResourcePack.java @@ -23,16 +23,23 @@ import com.google.common.base.Charsets; import net.minecraft.client.resources.FileResourcePack; import net.minecraft.util.ResourceLocation; +import nova.core.language.LanguageManager; import nova.core.wrapper.mc.forge.v1_11_2.NovaMinecraftPreloader; +import nova.internal.core.Game; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.Optional; +import java.util.Properties; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -109,8 +116,22 @@ public boolean resourceExists(ResourceLocation rl) { } @Override - public String getPackName() { - return NovaResourcePack.super.getPackName(); + public Set getLanguageFiles() { + Pattern langPattern = Pattern.compile("^assets/([^/]+)/(lang/[a-zA-Z0-9-]+\\.lang)$", Pattern.CASE_INSENSITIVE); + + try { + return getResourcePackZipFile().stream() + .map(e -> { + Matcher m = langPattern.matcher(e.getName()); + if (!m.matches()) + return null; + return new ResourceLocation(m.group(1), m.group(2)); + }) + .filter(e -> e != null) + .collect(Collectors.toSet()); + } catch (IOException ex) { + return Collections.emptySet(); + } } @Override diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/NovaFolderResourcePack.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/NovaFolderResourcePack.java index b6c9d6786..641575e65 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/NovaFolderResourcePack.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/NovaFolderResourcePack.java @@ -23,6 +23,7 @@ import com.google.common.base.Charsets; import net.minecraft.client.resources.FolderResourcePack; import net.minecraft.util.ResourceLocation; +import nova.core.language.LanguageManager; import nova.core.wrapper.mc.forge.v1_11_2.NovaMinecraftPreloader; import java.io.BufferedInputStream; @@ -34,7 +35,10 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Optional; +import java.util.Properties; import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; public class NovaFolderResourcePack extends FolderResourcePack implements NovaResourcePack { private final String modid; @@ -100,8 +104,20 @@ public boolean resourceExists(ResourceLocation rl) { } @Override - public String getPackName() { - return NovaResourcePack.super.getPackName(); + public Set getLanguageFiles() { + Pattern langPattern = Pattern.compile("^[a-zA-Z0-9-]+\\.lang$", Pattern.CASE_INSENSITIVE); + + Set langFiles = new HashSet<>(); + + for (String domain : getResourceDomains()) { + findFileCaseInsensitive("assets/" + domain + "/lang/").filter(File::isDirectory).ifPresent(file -> { + Arrays.stream(file.listFiles((dir, name) -> langPattern.asPredicate().test(name))) + .map(File::getName) + .forEach(name -> langFiles.add(new ResourceLocation(domain, name))); + }); + } + + return langFiles; } @Override diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/NovaResourcePack.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/NovaResourcePack.java index bd0e6fcdb..c655fe851 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/NovaResourcePack.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/assets/NovaResourcePack.java @@ -20,6 +20,7 @@ package nova.core.wrapper.mc.forge.v1_11_2.wrapper.assets; +import net.minecraft.client.resources.IResourcePack; import net.minecraft.util.ResourceLocation; import nova.core.util.Identifiable; @@ -27,11 +28,12 @@ import java.io.InputStream; import java.util.LinkedList; import java.util.Optional; +import java.util.Set; /** * @author ExE Boss */ -public interface NovaResourcePack extends Identifiable { +public interface NovaResourcePack extends Identifiable, IResourcePack { default String transform(ResourceLocation rl) { return transform(String.format("assets/%s/%s", rl.getResourceDomain(), toAbsolutePath(rl.getResourcePath()))); @@ -41,10 +43,13 @@ default String transform(String path) { return toAbsolutePath(path.toLowerCase().replace('\\', '/').replaceFirst("^assets/minecraft", "assets/" + getID())); } + @Override default String getPackName() { return getClass().getSimpleName() + ':' + getID(); } + Set getLanguageFiles(); + InputStream getInputStreamCaseInsensitive(String path) throws IOException; Optional findFileCaseInsensitive(String path); diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/BlockConverter.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/BlockConverter.java index 049bed661..919e5428a 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/BlockConverter.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/BlockConverter.java @@ -56,7 +56,7 @@ public class BlockConverter implements NativeConverter blockFactoryMap = new HashMap<>(); public static BlockConverter instance() { - return (BlockConverter) Game.natives().getNative(Block.class, net.minecraft.block.Block.class); + return Game.natives().getNative(Block.class, net.minecraft.block.Block.class); } @Override @@ -87,7 +87,7 @@ public Block toNova(net.minecraft.block.Block nativeBlock) { public net.minecraft.block.Block toNative(Block novaBlock) { //Prevent recursive wrapping if (novaBlock instanceof BWBlock) { - return ((BWBlock) novaBlock).mcBlock; + return ((BWBlock) novaBlock).block(); } return toNative(novaBlock.getFactory()); diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/backward/BWBlock.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/backward/BWBlock.java index 9c62b8fd3..89e558790 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/backward/BWBlock.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/backward/BWBlock.java @@ -23,6 +23,8 @@ import net.minecraft.block.BlockSnow; import net.minecraft.block.SoundType; import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -30,11 +32,13 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.IBlockAccess; import nova.core.block.Block; import nova.core.block.component.BlockProperty; import nova.core.block.component.LightEmitter; import nova.core.component.misc.Collider; +import nova.core.component.renderer.StaticRenderer; import nova.core.component.transform.BlockTransform; import nova.core.item.ItemFactory; import nova.core.retention.Data; @@ -44,26 +48,28 @@ import nova.core.util.shape.Cuboid; import nova.core.world.World; import nova.core.wrapper.mc.forge.v1_11_2.util.WrapperEvent; -import nova.core.wrapper.mc.forge.v1_11_2.wrapper.block.world.BWWorld; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.render.backward.BWBakedModel; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; public class BWBlock extends Block implements Storable { - public final net.minecraft.block.Block mcBlock; + private final net.minecraft.block.Block block; @Store - public int metadata; private TileEntity mcTileEntity; public BWBlock(net.minecraft.block.Block block) { - this.mcBlock = block; + this.block = block; } + @SuppressWarnings("deprecation") public BWBlock(net.minecraft.block.Block block, World world, Vector3D pos) { - this.mcBlock = block; + this.block = block; BlockTransform transform = components.add(new BlockTransform()); transform.setWorld(world); @@ -73,33 +79,36 @@ public BWBlock(net.minecraft.block.Block block, World world, Vector3D pos) { BlockProperty.BlockSound blockSound = components.add(new BlockProperty.BlockSound()); SoundType soundType; - if (getMcBlockAccess() instanceof net.minecraft.world.World) - soundType = mcBlock.getSoundType(blockState(), (net.minecraft.world.World)getMcBlockAccess(), new BlockPos(x(), y(), z()), null); + if (blockAccess() instanceof net.minecraft.world.World) + soundType = block.getSoundType(blockState(), (net.minecraft.world.World)blockAccess(), blockPos(), null); else - soundType = mcBlock.getSoundType(); + soundType = block.getSoundType(); - blockSound.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.PLACE, - new Sound(soundType.getPlaceSound().getSoundName().getResourceDomain(), - soundType.getPlaceSound().getSoundName().getResourcePath())); + if (soundType.getPlaceSound() != null) + blockSound.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.PLACE, + new Sound(soundType.getPlaceSound().getSoundName().getResourceDomain(), + soundType.getPlaceSound().getSoundName().getResourcePath())); - blockSound.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.BREAK, - new Sound(soundType.getBreakSound().getSoundName().getResourceDomain(), - soundType.getBreakSound().getSoundName().getResourcePath())); + if (soundType.getBreakSound() != null) + blockSound.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.BREAK, + new Sound(soundType.getBreakSound().getSoundName().getResourceDomain(), + soundType.getBreakSound().getSoundName().getResourcePath())); - blockSound.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.WALK, - new Sound(soundType.getStepSound().getSoundName().getResourceDomain(), - soundType.getStepSound().getSoundName().getResourcePath())); + if (soundType.getStepSound() != null) + blockSound.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.WALK, + new Sound(soundType.getStepSound().getSoundName().getResourceDomain(), + soundType.getStepSound().getSoundName().getResourcePath())); - components.add(new LightEmitter()).setEmittedLevel(() -> blockState().getLightValue(getMcBlockAccess(), new BlockPos(x(), y(), z())) / 15.0F); + components.add(new LightEmitter()).setEmittedLevel(() -> blockState().getLightValue(blockAccess(), blockPos()) / 15d); components.add(new Collider(this)) .setBoundingBox(() -> { - AxisAlignedBB aabb = blockState().getBoundingBox(getMcBlockAccess(), new BlockPos(x(), y(), z())); + AxisAlignedBB aabb = blockState().getBoundingBox(blockAccess(), blockPos()); return new Cuboid(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ); }).setOcclusionBoxes(entity -> { List aabbs = new ArrayList<>(); blockState().addCollisionBoxToList( Game.natives().toNative(world()), - new BlockPos(x(), y(), z()), + blockPos(), Game.natives().toNative(entity.isPresent() ? entity.get().components.get(Collider.class).boundingBox.get() : Cuboid.ONE.add(pos)), aabbs, entity.isPresent() ? Game.natives().toNative(entity.get()) : null, @@ -109,44 +118,93 @@ public BWBlock(net.minecraft.block.Block block, World world, Vector3D pos) { .map(aabb -> (Cuboid) Game.natives().toNova(aabb)) .map(cuboid -> cuboid.subtract(pos)) .collect(Collectors.toSet()); + }).setSelectionBoxes(entity -> { + AxisAlignedBB bb; + if (blockAccess() instanceof net.minecraft.world.World) { + @SuppressWarnings("deprecation") + AxisAlignedBB bb1 = block.getSelectedBoundingBox(blockState(), ((net.minecraft.world.World) blockAccess()), blockPos()); + bb = bb1; + } else { + bb = blockState().getBoundingBox(blockAccess(), blockPos()).offset(blockPos()); + } + Cuboid cuboid = Game.natives().toNova(bb); + return Collections.singleton(cuboid.subtract(position())); }); - WrapperEvent.BWBlockCreate event = new WrapperEvent.BWBlockCreate(world, pos, this, mcBlock); - Game.events().publish(event); //TODO: Set selection bounds + components.add(new StaticRenderer()) + .onRender(model -> { + switch (blockState().getRenderType()) { + case INVISIBLE: + // rendering of invisible type + break; + case LIQUID: + // fluid rendering + // TODO + break; + case ENTITYBLOCK_ANIMATED: + // dynamic block rendering + // Handled by DynamicRenderer + break; + case MODEL: + // model rendering + model.addChild(new BWBakedModel(Minecraft.getMinecraft().getBlockRendererDispatcher() + .getModelForState(blockState()), DefaultVertexFormats.BLOCK, + Optional.of(blockState()), MathHelper.getPositionRandom(blockPos()))); + break; + default: + break; + } + }); + // TODO: TileEntity rendering using DynamicRenderer + + WrapperEvent.BWBlockCreate event = new WrapperEvent.BWBlockCreate(world, pos, this, block); + Game.events().publish(event); } @Override public ItemFactory getItemFactory() { - return Game.natives().toNova(new ItemStack(Item.getItemFromBlock(mcBlock))); + return Game.natives().toNova(new ItemStack(Item.getItemFromBlock(block))); + } + + public net.minecraft.block.Block block() { + return block; } - public IBlockAccess getMcBlockAccess() { - return ((BWWorld) world()).access; + public int meta() { + return block.getMetaFromState(blockState()); + } + + public BlockPos blockPos() { + return new BlockPos(x(), y(), z()); + } + + public IBlockAccess blockAccess() { + return Game.natives().toNative(world()); } public IBlockState blockState() { - return getMcBlockAccess().getBlockState(new BlockPos(x(), y(), z())); + return blockAccess().getBlockState(blockPos()); } - public TileEntity getTileEntity() { - if (mcTileEntity == null && mcBlock.hasTileEntity(blockState())) { - mcTileEntity = getMcBlockAccess().getTileEntity(new BlockPos(x(), y(), z())); + public Optional tile() { + if (mcTileEntity == null && block.hasTileEntity(blockState())) { + mcTileEntity = blockAccess().getTileEntity(blockPos()); } - return mcTileEntity; + return Optional.ofNullable(mcTileEntity); } @Override public boolean canReplace() { - return mcBlock.canPlaceBlockAt((net.minecraft.world.World) getMcBlockAccess(), new BlockPos(x(), y(), z())); + return block.canPlaceBlockAt((net.minecraft.world.World) blockAccess(), blockPos()); } @Override public boolean shouldDisplacePlacement() { - if (mcBlock == Blocks.SNOW_LAYER && ((int) blockState().getValue(BlockSnow.LAYERS) < 1)) { + if (block == Blocks.SNOW_LAYER && (blockState().getValue(BlockSnow.LAYERS) < 1)) { return false; } - if (mcBlock == Blocks.VINE || mcBlock == Blocks.TALLGRASS || mcBlock == Blocks.DEADBUSH || mcBlock.isReplaceable(Game.natives().toNative(world()), new BlockPos(x(), y(), z()))) { + if (block == Blocks.VINE || block == Blocks.TALLGRASS || block == Blocks.DEADBUSH || block.isReplaceable(blockAccess(), blockPos())) { return false; } return super.shouldDisplacePlacement(); @@ -156,21 +214,34 @@ public boolean shouldDisplacePlacement() { public void save(Data data) { Storable.super.save(data); - TileEntity tileEntity = getTileEntity(); - if (tileEntity != null) { + tile().ifPresent(tile -> { NBTTagCompound nbt = new NBTTagCompound(); - tileEntity.writeToNBT(nbt); + tile.writeToNBT(nbt); data.putAll(Game.natives().toNova(nbt)); - } + }); } @Override public void load(Data data) { Storable.super.load(data); - TileEntity tileEntity = getTileEntity(); - if (tileEntity != null) { - tileEntity.writeToNBT(Game.natives().toNative(data)); - } + tile().ifPresent(tile -> { + tile.readFromNBT(Game.natives().toNative(data)); + }); + } + + @Override + public String getLocalizedName() { + return block.getLocalizedName(); + } + + @Override + public String getUnlocalizedName() { + return block.getUnlocalizedName(); + } + + @Override + public String toString() { + return getID() + '(' + world() + '@' + x() + ',' + y() + ',' + z() + ')'; } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWBlock.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWBlock.java index 538429691..c1e8c8faf 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWBlock.java @@ -49,8 +49,10 @@ import nova.core.sound.Sound; import nova.core.util.Direction; import nova.core.util.math.MathUtil; +import nova.core.util.math.Vector3DUtil; 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.VectorConverter; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; @@ -73,6 +75,9 @@ public class FWBlock extends net.minecraft.block.Block { */ private final BlockFactory factory; private final Class blockClass; + //TODO: Hack. Bad practice. + public IBlockAccess lastExtendedWorld; + public BlockPos lastExtendedStatePos; private Map harvestedBlocks = new HashMap<>(); private static Material getMcMaterial(BlockFactory factory) { @@ -96,9 +101,9 @@ public FWBlock(BlockFactory factory) { this.blockSoundType = new FWBlockSound(dummy.components.get(BlockProperty.BlockSound.class)); } else { BlockProperty.BlockSound properties = dummy.components.add(new BlockProperty.BlockSound()); - properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.BREAK, new Sound("", SoundType.STONE.getBreakSound().getSoundName().getResourcePath())); - properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.PLACE, new Sound("", SoundType.STONE.getPlaceSound().getSoundName().getResourcePath())); - properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.WALK, new Sound("", SoundType.STONE.getStepSound().getSoundName().getResourcePath())); + properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.BREAK, new Sound(SoundType.STONE.getBreakSound().getSoundName().getResourceDomain(), SoundType.STONE.getBreakSound().getSoundName().getResourcePath())); + properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.PLACE, new Sound(SoundType.STONE.getPlaceSound().getSoundName().getResourceDomain(), SoundType.STONE.getPlaceSound().getSoundName().getResourcePath())); + properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.WALK, new Sound(SoundType.STONE.getStepSound().getSoundName().getResourceDomain(), SoundType.STONE.getStepSound().getSoundName().getResourcePath())); this.blockSoundType = SoundType.STONE; } this.blockClass = dummy.getClass(); @@ -186,14 +191,32 @@ public boolean hasTileEntity(IBlockState state) { @Override public TileEntity createTileEntity(World world, IBlockState state) { - return FWTileLoader.loadTile(dummy.getID()); + FWTile fwTile = FWTileLoader.loadTile(dummy.getID()); + if (lastExtendedStatePos != null) { + fwTile.getBlock().components.getOrAdd(new MCBlockTransform(dummy, Game.natives().toNova(world), new Vector3D(lastExtendedStatePos.getX(), lastExtendedStatePos.getY(), lastExtendedStatePos.getZ()))); + lastExtendedStatePos = null; + } + if (!fwTile.getBlock().components.has(BlockProperty.BlockSound.class)) { + BlockProperty.BlockSound properties = fwTile.getBlock().components.add(new BlockProperty.BlockSound()); + properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.BREAK, new Sound(SoundType.STONE.getBreakSound().getSoundName().getResourceDomain(), SoundType.STONE.getBreakSound().getSoundName().getResourcePath())); + properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.PLACE, new Sound(SoundType.STONE.getPlaceSound().getSoundName().getResourceDomain(), SoundType.STONE.getPlaceSound().getSoundName().getResourcePath())); + properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.WALK, new Sound(SoundType.STONE.getStepSound().getSoundName().getResourceDomain(), SoundType.STONE.getStepSound().getSoundName().getResourcePath())); + } + return fwTile; + } + + @Override + public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) { + lastExtendedWorld = world; + lastExtendedStatePos = pos; + return super.getExtendedState(state, world, pos); } @Override - public void onNeighborChange(IBlockAccess world, BlockPos pos, BlockPos neighborBlock) { + public void onNeighborChange(IBlockAccess world, BlockPos pos, BlockPos neighbor) { Block blockInstance = getBlockInstance(world, new Vector3D(pos.getX(), pos.getY(), pos.getZ())); - // Minecraft does not provide the neighbor :( - Block.NeighborChangeEvent evt = new Block.NeighborChangeEvent(Optional.empty()); + Block.NeighborChangeEvent evt = new Block.NeighborChangeEvent( + Optional.of(VectorConverter.instance().toNova(neighbor))); blockInstance.events.publish(evt); } @@ -247,7 +270,10 @@ public AxisAlignedBB getSelectedBoundingBox(IBlockState state, World world, Bloc Block blockInstance = getBlockInstance(world, new Vector3D(pos.getX(), pos.getY(), pos.getZ())); if (blockInstance.components.has(Collider.class)) { - Cuboid cuboid = blockInstance.components.get(Collider.class).boundingBox.get(); + Collider collider = blockInstance.components.get(Collider.class); + Set cuboids = collider.selectionBoxes.apply(Optional.empty()); + Cuboid cuboid = cuboids.stream().reduce(collider.boundingBox.get(), + (c1, c2) -> new Cuboid(Vector3DUtil.min(c1.min, c2.min), Vector3DUtil.max(c1.max, c2.max))); return Game.natives().toNative(cuboid.add(new Vector3D(pos.getX(), pos.getY(), pos.getZ()))); } return super.getSelectedBoundingBox(state, world, pos); @@ -358,7 +384,12 @@ public int getStrongPower(IBlockState state, IBlockAccess access, BlockPos pos, @Override public String getUnlocalizedName() { - return super.getUnlocalizedName().replaceFirst("tile", "block"); + return factory.getUnlocalizedName(); + } + + @Override + public String getLocalizedName() { + return factory.getLocalizedName(); } @Override 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 d2bb46e56..3ac182b4b 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 @@ -110,9 +110,9 @@ public NBTTagCompound writeToNBT(NBTTagCompound nbt) { if (block != null) { if (block instanceof Storable) { - Data data = new Data(); - ((Storable) block).save(data); - nbt.setTag("nova", Game.natives().toNative(data)); + Data data = new Data(); + ((Storable) block).save(data); + nbt.setTag("nova", Game.natives().toNative(data)); } } @@ -162,9 +162,9 @@ public T getCapability(Capability capability, EnumFacing facing) { @Override public void setPos(BlockPos pos) { super.setPos(pos); - if (this.block.components.has(MCBlockTransform.class)) - this.block.components.remove(MCBlockTransform.class); - this.block.components.add(new MCBlockTransform(this.block, Game.natives().toNova(this.getWorld()), Game.natives().toNova(this.getPos()))); + if (block.components.has(MCBlockTransform.class)) + block.components.remove(MCBlockTransform.class); + block.components.add(new MCBlockTransform(block, Game.natives().toNova(this.getWorld()), Game.natives().toNova(this.getPos()))); } private static class FWPacketUpdateTileEntity extends SPacketUpdateTileEntity { diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWTileRenderer.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWTileRenderer.java index 9a6331749..0d141fb28 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWTileRenderer.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWTileRenderer.java @@ -42,7 +42,7 @@ public class FWTileRenderer extends TileEntitySpecialRenderer { public static final FWTileRenderer instance = new FWTileRenderer(); @Override - public void renderTileEntityAt(FWTile te, double x, double y, double z, float p_180535_8_, int p_180535_9_) { + public void renderTileEntityAt(FWTile te, double x, double y, double z, float partialTicks, int destroyStage) { Block block = te.getBlock(); Optional opRenderer = block.components.getOp(DynamicRenderer.class); if (opRenderer.isPresent()) { @@ -52,7 +52,7 @@ public void renderTileEntityAt(FWTile te, double x, double y, double z, float p_ bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); RenderUtility.enableBlending(); Tessellator.getInstance().getBuffer().begin(GL_QUADS, DefaultVertexFormats.BLOCK); - model.render(); + model.render(te.getWorld()); Tessellator.getInstance().draw(); RenderUtility.disableBlending(); } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWTileUpdater.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWTileUpdater.java index 43d189e12..112d778cd 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWTileUpdater.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/forward/FWTileUpdater.java @@ -28,7 +28,6 @@ */ public class FWTileUpdater extends FWTile implements ITickable { public FWTileUpdater() { - } public FWTileUpdater(String blockID) { diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/world/WorldConverter.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/world/WorldConverter.java index a4e70edb5..39c846414 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/world/WorldConverter.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/block/world/WorldConverter.java @@ -31,6 +31,11 @@ * @author Calclavia */ public class WorldConverter implements NativeConverter { + + public static WorldConverter instance() { + return Game.natives().getNative(World.class, IBlockAccess.class); + } + @Override public Class getNovaSide() { return World.class; @@ -56,10 +61,9 @@ public World toNova(IBlockAccess nativeObj) { @Override public IBlockAccess toNative(World novaObj) { if (novaObj instanceof BWWorld) { - return ((BWWorld) novaObj).world(); + return ((BWWorld) novaObj).access; } - //TODO: Right exception? - throw new RuntimeException("Attempt to convert a world that is not a BWWorld!"); + throw new UnsupportedOperationException("Attempt to convert a world that is not a BWWorld!"); } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/cuboid/CuboidConverter.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/cuboid/CuboidConverter.java index 888fb1100..864a99fc7 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/cuboid/CuboidConverter.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/cuboid/CuboidConverter.java @@ -23,12 +23,18 @@ import net.minecraft.util.math.AxisAlignedBB; import nova.core.nativewrapper.NativeConverter; import nova.core.util.shape.Cuboid; +import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; /** * @author Calclavia */ public class CuboidConverter implements NativeConverter { + + public static CuboidConverter instance() { + return Game.natives().getNative(Cuboid.class, AxisAlignedBB.class); + } + @Override public Class getNovaSide() { return Cuboid.class; diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/data/DataWrapper.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/data/DataConverter.java similarity index 96% rename from minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/data/DataWrapper.java rename to minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/data/DataConverter.java index d5cfc932c..8e4a55ace 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/data/DataWrapper.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/data/DataConverter.java @@ -41,10 +41,10 @@ * Utility that manages common NBT queueSave and load methods * @author Calclavia */ -public class DataWrapper implements NativeConverter { +public class DataConverter implements NativeConverter { - public static DataWrapper instance() { - return (DataWrapper) Game.natives().getNative(Data.class, NBTTagCompound.class); + public static DataConverter instance() { + return Game.natives().getNative(Data.class, NBTTagCompound.class); } @Override diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/EntityConverter.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/EntityConverter.java index 5eb83db59..a08eac203 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/EntityConverter.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/EntityConverter.java @@ -38,6 +38,10 @@ public class EntityConverter implements NativeConverter, ForgeLoadable { + public static EntityConverter instance() { + return Game.natives().getNative(Entity.class, net.minecraft.entity.Entity.class); + } + @Override public Class getNovaSide() { return Entity.class; diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/backward/BWEntity.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/backward/BWEntity.java index 9cd31e4fb..756b6feb5 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/backward/BWEntity.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/entity/backward/BWEntity.java @@ -45,18 +45,17 @@ public class BWEntity extends Entity { public BWEntity(net.minecraft.entity.Entity entity) { this.entity = entity; - if (entity != null) { - components.add(new MCEntityTransform(entity)); - components.add(new Damageable() { - @Override - public void damage(double amount, DamageType type) { - if (type == DamageType.generic) { - entity.attackEntityFrom(DamageSource.GENERIC, (float) amount); - } - // TODO: Apply other damage source wrappers? + + components.add(new MCEntityTransform(entity)); + components.add(new Damageable() { + @Override + public void damage(double amount, DamageType type) { + if (type == DamageType.generic) { + entity.attackEntityFrom(DamageSource.GENERIC, (float) amount); } - }); - } + // TODO: Apply other damage source wrappers? + } + }); if (entity instanceof EntityLivingBase) { if (entity instanceof EntityPlayer) { 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 c4bf2890c..971e65d27 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 @@ -37,7 +37,7 @@ 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.data.DataWrapper; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.data.DataConverter; import nova.internal.core.Game; import java.util.HashMap; @@ -83,7 +83,7 @@ protected void writeEntityToNBT(NBTTagCompound nbt) { if (wrapped instanceof Storable) { Data data = new Data(); ((Storable) wrapped).save(data); - DataWrapper.instance().toNative(nbt, data); + DataConverter.instance().toNative(nbt, data); } nbt.setString("novaID", wrapped.getID()); } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/inventory/InventoryConverter.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/inventory/InventoryConverter.java index 08d82c8e5..f53814f64 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/inventory/InventoryConverter.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/inventory/InventoryConverter.java @@ -23,11 +23,17 @@ import net.minecraft.inventory.IInventory; import nova.core.component.inventory.Inventory; import nova.core.nativewrapper.NativeConverter; +import nova.internal.core.Game; /** * @author Calclavia */ public class InventoryConverter implements NativeConverter { + + public static InventoryConverter instance() { + return Game.natives().getNative(Inventory.class, IInventory.class); + } + @Override public Class getNovaSide() { return Inventory.class; 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 f07912db7..6dca71931 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 @@ -60,7 +60,7 @@ public class ItemConverter implements NativeConverter, ForgeLoa private final HashBiMap map = HashBiMap.create(); public static ItemConverter instance() { - return (ItemConverter) Game.natives().getNative(Item.class, ItemStack.class); + return Game.natives().getNative(Item.class, ItemStack.class); } @Override @@ -78,8 +78,6 @@ public Item toNova(ItemStack itemStack) { return getNovaItem(itemStack).setCount(itemStack.getCount()); } - //TODO: Why is this method separate? - // Maybe because toNova calls setCount on the result of this method? public Item getNovaItem(ItemStack itemStack) { if (itemStack.getItemDamage() == net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE) { // TODO: Deal withPriority wildcard meta values - important for the ore dictionary @@ -87,7 +85,7 @@ public Item getNovaItem(ItemStack itemStack) { } if (itemStack.getTagCompound() != null && itemStack.getTagCompound() instanceof FWNBTTagCompound) { - return ((FWNBTTagCompound) itemStack.getTagCompound()).getItem(); + return Objects.requireNonNull((FWNBTTagCompound) itemStack.getTagCompound()).getItem(); } else { ItemFactory itemFactory = registerMinecraftMapping(itemStack.getItem(), itemStack.getItemDamage()); diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/OreDictionaryIntegration.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/OreDictionaryIntegration.java index a2a288c92..8a2c823cf 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/OreDictionaryIntegration.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/OreDictionaryIntegration.java @@ -21,7 +21,10 @@ package nova.core.wrapper.mc.forge.v1_11_2.wrapper.item; import net.minecraft.item.ItemStack; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.oredict.OreDictionary; +import nova.core.event.DictionaryEvent; import nova.core.item.Item; import nova.core.item.ItemDictionary; import nova.core.util.Dictionary; @@ -29,7 +32,9 @@ import nova.internal.core.Game; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Optional; /** * Created by Stan on 8/02/2015. @@ -44,44 +49,48 @@ private OreDictionaryIntegration() { public void registerOreDictionary() { ItemDictionary novaItemDictionary = Game.itemDictionary(); - for (String oredictEntry : novaItemDictionary.keys()) { - for (Item oreValue : novaItemDictionary.get(oredictEntry)) { - OreDictionary.registerOre(oredictEntry, ItemConverter.instance().toNative(oreValue)); - } - } + novaItemDictionary.stream().forEach(entry -> { + entry.getValue().stream() + .map(ItemConverter.instance()::toNative) + .filter(item -> !OreDictionary.getOres(entry.getKey()).contains(item)) + .forEach(item -> OreDictionary.registerOre(entry.getKey(), item)); + }); - for (String oredictEntry : OreDictionary.getOreNames()) { - for (ItemStack oreValue : OreDictionary.getOres(oredictEntry)) { - Item novaItem = ItemConverter.instance().getNovaItem(oreValue); - if (!novaItemDictionary.get(oredictEntry).contains(novaItem)) { - novaItemDictionary.add(oredictEntry, novaItem); - } - } - } + Arrays.stream(OreDictionary.getOreNames()).forEach(key -> { + OreDictionary.getOres(key).stream() + .map(ItemConverter.instance()::getNovaItem) + .filter(item -> !novaItemDictionary.get(key).contains(item)) + .forEach(item -> novaItemDictionary.add(key, item)); + }); - novaItemDictionary.whenEntryAdded(this::onEntryAdded); - novaItemDictionary.whenEntryRemoved(this::onEntryRemoved); + novaItemDictionary.whenEntryAdded(this::onNovaAdded); + novaItemDictionary.whenEntryRemoved(this::onNovaRemoved); + MinecraftForge.EVENT_BUS.register(this); } - private void onEntryAdded(Dictionary.AddEvent event) { - ItemStack nativeValue = ItemConverter.instance().toNative(event.value); - if (!OreDictionary.getOres(event.key).contains(nativeValue)) { - OreDictionary.registerOre(event.key, nativeValue); + private void onNovaAdded(DictionaryEvent.Add event) { + ItemStack nativeStack = ItemConverter.instance().toNative(event.value); + if (!OreDictionary.getOres(event.key).stream().anyMatch(stack -> stack.isItemEqual(nativeStack))) { + OreDictionary.registerOre(event.key, nativeStack); } } - private void onEntryRemoved(Dictionary.RemoveEvent event) { + private void onNovaRemoved(DictionaryEvent.Remove event) { int id = OreDictionary.getOreID(event.key); - ItemStack itemStack = ItemConverter.instance().toNative(event.value); - ItemStack toRemove = null; - for (ItemStack oreDictItemStack : OreDictionary.getOres(event.key)) { - if (oreDictItemStack.getItem() == itemStack.getItem() && toRemove.getItemDamage() == oreDictItemStack.getItemDamage()) { - toRemove = oreDictItemStack; - } + ItemStack nativeStack = ItemConverter.instance().toNative(event.value); + Optional toRemove = OreDictionary.getOres(event.key).stream().filter(stack -> stack.isItemEqual(nativeStack)).findFirst(); + + if (toRemove.isPresent()) { + OREDICT_CONTENTS.get(id).remove(toRemove.get()); } + } - if (toRemove != null) { - OREDICT_CONTENTS.get(id).remove(toRemove); + @SubscribeEvent + public void onForgeAdded(OreDictionary.OreRegisterEvent event) { + Item novaItem = ItemConverter.instance().getNovaItem(event.getOre()); + ItemDictionary novaItemDictionary = Game.itemDictionary(); + if (!novaItemDictionary.get(event.getName()).contains(novaItem)) { + novaItemDictionary.add(event.getName(), novaItem); } } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/backward/BWItem.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/backward/BWItem.java index b0d0eca3f..f1403e7e7 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/backward/BWItem.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/backward/BWItem.java @@ -20,10 +20,13 @@ package nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.backward; +import net.minecraft.client.Minecraft; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import nova.core.component.renderer.StaticRenderer; import nova.core.item.Item; import nova.core.retention.Storable; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.render.backward.BWBakedModel; /** * @author Stan @@ -42,6 +45,12 @@ public BWItem(net.minecraft.item.Item item, int meta, NBTTagCompound tag) { this.item = item; this.meta = meta; this.tag = tag; + + components.add(new StaticRenderer()) + .onRender(model -> { + model.addChild(new BWBakedModel(Minecraft.getMinecraft().getRenderItem() + .getItemModelMesher().getItemModel(makeItemStack(count())))); + }); } public net.minecraft.item.Item getItem() { @@ -64,6 +73,16 @@ public ItemStack makeItemStack(int stackSize) { return result; } + @Override + public String getLocalizedName() { + return this.item.getItemStackDisplayName(makeItemStack(count())); + } + + @Override + public String getUnlocalizedName() { + return this.item.getUnlocalizedName(makeItemStack(count())); + } + @Override public String toString() { return getID(); diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/backward/BWItemFactory.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/backward/BWItemFactory.java index 74535afa6..935587385 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/backward/BWItemFactory.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/backward/BWItemFactory.java @@ -52,6 +52,11 @@ public int getMeta() { return meta; } + @Override + public String getUnlocalizedName() { + return this.item.getUnlocalizedName(); + } + @Override public Item build(Data data) { int meta = (Integer) data.getOrDefault("damage", this.meta); 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 486f275a0..540e75daf 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 @@ -20,7 +20,6 @@ package nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.forward; -import nova.core.wrapper.mc.forge.v1_11_2.wrapper.capability.forward.FWCapabilityProvider; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -34,18 +33,16 @@ 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 java.util.List; - -import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.ItemWrapperMethods; -import nova.internal.core.Game; - import javax.annotation.Nullable; /** * @author Calclavia */ -public class FWItem extends net.minecraft.item.Item implements ItemWrapperMethods { +public class FWItem extends net.minecraft.item.Item implements IFWItem { public final ItemFactory itemFactory; @@ -58,7 +55,7 @@ public FWItem(ItemFactory item) { @Override @Nullable public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable NBTTagCompound nbt) { - Item item = Game.natives().toNova(stack); + Item item = ItemConverter.instance().toNova(stack); WrapperEvent.FWItemInitCapabilities event = new WrapperEvent.FWItemInitCapabilities(item, new FWCapabilityProvider()); return event.capabilityProvider.hasCapabilities() ? event.capabilityProvider : null; } @@ -70,22 +67,36 @@ public ItemFactory getItemFactory() { @Override public void addInformation(ItemStack itemStack, EntityPlayer player, List tooltip, boolean advanced) { - ItemWrapperMethods.super.addInformation(itemStack, player, tooltip, advanced); + IFWItem.super.addInformation(itemStack, player, tooltip, advanced); } @Override public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) { - return ItemWrapperMethods.super.onItemUse(player.getHeldItem(hand), player, world, pos.getX(), pos.getY(), pos.getZ(), side.ordinal(), hitX, hitY, hitZ); + return IFWItem.super.onItemUse(player.getHeldItem(hand), player, world, pos.getX(), pos.getY(), pos.getZ(), side.ordinal(), hitX, hitY, hitZ); + } + + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + return IFWItem.super.onItemRightClick(player.getHeldItem(hand), world, player); + } + + @Override + public int getColorFromItemStack(ItemStack itemStack, int renderPass) { + return IFWItem.super.getColorFromItemStack(itemStack, renderPass); } @Override - public ActionResult onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) { - return ItemWrapperMethods.super.onItemRightClick(itemStack, world, player); + public String getUnlocalizedName() { + return getItemFactory().getUnlocalizedName(); } @Override - public int getColorFromItemStack(ItemStack itemStack, int p_82790_2_) { - return ItemWrapperMethods.super.getColorFromItemStack(itemStack, p_82790_2_); + public String getUnlocalizedName(ItemStack stack) { + return ItemConverter.instance().toNova(stack).getUnlocalizedName(); } + @Override + public String getItemStackDisplayName(ItemStack stack) { + return ItemConverter.instance().toNova(stack).getLocalizedName(); + } } 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 685af5f22..b6f67c454 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 @@ -35,7 +35,7 @@ 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.ItemWrapperMethods; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.ItemConverter; import nova.internal.core.Game; import java.util.List; @@ -43,7 +43,7 @@ /** * @author Calclavia */ -public class FWItemBlock extends net.minecraft.item.ItemBlock implements ItemWrapperMethods { +public class FWItemBlock extends net.minecraft.item.ItemBlock implements IFWItem { public FWItemBlock(FWBlock block) { super(block); @@ -63,21 +63,36 @@ public ItemFactory getItemFactory() { @Override public void addInformation(ItemStack itemStack, EntityPlayer player, List tooltip, boolean advanced) { - ItemWrapperMethods.super.addInformation(itemStack, player, tooltip, advanced); + IFWItem.super.addInformation(itemStack, player, tooltip, advanced); } @Override public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) { - return ItemWrapperMethods.super.onItemUse(player.getHeldItem(hand), player, world, pos.getX(), pos.getY(), pos.getZ(), side.ordinal(), hitX, hitY, hitZ); + return IFWItem.super.onItemUse(player.getHeldItem(hand), player, world, pos.getX(), pos.getY(), pos.getZ(), side.ordinal(), hitX, hitY, hitZ); } @Override - public ActionResult onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) { - return ItemWrapperMethods.super.onItemRightClick(itemStack, world, player); + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + return IFWItem.super.onItemRightClick(player.getHeldItem(hand), world, player); } @Override - public int getColorFromItemStack(ItemStack itemStack, int p_82790_2_) { - return ItemWrapperMethods.super.getColorFromItemStack(itemStack, p_82790_2_); + public int getColorFromItemStack(ItemStack itemStack, int renderPass) { + return IFWItem.super.getColorFromItemStack(itemStack, renderPass); + } + + @Override + public String getUnlocalizedName() { + return getItemFactory().getUnlocalizedName(); + } + + @Override + public String getUnlocalizedName(ItemStack stack) { + return ItemConverter.instance().toNova(stack).getUnlocalizedName(); + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + return ItemConverter.instance().toNova(stack).getLocalizedName(); } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/ItemWrapperMethods.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/IFWItem.java similarity index 79% rename from minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/ItemWrapperMethods.java rename to minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/IFWItem.java index d2753bb14..8ab3a50d5 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/ItemWrapperMethods.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/item/forward/IFWItem.java @@ -18,7 +18,7 @@ * along with NOVA. If not, see . */ -package nova.core.wrapper.mc.forge.v1_11_2.wrapper.item; +package nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.forward; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; @@ -29,28 +29,28 @@ import nova.core.item.ItemFactory; import nova.core.util.Direction; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.entity.backward.BWEntity; -import nova.internal.core.Game; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.ItemConverter; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import java.util.List; import java.util.Optional; /** - * An interface implemented by ItemBlockWrapper and ItemWrapper classes to override Minecraft's item events. + * An interface implemented by {@link FWItem} and {@link FWItemBlock} classes to override Minecraft's item events. * @author Calclavia */ -public interface ItemWrapperMethods { +public interface IFWItem { ItemFactory getItemFactory(); default void addInformation(ItemStack itemStack, EntityPlayer player, List tooltip, boolean advanced) { - Item item = Game.natives().toNova(itemStack); + Item item = ItemConverter.instance().toNova(itemStack); item.setCount(itemStack.getCount()).events.publish(new Item.TooltipEvent(Optional.of(new BWEntity(player)), tooltip)); getItemFactory().save(item); } default EnumActionResult onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) { - Item item = Game.natives().toNova(itemStack); + Item item = ItemConverter.instance().toNova(itemStack); Item.UseEvent event = new Item.UseEvent(new BWEntity(player), new Vector3D(x, y, z), Direction.fromOrdinal(side), new Vector3D(hitX, hitY, hitZ)); item.events.publish(event); ItemConverter.instance().updateMCItemStack(itemStack, item); @@ -58,12 +58,13 @@ default EnumActionResult onItemUse(ItemStack itemStack, EntityPlayer player, Wor } default ActionResult onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) { - Item item = Game.natives().toNova(itemStack); + Item item = ItemConverter.instance().toNova(itemStack); item.events.publish(new Item.RightClickEvent(new BWEntity(player))); return new ActionResult<>(EnumActionResult.PASS, ItemConverter.instance().updateMCItemStack(itemStack, item)); } - default int getColorFromItemStack(ItemStack itemStack, int p_82790_2_) { - return ((Item) Game.natives().toNova(itemStack)).colorMultiplier().argb(); + @SuppressWarnings("deprecation") + default int getColorFromItemStack(ItemStack itemStack, int renderPass) { + return ItemConverter.instance().toNova(itemStack).colorMultiplier().argb(); } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/particle/backward/BWParticle.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/particle/backward/BWParticle.java index 59673bbe1..d3aac2bcc 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/particle/backward/BWParticle.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/particle/backward/BWParticle.java @@ -61,13 +61,11 @@ import net.minecraft.client.particle.ParticleWaterWake; import net.minecraft.util.EnumParticleTypes; import net.minecraftforge.fml.client.FMLClientHandler; +import nova.core.entity.Entity; import java.util.HashMap; import java.util.Map; -import nova.core.wrapper.mc.forge.v1_11_2.wrapper.entity.backward.BWEntity; -import nova.core.wrapper.mc.forge.v1_11_2.wrapper.particle.forward.MCParticleTransform; - /** * A backward entity particle that acts as a black box, which wraps a Minecraft particle. * @@ -75,7 +73,7 @@ * * @author Calclavia */ -public class BWParticle extends BWEntity { +public class BWParticle extends Entity { public static final HashBiMap> FX_CLASS_MAP = HashBiMap.create(); public static final Map FX_FACTORY_MAP = new HashMap<>(); @@ -184,8 +182,6 @@ public class BWParticle extends BWEntity { private final int particleID; public BWParticle(int particleID) { - //TODO: NPE - super(null); this.particleID = particleID; } @@ -193,9 +189,6 @@ public Particle createParticle(net.minecraft.world.World world) { //Look up for particle factory and pass it into BWParticle IParticleFactory particleFactory = FMLClientHandler.instance().getClient().effectRenderer.particleTypes.get(particleID); Particle particle = particleFactory.createParticle(0, world, 0, 0, 0, 0, 0, 0, 0); - if (components.has(MCParticleTransform.class)) - components.remove(MCParticleTransform.class); - components.add(new MCParticleTransform(particle)); return particle; } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/backward/BWBakedModel.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/backward/BWBakedModel.java new file mode 100644 index 000000000..53bc4c632 --- /dev/null +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/backward/BWBakedModel.java @@ -0,0 +1,218 @@ +/* + * 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.render.backward; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.renderer.vertex.VertexFormatElement; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import nova.core.render.Color; +import nova.core.render.model.Face; +import nova.core.render.model.MeshModel; +import nova.core.render.model.Model; +import nova.core.render.model.Vertex; +import nova.core.util.Direction; +import nova.core.util.math.MatrixStack; +import nova.core.util.math.TransformUtil; +import nova.core.util.math.Vector3DUtil; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.DirectionConverter; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.assets.AssetConverter; +import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; +import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; +import org.apache.commons.math3.linear.LUDecomposition; +import org.apache.commons.math3.linear.MatrixUtils; +import org.apache.commons.math3.linear.RealMatrix; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.annotation.Nullable; + +/** + * @author ExE Boss + */ +public class BWBakedModel extends MeshModel { + + @SuppressWarnings("deprecation") + public final IBakedModel wrapped; + + public final VertexFormat format; + + public final Optional blockState; + + public final long rand; + + public BWBakedModel(IBakedModel wrapped) { + this(wrapped, DefaultVertexFormats.ITEM); + } + + public BWBakedModel(IBakedModel wrapped, VertexFormat format) { + this(wrapped, format, Optional.empty(), 0); + } + + public BWBakedModel(IBakedModel wrapped, VertexFormat format, Optional state, long rand) { + this.wrapped = wrapped; + this.format = format; + this.matrix.translate(-0.5, -0.5, -0.5); + this.blockState = state; + this.rand = rand; + + if (!format.getElements().stream().anyMatch(VertexFormatElement::isPositionElement)) + return; // VertexFormat doesn't have a position + + Arrays.stream(Direction.values()) + .map(this::getQuads) + .flatMap(Collection::stream) + .map(this::quadToFace) + .forEachOrdered(faces::add); + } + + @Override + public Set flatten(MatrixStack matrixStack) { + Set models = new HashSet<>(); + + matrixStack.pushMatrix(); + matrixStack.transform(matrix.getMatrix()); + //Create a new model with transformation applied. + MeshModel transformedModel = clone(); + // correct formula for Normal Matrix is transpose(inverse(mat3(model_mat)) + // we have to augemnt that to 4x4 + RealMatrix normalMatrix3x3 = new LUDecomposition(matrixStack.getMatrix().getSubMatrix(0, 2, 0, 2), 1e-5).getSolver().getInverse().transpose(); + RealMatrix normalMatrix = MatrixUtils.createRealMatrix(4, 4); + normalMatrix.setSubMatrix(normalMatrix3x3.getData(), 0, 0); + normalMatrix.setEntry(3, 3, 1); + + transformedModel.faces.stream().forEach(f -> { + f.normal = TransformUtil.transform(f.normal, normalMatrix); + f.vertices.forEach(v -> v.vec = matrixStack.apply(v.vec)); + } + ); + + models.add(transformedModel); + //Flatten child models + matrixStack.pushMatrix(); + matrixStack.translate(0.5, 0.5, 0.5); + models.addAll(children.stream().flatMap(m -> m.flatten(matrixStack).stream()).collect(Collectors.toSet())); + matrixStack.popMatrix().popMatrix(); + return models; + } + + public List getQuads(Direction side) { + return getQuads(DirectionConverter.instance().toNative(side)); + } + + public List getQuads(@Nullable EnumFacing side) { + return wrapped.getQuads(blockState.orElse(null), side, rand); + } + + public Face quadToFace(BakedQuad quad) { + Face face = new Face(); + final VertexFormat format = quad.getFormat(); + + int[] data = quad.getVertexData(); + Optional texture = Optional.ofNullable(quad.getSprite() == null ? wrapped.getParticleTexture() : quad.getSprite()); + + final Optional posElement = ((Collection)format.getElements()).stream() + .filter(VertexFormatElement::isPositionElement) + .findFirst(); + + final Optional uvElement = ((Collection)format.getElements()).stream() + .filter(vfe -> vfe.getUsage() == VertexFormatElement.EnumUsage.UV) + .findFirst(); + + face.texture = texture + .filter(t -> uvElement.isPresent()) + .map(TextureAtlasSprite::getIconName) + .map(ResourceLocation::new) + .map(AssetConverter.instance()::toNovaTexture); + + // `VertexFormat` offsets are for a `ByteBuffer` + // `data` is an int array, so we convert it + + // TODO: support offsets which are not divisible by four + final int posOffset = posElement.map(VertexFormatElement::getIndex).map(i -> i / 4).orElse(-1); + final int uvOffset = uvElement.map(VertexFormatElement::getIndex).map(i -> i / 4).orElse(-1); + final int colorOffset = format.hasColor() ? (format.getColorOffset() / 4) : -1; + final int normalOffset = format.hasNormal() ? (format.getNormalOffset() / 4) : -1; + + for (int i = 0; i < data.length; i += 7) { + Vector3D pos = posElement.isPresent() ? new Vector3D( + Float.intBitsToFloat(data[i + posOffset]), + Float.intBitsToFloat(data[i + posOffset + 1]), + Float.intBitsToFloat(data[i + posOffset + 2])) : Vector3D.ZERO; + + Vector2D uv = uvElement.isPresent() ? new Vector2D( + deinterpolateU(Float.intBitsToFloat(data[i + uvOffset]), texture), + deinterpolateV(Float.intBitsToFloat(data[i + uvOffset + 1]), texture)) : Vector2D.ZERO; + + Vertex vertex = new Vertex(pos, uv); + if (format.hasColor()) { + vertex.color = Color.argb(data[i + colorOffset]); + } + + Optional normal = Optional.empty(); + if (format.hasNormal()) { + int mergedNormal = data[i + normalOffset]; + if (mergedNormal != 0) + normal = Optional.of(new Vector3D(((byte)(mergedNormal & 0xFF)) / 127D, + ((byte)((mergedNormal >> 8) & 0xFF)) / 127D, + ((byte)((mergedNormal >> 16) & 0xFF)) / 127D)); + } + +// if (format.hasNormal()) +// vertex.normal = normal; + face.drawVertex(vertex); + } + java.util.function.BinaryOperator cartesianProduct = Vector3DUtil::cartesianProduct; +// face.normal = Vector3DUtil.calculateNormal(face); + face.normal = calculateNormal(face); + return face; + } + + private double deinterpolateU(double u, Optional texture) { + return u; + } + + private double deinterpolateV(double v, Optional texture) { + return 1 - v; // Why do you change the format with every version, Mojang? + } + + private static Vector3D calculateNormal(Face face) { + // TODO: Possibly calculate from vertex normals + Vertex firstEntry = face.vertices.get(0); + Vertex secondEntry = face.vertices.get(1); + Vertex thirdEntry = face.vertices.get(2); + Vector3D v1 = secondEntry.vec.subtract(firstEntry.vec); + Vector3D v2 = thirdEntry.vec.subtract(firstEntry.vec); + + return v1.crossProduct(v2).normalize(); + } +} 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 a55769f9c..b85657b67 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,19 +20,31 @@ 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.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.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 java.util.Optional; +import javax.annotation.Nonnull; + /** * BWModel for dynamic rendering * @author Calclavia @@ -43,7 +55,15 @@ public void render() { render(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(Optional access, Optional entityRenderManager) { Tessellator tessellator = Tessellator.getInstance(); VertexBuffer worldRenderer = tessellator.getBuffer(); worldRenderer.color(1F, 1F, 1F, 1F); @@ -56,56 +76,71 @@ public void render(Optional entityRenderManager) { if (model instanceof MeshModel) { MeshModel meshModel = (MeshModel) model; meshModel.faces.forEach(face -> { - // TODO: See if this works, and possibly fix it - // Brightness is defined as: skyLight << 20 | blockLight << 4 - if (face.getBrightness() >= 0) { - worldRenderer.lightmap((int)(face.getBrightness() * (15 << 20)), (int)(face.getBrightness() * (11 << 4))); - //worldRenderer.setBrightness((int) (face.getBrightness() * (15 << 20 | 11 << 4))); - } else { - // Determine nearest adjacent block. - worldRenderer.lightmap(15 << 20, 11 << 4); - //worldRenderer.setBrightness(15 << 20 | 11 << 4); + boolean isEntityTexture = face.texture.map(t -> t instanceof EntityTexture).orElse(false); + if (entityRenderManager.isPresent() && isEntityTexture) { + entityRenderManager.get().renderEngine.bindTexture(AssetConverter.instance().toNative(face.texture.get())); } - worldRenderer.normal((float) face.normal.getX(), (float) face.normal.getY(), (float) face.normal.getZ()); - - System.out.println(face.texture); - if (face.texture.isPresent()) { - if (entityRenderManager.isPresent() && face.texture.get() instanceof EntityTexture) { - //We're not working on an atlas, so just do... this. - Texture t = face.texture.get(); - entityRenderManager.get().renderEngine.bindTexture(AssetConverter.instance().toNative(t)); - face.vertices.forEach( - v -> { - worldRenderer.color(v.color.red(), v.color.green(), v.color.blue(), v.color.alpha()); - worldRenderer.tex(v.uv.getX(), v.uv.getY()); + face.vertices.forEach(v -> { + worldRenderer.getVertexFormat().getElements().forEach(vfe -> { + switch (vfe.getUsage()) { + case POSITION: { worldRenderer.pos(v.vec.getX(), v.vec.getY(), v.vec.getZ()); - } - ); - } else { - Texture texture = face.texture.get(); - TextureAtlasSprite icon = RenderUtility.instance.getTexture(texture); - face.vertices.forEach( - v -> { + break; + } case NORMAL: { + Vector3D normal = face.normal;//v.normal.orElse(face.normal); + worldRenderer.normal((float)normal.getX(), (float)normal.getY(), (float)normal.getZ()); + break; + } case COLOR: { worldRenderer.color(v.color.red(), v.color.green(), v.color.blue(), v.color.alpha()); - if (icon != null) { - worldRenderer.tex(icon.getInterpolatedU(16 * v.uv.getX()), icon.getInterpolatedV(16 * v.uv.getY())); - worldRenderer.pos(v.vec.getX(), v.vec.getY(), v.vec.getZ()); - } else { - worldRenderer.tex(v.uv.getX(), v.uv.getY()); - worldRenderer.pos(v.vec.getX(), v.vec.getY(), v.vec.getZ()); + break; + } case UV: { + if (vfe.getIndex() == 0) { + if (entityRenderManager.isPresent() && isEntityTexture) { + //We're not working on an atlas, so just do... this. + worldRenderer.tex(v.uv.getX(), v.uv.getY()); + } else { + TextureAtlasSprite tex = face.texture.map(RenderUtility.instance::getTexture) + .orElseGet(Minecraft.getMinecraft().getTextureMapBlocks()::getMissingSprite); + 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); + IBlockState state = access.get().getBlockState(blockPos); + Block block = state.getBlock(); + @SuppressWarnings("deprecation") + int brightness = block.getPackedLightmapCoords(state, 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 brightnessTopLeft = getAoBrightness(aoBrightnessXYZNNP, aoBrightnessXYNN, aoBrightnessYZNP, i1); + int brightnessTopRight = getAoBrightness(aoBrightnessYZNP, aoBrightnessXYZPNP, aoBrightnessXYPN, i1); + int brightnessBottomRight = getAoBrightness(aoBrightnessYZNN, aoBrightnessXYPN, aoBrightnessXYZPNN, i1); + int brightnessBottomLeft = getAoBrightness(aoBrightnessXYNN, aoBrightnessXYZNNN, aoBrightnessYZNN, i1); + */ + + worldRenderer.lightmap((brightness >>> 20) & 0xFFFF, (brightness >>> 4) & 0xFFFF); + } else { + worldRenderer.lightmap(15, 11); + } } + break; } - ); - } - } else { - face.vertices.forEach( - v -> { - worldRenderer.color(v.color.red(), v.color.green(), v.color.blue(), v.color.alpha()); - worldRenderer.pos(v.vec.getX(), v.vec.getY(), v.vec.getZ()); } - ); - } + }); + worldRenderer.endVertex(); + }); }); } else if (model instanceof CustomModel) { CustomModel customModel = (CustomModel) model; diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWEmptyModel.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWEmptyModel.java index 7410a8832..6bc753c3b 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWEmptyModel.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWEmptyModel.java @@ -25,7 +25,10 @@ import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ItemOverrideList; import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; import java.util.Collections; import java.util.List; @@ -36,18 +39,14 @@ */ public class FWEmptyModel extends FWSmartModel implements IBakedModel { + //Item rendering @Override - public List getQuads(IBlockState state, EnumFacing side, long rand) { - return Collections.emptyList(); + public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) { + return this; } @Override - public TextureAtlasSprite getParticleTexture() { - return null; - } - - @Override - public ItemOverrideList getOverrides() { - return ItemOverrideList.NONE; + public List getQuads(IBlockState state, EnumFacing side, long rand) { + return Collections.emptyList(); } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWSmartBlockModel.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWSmartBlockModel.java index 4a9215c2b..793cc48d5 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWSmartBlockModel.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWSmartBlockModel.java @@ -24,32 +24,43 @@ import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; -import net.minecraft.client.renderer.block.model.ItemOverrideList; import net.minecraft.client.renderer.block.model.ItemTransformVec3f; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; import nova.core.block.Block; -import nova.core.component.renderer.DynamicRenderer; +import nova.core.component.renderer.Renderer; import nova.core.component.renderer.StaticRenderer; +import nova.core.item.Item; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.ItemConverter; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.render.backward.BWModel; import org.lwjgl.util.vector.Vector3f; import java.util.List; +import java.util.Optional; /** * Generates a smart model based on a NOVA Model * @author Calclavia */ -@SuppressWarnings("deprecation") public class FWSmartBlockModel extends FWSmartModel implements IBakedModel { private final Block block; - private final boolean isItem; + private final Optional item; + + public FWSmartBlockModel(Block block) { + this(block, Optional.empty()); + } + + public FWSmartBlockModel(Block block, Item item) { + this(block, Optional.of(item)); + } @SuppressWarnings("deprecation") - public FWSmartBlockModel(Block block, boolean isItem) { - super(); + public FWSmartBlockModel(Block block, Optional item) { this.block = block; - this.isItem = isItem; + this.item = item; // Change the default transforms to the default full Block transforms this.itemCameraTransforms = new ItemCameraTransforms( new ItemTransformVec3f(new Vector3f(75, 225, 0), new Vector3f(0, 0.1875f, 0.03125f), new Vector3f(0.375f, 0.375f, 0.375f)), // Third Person (Left) @@ -62,29 +73,33 @@ public FWSmartBlockModel(Block block, boolean isItem) { ItemTransformVec3f.DEFAULT);// Fixed } + //Item rendering + @Override + public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) { + Item item = ItemConverter.instance().toNova(stack); + + if (item.components.has(Renderer.class) || block.components.has(Renderer.class)) { + return new FWSmartBlockModel(block, item); + } + + return new FWEmptyModel(); + } + @Override public List getQuads(IBlockState state, EnumFacing side, long rand) { BWModel model = new BWModel(); model.matrix.translate(0.5, 0.5, 0.5); - if (isItem) { - if (block.components.has(StaticRenderer.class)) { - StaticRenderer staticRenderer = block.components.get(StaticRenderer.class); - staticRenderer.onRender.accept(model); - } else if (block.components.has(DynamicRenderer.class)) { - DynamicRenderer dynamicRenderer = block.components.get(DynamicRenderer.class); - dynamicRenderer.onRender.accept(model); + if (item.isPresent()) { + if (item.get().components.has(Renderer.class)) { + item.get().components.getSet(Renderer.class).forEach(r -> r.onRender.accept(model)); + } else { + block.components.getSet(Renderer.class).forEach(r -> r.onRender.accept(model)); } } else { - StaticRenderer renderer = block.components.get(StaticRenderer.class); - renderer.onRender.accept(model); + block.components.getOp(StaticRenderer.class).ifPresent(r -> r.onRender.accept(model)); } return modelToQuads(model); } - - @Override - public ItemOverrideList getOverrides() { - return ItemOverrideList.NONE; - } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWSmartItemModel.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWSmartItemModel.java index 1f3671e68..bf774cf51 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWSmartItemModel.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWSmartItemModel.java @@ -24,13 +24,14 @@ import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; -import net.minecraft.client.renderer.block.model.ItemOverrideList; import net.minecraft.client.renderer.block.model.ItemTransformVec3f; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; -import nova.core.component.renderer.DynamicRenderer; +import net.minecraft.world.World; import nova.core.component.renderer.Renderer; -import nova.core.component.renderer.StaticRenderer; import nova.core.item.Item; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.item.ItemConverter; import nova.core.wrapper.mc.forge.v1_11_2.wrapper.render.backward.BWModel; import org.lwjgl.util.vector.Vector3f; @@ -47,7 +48,6 @@ public class FWSmartItemModel extends FWSmartModel implements IBakedModel { @SuppressWarnings("deprecation") public FWSmartItemModel(Item item) { - super(); this.item = item; // Change the default transforms to the default Item transforms this.itemCameraTransforms = new ItemCameraTransforms( @@ -61,29 +61,28 @@ public FWSmartItemModel(Item item) { ItemTransformVec3f.DEFAULT);// Fixed } + //Item rendering @Override - public List getQuads(IBlockState state, EnumFacing side, long rand) { - BWModel model = new BWModel(); - model.matrix.translate(0.5, 0.5, 0.5); + public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) { + Item item = ItemConverter.instance().toNova(stack); - if (item.components.has(StaticRenderer.class)) { - StaticRenderer staticRenderer = item.components.get(StaticRenderer.class); - staticRenderer.onRender.accept(model); - } else if (item.components.has(DynamicRenderer.class)) { - DynamicRenderer dynamicRenderer = item.components.get(DynamicRenderer.class); - dynamicRenderer.onRender.accept(model); + if (item.components.has(Renderer.class)) { + return new FWSmartItemModel(item); } - return modelToQuads(model); + return new FWEmptyModel(); } @Override - public boolean isGui3d() { - return item.components.has(Renderer.class); + public List getQuads(IBlockState state, EnumFacing side, long rand) { + BWModel model = new BWModel(); + model.matrix.translate(0.5, 0.5, 0.5); + item.components.getSet(Renderer.class).forEach(r -> r.onRender.accept(model)); + return modelToQuads(model); } @Override - public ItemOverrideList getOverrides() { - return ItemOverrideList.NONE; + public boolean isGui3d() { + return item.components.has(Renderer.class); } } diff --git a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWSmartModel.java b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWSmartModel.java index 4fddcc6fd..5cd27c9cc 100644 --- a/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWSmartModel.java +++ b/minecraft/1.11.2/src/main/java/nova/core/wrapper/mc/forge/v1_11_2/wrapper/render/forward/FWSmartModel.java @@ -25,20 +25,24 @@ import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemOverrideList; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.VertexFormat; -import net.minecraft.util.EnumFacing; -import nova.core.render.model.CustomModel; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; import nova.core.render.model.MeshModel; import nova.core.render.model.Model; import nova.core.render.model.Vertex; import nova.core.util.Direction; import nova.core.util.math.MathUtil; import nova.core.wrapper.mc.forge.v1_11_2.render.RenderUtility; +import nova.core.wrapper.mc.forge.v1_11_2.wrapper.DirectionConverter; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -50,44 +54,41 @@ @SuppressWarnings("deprecation") public abstract class FWSmartModel implements IBakedModel { - protected static final VertexFormat NOVA_VERTEX_FORMAT; + protected static final VertexFormat NOVA_VERTEX_FORMAT = DefaultVertexFormats.ITEM; protected final VertexFormat format; // Default item transforms. Can be changed in subclasses. protected ItemCameraTransforms itemCameraTransforms = ItemCameraTransforms.DEFAULT; - - static { - NOVA_VERTEX_FORMAT = DefaultVertexFormats.ITEM; -// NOVA_VERTEX_FORMAT = new VertexFormat(); -// NOVA_VERTEX_FORMAT.addElement(DefaultVertexFormats.POSITION_3F); -// NOVA_VERTEX_FORMAT.addElement(DefaultVertexFormats.COLOR_4UB); -// NOVA_VERTEX_FORMAT.addElement(DefaultVertexFormats.TEX_2F); -// NOVA_VERTEX_FORMAT.addElement(DefaultVertexFormats.NORMAL_3B); -// NOVA_VERTEX_FORMAT.addElement(DefaultVertexFormats.PADDING_1B); - } + private final FWOverrideList overrides; protected FWSmartModel(VertexFormat format) { this.format = format; + this.overrides = new FWOverrideList(); } public FWSmartModel() { - this.format = NOVA_VERTEX_FORMAT; + this(NOVA_VERTEX_FORMAT); } public static int[] vertexToInts(Vertex vertex, TextureAtlasSprite texture, Vector3D normal) { + // TODO: Possibly support arbitrary `VertexFormat` +// if (vertex.normal.isPresent()) +// normal = vertex.normal.get(); return new int[] { Float.floatToRawIntBits((float) vertex.vec.getX()), Float.floatToRawIntBits((float) vertex.vec.getY()), Float.floatToRawIntBits((float) vertex.vec.getZ()), - vertex.color.argb(), + vertex.color.rgba(), Float.floatToRawIntBits(texture.getInterpolatedU(16 * vertex.uv.getX())), Float.floatToRawIntBits(texture.getInterpolatedV(16 * vertex.uv.getY())), ((((byte)(normal.getX() * 127)) & 0xFF) | ((((byte)(normal.getY() * 127)) & 0xFF) << 8) | - ((((byte)(normal.getZ() * 127)) & 0xFF) << 16)) // TODO: Normal + ((((byte)(normal.getZ() * 127)) & 0xFF) << 16)) }; } + public abstract IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity); + protected List modelToQuads(Model modelIn) { return modelIn .flatten() @@ -98,19 +99,23 @@ protected List modelToQuads(Model modelIn) { MeshModel meshModel = (MeshModel) model; return meshModel.faces .stream() + .filter(f -> f.vertices.size() > 2) .map( face -> { TextureAtlasSprite texture = face.texture.map(RenderUtility.instance::getTexture) - .orElse(Minecraft.getMinecraft().getTextureMapBlocks().getMissingSprite()); + .orElseGet(Minecraft.getMinecraft().getTextureMapBlocks()::getMissingSprite); List vertexData = face.vertices .stream() .map(v -> vertexToInts(v, texture, face.normal)) .collect(Collectors.toList()); + if (vertexData.size() < 4) + vertexData.add(vertexData.get(vertexData.size() - 1)); + int[] data = Ints.concat(vertexData.toArray(new int[][] {})); //TODO: The facing might be wrong - return new BakedQuad(Arrays.copyOf(data, MathUtil.max(data.length, 0)), -1, EnumFacing.values()[Direction.fromVector(face.normal).ordinal()], - texture, true, getFormat()); + return new BakedQuad(Arrays.copyOf(data, MathUtil.min(data.length, format.getNextOffset())), -1, + DirectionConverter.instance().toNative(Direction.fromVector(face.normal)), texture, true, getFormat()); } ); } @@ -142,11 +147,28 @@ public boolean isBuiltInRenderer() { @Override public TextureAtlasSprite getParticleTexture() { - return null; + return Minecraft.getMinecraft().getTextureMapBlocks().getMissingSprite(); } @Override + @Deprecated public ItemCameraTransforms getItemCameraTransforms() { return itemCameraTransforms; } + + @Override + public final ItemOverrideList getOverrides() { + return overrides; + } + + private final class FWOverrideList extends ItemOverrideList { + private FWOverrideList() { + super(Collections.emptyList()); + } + + @Override + public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) { + return FWSmartModel.this.handleItemState(originalModel, stack, world, entity); + } + } }