package makeo.gadomancy.common.utils; import cpw.mods.fml.common.network.NetworkRegistry; import makeo.gadomancy.common.Gadomancy; import makeo.gadomancy.common.blocks.tiles.TileExtendedNode; import makeo.gadomancy.common.blocks.tiles.TileExtendedNodeJar; import makeo.gadomancy.common.data.config.ModConfig; import makeo.gadomancy.common.entities.EntityAuraCore; import makeo.gadomancy.common.items.ItemAuraCore; import makeo.gadomancy.common.network.PacketHandler; import makeo.gadomancy.common.network.packets.PacketStartAnimation; import makeo.gadomancy.common.node.ExtendedNodeType; import makeo.gadomancy.common.registration.RegisteredBlocks; import makeo.gadomancy.common.registration.RegisteredIntegrations; import makeo.gadomancy.common.registration.RegisteredRecipes; import net.minecraft.block.Block; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.World; import net.minecraftforge.oredict.OreDictionary; import thaumcraft.api.ThaumcraftApiHelper; import thaumcraft.api.aspects.Aspect; import thaumcraft.api.aspects.AspectList; import thaumcraft.api.nodes.INode; import thaumcraft.api.nodes.NodeModifier; import thaumcraft.api.nodes.NodeType; import thaumcraft.common.blocks.BlockMagicalLog; import thaumcraft.common.config.ConfigBlocks; import thaumcraft.common.lib.research.ResearchManager; import thaumcraft.common.tiles.TileJarNode; import thaumcraft.common.tiles.TileOwned; import thaumcraft.common.tiles.TileWarded; import java.util.Iterator; import java.util.List; /** * This class is part of the Gadomancy Mod * Gadomancy is Open Source and distributed under the * GNU LESSER GENERAL PUBLIC LICENSE * for more read the LICENSE file * * Created by HellFirePvP @ 24.10.2015 18:09 */ public class WandHandler { //All wand interacts are redirected to this. public static void handleWandInteract(World world, int x, int y, int z, EntityPlayer entityPlayer, ItemStack i) { Block target = world.getBlock(x, y, z); if(target == null) return; if(ModConfig.enableAdditionalNodeTypes) { if (target.equals(Blocks.glass)) { if (ResearchManager.isResearchComplete(entityPlayer.getCommandSenderName(), "NODEJAR")) { tryTCJarNodeCreation(i, entityPlayer, world, x, y, z); } } else if (target.equals(ConfigBlocks.blockWarded)) { if (RegisteredIntegrations.automagy.isPresent() && ResearchManager.isResearchComplete(entityPlayer.getCommandSenderName(), "ADVNODEJAR")) { tryAutomagyJarNodeCreation(i, entityPlayer, world, x, y, z); } } } if(target.equals(ConfigBlocks.blockCrystal)) { if (ResearchManager.isResearchComplete(entityPlayer.getCommandSenderName(), Gadomancy.MODID.toUpperCase() + ".AURA_CORE")) tryAuraCoreCreation(i, entityPlayer, world, x, y, z); } } private static void tryAuraCoreCreation(ItemStack i, EntityPlayer entityPlayer, World world, int x, int y, int z) { if(world.isRemote) return; List items = world.getEntitiesWithinAABB(EntityItem.class, AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 1, z + 1) .expand(EntityAuraCore.CLUSTER_RANGE, EntityAuraCore.CLUSTER_RANGE, EntityAuraCore.CLUSTER_RANGE)); Iterator it = items.iterator(); EntityItem itemAuraCore = null; while(itemAuraCore == null && it.hasNext()) { Object item = it.next(); if(item != null && item instanceof EntityItem && !((EntityItem) item).isDead) { EntityItem entityItem = (EntityItem) item; if(entityItem.getEntityItem() != null && entityItem.getEntityItem().getItem() != null && entityItem.getEntityItem().getItem() instanceof ItemAuraCore && !(item instanceof EntityAuraCore)) { if(((ItemAuraCore) entityItem.getEntityItem().getItem()).isBlank(entityItem.getEntityItem())) itemAuraCore = entityItem; } } } if(itemAuraCore == null) return; int meta = world.getBlockMetadata(x, y, z); if(meta <= 6) { Aspect[] aspects; switch (meta) { case 0: aspects = new Aspect[]{Aspect.AIR}; break; case 1: aspects = new Aspect[]{Aspect.FIRE}; break; case 2: aspects = new Aspect[]{Aspect.WATER}; break; case 3: aspects = new Aspect[]{Aspect.EARTH}; break; case 4: aspects = new Aspect[]{Aspect.ORDER}; break; case 5: aspects = new Aspect[]{Aspect.ENTROPY}; break; case 6: aspects = new Aspect[]{Aspect.AIR, Aspect.FIRE, Aspect.EARTH, Aspect.WATER, Aspect.ORDER, Aspect.ENTROPY}; break; default: return; } if(!ThaumcraftApiHelper.consumeVisFromWandCrafting(i, entityPlayer, (AspectList)RegisteredRecipes.auraCoreRecipes[meta].get(0), true)) return; PacketStartAnimation packet = new PacketStartAnimation(PacketStartAnimation.ID_BURST, x, y, z); PacketHandler.INSTANCE.sendToAllAround(packet, new NetworkRegistry.TargetPoint(world.provider.dimensionId, x, y, z, 32.0D)); world.createExplosion(null, x + 0.5D, y + 0.5D, z + 0.5D, 1.5F, false); world.setBlockToAir(x, y, z); EntityAuraCore ea = new EntityAuraCore(itemAuraCore.worldObj, itemAuraCore.posX, itemAuraCore.posY, itemAuraCore.posZ, itemAuraCore.getEntityItem(), new ChunkCoordinates(x, y, z), aspects); ea.age = itemAuraCore.age; ea.hoverStart = itemAuraCore.hoverStart; ea.motionX = itemAuraCore.motionX; ea.motionY = itemAuraCore.motionY; ea.motionZ = itemAuraCore.motionZ; itemAuraCore.worldObj.spawnEntityInWorld(ea); itemAuraCore.setDead(); } } private static void tryTCJarNodeCreation(ItemStack wandStack, EntityPlayer player, World world, int x, int y, int z) { WandHandler.JarPieceEvaluationRunnable slabRunnable = new WandHandler.JarPieceEvaluationRunnable() { @Override public boolean isValidPieceAt(World world, int absX, int absY, int absZ, EntityPlayer player) { Block block = world.getBlock(absX, absY, absZ); int md = world.getBlockMetadata(absX, absY, absZ); return containsMatch(false, OreDictionary.getOres("slabWood"), new ItemStack(block, 1, md)); } }; WandHandler.JarPieceEvaluationRunnable glassRunnable = new WandHandler.JarPieceEvaluationRunnable() { @Override public boolean isValidPieceAt(World world, int absX, int absY, int absZ, EntityPlayer player) { return world.getBlock(absX, absY, absZ) == Blocks.glass; } }; WandHandler.JarPieceEvaluationRunnable nodeRunnable = new WandHandler.JarPieceEvaluationRunnable() { @Override public boolean isValidPieceAt(World world, int absX, int absY, int absZ, EntityPlayer player) { TileEntity tile = world.getTileEntity(absX, absY, absZ); if ((tile == null) || (!(tile instanceof INode)) || ((tile instanceof TileJarNode))) { return false; } return true; } }; int[] result = WandHandler.evaluateIfValidJarIsPresent(world, x, y, z, player, slabRunnable, glassRunnable, nodeRunnable); if (result == null){ return; } if(!ThaumcraftApiHelper.consumeVisFromWandCrafting(wandStack, player, new AspectList().add(Aspect.FIRE, 70).add(Aspect.EARTH, 70).add(Aspect.ORDER, 70).add(Aspect.AIR, 70).add(Aspect.ENTROPY, 70).add(Aspect.WATER, 70), true)) return; if(world.isRemote) return; replaceJar(world, result[0], result[1], result[2], true); } private static void tryAutomagyJarNodeCreation(ItemStack wandStack, EntityPlayer player, World world, int x, int y, int z) { WandHandler.JarPieceEvaluationRunnable silverWoodRunnable = new WandHandler.JarPieceEvaluationRunnable() { @Override public boolean isValidPieceAt(World world, int absX, int absY, int absZ, EntityPlayer player) { TileEntity te = world.getTileEntity(absX, absY, absZ); if ((te instanceof TileWarded)) { TileWarded warded = (TileWarded) te; if ((warded.block == ConfigBlocks.blockMagicalLog) && (BlockMagicalLog.limitToValidMetadata(warded.blockMd) == 1)) { return player.getCommandSenderName().hashCode() == warded.owner; } } return false; } }; WandHandler.JarPieceEvaluationRunnable glassRunnable = new WandHandler.JarPieceEvaluationRunnable() { @Override public boolean isValidPieceAt(World world, int absX, int absY, int absZ, EntityPlayer player) { if ((world.getBlock(absX, absY, absZ) == ConfigBlocks.blockCosmeticOpaque) && (world.getBlockMetadata(absX, absY, absZ) == 2)) { TileEntity te = world.getTileEntity(absX, absY, absZ); if ((te instanceof TileOwned)) { return player.getCommandSenderName().equals(((TileOwned) te).owner); } } return false; } }; WandHandler.JarPieceEvaluationRunnable nodeRunnable = new WandHandler.JarPieceEvaluationRunnable() { @Override public boolean isValidPieceAt(World world, int absX, int absY, int absZ, EntityPlayer player) { TileEntity tile = world.getTileEntity(absX, absY, absZ); if ((tile == null) || (!(tile instanceof INode)) || ((tile instanceof TileJarNode))) { return false; } return true; } }; int[] result = WandHandler.evaluateIfValidJarIsPresent(world, x, y, z, player, silverWoodRunnable, glassRunnable, nodeRunnable); if (result == null){ return; } if(!RegisteredIntegrations.automagy.handleNodeJarVisCost(wandStack, player)) return; if(world.isRemote) return; if(!RegisteredIntegrations.automagy.isPresent()) return; replaceJar(world, result[0], result[1], result[2], false); } private static boolean containsMatch(boolean strict, List<ItemStack> inputs, ItemStack... targets) { for (ItemStack input : inputs) { for (ItemStack target : targets) { if (OreDictionary.itemMatches(input, target, strict)) { return true; } } } return false; } private static int[] evaluateIfValidJarIsPresent(World world, int x, int y, int z, EntityPlayer player, JarPieceEvaluationRunnable topRunnable, JarPieceEvaluationRunnable glassRunnable, JarPieceEvaluationRunnable centerRunnable) { for (int xx = x - 2; xx <= x; xx++) { for (int yy = y - 3; yy <= y; yy++) { for (int zz = z - 2; zz <= z; zz++) { if (isValidJarAt(world, xx, yy, zz, player, topRunnable, glassRunnable, centerRunnable)) { return new int[] {xx, yy, zz}; } } } } return null; } private static boolean isValidJarAt(World world, int x, int y, int z, EntityPlayer player, JarPieceEvaluationRunnable topRunnable, JarPieceEvaluationRunnable glassRunnable, JarPieceEvaluationRunnable centerRunnable) { int[][][] blueprint = {{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, {{2, 2, 2}, {2, 2, 2}, {2, 2, 2}}, {{2, 2, 2}, {2, 3, 2}, {2, 2, 2}}, {{2, 2, 2}, {2, 2, 2}, {2, 2, 2}}}; for (int yy = 0; yy < 4; yy++) { for (int xx = 0; xx < 3; xx++) { for (int zz = 0; zz < 3; zz++) { int index = blueprint[yy][xx][zz]; if (index == 1) { if (!topRunnable.isValidPieceAt(world, x + xx, y - yy + 2, z + zz, player)) return false; } if (index == 2) { if (!glassRunnable.isValidPieceAt(world, x + xx, y - yy + 2, z + zz, player)) return false; } if (index == 3) { if (!centerRunnable.isValidPieceAt(world, x + xx, y - yy + 2, z + zz, player)) return false; } } } } return true; } private static void replaceJar(World world, int x, int y, int z, boolean isThaumcraft) { int[][][] blueprint = {{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, {{2, 2, 2}, {2, 2, 2}, {2, 2, 2}}, {{2, 2, 2}, {2, 3, 2}, {2, 2, 2}}, {{2, 2, 2}, {2, 2, 2}, {2, 2, 2}}}; for (int yy = 0; yy < 4; yy++) { for (int xx = 0; xx < 3; xx++) { for (int zz = 0; zz < 3; zz++) { if (blueprint[yy][xx][zz] == 3) { handleJarForming(world, x, y, z, xx, yy, zz, isThaumcraft); } else { world.setBlockToAir(x + xx, y - yy + 2, z + zz); } } } } if(isThaumcraft) world.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "thaumcraft:wand", 1.0F, 1.0F); } private static void handleJarForming(World world, int x, int y, int z, int xx, int yy, int zz, boolean degrade) { TileEntity tile = world.getTileEntity(x + xx, y - yy + 2, z + zz); INode node = (INode) tile; AspectList na = node.getAspects().copy(); int nt = node.getNodeType().ordinal(); int nm = -1; int exNt = -1; NBTTagCompound behaviorSnapshot = null; if (node.getNodeModifier() != null) { nm = node.getNodeModifier().ordinal(); } if(tile instanceof TileExtendedNode && ((TileExtendedNode) tile).getExtendedNodeType() != null) { exNt = ((TileExtendedNode) tile).getExtendedNodeType().ordinal(); behaviorSnapshot = ((TileExtendedNode) tile).getBehaviorSnapshot(); } if(degrade) { if (world.rand.nextFloat() < 0.75F) { if (node.getNodeModifier() == null) { nm = NodeModifier.PALE.ordinal(); } else if (node.getNodeModifier() == NodeModifier.BRIGHT) { nm = -1; } else if (node.getNodeModifier() == NodeModifier.PALE) { nm = NodeModifier.FADING.ordinal(); } } } String nid = node.getId(); node.setAspects(new AspectList()); world.removeTileEntity(x + xx, y - yy + 2, z + zz); if(exNt != -1) { world.setBlock(x + xx, y - yy + 2, z + zz, RegisteredBlocks.blockExtendedNodeJar, 0, 3); tile = world.getTileEntity(x + xx, y - yy + 2, z + zz); TileExtendedNodeJar exJar = (TileExtendedNodeJar) tile; exJar.setAspects(na); if (nm >= 0) { exJar.setNodeModifier(NodeModifier.values()[nm]); } exJar.setNodeType(NodeType.values()[nt]); exJar.setExtendedNodeType(ExtendedNodeType.values()[exNt]); if(behaviorSnapshot != null) { exJar.setBehaviorSnapshot(behaviorSnapshot); } exJar.setId(nid); world.addBlockEvent(x + xx, y - yy + 2, z + zz, RegisteredBlocks.blockExtendedNodeJar, 9, 0); } else { world.setBlock(x + xx, y - yy + 2, z + zz, ConfigBlocks.blockJar, 2, 3); tile = world.getTileEntity(x + xx, y - yy + 2, z + zz); TileJarNode jar = (TileJarNode) tile; jar.setAspects(na); if (nm >= 0) { jar.setNodeModifier(NodeModifier.values()[nm]); } jar.setNodeType(NodeType.values()[nt]); jar.setId(nid); world.addBlockEvent(x + xx, y - yy + 2, z + zz, ConfigBlocks.blockJar, 9, 0); } } public abstract static class JarPieceEvaluationRunnable { public abstract boolean isValidPieceAt(World world, int absX, int absY, int absZ, EntityPlayer player); } }