package slimeknights.tconstruct.common; import com.google.common.collect.ImmutableList; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.particle.Particle; import net.minecraft.client.renderer.ItemMeshDefinition; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.resources.IReloadableResourceManager; import net.minecraft.entity.Entity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StringUtils; import net.minecraft.world.Explosion; import net.minecraft.world.World; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.ModelLoaderRegistry; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.registry.GameData; import java.util.stream.Stream; import javax.annotation.Nonnull; import slimeknights.mantle.network.AbstractPacket; import slimeknights.tconstruct.TConstruct; import slimeknights.tconstruct.library.TinkerRegistry; import slimeknights.tconstruct.library.Util; import slimeknights.tconstruct.library.book.TinkerBook; import slimeknights.tconstruct.library.client.CustomFontRenderer; import slimeknights.tconstruct.library.client.CustomTextureCreator; import slimeknights.tconstruct.library.client.crosshair.CrosshairRenderEvents; import slimeknights.tconstruct.library.client.material.MaterialRenderInfoLoader; import slimeknights.tconstruct.library.client.material.deserializers.BlockRenderInfoDeserializer; import slimeknights.tconstruct.library.client.material.deserializers.ColoredRenderInfoDeserializer; import slimeknights.tconstruct.library.client.material.deserializers.InverseMultiColorRenderInfoDeserializer; import slimeknights.tconstruct.library.client.material.deserializers.MetalRenderInfoDeserializer; import slimeknights.tconstruct.library.client.material.deserializers.MultiColorRenderInfoDeserializer; import slimeknights.tconstruct.library.client.material.deserializers.TexturedMetalRenderInfoDeserializer; import slimeknights.tconstruct.library.client.model.MaterialModelLoader; import slimeknights.tconstruct.library.client.model.ModifierModelLoader; import slimeknights.tconstruct.library.client.model.ToolModelLoader; import slimeknights.tconstruct.library.client.particle.EntitySlimeFx; import slimeknights.tconstruct.library.client.particle.Particles; import slimeknights.tconstruct.library.client.texture.AbstractColoredTexture; import slimeknights.tconstruct.library.materials.Material; import slimeknights.tconstruct.library.materials.MaterialGUI; import slimeknights.tconstruct.library.tools.Pattern; import slimeknights.tconstruct.shared.TinkerCommons; import slimeknights.tconstruct.shared.client.ParticleEffect; import slimeknights.tconstruct.shared.client.ParticleEndspeed; import slimeknights.tconstruct.tools.TinkerTools; import slimeknights.tconstruct.tools.common.client.particle.ParticleAttackCleaver; import slimeknights.tconstruct.tools.common.client.particle.ParticleAttackFrypan; import slimeknights.tconstruct.tools.common.client.particle.ParticleAttackHammer; import slimeknights.tconstruct.tools.common.client.particle.ParticleAttackHatchet; import slimeknights.tconstruct.tools.common.client.particle.ParticleAttackLongsword; import slimeknights.tconstruct.tools.common.client.particle.ParticleAttackLumberAxe; import slimeknights.tconstruct.tools.common.client.particle.ParticleAttackRapier; import slimeknights.tconstruct.tools.harvest.TinkerHarvestTools; public abstract class ClientProxy extends CommonProxy { public static Material RenderMaterials[]; public static Material RenderMaterialString; public static final ResourceLocation BOOK_MODIFY = Util.getResource("textures/gui/book/modify.png"); private static final Minecraft mc = Minecraft.getMinecraft(); public static CustomFontRenderer fontRenderer; protected static final ToolModelLoader loader = new ToolModelLoader(); protected static final MaterialModelLoader materialLoader = new MaterialModelLoader(); protected static final ModifierModelLoader modifierLoader = new ModifierModelLoader(); public static void initClient() { // i wonder if this is OK :D ModelLoaderRegistry.registerLoader(loader); ModelLoaderRegistry.registerLoader(materialLoader); ModelLoaderRegistry.registerLoader(modifierLoader); MaterialRenderInfoLoader.addRenderInfo("colored", ColoredRenderInfoDeserializer.class); MaterialRenderInfoLoader.addRenderInfo("multicolor", MultiColorRenderInfoDeserializer.class); MaterialRenderInfoLoader.addRenderInfo("inverse_multicolor", InverseMultiColorRenderInfoDeserializer.class); MaterialRenderInfoLoader.addRenderInfo("metal", MetalRenderInfoDeserializer.class); MaterialRenderInfoLoader.addRenderInfo("metal_textured", TexturedMetalRenderInfoDeserializer.class); MaterialRenderInfoLoader.addRenderInfo("block", BlockRenderInfoDeserializer.class); } public static void initRenderMaterials() { RenderMaterials = new Material[4]; RenderMaterials[0] = new MaterialGUI("_internal_render1"); RenderMaterials[0].setRenderInfo(0x684e1e); RenderMaterials[1] = new MaterialGUI("_internal_render2"); RenderMaterials[1].setRenderInfo(0xc1c1c1); RenderMaterials[2] = new MaterialGUI("_internal_render3"); RenderMaterials[2].setRenderInfo(0x2376dd); RenderMaterials[3] = new MaterialGUI("_internal_render4"); RenderMaterials[3].setRenderInfo(0x7146b0); RenderMaterialString = new MaterialGUI("_internal_renderString"); RenderMaterialString.setRenderInfo(0xffffff); // yes, these will only be registered clientside // but it shouldn't matter because they're never used serverside and we don't use indices Stream.concat( Stream.of(RenderMaterials), Stream.of(RenderMaterialString) ).forEach(TinkerRegistry::addMaterial); if(TinkerHarvestTools.pickaxe != null) { TinkerRegistry.tabTools.setDisplayIcon(TinkerHarvestTools.pickaxe.buildItemForRendering(ImmutableList.of(RenderMaterials[0], RenderMaterials[1], RenderMaterials[2]))); } if(TinkerTools.pickHead != null) { TinkerRegistry.tabParts.setDisplayIcon(TinkerTools.pickHead.getItemstackWithMaterial(RenderMaterials[2])); } } public static void initRenderer() { CustomTextureCreator creator = CustomTextureCreator.INSTANCE; MinecraftForge.EVENT_BUS.register(creator); IReloadableResourceManager resourceManager = (IReloadableResourceManager) mc.getResourceManager(); resourceManager.registerReloadListener(MaterialRenderInfoLoader.INSTANCE); resourceManager.registerReloadListener(AbstractColoredTexture.CacheClearer.INSTANCE); resourceManager.registerReloadListener(creator); // Font renderer for tooltips and GUIs fontRenderer = new CustomFontRenderer(mc.gameSettings, new ResourceLocation("textures/font/ascii.png"), mc.renderEngine); if(mc.gameSettings.language != null) { fontRenderer.setUnicodeFlag(mc.getLanguageManager().isCurrentLocaleUnicode() || mc.gameSettings.forceUnicodeFont); fontRenderer.setBidiFlag(mc.getLanguageManager().isCurrentLanguageBidirectional()); } resourceManager.registerReloadListener(fontRenderer); // Font Renderer for the tinker books FontRenderer bookRenderer = new CustomFontRenderer(mc.gameSettings, new ResourceLocation("textures/font/ascii.png"), mc.renderEngine); bookRenderer.setUnicodeFlag(true); if(mc.gameSettings.language != null) { fontRenderer.setBidiFlag(mc.getLanguageManager().isCurrentLanguageBidirectional()); } TinkerBook.INSTANCE.fontRenderer = bookRenderer; MinecraftForge.EVENT_BUS.register(CrosshairRenderEvents.INSTANCE); } @Deprecated protected ResourceLocation registerModel(Item item, String... customVariants) { return registerModel(item, 0, customVariants); } /** * Registers a model variant for you. :3 The model-string is obtained through the game registry. * @deprecated Use registerItemModel */ @Deprecated protected ResourceLocation registerModel(Item item, int meta, String... customVariants) { // get the registered name for the object Object o = GameData.getItemRegistry().getNameForObject(item); // are you trying to add an unregistered item...? if(o == null) { TConstruct.log.error("Trying to register a model for an unregistered item: %s" + item.getUnlocalizedName()); // bad boi return null; } ResourceLocation location = (ResourceLocation) o; location = new ResourceLocation(location.getResourceDomain(), location.getResourcePath()); // and plop it in. // This here is needed for the model to be found ingame when the game looks for a model to render an Itemstack (Item:Meta) ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(location, "inventory")); // We have to readd the default variant if we have custom variants, since it wont be added otherwise if(customVariants.length > 0) { ModelLoader.registerItemVariants(item, location); } for(String customVariant : customVariants) { String custom = location.getResourceDomain() + ":" + customVariant; ModelLoader.registerItemVariants(item, new ResourceLocation(custom)); } return location; } /** Register with name only, defaults to TiC domain */ protected void registerItemModelTiC(ItemStack item, String name) { if(item != null && !StringUtils.isNullOrEmpty(name)) { ModelRegisterUtil.registerItemModel(item, Util.getResource(name)); } } @Override public void sendPacketToServerOnly(AbstractPacket packet) { TinkerNetwork.sendToServer(packet); } @Override public void spawnParticle(Particles particleType, World world, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed, int... data) { if(world == null) { world = mc.world; } Particle effect = createParticle(particleType, world, x, y, z, xSpeed, ySpeed, zSpeed, data); mc.effectRenderer.addEffect(effect); if(particleType == Particles.EFFECT && data[0] > 1) { for(int i = 0; i < data[0] - 1; i++) { effect = createParticle(particleType, world, x, y, z, xSpeed, ySpeed, zSpeed, data); mc.effectRenderer.addEffect(effect); } } } @Override public void spawnSlimeParticle(World world, double x, double y, double z) { mc.effectRenderer.addEffect(new EntitySlimeFx(world, x, y, z, TinkerCommons.matSlimeBallBlue.getItem(), TinkerCommons.matSlimeBallBlue.getItemDamage())); } public static Particle createParticle(Particles type, World world, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed, int... data) { switch(type) { // entities case BLUE_SLIME: return new EntitySlimeFx(world, x, y, z, TinkerCommons.matSlimeBallBlue.getItem(), TinkerCommons.matSlimeBallBlue.getItemDamage()); // attack case CLEAVER_ATTACK: return new ParticleAttackCleaver(world, x, y, z, xSpeed, ySpeed, zSpeed, mc.getTextureManager()); case LONGSWORD_ATTACK: return new ParticleAttackLongsword(world, x, y, z, xSpeed, ySpeed, zSpeed, mc.getTextureManager()); case RAPIER_ATTACK: return new ParticleAttackRapier(world, x, y, z, xSpeed, ySpeed, zSpeed, mc.getTextureManager()); case HATCHET_ATTACK: return new ParticleAttackHatchet(world, x, y, z, xSpeed, ySpeed, zSpeed, mc.getTextureManager()); case LUMBERAXE_ATTACK: return new ParticleAttackLumberAxe(world, x, y, z, xSpeed, ySpeed, zSpeed, mc.getTextureManager()); case FRYPAN_ATTACK: return new ParticleAttackFrypan(world, x, y, z, xSpeed, ySpeed, zSpeed, mc.getTextureManager()); case HAMMER_ATTACK: return new ParticleAttackHammer(world, x, y, z, xSpeed, ySpeed, zSpeed, mc.getTextureManager()); // effects case EFFECT: return new ParticleEffect(data[1], world, x, y, z, xSpeed, ySpeed, zSpeed); case ENDSPEED: return new ParticleEndspeed(world, x, y, z, xSpeed, ySpeed, zSpeed); } return null; } @Override public void preventPlayerSlowdown(Entity player, float originalSpeed, Item item) { // has to be done in onUpdate because onTickUsing is too early and gets overwritten. bleh. if(player instanceof EntityPlayerSP) { EntityPlayerSP playerSP = (EntityPlayerSP) player; ItemStack usingItem = playerSP.getActiveItemStack(); if(usingItem != null && usingItem.getItem() == item) { // no slowdown from charging it up playerSP.movementInput.moveForward *= originalSpeed * 5.0F; playerSP.movementInput.moveStrafe *= originalSpeed * 5.0F; } } } @Override public void customExplosion(World world, Explosion explosion) { if(net.minecraftforge.event.ForgeEventFactory.onExplosionStart(world, explosion)) { ; } explosion.doExplosionA(); explosion.doExplosionB(true); } public static class PatternMeshDefinition implements ItemMeshDefinition { private final ResourceLocation baseLocation; public PatternMeshDefinition(ResourceLocation baseLocation) { this.baseLocation = baseLocation; } @Nonnull @Override public ModelResourceLocation getModelLocation(@Nonnull ItemStack stack) { Item item = Pattern.getPartFromTag(stack); String suffix = ""; if(item != null) { suffix = Pattern.getTextureIdentifier(item); } return new ModelResourceLocation(new ResourceLocation(baseLocation.getResourceDomain(), baseLocation.getResourcePath() + suffix), "inventory"); } } @Override public void updateEquippedItemForRendering(EnumHand hand) { mc.getItemRenderer().resetEquippedProgress(hand); mc.getItemRenderer().updateEquippedItem(); } }