diff --git a/.gitignore b/.gitignore index 8d16946..4d59512 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .idea build run +bin \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c2a3e3c --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Aura Core + +A Thaumcraft 4 addon aiming to bring back Thaumcraft 3 concepts. + +Required Thaumcraft 4 and MixinBooterLegacy/GasStation \ No newline at end of file diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..38b5eb2 --- /dev/null +++ b/TODO.md @@ -0,0 +1,31 @@ +# TODO + +## Aura interaction +- Arcane Bore +- Mirror (+ Hand Mirror) +- Lifter/Levitator + +## Compat +- TC4 Aura Nodes <-> Aura interaction + +## Research +- Old Research Table +- No scanning required +- Knowing all aspects from beginning +- Crafting API + +## Crafting +- Old Arcane Workbench GUI +- Arcane Workbench Vis crafting +- Infusion Crafting implementation + +## Crucible +- Old Crucible crafting +- No Flux goo & gas +- No boiling down to primal aspects + +## Config +- Config options for many things + +## TC2 +- Taint level for Aura Nodes diff --git a/build.gradle b/build.gradle index 585fd0f..0993e6a 100644 --- a/build.gradle +++ b/build.gradle @@ -19,25 +19,32 @@ buildscript { apply plugin: 'forge' apply plugin: 'maven-publish' +apply from: './gradle/scripts/mixins.gradle' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 -version = "1.0" -group= "modgroup" -archivesBaseName = "modid" +version = "1.0.0" +group= "dev.tilera" +archivesBaseName = "auracore" minecraft { version = "1.7.10-10.13.4.1614-1.7.10" runDir = "run" + + replaceIn "dev/tilera/auracore/AuraCore.java" + replace "{VERSION}", project.version } repositories { maven { url = "https://maven.tilera.xyz" } + maven { url = "https://jitpack.io" } } dependencies { - + implementation "thaumcraft:Thaumcraft:1.7.10-4.2.3.5:deobf" + implementation "com.github.tox1cozZ:mixin-booter-legacy:1.1.2" + annotationProcessor "com.github.tox1cozZ:mixin-booter-legacy:1.1.2:processor" } processResources { @@ -49,9 +56,24 @@ processResources { } } +jar { + manifest { + attributes([ + "FMLCorePlugin" : "dev.tilera.auracore.MixinLoader", + "FMLCorePluginContainsFMLMod": "true" + ]) + } +} + task deobfJar(type: Jar) { from sourceSets.main.output classifier = 'deobf' + manifest { + attributes([ + "FMLCorePlugin" : "dev.tilera.auracore.MixinLoader", + "FMLCorePluginContainsFMLMod": "true" + ]) + } } task sourcesJar(type: Jar) { @@ -85,4 +107,8 @@ publishing { mavenLocal() } } +} + +mixin { + mixinRefMapName = 'auracore.refmap.json' } \ No newline at end of file diff --git a/gradle/scripts/mixins.gradle b/gradle/scripts/mixins.gradle new file mode 100644 index 0000000..91ba32d --- /dev/null +++ b/gradle/scripts/mixins.gradle @@ -0,0 +1,78 @@ +abstract class MixinTask extends DefaultTask { + + @Input + abstract Property getMixinRefMapName() + + private File mixinSrg + private File mixinRefMap + + MixinTask() { + mixinRefMapName.convention("mixin.${project.name.replaceAll('[_\\-.]', '').toLowerCase()}.refmap.json") + } + + @TaskAction + void action() { + def mixinDir = new File(project.buildDir, 'mixins') + if (!mixinDir.exists()) { + mixinDir.mkdirs() + } + def srgFile = new File(project.buildDir, 'srgs/mcp-srg.srg') + mixinSrg = new File(mixinDir, "${mixinRefMapName.get()}.srg") + mixinRefMap = new File(mixinDir, mixinRefMapName.get()) + + if (!mixinSrg.exists()) { + mixinSrg.createNewFile() + } + + project.tasks.reobf.configure { + addExtraSrgFile mixinSrg + } + + def compileJava = project.tasks.compileJava + compileJava.configure { + options.compilerArgs += [ + '-Xlint:-processing', + "-AoutSrgFile=${mixinSrg.canonicalPath}", + "-AoutRefMapFile=${mixinRefMap.canonicalPath}", + "-AreobfSrgFile=${srgFile.canonicalPath}" + ] + } + + project.tasks.jar.configure { + from mixinRefMap + } + } + + @Internal + File getMixinSrg() { + return mixinSrg + } + + @Internal + File getMixinRefMap() { + return mixinRefMap + } +} + +tasks.register('mixin', MixinTask) + +task copySrgs(type: Copy, dependsOn: 'genSrgs') { + from plugins.getPlugin('forge').delayedFile('{SRG_DIR}') + include '**/*.srg' + into layout.buildDirectory.file('srgs') +} + +compileJava.dependsOn(copySrgs, mixin) +tasks.findByPath(":prepareKotlinBuildScriptModel")?.dependsOn(copySrgs, mixin) + +processResources { + afterEvaluate { + def refmap = tasks.mixin.mixinRefMapName.get() + inputs.property 'mixin_refmap', refmap + from(sourceSets.main.resources.srcDirs) { + include '*.json' + expand 'mixin_refmap': refmap + duplicatesStrategy = DuplicatesStrategy.INCLUDE + } + } +} \ No newline at end of file diff --git a/src/main/java/dev/tilera/auracore/AuraCore.java b/src/main/java/dev/tilera/auracore/AuraCore.java new file mode 100644 index 0000000..f139b88 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/AuraCore.java @@ -0,0 +1,82 @@ +package dev.tilera.auracore; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.event.FMLPostInitializationEvent; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import dev.tilera.auracore.api.Aspects; +import dev.tilera.auracore.aura.AuraCalculationThread; +import dev.tilera.auracore.aura.AuraDeleteThread; +import dev.tilera.auracore.aura.AuraUpdateThread; +import dev.tilera.auracore.aura.AuraWorldTicker; +import dev.tilera.auracore.client.GUITicker; +import dev.tilera.auracore.client.RenderEventHandler; +import dev.tilera.auracore.network.AuraDeletePacket; +import dev.tilera.auracore.network.AuraDeletePacketHandler; +import dev.tilera.auracore.network.AuraPacket; +import dev.tilera.auracore.network.AuraPacketHandler; +import dev.tilera.auracore.network.AuraTransferFXPacket; +import dev.tilera.auracore.network.AuraTransferFXPacketHandler; +import dev.tilera.auracore.network.NodeZapPacket; +import dev.tilera.auracore.network.NodeZapPacketHandler; +import dev.tilera.auracore.world.WorldGenerator; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.MinecraftForge; +import thaumcraft.api.ThaumcraftApi; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.common.config.ConfigBlocks; +import thaumcraft.common.config.ConfigItems; + +@Mod(modid = "auracore", name = "AuraCore", version = "{VERSION}", dependencies = "required-after:Thaumcraft") +public class AuraCore { + + public static SimpleNetworkWrapper CHANNEL; + + @Mod.EventHandler + public void preInit(FMLPreInitializationEvent e) { + Aspects.load(); + CHANNEL = NetworkRegistry.INSTANCE.newSimpleChannel("auracore"); + int pktID = 0; + CHANNEL.registerMessage(AuraPacketHandler.class, AuraPacket.class, pktID++, Side.CLIENT); + CHANNEL.registerMessage(AuraDeletePacketHandler.class, AuraDeletePacket.class, pktID++, Side.CLIENT); + CHANNEL.registerMessage(AuraTransferFXPacketHandler.class, AuraTransferFXPacket.class, pktID++, Side.CLIENT); + CHANNEL.registerMessage(NodeZapPacketHandler.class, NodeZapPacket.class, pktID++, Side.CLIENT); + MinecraftForge.EVENT_BUS.register(new EventHandler()); + MinecraftForge.EVENT_BUS.register(new RenderEventHandler()); + FMLCommonHandler.instance().bus().register(new AuraWorldTicker()); + FMLCommonHandler.instance().bus().register(new GUITicker()); + Thread auraCalcThread = new Thread(new AuraCalculationThread()); + auraCalcThread.setName("TC Aura Calculation Thread"); + auraCalcThread.start(); + Thread auraDelThread = new Thread(new AuraDeleteThread()); + auraDelThread.setName("TC Aura Deletion Thread"); + auraDelThread.start(); + Thread auraUpdateThread = new Thread(new AuraUpdateThread()); + auraUpdateThread.setName("TC Aura Update Thread"); + auraUpdateThread.start(); + GameRegistry.registerWorldGenerator(new WorldGenerator(), 100); + } + + @Mod.EventHandler + public void postInit(FMLPostInitializationEvent e) { + ThaumcraftApi.registerObjectTag(new ItemStack(ConfigItems.itemShard, 1, 0), new AspectList().add(Aspect.MAGIC, 2).add(Aspect.AIR, 2).add(Aspect.CRYSTAL, 2).add(Aspect.MOTION, 2)); + ThaumcraftApi.registerObjectTag(new ItemStack(ConfigItems.itemShard, 1, 1), new AspectList().add(Aspect.MAGIC, 2).add(Aspect.FIRE, 2).add(Aspect.CRYSTAL, 2).add(Aspect.ENERGY, 2)); + ThaumcraftApi.registerObjectTag(new ItemStack(ConfigItems.itemShard, 1, 2), new AspectList().add(Aspect.MAGIC, 2).add(Aspect.WATER, 2).add(Aspect.CRYSTAL, 2).add(Aspect.COLD, 2)); + ThaumcraftApi.registerObjectTag(new ItemStack(ConfigItems.itemShard, 1, 3), new AspectList().add(Aspect.MAGIC, 2).add(Aspect.EARTH, 2).add(Aspect.CRYSTAL, 2).add(Aspects.ROCK, 2)); + ThaumcraftApi.registerObjectTag(new ItemStack(ConfigItems.itemShard, 1, 4), new AspectList().add(Aspect.MAGIC, 2).add(Aspect.ORDER, 2).add(Aspect.CRYSTAL, 2).add(Aspects.CONTROL, 2)); + ThaumcraftApi.registerObjectTag(new ItemStack(ConfigItems.itemShard, 1, 5), new AspectList().add(Aspect.MAGIC, 2).add(Aspect.ENTROPY, 2).add(Aspect.CRYSTAL, 2).add(Aspects.DESTRUCTION, 2)); + ThaumcraftApi.registerObjectTag(new ItemStack(ConfigItems.itemShard, 1, 7), new AspectList().add(Aspect.MAGIC, 6).add(Aspect.CRYSTAL, 2)); + ThaumcraftApi.registerObjectTag(new ItemStack(ConfigItems.itemShard, 1, 8), new AspectList().add(Aspect.MAGIC, 2).add(Aspect.CRYSTAL, 2)); + ThaumcraftApi.registerObjectTag(new ItemStack(ConfigItems.itemShard, 1, 9), new AspectList().add(Aspect.MAGIC, 2).add(Aspect.TAINT, 2).add(Aspect.CRYSTAL, 2).add(Aspects.FLUX, 2)); + + ThaumcraftApi.registerObjectTag(new ItemStack(ConfigBlocks.blockCustomOre, 1, 8), new AspectList().add(Aspect.EARTH, 1).add(Aspect.MAGIC, 3).add(Aspect.CRYSTAL, 2)); + ThaumcraftApi.registerObjectTag(new ItemStack(ConfigBlocks.blockCustomOre, 1, 9), new AspectList().add(Aspect.EARTH, 1).add(Aspect.CRYSTAL, 2)); + ThaumcraftApi.registerObjectTag(new ItemStack(ConfigBlocks.blockCustomOre, 1, 10), new AspectList().add(Aspect.EARTH, 1).add(Aspect.TAINT, 3).add(Aspect.CRYSTAL, 2)); + } + +} diff --git a/src/main/java/dev/tilera/auracore/EventHandler.java b/src/main/java/dev/tilera/auracore/EventHandler.java new file mode 100644 index 0000000..aa28d39 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/EventHandler.java @@ -0,0 +1,91 @@ +package dev.tilera.auracore; + +import java.util.Arrays; +import java.util.List; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import dev.tilera.auracore.api.AuraNode; +import dev.tilera.auracore.api.EnumNodeType; +import dev.tilera.auracore.aura.AuraManager; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.event.world.ChunkDataEvent; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; + +public class EventHandler { + + @SubscribeEvent + public void chunkSave(ChunkDataEvent.Save event) { + NBTTagList nodelist = new NBTTagList(); + Object object = AuraManager.saveLock; + synchronized (object) { + List nds = AuraManager.nodeChunks.get(Arrays.asList(event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition)); + if (nds != null && nds.size() > 0) { + for (Integer key : nds) { + AuraNode node = AuraManager.getNode(key); + if (node == null) continue; + NBTTagCompound nodeNBT = new NBTTagCompound(); + nodeNBT.setInteger("key", node.key); + nodeNBT.setShort("level", node.level); + nodeNBT.setShort("baseLevel", node.baseLevel); + nodeNBT.setByte("type", (byte)node.type.ordinal()); + nodeNBT.setDouble("xPos", node.xPos); + nodeNBT.setDouble("yPos", node.yPos); + nodeNBT.setDouble("zPos", node.zPos); + nodeNBT.setBoolean("locked", node.locked); + nodeNBT.setBoolean("isVirtual", node.isVirtual); + NBTTagList flux = new NBTTagList(); + if (node.flux.size() > 0) { + for (Aspect tag : node.flux.getAspects()) { + if (tag == null) continue; + NBTTagCompound f = new NBTTagCompound(); + f.setString("id", tag.getTag()); + f.setInteger("amount", node.flux.getAmount(tag)); + flux.appendTag(f); + } + } + nodeNBT.setTag("flux", flux); + nodelist.appendTag(nodeNBT); + } + } + event.getData().setTag("TCNODES", nodelist); + } + } + + @SubscribeEvent + public void chunkLoad(ChunkDataEvent.Load event) { + if (event.getData().hasKey("TCNODES")) { + Object object = AuraManager.saveLock; + synchronized (object) { + NBTTagList nodeList = event.getData().getTagList("TCNODES", 10); + for (int i = 0; i < nodeList.tagCount(); ++i) { + NBTTagCompound nodeData = nodeList.getCompoundTagAt(i); + AuraNode node = new AuraNode(); + node.key = nodeData.getInteger("key"); + node.dimension = event.world.provider.dimensionId; + node.level = nodeData.getShort("level"); + node.baseLevel = nodeData.getShort("baseLevel"); + node.locked = nodeData.getBoolean("locked"); + if(nodeData.hasKey("isVirtual")) + node.isVirtual = nodeData.getBoolean("isVirtual"); + node.type = EnumNodeType.getType(nodeData.getByte("type")); + node.xPos = nodeData.getDouble("xPos"); + node.yPos = nodeData.getDouble("yPos"); + node.zPos = nodeData.getDouble("zPos"); + node.flux = new AspectList(); + NBTTagList fluxTags = nodeData.getTagList("flux", 10); + for (int j = 0; j < fluxTags.tagCount(); ++j) { + NBTTagCompound flux = fluxTags.getCompoundTagAt(j); + if (!flux.hasKey("id") || !flux.hasKey("amount")) continue; + node.flux.add(Aspect.getAspect(flux.getString("id")), flux.getInteger("amount")); + } + AuraManager.auraNodes.put(node.key, node); + AuraManager.addToAuraUpdateList(node); + AuraManager.generateNodeNeighbours(node); + } + } + } + } + +} diff --git a/src/main/java/dev/tilera/auracore/MixinLoader.java b/src/main/java/dev/tilera/auracore/MixinLoader.java new file mode 100644 index 0000000..866e18a --- /dev/null +++ b/src/main/java/dev/tilera/auracore/MixinLoader.java @@ -0,0 +1,58 @@ +package dev.tilera.auracore; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import cpw.mods.fml.common.DummyModContainer; +import cpw.mods.fml.common.ModMetadata; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin; +import io.github.tox1cozz.mixinbooterlegacy.IEarlyMixinLoader; + +public class MixinLoader implements IFMLLoadingPlugin, IEarlyMixinLoader { + + @Override + public String[] getASMTransformerClass() { + return new String[0]; + } + + @Override + public String getModContainerClass() { + return "dev.tilera.auracore.MixinLoader$Container"; + } + + @Override + public String getSetupClass() { + return null; + } + + @Override + public void injectData(Map data) { + + } + + @Override + public String getAccessTransformerClass() { + return null; + } + + public static class Container extends DummyModContainer { + + public Container() { + super(new ModMetadata()); + ModMetadata meta = getMetadata(); + meta.modId = "acmixin"; + meta.name = "AuraCore Mixin Loader"; + meta.version = "1.0.0"; + } + + } + + @Override + public List getMixinConfigs() { + List mixins = new ArrayList<>(); + mixins.add("auracore.mixins.json"); + return mixins; + } + +} diff --git a/src/main/java/dev/tilera/auracore/api/Aspects.java b/src/main/java/dev/tilera/auracore/api/Aspects.java new file mode 100644 index 0000000..cf3c70d --- /dev/null +++ b/src/main/java/dev/tilera/auracore/api/Aspects.java @@ -0,0 +1,25 @@ +package dev.tilera.auracore.api; + +import net.minecraft.util.ResourceLocation; +import thaumcraft.api.aspects.Aspect; + +public class Aspects { + + public static final Aspect INSECT = new Aspect("bestiola", 0x808880, new Aspect[] {Aspect.POISON, Aspect.BEAST}, new ResourceLocation("auracore", "textures/aspects/bestiola.png"), 1); + public static final Aspect EVIL = new Aspect("malum", 0x700000, new Aspect[] {Aspect.TAINT, Aspect.FIRE}, new ResourceLocation("auracore", "textures/aspects/malum.png"), 1); + public static final Aspect FLUX = new Aspect("mutatio", 12061625, new Aspect[] {Aspect.MAGIC, Aspects.EVIL}, new ResourceLocation("auracore", "textures/aspects/mutatio.png"), 1); + public static final Aspect SOUND = new Aspect("sonus", 1100224, new Aspect[] {Aspect.SENSES, Aspect.AIR}, new ResourceLocation("auracore", "textures/aspects/sonus.png"), 1); + public static final Aspect VISION = new Aspect("visum", 14013676, new Aspect[] {Aspect.SENSES, Aspect.LIGHT}, new ResourceLocation("auracore", "textures/aspects/visum.png"), 1); + public static final Aspect TIME = new Aspect("tempus", 9466080, new Aspect[] {Aspect.VOID, Aspect.ORDER}, new ResourceLocation("auracore", "textures/aspects/tempus.png"), 1); + public static final Aspect ROCK = new Aspect("saxum", 6047810, new Aspect[] {Aspect.EARTH, Aspect.EARTH}, new ResourceLocation("auracore", "textures/aspects/saxum.png"), 1); + public static final Aspect DESTRUCTION = new Aspect("fractus", 0x506050, new Aspect[] {Aspect.ENTROPY, Aspect.ENTROPY}, new ResourceLocation("auracore", "textures/aspects/fractus.png"), 1); + public static final Aspect PURE = new Aspect("purus", 10878973, new Aspect[] {Aspect.CRYSTAL, Aspect.ORDER}, new ResourceLocation("auracore", "textures/aspects/purus.png"), 1); + public static final Aspect VALUABLE = new Aspect("carus", 15121988, new Aspect[] {Aspect.GREED, Aspects.PURE}, new ResourceLocation("auracore", "textures/aspects/carus.png"), 1); + public static final Aspect CONTROL = new Aspect("imperito", 10000715, new Aspect[] {Aspect.MIND, Aspect.ORDER}, new ResourceLocation("auracore", "textures/aspects/imperito.png"), 1); + public static final Aspect SOIL = new Aspect("solum", 7421741, new Aspect[] {Aspect.EARTH, Aspects.ROCK}, new ResourceLocation("auracore", "textures/aspects/solum.png"), 1); + public static final Aspect FLOWER = new Aspect("flos", 0xFFFF40, new Aspect[] {Aspect.PLANT, Aspects.SOIL}, new ResourceLocation("auracore", "textures/aspects/flos.png"), 1); + public static final Aspect FUNGUS = new Aspect("fungus", 16246215, new Aspect[] {Aspect.PLANT, Aspect.TREE}, new ResourceLocation("auracore", "textures/aspects/fungus.png"), 1); + + public static void load() {} + +} diff --git a/src/main/java/dev/tilera/auracore/api/AuraNode.java b/src/main/java/dev/tilera/auracore/api/AuraNode.java new file mode 100644 index 0000000..b91ad60 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/api/AuraNode.java @@ -0,0 +1,34 @@ +package dev.tilera.auracore.api; + +import java.io.Serializable; + +import thaumcraft.api.aspects.AspectList; + +public class AuraNode implements Serializable { + public int key; + public short level; + public short baseLevel; + public AspectList flux = new AspectList(); + public EnumNodeType type; + public int dimension; + public double xPos; + public double yPos; + public double zPos; + public boolean locked; + public boolean isVirtual; + + public AuraNode(int key, short lvl, EnumNodeType type, int dim, int x, int y, int z) { + this.key = key; + this.level = lvl; + this.baseLevel = lvl; + this.type = type; + this.dimension = dim; + this.xPos = (double)x + 0.5; + this.yPos = (double)y + 0.5; + this.zPos = (double)z + 0.5; + this.isVirtual = false; + } + + public AuraNode() { + } +} diff --git a/src/main/java/dev/tilera/auracore/api/CrystalColors.java b/src/main/java/dev/tilera/auracore/api/CrystalColors.java new file mode 100644 index 0000000..f74a623 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/api/CrystalColors.java @@ -0,0 +1,27 @@ +package dev.tilera.auracore.api; + +public class CrystalColors { + + public static final int[] colors = new int[]{16777215, 16777086, 16727041, 37119, 40960, 15650047, 5592439, 11154172, 0xB0B0BC, 0x800080}; + + public static int getColorForShard(int meta) { + if (meta > 9 || meta < 0) { + return 0xFFFFFF; + } else if (meta > 6) { + return colors[meta]; + } else { + return colors[meta + 1]; + } + } + + public static int getColorForOre(int meta) { + if (meta > 10 || meta < 0) { + return 0xFFFFFF; + } else if (meta > 7) { + return colors[meta - 1]; + } else { + return colors[meta]; + } + } + +} diff --git a/src/main/java/dev/tilera/auracore/api/EnumNodeType.java b/src/main/java/dev/tilera/auracore/api/EnumNodeType.java new file mode 100644 index 0000000..61b3b40 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/api/EnumNodeType.java @@ -0,0 +1,21 @@ +package dev.tilera.auracore.api; + +public enum EnumNodeType { + NORMAL, + PURE, + DARK, + UNSTABLE; + + public static final EnumNodeType[] VALID_TYPES; + + public static EnumNodeType getType(int id) { + if (id >= 0 && id < VALID_TYPES.length) { + return VALID_TYPES[id]; + } + return NORMAL; + } + + static { + VALID_TYPES = new EnumNodeType[]{NORMAL, PURE, DARK, UNSTABLE}; + } +} diff --git a/src/main/java/dev/tilera/auracore/api/IAlembic.java b/src/main/java/dev/tilera/auracore/api/IAlembic.java new file mode 100644 index 0000000..1a155e0 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/api/IAlembic.java @@ -0,0 +1,7 @@ +package dev.tilera.auracore.api; + +import thaumcraft.api.aspects.IAspectSource; + +public interface IAlembic extends IAspectSource { + +} diff --git a/src/main/java/dev/tilera/auracore/api/IEssenceContainer.java b/src/main/java/dev/tilera/auracore/api/IEssenceContainer.java new file mode 100644 index 0000000..4cea801 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/api/IEssenceContainer.java @@ -0,0 +1,12 @@ +package dev.tilera.auracore.api; + +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.IAspectContainer; + +public interface IEssenceContainer extends IAspectContainer { + + Aspect getAspect(); + + int getAmount(); + +} diff --git a/src/main/java/dev/tilera/auracore/api/IWand.java b/src/main/java/dev/tilera/auracore/api/IWand.java new file mode 100644 index 0000000..137718d --- /dev/null +++ b/src/main/java/dev/tilera/auracore/api/IWand.java @@ -0,0 +1,13 @@ +package dev.tilera.auracore.api; + +import net.minecraft.item.ItemStack; + +public interface IWand { + + int getVis(ItemStack stack); + + int getMaxVis(ItemStack stack); + + boolean consumeVis(ItemStack stack, int amount); + +} diff --git a/src/main/java/dev/tilera/auracore/api/crafting/CrucibleRecipe.java b/src/main/java/dev/tilera/auracore/api/crafting/CrucibleRecipe.java new file mode 100644 index 0000000..73e83e3 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/api/crafting/CrucibleRecipe.java @@ -0,0 +1,53 @@ +package dev.tilera.auracore.api.crafting; + +import net.minecraft.item.ItemStack; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; + +public class CrucibleRecipe { + + public ItemStack recipeOutput; + public AspectList aspects; + public String key; + public String researchKey; + public int cost; + + public CrucibleRecipe(String researchKey, String key, ItemStack result, AspectList tags, int cost) { + this.recipeOutput = result; + this.aspects = tags; + this.key = key; + this.researchKey = researchKey; + this.cost = cost; + } + + public CrucibleRecipe(String key, ItemStack result, AspectList tags, int cost) { + this.recipeOutput = result; + this.aspects = tags; + this.key = key; + this.researchKey = key; + this.cost = cost; + } + + public boolean matches(AspectList itags) { + if (itags == null) { + return false; + } + for (Aspect tag : this.aspects.getAspects()) { + if (itags.getAmount(tag) >= this.aspects.getAmount(tag)) continue; + return false; + } + return true; + } + + public AspectList removeMatching(AspectList itags) { + AspectList temptags = new AspectList(); + temptags.aspects.putAll(itags.aspects); + for (Aspect tag : this.aspects.getAspects()) { + if (temptags.reduce(tag, this.aspects.getAmount(tag))) continue; + return null; + } + itags = temptags; + return itags; + } + +} diff --git a/src/main/java/dev/tilera/auracore/api/crafting/IInfusionRecipe.java b/src/main/java/dev/tilera/auracore/api/crafting/IInfusionRecipe.java new file mode 100644 index 0000000..76fe3e8 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/api/crafting/IInfusionRecipe.java @@ -0,0 +1,29 @@ +package dev.tilera.auracore.api.crafting; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import thaumcraft.api.aspects.AspectList; + +public interface IInfusionRecipe { + boolean matches(IInventory var1, World var2, EntityPlayer var3); + + ItemStack getCraftingResult(IInventory var1); + + int getRecipeSize(); + + ItemStack getRecipeOutput(); + + int getCost(); + + AspectList getAspects(); + + String getKey(); + + String getResearch(); + + default boolean isSimple() { + return getAspects() == null || getRecipeSize() <= 6; + } +} diff --git a/src/main/java/dev/tilera/auracore/aura/AuraCalculationThread.java b/src/main/java/dev/tilera/auracore/aura/AuraCalculationThread.java new file mode 100644 index 0000000..ba399a4 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/aura/AuraCalculationThread.java @@ -0,0 +1,241 @@ +package dev.tilera.auracore.aura; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import dev.tilera.auracore.api.Aspects; +import dev.tilera.auracore.api.AuraNode; +import dev.tilera.auracore.helper.Utils; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; + +public class AuraCalculationThread + implements Runnable { + + @Override + public void run() { + try { + while (true) { + try { + while (true) { + List up = AuraManager.auraCalcQueue.take(); + Object object = AuraManager.saveLock; + synchronized (object) { + AuraNode node = AuraManager.copyNode(AuraManager.getNode((Integer) up.get(0))); + this.updateNode((World) up.get(1), node); + this.checkFlux((World) up.get(1), node); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + continue; + } + } + } catch (Exception ex) { + ex.printStackTrace(); + return; + } + } + + public int getAverageFlux(AspectList ot) { + int ret = 0; + if (ot.size() > 0) { + ret = ot.visSize(); + ret /= ot.size(); + } + return ret; + } + + private synchronized void updateNode(World world, AuraNode node) { + int dim = world.provider.dimensionId; + List updateList = AuraManager.getNodeNeighbours(node.key); + if (updateList.size() == 0) { + AuraManager.generateNodeNeighbours(node); + } + int fluxTotal = this.getAverageFlux(node.flux); + switch (node.type) { + case PURE: { + if (world.rand.nextInt(20) != 7) + break; + this.removeRandomFlux(world, node, 1); + break; + } + case DARK: { + if (world.rand.nextInt(5 + fluxTotal) != 0) + break; + if (world.rand.nextBoolean()) { + AuraManager.queueNodeChanges(node.key, 0, 0, false, new AspectList().add(Aspects.EVIL, 1), 0.0f, + 0.0f, 0.0f); + break; + } + AuraManager.queueNodeChanges(node.key, 0, 0, false, new AspectList().add(Aspect.DEATH, 1), 0.0f, 0.0f, + 0.0f); + break; + } + case UNSTABLE: { + if (world.rand.nextInt(1 + fluxTotal) != 0) + break; + this.addRandomFlux(world, node, 1); + } + } + /* + * if (Config.foundIMP && node.level >= 5) { + * AuraManager.queueNodeChanges(node.key, -5, 0, false, null, 0.0f, 0.0f, 0.0f); + * } + */ // TODO: WTF + if (node.level > node.baseLevel && world.rand.nextFloat() > (float) node.baseLevel / (float) node.level) { + this.addRandomFlux(world, node, 1); + } + if (updateList != null && updateList.size() > 0) { + for (Integer nk : updateList) { + double zd; + double yd; + double xd; + double distSq; + boolean sendTransferFX = false; + boolean toT = false; + AuraNode targetNode = AuraManager.copyNode(AuraManager.getNode(nk)); + if (targetNode == null || !Utils.isChunkLoaded(world, MathHelper.floor_double((double) targetNode.xPos), + MathHelper.floor_double((double) targetNode.zPos))) + continue; + if (node.level < node.baseLevel && node.level < targetNode.level + && world.rand.nextFloat() > (float) node.level / (float) targetNode.level) { + node.level = (short) (node.level + 1); + targetNode.level = (short) (targetNode.level - 1); + AuraManager.queueNodeChanges(node.key, 1, 0, false, null, 0.0f, 0.0f, 0.0f); + AuraManager.queueNodeChanges(targetNode.key, -1, 0, false, null, 0.0f, 0.0f, 0.0f); + this.addRandomFlux(world, node, 1); + sendTransferFX = true; + } + if ((distSq = (xd = node.xPos - targetNode.xPos) * xd + (yd = node.yPos - targetNode.yPos) * yd + + (zd = node.zPos - targetNode.zPos) * zd) < (double) ((node.level + targetNode.level) / 2) + && distSq > 0.25) { + AspectList flx; + float zm; + float ym; + float xm; + float tq = node.level + targetNode.level; + if (!node.locked && !node.isVirtual && !targetNode.isVirtual) { + xm = (float) (-xd / distSq / (double) tq * (double) targetNode.level); + ym = (float) (-yd / distSq / (double) tq * (double) targetNode.level); + zm = (float) (-zd / distSq / (double) tq * (double) targetNode.level); + node.xPos += (double) xm; + node.yPos += (double) ym; + node.zPos += (double) zm; + flx = null; + if (world.rand.nextInt(25) == 0) { + flx = new AspectList(); + flx.add(Aspect.MOTION, 1); + } + AuraManager.queueNodeChanges(node.key, 0, 0, false, flx, xm, ym, zm); + } + if (!targetNode.locked && !node.isVirtual && !targetNode.isVirtual) { + xm = (float) (xd / distSq / (double) tq * (double) node.level); + ym = (float) (yd / distSq / (double) tq * (double) node.level); + zm = (float) (zd / distSq / (double) tq * (double) node.level); + targetNode.xPos += (double) xm; + targetNode.yPos += (double) ym; + targetNode.zPos += (double) zm; + flx = null; + if (world.rand.nextInt(25) == 0) { + flx = new AspectList(); + flx.add(Aspect.MOTION, 1); + } + AuraManager.queueNodeChanges(targetNode.key, 0, 0, false, flx, xm, ym, zm); + } + } else if (distSq <= (double) 0.3f && !node.isVirtual && !targetNode.isVirtual) { + AspectList flx; + if (node.baseLevel > targetNode.baseLevel) { + node.level = (short) ((float) node.level + (float) targetNode.level * 0.75f); + node.baseLevel = (short) ((float) node.baseLevel + (float) targetNode.baseLevel * 0.33f); + double ox = node.xPos; + double oy = node.yPos; + double oz = node.zPos; + node.xPos = (node.xPos + targetNode.xPos) / 2.0; + node.yPos = (node.yPos + targetNode.yPos) / 2.0; + node.zPos = (node.zPos + targetNode.zPos) / 2.0; + flx = new AspectList(); + if (targetNode.flux.size() > 0) { + for (Aspect tt : targetNode.flux.getAspects()) { + flx.add(tt, targetNode.flux.getAmount(tt)); + } + } + flx.add(Aspect.EXCHANGE, (int) ((float) targetNode.baseLevel * 0.1f)); + this.addRandomFlux(world, node, (int) ((float) targetNode.baseLevel * 0.3f)); + AuraManager.queueNodeChanges(node.key, (int) ((float) targetNode.level * 0.75f), + (int) ((float) targetNode.baseLevel * 0.33f), false, flx, (float) (node.xPos - ox), + (float) (node.yPos - oy), (float) (node.zPos - oz)); + AuraManager.auraDeleteQueue.add(targetNode.key); + AuraManager.sendNodeDeletionPacket(targetNode); + } else { + targetNode.level = (short) ((float) targetNode.level + (float) node.level * 0.75f); + targetNode.baseLevel = (short) ((float) targetNode.baseLevel + (float) node.baseLevel * 0.33f); + double ox = targetNode.xPos; + double oy = targetNode.yPos; + double oz = targetNode.zPos; + targetNode.xPos = (node.xPos + targetNode.xPos) / 2.0; + targetNode.yPos = (node.yPos + targetNode.yPos) / 2.0; + targetNode.zPos = (node.zPos + targetNode.zPos) / 2.0; + flx = new AspectList(); + if (node.flux.size() > 0) { + for (Aspect tt : node.flux.getAspects()) { + flx.add(tt, node.flux.getAmount(tt)); + } + } + flx.add(Aspect.EXCHANGE, (int) ((float) targetNode.baseLevel * 0.1f)); + this.addRandomFlux(world, targetNode, (int) ((float) targetNode.baseLevel * 0.3f)); + AuraManager.queueNodeChanges(targetNode.key, (int) ((float) node.level * 0.75f), + (int) ((float) node.baseLevel * 0.33f), false, flx, (float) (targetNode.xPos - ox), + (float) (targetNode.yPos - oy), (float) (targetNode.zPos - oz)); + AuraManager.auraDeleteQueue.add(node.key); + AuraManager.sendNodeDeletionPacket(node); + } + } + if (!sendTransferFX) + continue; + AuraManager.sendNodeTransferFXPacket(targetNode, node, distSq); + } + } + } + + private void checkFlux(World world, AuraNode node) { + if (node != null && node.flux != null) { + for (Aspect fluxTag : node.flux.getAspects()) { + int fluxAmt = node.flux.getAmount(fluxTag); + int q = world.rand.nextInt(2500); + if (AuraManager.fluxEventList == null) { + AuraManager.fluxEventList = new ArrayList<>(); + } + if (q < 10 && fluxAmt >= 10) { + if (AuraManager.fluxEventList == null) + break; + AuraManager.fluxEventList.add(Arrays.asList(new Object[] { world, node, fluxTag, 0 })); + break; + } + if (q < 15 && fluxAmt >= 25) { + if (AuraManager.fluxEventList == null) + break; + AuraManager.fluxEventList.add(Arrays.asList(new Object[] { world, node, fluxTag, 1 })); + break; + } + if (q >= 20 || fluxAmt < 50) + continue; + if (AuraManager.fluxEventList == null) + break; + AuraManager.fluxEventList.add(Arrays.asList(new Object[] { world, node, fluxTag, 2 })); + break; + } + } + } + + private void addRandomFlux(World world, AuraNode node, int i) { + AuraManager.addRandomFlux(world, node, i); + } + + private void removeRandomFlux(World world, AuraNode node, int i) { + AuraManager.removeRandomFlux(world, node, i); + } +} diff --git a/src/main/java/dev/tilera/auracore/aura/AuraDeleteThread.java b/src/main/java/dev/tilera/auracore/aura/AuraDeleteThread.java new file mode 100644 index 0000000..7fc361f --- /dev/null +++ b/src/main/java/dev/tilera/auracore/aura/AuraDeleteThread.java @@ -0,0 +1,45 @@ +package dev.tilera.auracore.aura; + +import java.util.Arrays; +import java.util.List; + +import dev.tilera.auracore.api.AuraNode; +import net.minecraft.util.MathHelper; + +public class AuraDeleteThread + implements Runnable { + + @Override + public void run() { + try { + while (true) { + boolean done = false; + int count = 0; + int dl = (Integer) AuraManager.auraDeleteQueue.take(); + Object object = AuraManager.saveLock; + synchronized (object) { + while (AuraManager.auraNodes.get(dl) != null && !done && count < 10) { + ++count; + try { + AuraNode t = AuraManager.getNode(dl); + AuraManager.auraNodes.remove(dl); + AuraManager.nodeNeighbours.remove(dl); + int cx = MathHelper.floor_double((double) t.xPos) / 16; + int cz = MathHelper.floor_double((double) t.zPos) / 16; + if (AuraManager.nodeChunks.get(Arrays.asList(t.dimension, cx, cz)) != null) { + List nds = AuraManager.nodeChunks.get(Arrays.asList(t.dimension, cx, cz)); + if (nds.remove((Object) dl)) { + AuraManager.nodeChunks.put(Arrays.asList(t.dimension, cx, cz), nds); + } + } + done = true; + } catch (Exception e1) { + } + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } +} diff --git a/src/main/java/dev/tilera/auracore/aura/AuraManager.java b/src/main/java/dev/tilera/auracore/aura/AuraManager.java new file mode 100644 index 0000000..ba8e838 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/aura/AuraManager.java @@ -0,0 +1,848 @@ +package dev.tilera.auracore.aura; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingQueue; + +import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityWitch; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +import dev.tilera.auracore.AuraCore; +import dev.tilera.auracore.api.Aspects; +import dev.tilera.auracore.api.AuraNode; +import dev.tilera.auracore.api.EnumNodeType; +import dev.tilera.auracore.helper.Utils; +import dev.tilera.auracore.network.AuraDeletePacket; +import dev.tilera.auracore.network.AuraPacket; +import dev.tilera.auracore.network.AuraTransferFXPacket; +import dev.tilera.auracore.network.NodeZapPacket; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.common.entities.monster.EntityBrainyZombie; +import thaumcraft.common.entities.monster.EntityFireBat; +import thaumcraft.common.entities.monster.EntityGiantBrainyZombie; +import thaumcraft.common.entities.monster.EntityWisp; +import thaumcraft.common.lib.world.biomes.BiomeHandler; + +public class AuraManager { + public static ConcurrentHashMap auraNodes = new ConcurrentHashMap<>(); + public static ConcurrentHashMap> auraUpdateList = new ConcurrentHashMap<>(); + public static volatile ConcurrentHashMap> nodeNeighbours = new ConcurrentHashMap<>(); + public static volatile ConcurrentHashMap, List> nodeChunks = new ConcurrentHashMap<>(); + public static volatile ConcurrentHashMap markedForTransmission = new ConcurrentHashMap<>(); + public static volatile ArrayList> fluxEventList = new ArrayList<>(); + public static LinkedBlockingQueue> auraCalcQueue = new LinkedBlockingQueue<>(); + public static LinkedBlockingQueue auraDeleteQueue = new LinkedBlockingQueue<>(); + public static LinkedBlockingQueue auraUpdateQueue = new LinkedBlockingQueue<>(); + public static Object saveLock = new Object(); + public static NodeIdStorage nodeIdStore = null; + + public static int registerAuraNode(World world, short lvl, EnumNodeType type, int dim, int x, int y, int z) { + return registerAuraNode(world, lvl, type, dim, x, y, z, false); + } + + public static int registerAuraNode(World world, short lvl, EnumNodeType type, int dim, int x, int y, int z, boolean virtual) { + if (nodeIdStore == null) { + nodeIdStore = new NodeIdStorage(world.getSaveHandler()); + } + int key = nodeIdStore.getUniqueDataId("tcnode"); + AuraNode node = new AuraNode(key, lvl, type, dim, x, y, z); + if (virtual) { + node.isVirtual = true; + + } + auraNodes.put(node.key, node); + LinkedList temp = (LinkedList)auraUpdateList.get(dim); + if (temp == null) { + temp = new LinkedList(); + auraUpdateList.put(dim, temp); + } + temp.add(node.key); + return key; + } + + public static List getNodeNeighbours(int nkey) { + ArrayList neighbours = new ArrayList<>(); + if (nodeNeighbours.get(nkey) != null) { + neighbours.addAll(nodeNeighbours.get(nkey)); + } + return neighbours; + } + + public static List getNodeNeighboursNeighbours(int nkey) { + List neighbours = AuraManager.getNodeNeighbours(nkey); + if (neighbours != null && neighbours.size() > 0) { + ArrayList neighboursNeighbours = new ArrayList(); + neighboursNeighbours.addAll(neighbours); + for (Integer key : neighbours) { + try { + for (Integer key2 : AuraManager.getNodeNeighbours(key)) { + if (neighboursNeighbours.contains(key2)) continue; + neighboursNeighbours.add(key2); + } + } + catch (Exception e) { + } + } + return neighboursNeighbours; + } + return null; + } + + public static synchronized void addToAuraUpdateList(AuraNode node) { + LinkedList temp = (LinkedList)auraUpdateList.get(node.dimension); + if (temp == null) { + temp = new LinkedList(); + auraUpdateList.put(node.dimension, temp); + } + if (!temp.contains(node.key)) { + temp.add(node.key); + } + auraUpdateList.put(node.dimension, temp); + } + + public static void generateNodeNeighbours(AuraNode node) { + int dim = node.dimension; + synchronized (saveLock) { + Integer[] updateList = AuraManager.getUpdateList(dim); + ArrayList neighbours = new ArrayList(); + for (int a = 0; a < updateList.length && a < updateList.length; ++a) { + double zd; + double yd; + double xd; + double distSq; + float influence; + int nk; + AuraNode targetNode; + if (updateList[a] == null || updateList[a] == node.key || (targetNode = AuraManager.copyNode(AuraManager.getNode(nk = updateList[a].intValue()))) == null || !((double)((influence = Math.max((float)node.baseLevel / 4.0f, (float)targetNode.baseLevel / 4.0f)) * influence) >= (distSq = (xd = node.xPos - targetNode.xPos) * xd + (yd = node.yPos - targetNode.yPos) * yd + (zd = node.zPos - targetNode.zPos) * zd))) continue; + neighbours.add(targetNode.key); + } + nodeNeighbours.put(node.key, neighbours); + int cx = MathHelper.floor_double((double)node.xPos) / 16; + int cz = MathHelper.floor_double((double)node.zPos) / 16; + if (nodeChunks.get(Arrays.asList(dim, cx, cz)) != null) { + ArrayList nds = (ArrayList)nodeChunks.get(Arrays.asList(dim, cx, cz)); + if (!nds.contains(node.key) && nds.size() > 0) { + nds.add(node.key); + nodeChunks.put(Arrays.asList(dim, cx, cz), nds); + } + } else { + ArrayList temp = new ArrayList(); + temp.add(node.key); + nodeChunks.put(Arrays.asList(dim, cx, cz), temp); + } + } + } + + public static void updateNodeNeighbours(AuraNode node) { + int dim = node.dimension; + List updateList = AuraManager.getNodeNeighboursNeighbours(node.key); + ArrayList newNeighbours = new ArrayList(); + ArrayList deadNodes = new ArrayList(); + if (updateList != null && updateList.size() > 0) { + for (Integer key : updateList) { + List nlist; + double zd; + double yd; + double xd; + double distSq; + AuraNode targetNode = AuraManager.copyNode(AuraManager.getNode(key)); + if (targetNode == null || key == node.key) continue; + float influence = Math.max((float)node.baseLevel / 4.0f, (float)targetNode.baseLevel / 4.0f); + if ((double)(influence * influence) >= (distSq = (xd = node.xPos - targetNode.xPos) * xd + (yd = node.yPos - targetNode.yPos) * yd + (zd = node.zPos - targetNode.zPos) * zd)) { + newNeighbours.add(targetNode.key); + nlist = AuraManager.getNodeNeighbours(targetNode.key); + if (nlist.contains(node.key)) continue; + nlist.add(node.key); + nodeNeighbours.put(targetNode.key, nlist); + continue; + } + nlist = AuraManager.getNodeNeighbours(targetNode.key); + int index = nlist.indexOf(node.key); + if (index <= -1) continue; + nlist.remove(index); + nodeNeighbours.put(targetNode.key, nlist); + } + nodeNeighbours.put(node.key, newNeighbours); + } else { + AuraManager.generateNodeNeighbours(node); + } + } + + public static int getClosestAuraWithinRange(World world, double x, double y, double z, double range) { + int dim = world.provider.dimensionId; + int cx = MathHelper.floor_double((double)x) / 16; + int cz = MathHelper.floor_double((double)z) / 16; + if (world.isRemote) { + return -1; + } + int size = 5; + int closest = -1; + double clRange = Double.MAX_VALUE; + synchronized (saveLock) { + for (int xx = -size; xx <= size; ++xx) { + for (int zz = -size; zz <= size; ++zz) { + List nc = nodeChunks.get(Arrays.asList(dim, cx + xx, cz + zz)); + if (nc == null || nc.size() <= 0) continue; + for (Integer key : nc) { + try { + double zd; + double yd; + double xd; + double distSq; + AuraNode node = AuraManager.copyNode(AuraManager.getNode(key)); + if (node == null || node.locked || !Utils.isChunkLoaded(world, MathHelper.floor_double((double)node.xPos), MathHelper.floor_double((double)node.zPos)) || !(range * range >= (distSq = (xd = node.xPos - x) * xd + (yd = node.yPos - y) * yd + (zd = node.zPos - z) * zd)) || !(distSq < clRange)) continue; + closest = key; + clRange = distSq; + } + catch (Exception e) {} + } + } + } + } + return closest; + } + + public static ArrayList getAurasWithin(World world, double x, double y, double z) { + int dim = world.provider.dimensionId; + int cx = MathHelper.floor_double((double)x) / 16; + int cz = MathHelper.floor_double((double)z) / 16; + ArrayList ret = new ArrayList(); + if (world.isRemote) { + return ret; + } + synchronized (saveLock) { + for (int xx = -16; xx <= 16; ++xx) { + for (int zz = -16; zz <= 16; ++zz) { + List nc = nodeChunks.get(Arrays.asList(dim, cx + xx, cz + zz)); + if (nc == null || nc.size() <= 0) continue; + for (Integer key : nc) { + try { + double zd; + double yd; + double xd; + double distSq; + float influence; + AuraNode node = AuraManager.copyNode(AuraManager.getNode(key)); + if (node == null || !Utils.isChunkLoaded(world, MathHelper.floor_double((double)node.xPos), MathHelper.floor_double((double)node.zPos)) || !((double)((influence = (float)node.baseLevel) * influence) >= (distSq = (xd = node.xPos - x) * xd + (yd = node.yPos - y) * yd + (zd = node.zPos - z) * zd))) continue; + ret.add(key); + } + catch (Exception e) {} + } + } + } + } + return ret; + } + + public static boolean decreaseClosestAura(World world, double x, double y, double z, int amount) { + if (amount == 0) { + return true; + } + return AuraManager.decreaseClosestAura(world, x, y, z, amount, true); + } + + public static boolean decreaseClosestAura(World world, double x, double y, double z, int amount, boolean doit) { + AuraNode node; + if (world.isRemote) { + return false; + } + int dim = world.provider.dimensionId; + ArrayList nodes = AuraManager.getAurasWithin(world, x, y, z); + int total = 0; + ArrayList> sortednodes = new ArrayList>(); + ArrayList> depnodes = new ArrayList>(); + for (Integer n : nodes) { + int a; + double zd; + double yd; + double xd; + double distSq; + float influence; + node = AuraManager.getNode(n); + if (node == null || node.level <= 0 || !((double)((influence = (float)node.baseLevel / 4.0f) * influence) >= (distSq = (xd = node.xPos - x) * xd + (yd = node.yPos - y) * yd + (zd = node.zPos - z) * zd))) continue; + if (sortednodes.size() == 0) { + sortednodes.add(Arrays.asList(distSq, node.key)); + continue; + } + for (a = 0; !(a > sortednodes.size() || a < sortednodes.size() && (Double)((List)sortednodes.get(a)).get(0) > distSq); ++a) { + } + if (a < sortednodes.size()) { + sortednodes.add(a, Arrays.asList(distSq, node.key)); + continue; + } + sortednodes.add(Arrays.asList(distSq, node.key)); + } + if (sortednodes.size() == 0) { + return false; + } + for (List list : sortednodes) { + node = AuraManager.getNode((Integer)list.get(1)); + if (node != null && node.level > 0) { + if (node.level >= amount - total) { + depnodes.add(Arrays.asList(amount - total, node.key)); + total += amount - total; + break; + } + depnodes.add(Arrays.asList((int)node.level, node.key)); + total += node.level; + } + if (amount - total != 0) continue; + break; + } + if (total == amount) { + for (List list : depnodes) { + int amt = (Integer)list.get(0); + AuraNode node2 = AuraManager.getNode((Integer)list.get(1)); + if (node2 == null || !doit) continue; + AuraManager.queueNodeChanges(node2.key, -amt, 0, false, null, 0.0f, 0.0f, 0.0f); + } + return true; + } + return false; + } + + public static boolean increaseLowestAura(World world, double x, double y, double z, int amount) { + if (world.isRemote) { + return false; + } + int dim = world.provider.dimensionId; + ArrayList nodes = AuraManager.getAurasWithin(world, x, y, z); + int n = Integer.MAX_VALUE; + AuraNode lowest = null; + for (Integer nk : nodes) { + double zd; + double yd; + double xd; + double distSq; + float influence; + short s = Short.MAX_VALUE; + AuraNode node = AuraManager.getNode(nk); + if (node == null || node.level >= s || !((double)((influence = (float)node.baseLevel / 4.0f) * influence) >= (distSq = (xd = node.xPos - x) * xd + (yd = node.yPos - y) * yd + (zd = node.zPos - z) * zd))) continue; + lowest = node; + s = node.level; + } + if (lowest != null) { + AuraNode node = AuraManager.getNode(lowest.key); + if (node != null) { + AuraManager.queueNodeChanges(node.key, amount, 0, false, null, 0.0f, 0.0f, 0.0f); + } + return true; + } + return false; + } + + public static boolean increaseLowestAuraWithLimit(World world, double x, double y, double z, int amount, float limit) { + if (world.isRemote) { + return false; + } + int dim = world.provider.dimensionId; + ArrayList nodes = AuraManager.getAurasWithin(world, x, y, z); + int n = Integer.MAX_VALUE; + AuraNode lowest = null; + for (Integer nk : nodes) { + double zd; + double yd; + double xd; + double distSq; + float influence; + short s = Short.MAX_VALUE; + AuraNode node = AuraManager.getNode(nk); + if (node == null || node.level >= s || !((float)node.level < (float)node.baseLevel * limit) || !((double)((influence = (float)node.baseLevel / 4.0f) * influence) >= (distSq = (xd = node.xPos - x) * xd + (yd = node.yPos - y) * yd + (zd = node.zPos - z) * zd))) continue; + lowest = node; + s = node.level; + } + if (lowest != null) { + AuraNode node = AuraManager.getNode(lowest.key); + if (node != null) { + AuraManager.queueNodeChanges(node.key, amount, 0, false, null, 0.0f, 0.0f, 0.0f); + } + return true; + } + return false; + } + + public static boolean auraNearby(int dim, int x, int y, int z, int range) { + Collection col = auraNodes.values(); + for (AuraNode an : col) { + float pz; + double zd; + float py; + double yd; + float px; + double xd; + double distSq; + if (dim != an.dimension || !((distSq = (xd = (double)((px = (float)an.xPos) - (float)x + 0.5f)) * xd + (yd = (double)((py = (float)an.yPos) - (float)y + 0.5f)) * yd + (zd = (double)((pz = (float)an.zPos) - (float)z + 0.5f)) * zd) < (double)(range * range))) continue; + return true; + } + return false; + } + + public static boolean specificAuraTypeNearby(int dim, int x, int y, int z, EnumNodeType type, int range) { + Collection col = auraNodes.values(); + for (AuraNode an : col) { + float pz; + double zd; + float py; + double yd; + float px; + double xd; + double distSq; + if (dim != an.dimension || an.type != type || !((distSq = (xd = (double)((px = (float)an.xPos) - (float)x + 0.5f)) * xd + (yd = (double)((py = (float)an.yPos) - (float)y + 0.5f)) * yd + (zd = (double)((pz = (float)an.zPos) - (float)z + 0.5f)) * zd) < (double)(range * range))) continue; + return true; + } + return false; + } + + public static void sendNodePacket(AuraNode node) { + AuraCore.CHANNEL.sendToAllAround(new AuraPacket(node), new TargetPoint(node.dimension, node.xPos, node.yPos, node.zPos, Math.max(32.0f, (float)node.baseLevel / 4.0f))); + } + + public static void sendNodeTransferFXPacket(AuraNode node, AuraNode tnode, double distance) { + double xx = (node.xPos + tnode.xPos) / 2.0; + double yy = (node.yPos + tnode.yPos) / 2.0; + double zz = (node.zPos + tnode.zPos) / 2.0; + AuraCore.CHANNEL.sendToAllAround(new AuraTransferFXPacket(node, tnode), new TargetPoint(node.dimension, xx, yy, zz, MathHelper.sqrt_double((double)distance) + 32.0f)); + } + + public static void sendNodeDeletionPacket(AuraNode node) { + AuraCore.CHANNEL.sendToAll(new AuraDeletePacket(node)); + } + + public static void addFluxToClosest(World world, float x, float y, float z, AspectList tags) { + if (world.isRemote) { + return; + } + int dim = world.provider.dimensionId; + ArrayList nodes = AuraManager.getAurasWithin(world, x, y, z); + if (nodes == null || nodes.size() == 0) { + return; + } + boolean total = false; + double cDist = Double.MAX_VALUE; + int cKey = -1; + for (Integer nk : nodes) { + double zd; + double yd; + double xd; + double distSq; + float influence; + AuraNode node = AuraManager.getNode(nk); + if (node == null || !((double)((influence = (float)node.baseLevel / 4.0f) * influence) >= (distSq = (xd = node.xPos - (double)x) * xd + (yd = node.yPos - (double)y) * yd + (zd = node.zPos - (double)z) * zd)) || !(distSq < cDist)) continue; + cDist = distSq; + cKey = nk; + } + if (cKey < 0) { + return; + } + AuraNode node = AuraManager.getNode(cKey); + if (node != null) { + AspectList flux = new AspectList(); + for (Aspect tag : tags.getAspects()) { + if (tags.getAmount(tag) <= 0) continue; + flux.add(tag, tags.getAmount(tag)); + } + if (flux.size() > 0) { + AuraManager.queueNodeChanges(node.key, 0, 0, false, flux, 0.0f, 0.0f, 0.0f); + } + } + } + + public static void removeRandomFlux(World world, AuraNode node, int amount) { + AspectList flux = new AspectList(); + for (int a = 0; a < amount; ++a) { + int i$ = 0; + Aspect[] arr$ = node.flux.getAspects(); + int len$ = arr$.length; + if (i$ >= len$) continue; + Aspect tg = arr$[i$]; + if (world.rand.nextInt(5) != 0 || -flux.getAmount(tg) >= node.flux.getAmount(tg)) continue; + flux.add(tg, -1); + } + if (flux.size() > 0) { + AuraManager.queueNodeChanges(node.key, 0, 0, false, flux, 0.0f, 0.0f, 0.0f); + } + } + + public static void addRandomFlux(World world, AuraNode node, int amount) { + AspectList flux = new AspectList(); + block20: for (int a = 0; a < amount; ++a) { + if (world.rand.nextInt(5) != 0) continue; + switch (world.rand.nextInt(3)) { + case 0: { + int biome = world.getBiomeGenForCoords((int)((int)node.xPos), (int)((int)node.zPos)).biomeID; + flux.add(BiomeHandler.getRandomBiomeTag(biome, world.rand), 1); + continue block20; + } + case 1: { + switch (world.rand.nextInt(20)) { + case 0: + case 1: { + flux.add(Aspect.AIR, 1); + continue block20; + } + case 2: { + flux.add(Aspect.MOTION, 1); + continue block20; + } + case 3: + case 4: { + flux.add(Aspect.FIRE, 1); + continue block20; + } + case 5: { + flux.add(Aspect.ENERGY, 1); + continue block20; + } + case 6: + case 7: { + flux.add(Aspect.WATER, 1); + continue block20; + } + case 8: { + flux.add(Aspect.COLD, 1); + continue block20; + } + case 9: + case 10: { + flux.add(Aspect.EARTH, 1); + continue block20; + } + case 11: { + flux.add(Aspects.ROCK, 1); + continue block20; + } + case 12: { + flux.add(Aspect.POISON, 1); + continue block20; + } + case 13: { + flux.add(Aspect.PLANT, 1); + continue block20; + } + case 14: { + flux.add(Aspect.TREE, 1); + continue block20; + } + case 15: + case 16: { + flux.add(Aspect.MAGIC, 1); + continue block20; + } + case 17: { + flux.add(Aspect.BEAST, 1); + continue block20; + } + case 18: { + flux.add(Aspect.DEATH, 1); + continue block20; + } + } + flux.add(Aspect.WEATHER, 1); + continue block20; + } + default: { + flux.add(Aspects.FLUX, 1); + } + } + } + if (flux.size() > 0) { + AuraManager.queueNodeChanges(node.key, 0, 0, false, flux, 0.0f, 0.0f, 0.0f); + } + } + + public static void deleteNode(AuraNode node) { + auraDeleteQueue.add(node.key); + sendNodeDeletionPacket(node); + } + + public static boolean spawnMajorFluxEvent(World world, AuraNode node, Aspect fluxTag) { + boolean success = false; + if (fluxTag == Aspects.PURE) { + success = true; + } + if (success) { + AuraManager.queueNodeChanges(node.key, 0, 0, false, new AspectList().add(fluxTag, -50), 0.0f, 0.0f, 0.0f); + } + return success; + } + + public static boolean spawnModerateFluxEvent(World world, AuraNode node, Aspect fluxTag) { + boolean success = false; + if (fluxTag == Aspects.PURE) { + success = true; + } else if (fluxTag == Aspect.DEATH) { + success = AuraManager.spawnGiant(world, node); + } + if (success) { + AuraManager.queueNodeChanges(node.key, 0, 0, false, new AspectList().add(fluxTag, -25), 0.0f, 0.0f, 0.0f); + } + return success; + } + + public static boolean spawnMinorFluxEvent(World world, AuraNode node, Aspect fluxTag) { + boolean success = false; + if (world.rand.nextInt(3) == 0) { + success = AuraManager.spawnWisp(world, node, fluxTag); + } else { + if (fluxTag == Aspect.ENERGY || fluxTag == Aspects.DESTRUCTION) { + success = AuraManager.spawnLightning(world, node); + } else if (fluxTag == Aspect.POISON || fluxTag == Aspects.INSECT) { + success = AuraManager.poisonCreature(world, node, Potion.poison.id); + } else if (fluxTag == Aspect.DARKNESS || fluxTag == Aspect.VOID) { + success = AuraManager.poisonCreature(world, node, Potion.blindness.id); + } else if (fluxTag == Aspect.ARMOR) { + success = AuraManager.poisonCreature(world, node, Potion.resistance.id); + } else if (fluxTag == Aspect.MOTION) { + success = AuraManager.poisonCreature(world, node, Potion.moveSpeed.id); + } else if (fluxTag == Aspect.FLIGHT) { + success = AuraManager.poisonCreature(world, node, Potion.jump.id); + } else if (fluxTag == Aspect.TOOL) { + success = AuraManager.poisonCreature(world, node, Potion.digSpeed.id); + } else if (fluxTag == Aspects.ROCK) { + success = AuraManager.poisonCreature(world, node, Potion.digSlowdown.id); + } else if (fluxTag == Aspect.COLD) { + success = AuraManager.poisonCreature(world, node, Potion.moveSlowdown.id); + } else if (fluxTag == Aspects.SOUND || fluxTag == Aspect.MIND || fluxTag == Aspects.FUNGUS) { + success = AuraManager.poisonCreature(world, node, Potion.confusion.id); + } else if (fluxTag == Aspects.EVIL) { + success = AuraManager.spawnEvil(world, node); + } else if (fluxTag == Aspect.DEATH) { + success = AuraManager.spawnDeath(world, node); + } else if (fluxTag == Aspect.FIRE) { + success = AuraManager.spawnFire(world, node); + } else if (fluxTag == Aspect.CROP || fluxTag == Aspect.PLANT || fluxTag == Aspect.TREE) { + success = AuraManager.promoteGrowth(world, node); + } else if (fluxTag == Aspects.PURE) { + success = true; + } + } + if (success) { + AuraManager.queueNodeChanges(node.key, 0, 0, false, new AspectList().add(fluxTag, -10), 0.0f, 0.0f, 0.0f); + } + return success; + } + + private static boolean promoteGrowth(World world, AuraNode node) { + int fuzz = (int)((float)node.baseLevel / 8.0f); + double xx = node.xPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); + double zz = node.zPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); + double yy = Utils.getFirstUncoveredBlockHeight(world, (int)xx, (int)zz); + if (!Utils.isChunkLoaded(world, MathHelper.floor_double((double)xx), MathHelper.floor_double((double)zz))) { + return false; + } + return Utils.useBonemealAtLoc(world, (int)xx, (int)yy, (int)zz); + } + + private static boolean poisonCreature(World world, AuraNode node, int type) { + boolean did = false; + List ents = world.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(node.xPos - 1.0, node.yPos - 1.0, node.zPos - 1.0, node.xPos + 1.0, node.yPos + 1.0, node.zPos + 1.0).expand((double)((float)node.baseLevel / 4.0f), (double)((float)node.baseLevel / 4.0f), (double)((float)node.baseLevel / 4.0f))); + if (ents.size() > 0) { + for (int a = 0; a < 3 && ents.size() >= 1; ++a) { + int q = world.rand.nextInt(ents.size()); + EntityLivingBase el = ents.get(q); + if (!Utils.isChunkLoaded(world, MathHelper.floor_double((double)el.posX), MathHelper.floor_double((double)el.posZ))) continue; + el.addPotionEffect(new PotionEffect(type, 100 + world.rand.nextInt(200), 0)); + if (el instanceof EntityPlayer) { + ((EntityPlayer)el).addChatMessage(new ChatComponentText("\u00a72\u00a7oThe air around you suddenly becomes suffused with strange energies.")); + } + did = true; + ents.remove(q); + } + } + return did; + } + + private static boolean spawnLightning(World world, AuraNode node) { + List ents = world.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(node.xPos - 1.0, node.yPos - 1.0, node.zPos - 1.0, node.xPos + 1.0, node.yPos + 1.0, node.zPos + 1.0).expand((double)((float)node.baseLevel / 4.0f / 2.0f), (double)((float)node.baseLevel / 4.0f / 2.0f), (double)((float)node.baseLevel / 4.0f / 2.0f))); + if (ents.size() > 0) { + for (EntityLivingBase ent : ents) { + if (!Utils.isChunkLoaded(world, MathHelper.floor_double((double)ent.posX), MathHelper.floor_double((double)ent.posZ))) continue; + AuraCore.CHANNEL.sendToAllAround(new NodeZapPacket(node.xPos, node.yPos, node.zPos, ent), new TargetPoint(ent.dimension, ent.posX, ent.posY, ent.posZ, 64.0)); + world.playSoundEffect(node.xPos, node.yPos, node.zPos, "thaumcraft.zap", 1.0f, 1.1f); + ent.attackEntityFrom(DamageSource.magic, 5); + return true; + } + } + return false; + } + + private static boolean spawnGiant(World world, AuraNode node) { + boolean spawn; + int fuzz = (int)((float)node.baseLevel / 4.0f) / 3; + double xx = node.xPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); + double zz = node.zPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); + double yy = world.getHeightValue((int)xx, (int)zz) + 5; + if (!Utils.isChunkLoaded(world, MathHelper.floor_double((double)xx), MathHelper.floor_double((double)zz))) { + return false; + } + EntityGiantBrainyZombie zombie = new EntityGiantBrainyZombie(world); + zombie.setLocationAndAngles(xx, yy, zz, world.rand.nextFloat() * 360.0f, 0.0f); + boolean bl = spawn = zombie.getCanSpawnHere() && world.spawnEntityInWorld((Entity)zombie); + if (spawn) { + Utils.sendChatNearby(world, xx, yy, zz, 64.0, "\u00a75\u00a7oA nearby node spews forth something foul."); + } + return spawn; + } + + private static boolean spawnFire(World world, AuraNode node) { + int fuzz = (int)((float)node.baseLevel / 4.0f) / 3; + double xx = node.xPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); + double yy = node.yPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); + double zz = node.zPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); + if (!Utils.isChunkLoaded(world, MathHelper.floor_double((double)xx), MathHelper.floor_double((double)zz))) { + return false; + } + EntityFireBat firebat = new EntityFireBat(world); + firebat.setLocationAndAngles(xx, yy, zz, world.rand.nextFloat() * 360.0f, 0.0f); + firebat.addPotionEffect(new PotionEffect(Potion.damageBoost.id, 32000, 0)); + boolean spawn = firebat.getCanSpawnHere() && world.spawnEntityInWorld((Entity)firebat); + return spawn; + } + + private static boolean spawnDeath(World world, AuraNode node) { + double yy; + int fuzz = (int)((float)node.baseLevel / 4.0f) / 3; + double xx = node.xPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); + double zz = node.zPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); + if (!Utils.isChunkLoaded(world, MathHelper.floor_double((double)xx), MathHelper.floor_double((double)zz))) { + return false; + } + EntityBrainyZombie zombie = new EntityBrainyZombie(world); + for (yy = node.yPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); world.isAirBlock((int)xx, (int)yy - 2, (int)zz) && yy > 10.0; yy -= 1.0) { + } + zombie.setLocationAndAngles(xx, yy, zz, world.rand.nextFloat() * 360.0f, 0.0f); + zombie.addPotionEffect(new PotionEffect(Potion.damageBoost.id, 32000, 0)); + boolean spawn = zombie.getCanSpawnHere() && world.spawnEntityInWorld((Entity)zombie); + return spawn; + } + + private static boolean spawnEvil(World world, AuraNode node) { + double yy; + int fuzz = (int)((float)node.baseLevel / 4.0f) / 3; + double xx = node.xPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); + double zz = node.zPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); + if (!Utils.isChunkLoaded(world, MathHelper.floor_double((double)xx), MathHelper.floor_double((double)zz))) { + return false; + } + EntityWitch witch = new EntityWitch(world); + for (yy = node.yPos + (double)world.rand.nextInt(fuzz) - (double)world.rand.nextInt(fuzz); world.isAirBlock((int)xx, (int)yy - 2, (int)zz) && yy > 10.0; yy -= 1.0) { + } + witch.setLocationAndAngles(xx, yy + 0.5, zz, world.rand.nextFloat() * 360.0f, 0.0f); + boolean spawn = witch.getCanSpawnHere() && world.spawnEntityInWorld((Entity)witch); + return spawn; + } + + private static boolean spawnWisp(World world, AuraNode node, Aspect type) { + if (!Utils.isChunkLoaded(world, MathHelper.floor_double((double)node.xPos), MathHelper.floor_double((double)node.zPos))) { + return false; + } + EntityWisp wisp = new EntityWisp(world); + wisp.setLocationAndAngles(node.xPos, node.yPos, node.zPos, world.rand.nextFloat() * 360.0f, 0.0f); + //wisp.type = type; + wisp.playLivingSound(); + return wisp.getCanSpawnHere() && world.spawnEntityInWorld((Entity)wisp); + } + + public static synchronized AuraNode getNode(int key) { + return (AuraNode)auraNodes.get(key); + } + + public static synchronized AuraNode getNodeCopy(int key) { + return AuraManager.copyNode((AuraNode)auraNodes.get(key)); + } + + public static synchronized Integer[] getUpdateList(int dim) { + int count = 0; + while (auraUpdateList.get(dim) != null && count < 10) { + try { + ++count; + return ((List)auraUpdateList.get(dim)).toArray(new Integer[]{0}); + } + catch (Exception exception) { + } + } + return null; + } + + public static void queueNodeChanges(int key, int levelMod, int baseMod, boolean toggleLock, AspectList flx, float x, float y, float z) { + NodeChanges nc = new NodeChanges(key, levelMod, baseMod, toggleLock, flx, x, y, z); + auraUpdateQueue.add(nc); + } + + public static AuraNode copyNode(AuraNode in) { + try { + AuraNode out = new AuraNode(); + out.key = in.key; + out.level = in.level; + out.baseLevel = in.baseLevel; + out.type = in.type; + AspectList outflux = new AspectList(); + for (Aspect tag : in.flux.getAspects()) { + outflux.add(tag, in.flux.getAmount(tag)); + } + out.flux = outflux; + out.dimension = in.dimension; + out.xPos = in.xPos; + out.yPos = in.yPos; + out.zPos = in.zPos; + out.locked = in.locked; + out.isVirtual = in.isVirtual; + return out; + } + catch (NullPointerException e) { + return null; + } + } + + public static void replaceNode(AuraNode in, AuraNode out) { + out.key = in.key; + out.level = in.level; + out.baseLevel = in.baseLevel; + out.type = in.type; + out.flux = in.flux; + out.dimension = in.dimension; + out.xPos = in.xPos; + out.yPos = in.yPos; + out.zPos = in.zPos; + out.locked = in.locked; + out.isVirtual = in.isVirtual; + } + + public static class NodeChanges { + int key = 0; + int levelMod = 0; + int baseMod = 0; + boolean lock = false; + AspectList flux = null; + float motionX; + float motionY; + float motionZ; + + NodeChanges(int k, int l, int b, boolean lo, AspectList ot, float x, float y, float z) { + this.key = k; + this.levelMod = l; + this.baseMod = b; + this.lock = lo; + this.flux = ot; + this.motionX = x; + this.motionY = y; + this.motionZ = z; + } + } +} + + diff --git a/src/main/java/dev/tilera/auracore/aura/AuraUpdateThread.java b/src/main/java/dev/tilera/auracore/aura/AuraUpdateThread.java new file mode 100644 index 0000000..49e8120 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/aura/AuraUpdateThread.java @@ -0,0 +1,120 @@ +package dev.tilera.auracore.aura; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import dev.tilera.auracore.api.AuraNode; +import net.minecraft.util.MathHelper; +import thaumcraft.api.aspects.Aspect; + +public class AuraUpdateThread + implements Runnable { + + @Override + public void run() { + try { + while (true) { + boolean done = false; + int count = 0; + AuraManager.NodeChanges nc = (AuraManager.NodeChanges) AuraManager.auraUpdateQueue.take(); + Object object = AuraManager.saveLock; + synchronized (object) { + while (AuraManager.getNode(nc.key) != null && !done && count < 10) { + ++count; + try { + int cz; + AuraNode node = AuraManager.getNode(nc.key); + if (node == null) + continue; + node.level = (short) (node.level + nc.levelMod); + node.baseLevel = (short) (node.baseLevel + nc.baseMod); + if (nc.lock) { + node.locked = !node.locked; + } + if (node.level < 0) { + node.level = 0; + } + if (node.baseLevel < 0) { + node.baseLevel = 0; + } + if (nc.flux != null) { + for (Aspect tag : nc.flux.getAspects()) { + if (nc.flux.getAmount(tag) > 0) { + node.flux.add(tag, nc.flux.getAmount(tag)); + continue; + } + node.flux.reduce(tag, -nc.flux.getAmount(tag)); // TODO:WTF + } + } + if (node.flux.size() > 0) { + ArrayList dt = new ArrayList<>(); + ArrayList red = new ArrayList<>(); + for (Aspect tag : node.flux.getAspects()) { + if (node.flux.getAmount(tag) <= 0) { + dt.add(tag); + continue; + } + if (node.flux.getAmount(tag) <= 100) + continue; + red.add(tag); + } + if (red.size() > 0) { + for (Aspect tag : red) { + node.flux.reduce(tag, node.flux.getAmount(tag) - 100); + } + } + if (dt.size() > 0) { + for (Aspect tag : dt) { + node.flux.remove(tag); + } + } + } + if (nc.motionX != 0.0f || nc.motionY != 0.0f || nc.motionZ != 0.0f) { + int cx = MathHelper.floor_double((double) node.xPos) / 16; + cz = MathHelper.floor_double((double) node.zPos) / 16; + if (AuraManager.nodeChunks.get(Arrays.asList(node.dimension, cx, cz)) != null) { + try { + List nds = AuraManager.nodeChunks + .get(Arrays.asList(node.dimension, cx, cz)); + nds.remove(nds.indexOf(node.key)); + AuraManager.nodeChunks.put(Arrays.asList(node.dimension, cx, cz), nds); + } catch (Exception e) { + + } + } + } + node.xPos += (double) nc.motionX; + node.yPos += (double) nc.motionY; + node.zPos += (double) nc.motionZ; + AuraManager.auraNodes.put(node.key, node); + done = true; + if (nc.motionX != 0.0f || nc.motionY != 0.0f || nc.motionZ != 0.0f) { + AuraManager.updateNodeNeighbours(node); + int cx = MathHelper.floor_double((double) node.xPos) / 16; + cz = MathHelper.floor_double((double) node.zPos) / 16; + if (AuraManager.nodeChunks.get(Arrays.asList(node.dimension, cx, cz)) != null) { + List nds = AuraManager.nodeChunks + .get(Arrays.asList(node.dimension, cx, cz)); + if (!nds.contains(node.key)) { + nds.add(node.key); + AuraManager.nodeChunks.put(Arrays.asList(node.dimension, cx, cz), nds); + } + } else { + ArrayList temp = new ArrayList(); + temp.add(node.key); + AuraManager.nodeChunks.put(Arrays.asList(node.dimension, cx, cz), temp); + } + } + AuraManager.markedForTransmission.put(node.key, 0L); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } +} diff --git a/src/main/java/dev/tilera/auracore/aura/AuraWorldTicker.java b/src/main/java/dev/tilera/auracore/aura/AuraWorldTicker.java new file mode 100644 index 0000000..2f24222 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/aura/AuraWorldTicker.java @@ -0,0 +1,112 @@ +package dev.tilera.auracore.aura; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; +import cpw.mods.fml.common.gameevent.TickEvent.Phase; +import cpw.mods.fml.relauncher.Side; +import dev.tilera.auracore.api.AuraNode; +import dev.tilera.auracore.helper.Utils; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.nodes.INode; + +public class AuraWorldTicker { + public static volatile long timeThisTick = 0L; + private int age = 0; + + @SubscribeEvent + public void tickEnd(TickEvent.WorldTickEvent e) { + if (e.side == Side.SERVER && e.phase == Phase.END) { + WorldServer world = (WorldServer)e.world; + int dim = world.provider.dimensionId; + timeThisTick = System.currentTimeMillis(); + ++this.age; + List updateList = AuraManager.auraUpdateList.get(dim); + if (updateList == null || updateList.size() == 0) { + this.populateAuraUpdateList(dim); + updateList = AuraManager.auraUpdateList.get(dim); + } + if (updateList != null && updateList.size() >= 1 + this.age % 20) { + int limit = Math.max(1, updateList.size() / 20); + for (int a = 0; a < limit; ++a) { + int nk = (Integer)updateList.get(0); + AuraNode node = AuraManager.copyNode(AuraManager.getNode(nk)); + if (node != null) { + if (Utils.isChunkLoaded((World)world, MathHelper.floor_double((double)node.xPos), MathHelper.floor_double((double)node.zPos))) { + long time; + AuraManager.auraCalcQueue.offer(Arrays.asList(new Object[]{node.key, world})); + if (AuraManager.markedForTransmission.get(node.key) == null) { + AuraManager.markedForTransmission.put(node.key, timeThisTick + (long)world.rand.nextInt(/*Config.nodeRefresh*/ 10 * 1000)); + } + if ((time = ((Long)AuraManager.markedForTransmission.get(node.key)).longValue()) <= timeThisTick) { + AuraManager.sendNodePacket(node); + AuraManager.markedForTransmission.put(node.key, timeThisTick + (long)(/*Config.nodeRefresh*/ 10 * 1000)); + } + } + updateList.remove(0); + if (!node.isVirtual || checkLinkedAura(node, world)) { + updateList.add(nk); + } else{ + AuraManager.deleteNode(node); + } + continue; + } + updateList.remove(0); + } + } + if (AuraManager.fluxEventList == null) { + AuraManager.fluxEventList = new ArrayList<>(); + } + try { + if (AuraManager.fluxEventList != null && AuraManager.fluxEventList.size() > 0 && AuraManager.fluxEventList.get(0) != null) { + switch ((Integer)AuraManager.fluxEventList.get(0).get(3)) { + case 0: { + AuraManager.spawnMinorFluxEvent((World)AuraManager.fluxEventList.get(0).get(0), (AuraNode)AuraManager.fluxEventList.get(0).get(1), (Aspect)AuraManager.fluxEventList.get(0).get(2)); + break; + } + case 1: { + AuraManager.spawnModerateFluxEvent((World)AuraManager.fluxEventList.get(0).get(0), (AuraNode)AuraManager.fluxEventList.get(0).get(1), (Aspect)AuraManager.fluxEventList.get(0).get(2)); + break; + } + case 2: { + AuraManager.spawnMajorFluxEvent((World)AuraManager.fluxEventList.get(0).get(0), (AuraNode)AuraManager.fluxEventList.get(0).get(1), (Aspect)AuraManager.fluxEventList.get(0).get(2)); + } + } + AuraManager.fluxEventList.remove(0); + } + } + catch (Exception ex) { + + } + } + } + + private synchronized void populateAuraUpdateList(int dim) { + LinkedList temp = new LinkedList(); + Collection nodes = AuraManager.auraNodes.values(); + for (AuraNode node : nodes) { + if (node.dimension != dim) continue; + temp.add(node.key); + } + AuraManager.auraUpdateList.put(dim, temp); + } + + private boolean checkLinkedAura(AuraNode node, World world) { + int x = (int) Math.floor(node.xPos); + int y = (int) Math.floor(node.yPos); + int z = (int) Math.floor(node.zPos); + if (!Utils.isChunkLoaded(world, x, z)) return true; + TileEntity te = world.getTileEntity(x, y, z); + return te instanceof INode; + } + +} diff --git a/src/main/java/dev/tilera/auracore/aura/NodeIdStorage.java b/src/main/java/dev/tilera/auracore/aura/NodeIdStorage.java new file mode 100644 index 0000000..4f65f89 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/aura/NodeIdStorage.java @@ -0,0 +1,78 @@ +package dev.tilera.auracore.aura; + +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagInt; +import net.minecraft.world.storage.ISaveHandler; + +public class NodeIdStorage { + private ISaveHandler saveHandler; + private Map idCounts = new HashMap<>(); + + public NodeIdStorage(ISaveHandler par1ISaveHandler) { + this.saveHandler = par1ISaveHandler; + this.loadIdCounts(); + } + + private void loadIdCounts() { + try { + this.idCounts.clear(); + if (this.saveHandler == null) { + return; + } + File var1 = this.saveHandler.getMapFileFromName("idcounts"); + if (var1 != null && var1.exists()) { + DataInputStream var2 = new DataInputStream(new FileInputStream(var1)); + NBTTagCompound var3 = CompressedStreamTools.read(var2); + var2.close(); + for (String key : (Set)var3.func_150296_c()) { + NBTBase var5 = var3.getTag(key); + if (!(var5 instanceof NBTTagInt)) continue; + NBTTagInt var6 = (NBTTagInt)var5; + int var8 = var6.func_150287_d(); + this.idCounts.put(key, var8); + } + } + } + catch (Exception var9) { + var9.printStackTrace(); + } + } + + public int getUniqueDataId(String par1Str) { + Integer var2 = (Integer)this.idCounts.get(par1Str); + var2 = var2 == null ? Integer.valueOf(0) : Integer.valueOf(var2 + 1); + this.idCounts.put(par1Str, var2); + if (this.saveHandler == null) { + return var2; + } + try { + File var3 = this.saveHandler.getMapFileFromName("idcounts"); + if (var3 != null) { + NBTTagCompound var4 = new NBTTagCompound(); + for (String var6 : this.idCounts.keySet()) { + int var7 = (Integer)this.idCounts.get(var6); + var4.setInteger(var6, var7); + } + DataOutputStream var9 = new DataOutputStream(new FileOutputStream(var3)); + CompressedStreamTools.write((NBTTagCompound)var4, (DataOutput)var9); + var9.close(); + } + } + catch (Exception var8) { + var8.printStackTrace(); + } + return var2; + } +} diff --git a/src/main/java/dev/tilera/auracore/client/AuraManagerClient.java b/src/main/java/dev/tilera/auracore/client/AuraManagerClient.java new file mode 100644 index 0000000..9172a61 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/client/AuraManagerClient.java @@ -0,0 +1,70 @@ +package dev.tilera.auracore.client; + +import java.util.HashMap; + +import dev.tilera.auracore.network.AuraPacket; + +public class AuraManagerClient { + public static HashMap auraClientList = new HashMap<>(); + public static HashMap auraClientHistory = new HashMap<>(); + public static HashMap auraClientMovementList = new HashMap<>(); + + public static class NodeRenderInfo { + public float x = 0.0f; + public float y = 0.0f; + public float z = 0.0f; + + public NodeRenderInfo(float xx, float yy, float zz) { + this.x = xx; + this.y = yy; + this.z = zz; + } + } + + public static class NodeStats { + public int key; + public double x; + public double y; + public double z; + public short level; + public short base; + public int flux; + public boolean lock; + public byte type; + public int dimension; + + public NodeStats(AuraPacket packet, int dimension) { + key = packet.key; + x = packet.x; + y = packet.y; + z = packet.z; + level = packet.level; + base = packet.base; + flux = packet.flux; + lock = packet.lock; + type = packet.type; + this.dimension = dimension; + } + + } + + public static class NodeHistoryStats { + + public short level; + public int flux; + + public NodeHistoryStats(short level, int flux) { + this.level = level; + this.flux = flux; + } + + public NodeHistoryStats(NodeStats stats) { + if (stats != null) { + this.level = stats.level; + this.flux = stats.flux; + } + } + + } + +} diff --git a/src/main/java/dev/tilera/auracore/client/FXSparkle.java b/src/main/java/dev/tilera/auracore/client/FXSparkle.java new file mode 100644 index 0000000..52d907a --- /dev/null +++ b/src/main/java/dev/tilera/auracore/client/FXSparkle.java @@ -0,0 +1,256 @@ +package dev.tilera.auracore.client; + +import org.lwjgl.opengl.GL11; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import thaumcraft.client.lib.UtilsFX; + +public class FXSparkle extends EntityFX { + public boolean leyLineEffect = false; + public int multiplier = 2; + public boolean shrink = true; + public int particle = 16; + public boolean tinkle = false; + public int blendmode = 1; + public boolean slowdown = true; + public int currentColor = 0; + + public FXSparkle(World world, double d, double d1, double d2, float f, float f1, float f2, float f3, int m) { + super(world, d, d1, d2, 0.0, 0.0, 0.0); + if (f1 == 0.0f) { + f1 = 1.0f; + } + this.particleRed = f1; + this.particleGreen = f2; + this.particleBlue = f3; + this.particleGravity = 0.0f; + (this).motionZ = 0.0; + (this).motionY = 0.0; + (this).motionX = 0.0; + this.particleScale *= f; + this.particleMaxAge = 3 * m; + this.multiplier = m; + (this).noClip = false; + this.setSize(0.01f, 0.01f); + (this).prevPosX = (this).posX; + (this).prevPosY = (this).posY; + (this).prevPosZ = (this).posZ; + } + + public FXSparkle(World world, double d, double d1, double d2, float f, int type, int m) { + this(world, d, d1, d2, f, 0.0f, 0.0f, 0.0f, m); + this.currentColor = type; + switch (type) { + case 0: { + this.particleRed = 0.75f + world.rand.nextFloat() * 0.25f; + this.particleGreen = 0.25f + world.rand.nextFloat() * 0.25f; + this.particleBlue = 0.75f + world.rand.nextFloat() * 0.25f; + break; + } + case 1: { + this.particleRed = 0.5f + world.rand.nextFloat() * 0.3f; + this.particleGreen = 0.5f + world.rand.nextFloat() * 0.3f; + this.particleBlue = 0.2f; + break; + } + case 2: { + this.particleRed = 0.2f; + this.particleGreen = 0.2f; + this.particleBlue = 0.7f + world.rand.nextFloat() * 0.3f; + break; + } + case 3: { + this.particleRed = 0.2f; + this.particleGreen = 0.7f + world.rand.nextFloat() * 0.3f; + this.particleBlue = 0.2f; + break; + } + case 4: { + this.particleRed = 0.7f + world.rand.nextFloat() * 0.3f; + this.particleGreen = 0.2f; + this.particleBlue = 0.2f; + break; + } + case 5: { + this.blendmode = 771; + this.particleRed = world.rand.nextFloat() * 0.1f; + this.particleGreen = world.rand.nextFloat() * 0.1f; + this.particleBlue = world.rand.nextFloat() * 0.1f; + break; + } + case 6: { + this.particleRed = 0.8f + world.rand.nextFloat() * 0.2f; + this.particleGreen = 0.8f + world.rand.nextFloat() * 0.2f; + this.particleBlue = 0.8f + world.rand.nextFloat() * 0.2f; + break; + } + case 7: { + this.particleRed = 0.2f; + this.particleGreen = 0.5f + world.rand.nextFloat() * 0.3f; + this.particleBlue = 0.6f + world.rand.nextFloat() * 0.3f; + } + } + } + + public FXSparkle(World world, double d, double d1, double d2, double x, double y, double z, float f, int type, int m) { + this(world, d, d1, d2, f, type, m); + double dx = x - (this).posX; + double dy = y - (this).posY; + double dz = z - (this).posZ; + (this).motionX = dx / (double)this.particleMaxAge; + (this).motionY = dy / (double)this.particleMaxAge; + (this).motionZ = dz / (double)this.particleMaxAge; + } + + @Override + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) { + tessellator.draw(); + GL11.glPushMatrix(); + GL11.glDepthMask((boolean)false); + GL11.glEnable((int)3042); + GL11.glBlendFunc((int)770, (int)this.blendmode); + UtilsFX.bindTexture(new ResourceLocation("auracore", "textures/misc/particles.png")); + GL11.glColor4f((float)1.0f, (float)1.0f, (float)1.0f, (float)0.75f); + int part = this.particle + this.particleAge / this.multiplier; + float var8 = (float)(part % 8) / 8.0f; + float var9 = var8 + 0.124875f; + float var10 = (float)(part / 8) / 8.0f; + float var11 = var10 + 0.124875f; + float var12 = 0.1f * this.particleScale; + if (this.shrink) { + var12 *= (float)(this.particleMaxAge - this.particleAge + 1) / (float)this.particleMaxAge; + } + float var13 = (float)((this).prevPosX + ((this).posX - (this).prevPosX) * (double)f - EntityFX.interpPosX); + float var14 = (float)((this).prevPosY + ((this).posY - (this).prevPosY) * (double)f - EntityFX.interpPosY); + float var15 = (float)((this).prevPosZ + ((this).posZ - (this).prevPosZ) * (double)f - EntityFX.interpPosZ); + float var16 = 1.0f; + tessellator.startDrawingQuads(); + tessellator.setBrightness(240); + tessellator.setColorRGBA_F(this.particleRed * var16, this.particleGreen * var16, this.particleBlue * var16, 1.0f); + tessellator.addVertexWithUV((double)(var13 - f1 * var12 - f4 * var12), (double)(var14 - f2 * var12), (double)(var15 - f3 * var12 - f5 * var12), (double)var9, (double)var11); + tessellator.addVertexWithUV((double)(var13 - f1 * var12 + f4 * var12), (double)(var14 + f2 * var12), (double)(var15 - f3 * var12 + f5 * var12), (double)var9, (double)var10); + tessellator.addVertexWithUV((double)(var13 + f1 * var12 + f4 * var12), (double)(var14 + f2 * var12), (double)(var15 + f3 * var12 + f5 * var12), (double)var8, (double)var10); + tessellator.addVertexWithUV((double)(var13 + f1 * var12 - f4 * var12), (double)(var14 - f2 * var12), (double)(var15 + f3 * var12 - f5 * var12), (double)var8, (double)var11); + tessellator.draw(); + GL11.glDisable((int)3042); + GL11.glDepthMask((boolean)true); + GL11.glPopMatrix(); + UtilsFX.bindTexture(new ResourceLocation("textures/particle/particles.png")); + tessellator.startDrawingQuads(); + } + + @Override + public void onUpdate() { + (this).prevPosX = (this).posX; + (this).prevPosY = (this).posY; + (this).prevPosZ = (this).posZ; + if (this.particleAge == 0 && this.tinkle && this.worldObj.rand.nextInt(10) == 0) { + (this).worldObj.playSoundAtEntity(this, "random.orb", 0.02f, 0.7f * ((this.worldObj.rand.nextFloat() - this.worldObj.rand.nextFloat()) * 0.6f + 2.0f)); + } + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + (this).motionY -= 0.04 * (double)this.particleGravity; + if (!(this).noClip) { + this.func_145771_j((this).posX, (this.boundingBox.minY + this.boundingBox.maxY) / 2.0, (this).posZ); + } + (this).posX += (this).motionX; + (this).posY += (this).motionY; + (this).posZ += (this).motionZ; + if (this.slowdown) { + (this).motionX *= 0.9080000019073486; + (this).motionY *= 0.9080000019073486; + (this).motionZ *= 0.9080000019073486; + if ((this).onGround) { + (this).motionX *= (double)0.7f; + (this).motionZ *= (double)0.7f; + } + } + if (this.leyLineEffect) { + FXSparkle fx = new FXSparkle((this).worldObj, (this).prevPosX + (double)((this.worldObj.rand.nextFloat() - this.worldObj.rand.nextFloat()) * 0.1f), (this).prevPosY + (double)((this.worldObj.rand.nextFloat() - this.worldObj.rand.nextFloat()) * 0.1f), (this).prevPosZ + (double)((this.worldObj.rand.nextFloat() - this.worldObj.rand.nextFloat()) * 0.1f), 1.0f, this.currentColor, 3 + this.worldObj.rand.nextInt(3)); + (fx).noClip = true; + Minecraft.getMinecraft().effectRenderer.addEffect((EntityFX)fx); + } + } + + public void setGravity(float value) { + this.particleGravity = value; + } + + @Override + protected boolean func_145771_j(double par1, double par3, double par5) { + int var7 = MathHelper.floor_double((double)par1); + int var8 = MathHelper.floor_double((double)par3); + int var9 = MathHelper.floor_double((double)par5); + double var10 = par1 - (double)var7; + double var12 = par3 - (double)var8; + double var14 = par5 - (double)var9; + if (!(this).worldObj.isAirBlock(var7, var8, var9)) { + boolean var16 = !(this).worldObj.isBlockNormalCubeDefault(var7 - 1, var8, var9, false); + boolean var17 = !(this).worldObj.isBlockNormalCubeDefault(var7 + 1, var8, var9, false); + boolean var18 = !(this).worldObj.isBlockNormalCubeDefault(var7, var8 - 1, var9, false); + boolean var19 = !(this).worldObj.isBlockNormalCubeDefault(var7, var8 + 1, var9, false); + boolean var20 = !(this).worldObj.isBlockNormalCubeDefault(var7, var8, var9 - 1, false); + boolean var21 = !(this).worldObj.isBlockNormalCubeDefault(var7, var8, var9 + 1, false); + int var22 = -1; + double var23 = 9999.0; + if (var16 && var10 < var23) { + var23 = var10; + var22 = 0; + } + if (var17 && 1.0 - var10 < var23) { + var23 = 1.0 - var10; + var22 = 1; + } + if (var18 && var12 < var23) { + var23 = var12; + var22 = 2; + } + if (var19 && 1.0 - var12 < var23) { + var23 = 1.0 - var12; + var22 = 3; + } + if (var20 && var14 < var23) { + var23 = var14; + var22 = 4; + } + if (var21 && 1.0 - var14 < var23) { + var23 = 1.0 - var14; + var22 = 5; + } + float var25 = (this).rand.nextFloat() * 0.05f + 0.025f; + float var26 = ((this).rand.nextFloat() - (this).rand.nextFloat()) * 0.1f; + if (var22 == 0) { + (this).motionX = -var25; + (this).motionY = (this).motionZ = (double)var26; + } + if (var22 == 1) { + (this).motionX = var25; + (this).motionY = (this).motionZ = (double)var26; + } + if (var22 == 2) { + (this).motionY = -var25; + (this).motionX = (this).motionZ = (double)var26; + } + if (var22 == 3) { + (this).motionY = var25; + (this).motionX = (this).motionZ = (double)var26; + } + if (var22 == 4) { + (this).motionZ = -var25; + (this).motionY = (this).motionX = (double)var26; + } + if (var22 == 5) { + (this).motionZ = var25; + (this).motionY = (this).motionX = (double)var26; + } + return true; + } + return false; + } +} diff --git a/src/main/java/dev/tilera/auracore/client/GUITicker.java b/src/main/java/dev/tilera/auracore/client/GUITicker.java new file mode 100644 index 0000000..fe5f0cc --- /dev/null +++ b/src/main/java/dev/tilera/auracore/client/GUITicker.java @@ -0,0 +1,164 @@ +package dev.tilera.auracore.client; + +import java.util.Collection; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.client.FMLClientHandler; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent.Phase; +import cpw.mods.fml.common.gameevent.TickEvent.RenderTickEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import dev.tilera.auracore.client.AuraManagerClient.NodeStats; +import dev.tilera.auracore.helper.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ResourceLocation; +import thaumcraft.client.fx.bolt.FXLightningBolt; +import thaumcraft.client.lib.UtilsFX; + +public class GUITicker { + + @SideOnly(Side.CLIENT) + @SubscribeEvent + public void hudTick(RenderTickEvent event) { + if (event.phase == Phase.END && event.side == Side.CLIENT) { + EntityPlayer player = FMLClientHandler.instance().getClientPlayerEntity(); + Minecraft mc = FMLClientHandler.instance().getClient(); + long time = System.currentTimeMillis(); + if (player != null && mc.inGameHasFocus && Minecraft.isGuiEnabled()) { + if (Utils.hasGoggles(player)) { + renderGogglesHUD(event.renderTickTime, player, time); + int limit = 0; + Collection col = AuraManagerClient.auraClientList.values(); + for (NodeStats l : col) { + float px = (float) l.x; + float py = (float) l.y; + float pz = (float) l.z; + int dim = l.dimension; + short lvl = l.level; + int key = l.key; + int flux = l.flux; + if (flux <= 0 || limit >= 10 || player.dimension != dim) continue; + ++limit; + AuraManagerClient.NodeRenderInfo nri = (AuraManagerClient.NodeRenderInfo)AuraManagerClient.auraClientMovementList.get(key); + if (nri == null) { + nri = new AuraManagerClient.NodeRenderInfo(px, py, pz); + AuraManagerClient.auraClientMovementList.put(key, nri); + } + nri.x += (px - nri.x) / 50.0f; + nri.y += (py - nri.y) / 50.0f; + nri.z += (pz - nri.z) / 50.0f; + AuraManagerClient.auraClientMovementList.put(key, nri); + if (player.worldObj.rand.nextInt(1000) >= flux) continue; + FXLightningBolt bolt = new FXLightningBolt(player.worldObj, nri.x, nri.y, nri.z, nri.x + (player.worldObj.rand.nextFloat() - player.worldObj.rand.nextFloat()) * 5.0f, nri.y + (player.worldObj.rand.nextFloat() - player.worldObj.rand.nextFloat()) * 5.0f, nri.z + (player.worldObj.rand.nextFloat() - player.worldObj.rand.nextFloat()) * 5.0f, player.worldObj.rand.nextLong(), 10, 2.0f, 5); + bolt.defaultFractal(); + bolt.setType(5); + bolt.finalizeBolt(); + } + } + } + } + } + + @SideOnly(value=Side.CLIENT) + public void renderGogglesHUD(float partialTicks, EntityPlayer player, long time) { + Minecraft mc = Minecraft.getMinecraft(); + GL11.glPushMatrix(); + ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + GL11.glClear((int)256); + GL11.glMatrixMode((int)5889); + GL11.glLoadIdentity(); + GL11.glOrtho((double)0.0, (double)sr.getScaledWidth_double(), (double)sr.getScaledHeight_double(), (double)0.0, (double)1000.0, (double)3000.0); + GL11.glMatrixMode((int)5888); + GL11.glLoadIdentity(); + GL11.glTranslatef((float)0.0f, (float)0.0f, (float)-2000.0f); + GL11.glDisable((int)2929); + GL11.glDepthMask((boolean)false); + GL11.glEnable((int)3042); + GL11.glBlendFunc((int)770, (int)771); + GL11.glDisable((int)3008); + int k = sr.getScaledWidth(); + int l = sr.getScaledHeight(); + double closestX = 0.0f; + double closestY = 0.0f; + double closestZ = 0.0f; + double closestDistance = Double.MAX_VALUE; + short closestLevel = 0; + int closestBase = 0; + int closestKey = 0; + int closestFlux = 0; + boolean foundSomething = false; + Collection col = AuraManagerClient.auraClientList.values(); + for (NodeStats stats : col) { + int dim = stats.dimension; + if (player.dimension != dim) continue; + double px = stats.x; + double py = stats.y; + double pz = stats.z; + short lvl = stats.level; + short base = stats.base; + int key = stats.key; + int flux = stats.flux; + double xd = px - player.posX; + double yd = py - player.posY; + double zd = pz - player.posZ; + double distSq = xd * xd + yd * yd + zd * zd; + if (!(distSq < closestDistance)) continue; + closestDistance = distSq; + closestX = px; + closestY = py; + closestZ = pz; + closestLevel = lvl; + closestBase = base; + closestKey = key; + closestFlux = flux; + foundSomething = true; + } + if (foundSomething) { + int h = (int)((float)closestLevel / ((float)closestBase * 2.0f) * 48.0f); + mc.ingameGUI.drawString(mc.fontRenderer, "A: " + closestLevel + "/" + closestBase, 18, l - 28, 0xFFFFFF); + String msg = "None"; + int color = 0x888888; + if (closestFlux > 0) { + msg = "Minimal"; + color = 0x8888AA; + } + if (closestFlux > 50) { + msg = "Moderate"; + color = 0xAA8888; + } + if (closestFlux > 150) { + msg = "High"; + color = 0xFF8888; + } + if (closestFlux > 500) { + msg = "Dangerous"; + color = 0xFF1111; + } + mc.ingameGUI.drawString(mc.fontRenderer, "F: " + msg, 18, l - 18, color); + GL11.glColor4f((float)1.0f, (float)1.0f, (float)1.0f, (float)1.0f); + mc.renderEngine.bindTexture(new ResourceLocation("auracore", "textures/misc/particles.png")); + UtilsFX.drawTexturedQuad(6, l - 9 - h, 224, 48 - h, 8, h, -91.0); + UtilsFX.drawTexturedQuad(5, l - 61, 240, 0, 10, 56, -90.0); + short prevLevel = (AuraManagerClient.auraClientHistory.get(closestKey)).level; + int prevFlux = (AuraManagerClient.auraClientHistory.get(closestKey)).flux; + if (prevLevel < closestLevel) { + UtilsFX.drawTexturedQuad(6, l - 37, 208, 0, 8, 8, -90.0); + } else if (prevLevel > closestLevel) { + UtilsFX.drawTexturedQuad(6, l - 37, 216, 0, 8, 8, -90.0); + } + if (prevFlux < closestFlux) { + UtilsFX.drawTexturedQuad(2, l - (65 - (int)(Minecraft.getSystemTime() % 1250L) / 50 * 2), 16 * ((int)(Minecraft.getSystemTime() % 700L) / 50), 32, 16, 16, -90.0); + } + } + GL11.glDepthMask((boolean)true); + GL11.glEnable((int)2929); + GL11.glEnable((int)3008); + GL11.glColor4f((float)1.0f, (float)1.0f, (float)1.0f, (float)1.0f); + GL11.glPopMatrix(); + } + +} diff --git a/src/main/java/dev/tilera/auracore/client/RenderEventHandler.java b/src/main/java/dev/tilera/auracore/client/RenderEventHandler.java new file mode 100644 index 0000000..35168ac --- /dev/null +++ b/src/main/java/dev/tilera/auracore/client/RenderEventHandler.java @@ -0,0 +1,138 @@ +package dev.tilera.auracore.client; + +import java.util.Collection; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import dev.tilera.auracore.client.AuraManagerClient.NodeStats; +import dev.tilera.auracore.helper.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.RenderWorldLastEvent; +import thaumcraft.client.lib.UtilsFX; + +public class RenderEventHandler { + + ResourceLocation tx1 = new ResourceLocation("auracore", "textures/misc/aura_1.png"); + ResourceLocation tx2 = new ResourceLocation("auracore", "textures/misc/aura_2.png"); + ResourceLocation tx3 = new ResourceLocation("auracore", "textures/misc/aura_3.png"); + ResourceLocation tx3p = new ResourceLocation("auracore", "textures/misc/pure.png"); + ResourceLocation tx3d = new ResourceLocation("auracore", "textures/misc/vortex.png"); + ResourceLocation tx3c = new ResourceLocation("auracore", "textures/misc/chaos.png"); + ResourceLocation txlock = new ResourceLocation("auracore", "textures/misc/aura_lock.png"); + + @SideOnly(Side.CLIENT) + @SubscribeEvent + public void renderLast(RenderWorldLastEvent event) { + float partialTicks = event.partialTicks; + Minecraft mc = Minecraft.getMinecraft(); + if (Minecraft.getMinecraft().renderViewEntity instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer)Minecraft.getMinecraft().renderViewEntity; + long time = mc.theWorld.getWorldTime(); + if (Utils.hasGoggles(player)) { + GL11.glPushMatrix(); + GL11.glDepthMask((boolean)false); + GL11.glEnable((int)3042); + GL11.glBlendFunc((int)770, (int)1); + GL11.glDisable((int)2884); + GL11.glDisable((int)2896); + this.renderAuraNodes(event, partialTicks, player, time); + GL11.glDisable((int)3042); + GL11.glEnable((int)2896); + GL11.glDepthMask((boolean)true); + GL11.glPopMatrix(); + } + } + } + + @SideOnly(value=Side.CLIENT) + public void renderAuraNodes(RenderWorldLastEvent event, float partialTicks, EntityPlayer player, long time) { + GL11.glPushMatrix(); + int limit = 0; + Collection col = AuraManagerClient.auraClientList.values(); + for (NodeStats l : col) { + float px = (float) l.x; + float py = (float) l.y; + float pz = (float) l.z; + int dim = l.dimension; + short lvl = l.level; + int key = l.key; + boolean lock = l.lock; + byte type = l.type; + if (limit >= 10 || player.dimension != dim || !(player.getDistanceSq((double)px, (double)py, (double)pz) < 4096.0)) continue; + ++limit; + AuraManagerClient.NodeRenderInfo nri = (AuraManagerClient.NodeRenderInfo)AuraManagerClient.auraClientMovementList.get(key); + if (nri == null) { + nri = new AuraManagerClient.NodeRenderInfo(px, py, pz); + AuraManagerClient.auraClientMovementList.put(key, nri); + } + float bscale = (float)lvl / 1000.0f; + nri.x += (px - nri.x) / 50.0f * partialTicks; + nri.y += (py - nri.y) / 50.0f * partialTicks; + nri.z += (pz - nri.z) / 50.0f * partialTicks; + AuraManagerClient.auraClientMovementList.put(key, nri); + float rad = (float)Math.PI * 2; + GL11.glColor4f((float)1.0f, (float)1.0f, (float)1.0f, (float)0.1f); + GL11.glPushMatrix(); + UtilsFX.bindTexture(tx1); + float scale = MathHelper.sin((float)(((float)time + nri.x) / 14.0f)) * bscale + bscale * 2.0f; + float angle = (float)(time % 500L) / 500.0f * rad; + UtilsFX.renderFacingQuad(nri.x, nri.y, nri.z, angle, scale, 1, 1, 0, partialTicks, 0xFFFFFF); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + UtilsFX.bindTexture(tx2); + angle = (float)(time % 400L) / -400.0f * rad; + scale = MathHelper.sin((float)(((float)time + nri.y) / 11.0f)) * bscale + bscale * 2.0f; + UtilsFX.renderFacingQuad(nri.x, nri.y, nri.z, angle, scale, 1, 1, 0, partialTicks, 0xFFFFFF); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + UtilsFX.bindTexture(tx3); + angle = (float)(time % 300L) / 300.0f * rad; + scale = MathHelper.sin((float)(((float)time + nri.z) / 9.0f)) * bscale + bscale * 2.0f; + UtilsFX.renderFacingQuad(nri.x, nri.y, nri.z, angle, scale, 1, 1, 0, partialTicks, 0xFFFFFF); + GL11.glPopMatrix(); + if (type == 0) { + GL11.glPushMatrix(); + UtilsFX.bindTexture(tx1); + angle = (float)(time % 200L) / -200.0f * rad; + scale = MathHelper.sin((float)(((float)time + nri.x) / 7.0f)) * bscale / 2.0f + bscale * 2.0f; + UtilsFX.renderFacingQuad(nri.x, nri.y, nri.z, angle, scale, 1, 1, 0, partialTicks, 0xFFFFFF); + GL11.glPopMatrix(); + } else { + GL11.glPushMatrix(); + switch (type) { + case 1: { + UtilsFX.bindTexture(tx3p); + break; + } + case 2: { + GL11.glBlendFunc((int)770, (int)771); + UtilsFX.bindTexture(tx3d); + break; + } + case 3: { + UtilsFX.bindTexture(tx3c); + } + } + angle = (float)(time % 90L) / -90.0f * rad; + scale = MathHelper.sin((float)(((float)time + nri.x) / 10.0f)) * bscale / 4.0f + bscale * 1.75f; + UtilsFX.renderFacingQuad(nri.x, nri.y, nri.z, angle, scale, 1, 1, 0, partialTicks, 0xFFFFFF); + GL11.glPopMatrix(); + GL11.glBlendFunc((int)770, (int)1); + } + if (!lock) continue; + GL11.glPushMatrix(); + UtilsFX.bindTexture(txlock); + UtilsFX.renderFacingQuad(nri.x, nri.y, nri.z, 0.0f, bscale * 3.5f, 1, 1, 0, partialTicks, 0xFFFFFF); + GL11.glPopMatrix(); + } + GL11.glColor4f((float)1.0f, (float)1.0f, (float)1.0f, (float)1.0f); + GL11.glPopMatrix(); + } + +} diff --git a/src/main/java/dev/tilera/auracore/helper/Utils.java b/src/main/java/dev/tilera/auracore/helper/Utils.java new file mode 100644 index 0000000..6ec5c17 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/helper/Utils.java @@ -0,0 +1,148 @@ +package dev.tilera.auracore.helper; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.nio.channels.spi.AbstractInterruptibleChannel; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockCrops; +import net.minecraft.block.BlockDirectional; +import net.minecraft.block.BlockMushroom; +import net.minecraft.block.BlockSapling; +import net.minecraft.block.BlockStem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.ForgeHooks; +import thaumcraft.api.IGoggles; + +public class Utils { + + public static boolean hasGoggles(EntityPlayer player) { + ItemStack goggles = player.inventory.armorItemInSlot(3); + return goggles != null && goggles.getItem() instanceof IGoggles && ((IGoggles)goggles.getItem()).showIngamePopups(goggles, player); + } + + public static void sendChatNearby(World world, double x, double y, double z, double radius, String text) { + //MinecraftServer.getServer().getConfigurationManager().sendChatNearby(x, y, z, radius, world.provider.dimensionId, (Packet)new Packet3Chat(text)); + } + + public static boolean isChunkLoaded(World world, int x, int z) { + int xx = x / 16; + int zz = z / 16; + return world.getChunkProvider().chunkExists(xx, zz); + } + + public static boolean useBonemealAtLoc(World world, int x, int y, int z) { + Block bi = world.getBlock(x, y, z); + if (bi == Blocks.sapling) { + if (!world.isRemote) { + ((BlockSapling)bi).func_149878_d(world, x, y, z, world.rand); //TODO func + } + return true; + } + if (bi == Blocks.brown_mushroom || bi == Blocks.red_mushroom_block) { + if (!world.isRemote) { + ((BlockMushroom)bi).func_149884_c(world, x, y, z, world.rand); //TODO func + } + return true; + } + if (bi == Blocks.melon_stem || bi == Blocks.pumpkin_stem) { + if (world.getBlockMetadata(x, y, z) == 7) { + return false; + } + if (!world.isRemote) { + ((BlockStem)bi).func_149874_m(world, x, y, z); //TODO func + } + return true; + } + if (bi instanceof BlockCrops) { + if (world.getBlockMetadata(x, y, z) == 7) { + return false; + } + if (!world.isRemote) { + ((BlockCrops)bi).func_149863_m(world, x, y, z); //TODO func + } + return true; + } + if (bi == Blocks.cocoa) { + if (!world.isRemote) { + world.setBlockMetadataWithNotify(x, y, z, 8 | BlockDirectional.getDirection((int)world.getBlockMetadata(x, y, z)), 3); + } + return true; + } + /*if (bi == Blocks.grass) { + if (!world.isRemote) { + block0: for (int var12 = 0; var12 < 128; ++var12) { + int var13 = x; + int var14 = y + 1; + int var15 = z; + for (int var16 = 0; var16 < var12 / 16; ++var16) { + if (world.getBlock(var13 += world.rand.nextInt(3) - 1, (var14 += (world.rand.nextInt(3) - 1) * world.rand.nextInt(3) / 2) - 1, var15 += world.rand.nextInt(3) - 1) != Blocks.grass || world.(var13, var14, var15)) continue block0; + } + if (world.getBlock(var13, var14, var15) != 0) continue; + if (world.rand.nextInt(10) != 0) { + if (!Block.field_71962_X.func_71854_d(world, var13, var14, var15)) continue; + world.func_72832_d(var13, var14, var15, Block.field_71962_X.field_71990_ca, 1, 3); + continue; + + } + ForgeHooks.plantGrass((World)world, (int)var13, (int)var14, (int)var15); + } + } + return true; + }*/ //TODO: WTF + return false; + } + + public static int getFirstUncoveredBlockHeight(World world, int par1, int par2) { + int var3; + for (var3 = 10; !world.isAirBlock(par1, var3 + 1, par2) || var3 > 250; ++var3) { + } + return var3; + } + + public static boolean isBlockTouching(IBlockAccess world, int x, int y, int z, Block id, int md) { + return world.getBlock(x, y, z + 1) == id && world.getBlockMetadata(x, y, z + 1) == md || world.getBlock(x, y, z - 1) == id && world.getBlockMetadata(x, y, z - 1) == md || world.getBlock(x + 1, y, z) == id && world.getBlockMetadata(x + 1, y, z) == md || world.getBlock(x - 1, y, z) == id && world.getBlockMetadata(x - 1, y, z) == md || world.getBlock(x, y + 1, z) == id && world.getBlockMetadata(x, y + 1, z) == md || world.getBlock(x, y - 1, z) == id && world.getBlockMetadata(x, y - 1, z) == md; + } + + public static boolean isBlockTouching(IBlockAccess world, int x, int y, int z, Block id) { + return world.getBlock(x, y, z + 1) == id || world.getBlock(x, y, z - 1) == id || world.getBlock(x + 1, y, z) == id || world.getBlock(x - 1, y, z) == id || world.getBlock(x, y + 1, z) == id || world.getBlock(x, y - 1, z) == id; + } + + public static void copyFile(File sourceFile, File destFile) throws IOException { + if (!destFile.exists()) { + destFile.createNewFile(); + } + FileChannel source = null; + AbstractInterruptibleChannel destination = null; + try { + source = new FileInputStream(sourceFile).getChannel(); + destination = new FileOutputStream(destFile).getChannel(); + ((FileChannel)destination).transferFrom(source, 0L, source.size()); + } + finally { + if (source != null) { + source.close(); + } + if (destination != null) { + destination.close(); + } + } + } + + public static int getFirstUncoveredY(World world, int par1, int par2) { + int var3 = 5; + while (!world.isAirBlock(par1, var3 + 1, par2)) { + ++var3; + } + return var3; + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinBlockCustomOre.java b/src/main/java/dev/tilera/auracore/mixins/MixinBlockCustomOre.java new file mode 100644 index 0000000..b9b9401 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinBlockCustomOre.java @@ -0,0 +1,155 @@ +package dev.tilera.auracore.mixins; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import dev.tilera.auracore.api.AuraNode; +import dev.tilera.auracore.aura.AuraManager; +import dev.tilera.auracore.helper.Utils; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.common.blocks.BlockCustomOre; +import thaumcraft.common.config.ConfigBlocks; +import thaumcraft.common.lib.world.ThaumcraftWorldGenerator; +import thaumcraft.common.lib.world.biomes.BiomeHandler; + +@Mixin(BlockCustomOre.class) +public abstract class MixinBlockCustomOre extends Block { + + MixinBlockCustomOre(Material p_i45394_1_) { + super(p_i45394_1_); + } + + /** + * @author tilera + * @reason Vis, Tainted and Dull ores + */ + @Overwrite + @SideOnly(Side.CLIENT) + public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + par3List.add(new ItemStack(par1, 1, 1)); + par3List.add(new ItemStack(par1, 1, 2)); + par3List.add(new ItemStack(par1, 1, 3)); + par3List.add(new ItemStack(par1, 1, 4)); + par3List.add(new ItemStack(par1, 1, 5)); + par3List.add(new ItemStack(par1, 1, 6)); + par3List.add(new ItemStack(par1, 1, 7)); + par3List.add(new ItemStack(par1, 1, 8)); + par3List.add(new ItemStack(par1, 1, 9)); + par3List.add(new ItemStack(par1, 1, 10)); + } + + @Override + public void updateTick(final World world, final int x, final int y, final int z, final Random rand) { + if (world.isRemote) { + return; + } + try { + final int md = world.getBlockMetadata(x, y, z); + if (md != 0 && md != 7 && md != 10 && rand.nextInt(500) == 42) { + if (world.getBiomeGenForCoords(x, z).biomeID == ThaumcraftWorldGenerator.biomeTaint.biomeID) { + world.setBlock(x, y, z, this, 10, 3); + return; + } + final ArrayList nodes = AuraManager.getAurasWithin(world, x + 0.5f, y + 0.5f, z + 0.5f); + if (nodes.size() == 0) { + return; + } + if (md == 9) { + for (final Integer key : nodes) { + final AuraNode nd = AuraManager.getNode(key); + if (nd == null) { + continue; + } + if (nd.level - 10 >= nd.baseLevel) { + AuraManager.queueNodeChanges(nd.key, -10, 0, false, null, 0.0f, 0.0f, 0.0f); + int tmd = 0; + if (Utils.isBlockTouching(world, x, y, z, this, 1)) { + tmd = 1; + } else if (Utils.isBlockTouching(world, x, y, z, this, 2)) { + tmd = 2; + } else if (Utils.isBlockTouching(world, x, y, z, this, 3)) { + tmd = 3; + } else if (Utils.isBlockTouching(world, x, y, z, this, 4)) { + tmd = 4; + } else if (Utils.isBlockTouching(world, x, y, z, this, 5)) { + tmd = 5; + } else if (Utils.isBlockTouching(world, x, y, z, this, 6)) { + tmd = 6; + } else if (Utils.isBlockTouching(world, x, y, z, this, 8)) { + tmd = 8; + } else { + Aspect aspect = BiomeHandler.getRandomBiomeTag(world.getBiomeGenForCoords(x, z).biomeID, rand); + if (aspect == Aspect.AIR) { + tmd = 1; + } else if (aspect == Aspect.FIRE) { + tmd = 2; + } else if (aspect == Aspect.WATER) { + tmd = 3; + } else if (aspect == Aspect.EARTH) { + tmd = 4; + } else if (aspect == Aspect.ORDER) { + tmd = 5; + } else if (aspect == Aspect.ENTROPY) { + tmd = 6; + } else if (aspect == Aspect.MAGIC) { + tmd = 8; + } else if (aspect == Aspect.TAINT) { + tmd = 10; + } else { + tmd = rand.nextInt(6) + 1; + } + } + world.setBlock(x, y, z, this, tmd, 3); + break; + } + } + } else { + for (final Integer key : nodes) { + final AuraNode nd = AuraManager.getNode(key); + if (nd == null) { + continue; + } + if (nd.level + 10 <= nd.baseLevel) { + AuraManager.queueNodeChanges(nd.key, 10, 0, false, null, 0.0f, 0.0f, 0.0f); + world.setBlock(x, y, z, this, 9, 3); + break; + } + if (rand.nextInt(50) != 42 || nd.level - 100 < nd.baseLevel) { + continue; + } + for (int a = 0; a < 6; ++a) { + if (world.getBlock(x + ForgeDirection.getOrientation(a).offsetX, + y + ForgeDirection.getOrientation(a).offsetY, + z + ForgeDirection.getOrientation(a).offsetZ) == Blocks.stone) { + AuraManager.queueNodeChanges(nd.key, -50, 0, false, null, 0.0f, 0.0f, 0.0f); + world.setBlock(x + ForgeDirection.getOrientation(a).offsetX, + y + ForgeDirection.getOrientation(a).offsetY, + z + ForgeDirection.getOrientation(a).offsetZ, ConfigBlocks.blockCustomOre, md, + 3); + return; + } + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinBlockCustomOreRenderer.java b/src/main/java/dev/tilera/auracore/mixins/MixinBlockCustomOreRenderer.java new file mode 100644 index 0000000..2ecdc06 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinBlockCustomOreRenderer.java @@ -0,0 +1,80 @@ +package dev.tilera.auracore.mixins; + +import org.lwjgl.opengl.GL11; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import java.awt.Color; +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; +import dev.tilera.auracore.api.CrystalColors; +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.init.Blocks; +import net.minecraft.world.IBlockAccess; +import thaumcraft.client.renderers.block.BlockCustomOreRenderer; +import thaumcraft.client.renderers.block.BlockRenderer; +import thaumcraft.common.blocks.BlockCustomOre; + +@Mixin(BlockCustomOreRenderer.class) +public abstract class MixinBlockCustomOreRenderer extends BlockRenderer implements ISimpleBlockRenderingHandler { + + /** + * @author tilera + * @reason Vis, Tainted and Dull ores + */ + @Overwrite(remap = false) + public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { + block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + renderer.setRenderBoundsFromBlock(block); + if (metadata == 0) { + drawFaces(renderer, block, ((BlockCustomOre)block).icon[0], false); + } else if (metadata == 7) { + drawFaces(renderer, block, ((BlockCustomOre)block).icon[3], false); + } else { + drawFaces(renderer, block, ((BlockCustomOre)block).icon[1], false); + Color c = new Color(CrystalColors.getColorForOre(metadata)); + float r = (float)c.getRed() / 255.0F; + float g = (float)c.getGreen() / 255.0F; + float b = (float)c.getBlue() / 255.0F; + GL11.glColor3f(r, g, b); + block.setBlockBounds(0.005F, 0.005F, 0.005F, 0.995F, 0.995F, 0.995F); + renderer.setRenderBoundsFromBlock(block); + drawFaces(renderer, block, ((BlockCustomOre)block).icon[2], false); + GL11.glColor3f(1.0F, 1.0F, 1.0F); + } + + } + + /** + * @author tilera + * @reason Vis, Tainted and Dull ores + */ + @Overwrite(remap = false) + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + int bb = setBrightness(world, x, y, z, block); + int metadata = world.getBlockMetadata(x, y, z); + block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + renderer.setRenderBoundsFromBlock(block); + renderer.renderStandardBlock(block, x, y, z); + if (metadata != 0 && metadata != 7) { + Tessellator t = Tessellator.instance; + t.setColorOpaque_I(CrystalColors.getColorForOre(metadata)); + t.setBrightness(Math.max(bb, 160)); + renderAllSides(world, x, y, z, block, renderer, ((BlockCustomOre)block).icon[2], false); + if (Minecraft.getMinecraft().gameSettings.anisotropicFiltering > 1) { + block.setBlockBounds(0.005F, 0.005F, 0.005F, 0.995F, 0.995F, 0.995F); + renderer.setRenderBoundsFromBlock(block); + t.setBrightness(bb); + renderAllSides(world, x, y, z, block, renderer, Blocks.stone.getIcon(0, 0), false); + } + } + + renderer.clearOverrideBlockTexture(); + block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + renderer.setRenderBoundsFromBlock(block); + return true; + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinBlockCustomPlant.java b/src/main/java/dev/tilera/auracore/mixins/MixinBlockCustomPlant.java new file mode 100644 index 0000000..9f9a754 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinBlockCustomPlant.java @@ -0,0 +1,45 @@ +package dev.tilera.auracore.mixins; + +import java.util.Random; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import dev.tilera.auracore.api.EnumNodeType; +import dev.tilera.auracore.aura.AuraManager; +import dev.tilera.auracore.world.WorldGenSilverwoodTreesOld; +import net.minecraft.block.BlockBush; +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import thaumcraft.common.blocks.BlockCustomPlant; + +@Mixin(BlockCustomPlant.class) +public abstract class MixinBlockCustomPlant extends BlockBush { + + /** + * @author tilera + * @reason Old Silverwood tree + */ + @Overwrite(remap = false) + public void growSilverTree(World world, int i, int j, int k, Random random) { + if (world == null || world.provider == null) { + return; + } + world.setBlock(i, j, k, Blocks.air, 0, 3); + WorldGenSilverwoodTreesOld obj = new WorldGenSilverwoodTreesOld(true); + int value = random.nextInt(50) + 50; + if (!AuraManager.decreaseClosestAura(world, i, j, k, (int)((float)value * 1.5f), false) || !obj.generate(world, random, i, j, k)) { + world.setBlock(i, j, k, this, 1, 0); + } else { + try { + if (AuraManager.decreaseClosestAura(world, i, j, k, (int)((float)value * 1.5f))) { + AuraManager.registerAuraNode(world, (short)value, EnumNodeType.PURE, world.provider.dimensionId, i, j + 1, k); + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinEventHandlerEntity.java b/src/main/java/dev/tilera/auracore/mixins/MixinEventHandlerEntity.java new file mode 100644 index 0000000..73cf121 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinEventHandlerEntity.java @@ -0,0 +1,58 @@ +package dev.tilera.auracore.mixins; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import dev.tilera.auracore.aura.AuraManager; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import thaumcraft.api.IRepairableExtended; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.common.config.Config; +import thaumcraft.common.items.wands.WandManager; +import thaumcraft.common.lib.crafting.ThaumcraftCraftingManager; +import thaumcraft.common.lib.events.EventHandlerEntity; +import thaumcraft.common.lib.research.ResearchManager; + +@Mixin(EventHandlerEntity.class) +public abstract class MixinEventHandlerEntity { + + /** + * @author tilera + * @reason Repair using Vis from the aura + */ + @Overwrite(remap = false) + public static void doRepair(ItemStack is, EntityPlayer player) { + int level = EnchantmentHelper.getEnchantmentLevel(Config.enchRepair.effectId, is); + if (level > 0) { + if (level > 2) { + level = 2; + } + + AspectList cost = ThaumcraftCraftingManager.getObjectTags(is); + if (cost != null && cost.size() != 0) { + cost = ResearchManager.reduceToPrimals(cost); + AspectList finalCost = new AspectList(); + Aspect[] aspects = cost.getAspects(); + + for(Aspect a : aspects) { + if (a != null) { + finalCost.merge(a, (int)Math.sqrt((double)(cost.getAmount(a) * 2)) * level); + } + } + + if (is.getItem() instanceof IRepairableExtended) { + if (((IRepairableExtended)is.getItem()).doRepair(is, player, level) && WandManager.consumeVisFromInventory(player, finalCost)) { + is.damageItem(-level, player); + } + } else if (WandManager.consumeVisFromInventory(player, finalCost) || AuraManager.decreaseClosestAura(player.worldObj, player.posX, player.posY, player.posZ, 1)) { + is.damageItem(-level, player); + } + + } + } + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinItemEssence.java b/src/main/java/dev/tilera/auracore/mixins/MixinItemEssence.java new file mode 100644 index 0000000..5b3d420 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinItemEssence.java @@ -0,0 +1,85 @@ +package dev.tilera.auracore.mixins; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import dev.tilera.auracore.api.IEssenceContainer; +import net.minecraft.block.Block; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.aspects.IEssentiaContainerItem; +import thaumcraft.common.config.ConfigBlocks; +import thaumcraft.common.items.ItemEssence; +import thaumcraft.common.tiles.TileJarFillable; + +@Mixin(ItemEssence.class) +public abstract class MixinItemEssence extends Item implements IEssentiaContainerItem { + + /** + * @author tilera + * @reason API for essence containers + */ + @Overwrite(remap = false) + public boolean onItemUseFirst(ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z, int side, float f1, float f2, float f3) { + Block bi = world.getBlock(x, y, z); + int md = world.getBlockMetadata(x, y, z); + TileEntity te = world.getTileEntity(x, y, z); + if (itemstack.getItemDamage() == 0 && te instanceof IEssenceContainer) { + IEssenceContainer tile = (IEssenceContainer) te; + if (tile.getAmount() >= 8) { + if (world.isRemote) { + player.swingItem(); + return false; + } + + ItemStack phial = new ItemStack(this, 1, 1); + this.setAspects(phial, (new AspectList()).add(tile.getAspect(), 8)); + if (tile.takeFromContainer(tile.getAspect(), 8)) { + --itemstack.stackSize; + if (!player.inventory.addItemStackToInventory(phial)) { + world.spawnEntityInWorld(new EntityItem(world, (double)((float)x + 0.5F), (double)((float)y + 0.5F), (double)((float)z + 0.5F), phial)); + } + + world.playSoundAtEntity(player, "game.neutral.swim", 0.25F, 1.0F); + player.inventoryContainer.detectAndSendChanges(); + return true; + } + } + } + + AspectList al = this.getAspects(itemstack); + if (al != null && al.size() == 1) { + Aspect aspect = al.getAspects()[0]; + if (itemstack.getItemDamage() != 0 && bi == ConfigBlocks.blockJar && (md == 0 || md == 3)) { + TileJarFillable tile = (TileJarFillable)world.getTileEntity(x, y, z); + if (tile.amount <= tile.maxAmount - 8 && tile.doesContainerAccept(aspect)) { + if (world.isRemote) { + player.swingItem(); + return false; + } + + if (tile.addToContainer(aspect, 8) == 0) { + world.markBlockForUpdate(x, y, z); + tile.markDirty(); + --itemstack.stackSize; + if (!player.inventory.addItemStackToInventory(new ItemStack(this, 1, 0))) { + world.spawnEntityInWorld(new EntityItem(world, (double)((float)x + 0.5F), (double)((float)y + 0.5F), (double)((float)z + 0.5F), new ItemStack(this, 1, 0))); + } + + world.playSoundAtEntity(player, "game.neutral.swim", 0.25F, 1.0F); + player.inventoryContainer.detectAndSendChanges(); + return true; + } + } + } + } + + return false; + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinItemShard.java b/src/main/java/dev/tilera/auracore/mixins/MixinItemShard.java new file mode 100644 index 0000000..fed238c --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinItemShard.java @@ -0,0 +1,41 @@ +package dev.tilera.auracore.mixins; + +import java.util.List; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import dev.tilera.auracore.api.CrystalColors; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import thaumcraft.common.items.ItemShard; + +@Mixin(ItemShard.class) +public abstract class MixinItemShard extends Item { + + /** + * @author tilera + * @reason Vis, Tainted and Dull shards + */ + @Overwrite + @SideOnly(Side.CLIENT) + public int getColorFromItemStack(ItemStack stack, int par2) { + return stack.getItemDamage() == 6 ? super.getColorFromItemStack(stack, par2) : CrystalColors.getColorForShard(stack.getItemDamage()); + } + + /** + * @author tilera + * @reason Vis, Tainted and Dull shards + */ + @Overwrite + @SideOnly(Side.CLIENT) + public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) { + for(int a = 0; a <= 9; ++a) { + par3List.add(new ItemStack(this, 1, a)); + } + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinSlotLimitedByWand.java b/src/main/java/dev/tilera/auracore/mixins/MixinSlotLimitedByWand.java new file mode 100644 index 0000000..9bf2957 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinSlotLimitedByWand.java @@ -0,0 +1,29 @@ +package dev.tilera.auracore.mixins; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import dev.tilera.auracore.api.IWand; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import thaumcraft.common.container.SlotLimitedByWand; +import thaumcraft.common.items.wands.ItemWandCasting; + +@Mixin(SlotLimitedByWand.class) +public abstract class MixinSlotLimitedByWand extends Slot { + + public MixinSlotLimitedByWand(IInventory p_i1824_1_, int p_i1824_2_, int p_i1824_3_, int p_i1824_4_) { + super(p_i1824_1_, p_i1824_2_, p_i1824_3_, p_i1824_4_); + } + + /** + * @author tilera + * @reason Allow classic wands in Arcane Worktable + */ + @Overwrite + public boolean isItemValid(final ItemStack stack) { + return stack != null && stack.getItem() != null && ((stack.getItem() instanceof ItemWandCasting && !((ItemWandCasting)stack.getItem()).isStaff(stack)) || stack.getItem() instanceof IWand); + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinThaumcraftWorldGenerator.java b/src/main/java/dev/tilera/auracore/mixins/MixinThaumcraftWorldGenerator.java new file mode 100644 index 0000000..153aa4f --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinThaumcraftWorldGenerator.java @@ -0,0 +1,126 @@ +package dev.tilera.auracore.mixins; + +import java.util.Random; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import dev.tilera.auracore.api.EnumNodeType; +import dev.tilera.auracore.aura.AuraManager; +import dev.tilera.auracore.world.WorldGenSilverwoodTreesOld; +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.gen.feature.WorldGenMinable; +import net.minecraftforge.common.BiomeDictionary; +import net.minecraftforge.common.BiomeDictionary.Type; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.common.config.Config; +import thaumcraft.common.config.ConfigBlocks; +import thaumcraft.common.lib.world.ThaumcraftWorldGenerator; +import thaumcraft.common.lib.world.biomes.BiomeHandler; + +@Mixin(ThaumcraftWorldGenerator.class) +public abstract class MixinThaumcraftWorldGenerator { + + /** + * @author tilera + * @reason Old Silverwood trees + */ + @Overwrite(remap = false) + public static boolean generateSilverwood(World world, Random random, int chunkX, int chunkZ) { + int x = chunkX * 16 + random.nextInt(16); + int z = chunkZ * 16 + random.nextInt(16); + int y = world.getHeightValue(x, z); + BiomeGenBase bio = world.getBiomeGenForCoords(x, z); + if (bio.equals(ThaumcraftWorldGenerator.biomeMagicalForest) || bio.equals(ThaumcraftWorldGenerator.biomeTaint) || !BiomeDictionary.isBiomeOfType(bio, Type.MAGICAL) && bio.biomeID != BiomeGenBase.forestHills.biomeID && bio.biomeID != BiomeGenBase.birchForestHills.biomeID) { + return false; + } else { + boolean t = (new WorldGenSilverwoodTreesOld(false)).generate(world, random, x, y, z); + if (t) { + int value = random.nextInt(200) + 200; + AuraManager.registerAuraNode(world, (short)value, EnumNodeType.PURE, world.provider.dimensionId, x, y + 1, z); + ThaumcraftWorldGenerator.generateFlowers(world, random, x, y, z, 2); + } + return t; + } + } + + /** + * @author tilera + * @reason Generate infused ores + */ + @Overwrite(remap = false) + private void generateOres(World world, Random random, int chunkX, int chunkZ, boolean newGen) { + BiomeGenBase bgb = world.getBiomeGenForCoords(chunkX * 16 + 8, chunkZ * 16 + 8); + if (ThaumcraftWorldGenerator.getBiomeBlacklist(bgb.biomeID) != 0 && ThaumcraftWorldGenerator.getBiomeBlacklist(bgb.biomeID) != 2) { + int i; + int randPosX; + int randPosZ; + int randPosY; + Block block; + if (Config.genCinnibar && (newGen || Config.regenCinnibar)) { + for(i = 0; i < 18; ++i) { + randPosX = chunkX * 16 + random.nextInt(16); + randPosZ = random.nextInt(world.getHeight() / 5); + randPosY = chunkZ * 16 + random.nextInt(16); + block = world.getBlock(randPosX, randPosZ, randPosY); + if (block != null && block.isReplaceableOreGen(world, randPosX, randPosZ, randPosY, Blocks.stone)) { + world.setBlock(randPosX, randPosZ, randPosY, ConfigBlocks.blockCustomOre, 0, 0); + } + } + } + + if (Config.genAmber && (newGen || Config.regenAmber)) { + for(i = 0; i < 20; ++i) { + randPosX = chunkX * 16 + random.nextInt(16); + randPosZ = chunkZ * 16 + random.nextInt(16); + randPosY = world.getHeightValue(randPosX, randPosZ) - random.nextInt(25); + block = world.getBlock(randPosX, randPosY, randPosZ); + if (block != null && block.isReplaceableOreGen(world, randPosX, randPosY, randPosZ, Blocks.stone)) { + world.setBlock(randPosX, randPosY, randPosZ, ConfigBlocks.blockCustomOre, 7, 2); + } + } + } + + if (Config.genInfusedStone && (newGen || Config.regenInfusedStone)) { + for(i = 0; i < 8; ++i) { + randPosX = chunkX * 16 + random.nextInt(16); + randPosZ = chunkZ * 16 + random.nextInt(16); + randPosY = random.nextInt(Math.max(5, world.getHeightValue(randPosX, randPosZ) - 5)); + int md = random.nextInt(7) + 1; + if (random.nextInt(3) == 0) { + Aspect tag = BiomeHandler.getRandomBiomeTag(world.getBiomeGenForCoords(randPosX, randPosZ).biomeID, random); + if (tag == null) { + md = 1 + random.nextInt(7); + } else if (tag == Aspect.AIR) { + md = 1; + } else if (tag == Aspect.FIRE) { + md = 2; + } else if (tag == Aspect.WATER) { + md = 3; + } else if (tag == Aspect.EARTH) { + md = 4; + } else if (tag == Aspect.ORDER) { + md = 5; + } else if (tag == Aspect.ENTROPY) { + md = 6; + } + } + if (md > 6) { + md = 8; + } + + try { + (new WorldGenMinable(ConfigBlocks.blockCustomOre, md, 6, Blocks.stone)).generate(world, random, randPosX, randPosY, randPosZ); + } catch (Exception var13) { + var13.printStackTrace(); + } + } + } + + } + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinTileAlembic.java b/src/main/java/dev/tilera/auracore/mixins/MixinTileAlembic.java new file mode 100644 index 0000000..a188a45 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinTileAlembic.java @@ -0,0 +1,29 @@ +package dev.tilera.auracore.mixins; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import dev.tilera.auracore.api.IEssenceContainer; +import thaumcraft.api.TileThaumcraft; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.common.tiles.TileAlembic; + +@Mixin(TileAlembic.class) +public abstract class MixinTileAlembic extends TileThaumcraft implements IEssenceContainer { + + @Shadow(remap = false) + public Aspect aspect; + @Shadow(remap = false) + public int amount; + + @Override + public Aspect getAspect() { + return aspect; + } + + @Override + public int getAmount() { + return amount; + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinTileArcaneFurnace.java b/src/main/java/dev/tilera/auracore/mixins/MixinTileArcaneFurnace.java new file mode 100644 index 0000000..0202007 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinTileArcaneFurnace.java @@ -0,0 +1,192 @@ +package dev.tilera.auracore.mixins; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import dev.tilera.auracore.api.Aspects; +import dev.tilera.auracore.aura.AuraManager; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.item.EntityXPOrb; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.FurnaceRecipes; +import net.minecraft.util.MathHelper; +import thaumcraft.api.ThaumcraftApi; +import thaumcraft.api.TileThaumcraft; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.visnet.VisNetHandler; +import thaumcraft.common.config.ConfigBlocks; +import thaumcraft.common.tiles.TileArcaneFurnace; + +@Mixin(TileArcaneFurnace.class) +public abstract class MixinTileArcaneFurnace extends TileThaumcraft { + + @Shadow(remap = false) + private ItemStack[] furnaceItemStacks; + @Shadow(remap = false) + public int furnaceCookTime; + @Shadow(remap = false) + public int furnaceMaxCookTime; + @Shadow(remap = false) + public int speedyTime; + @Shadow(remap = false) + public int facingX; + @Shadow(remap = false) + public int facingZ; + + @Shadow(remap = false) + protected abstract int getBellows(); + @Shadow(remap = false) + protected abstract void getFacing(); + @Shadow(remap = false) + protected abstract int calcCookTime(); + @Shadow(remap = false) + public abstract int getSizeInventory(); + @Shadow(remap = false) + protected abstract boolean canSmelt(int slotIn); + + /** + * @author tilera + * @reason Use Vis from the aura + */ + @Overwrite + public void updateEntity() { + super.updateEntity(); + if (this.facingX == -5) { + this.getFacing(); + } + + if (!super.worldObj.isRemote) { + boolean cookedflag = false; + if (this.furnaceCookTime > 0) { + --this.furnaceCookTime; + cookedflag = true; + } + + if (cookedflag && this.speedyTime > 0) { + --this.speedyTime; + } + + if (this.speedyTime <= 0) { + this.speedyTime = VisNetHandler.drainVis(super.worldObj, super.xCoord, super.yCoord, super.zCoord, Aspect.FIRE, 5); + } + + if (this.furnaceMaxCookTime == 0) { + this.furnaceMaxCookTime = this.calcCookTime(); + } + + if (this.furnaceCookTime > this.furnaceMaxCookTime) { + this.furnaceCookTime = this.furnaceMaxCookTime; + } + + int a; + if (this.furnaceCookTime == 0 && cookedflag) { + for(a = 0; a < this.getSizeInventory(); ++a) { + if (this.furnaceItemStacks[a] != null) { + ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(this.furnaceItemStacks[a]); + if (itemstack != null && AuraManager.decreaseClosestAura(this.worldObj, this.xCoord, this.yCoord, this.zCoord, 1)) { + this.ejectItem(itemstack.copy(), this.furnaceItemStacks[a]); + super.worldObj.addBlockEvent(super.xCoord, super.yCoord, super.zCoord, ConfigBlocks.blockArcaneFurnace, 3, 0); + --this.furnaceItemStacks[a].stackSize; + if (this.furnaceItemStacks[a].stackSize <= 0) { + this.furnaceItemStacks[a] = null; + } + break; + } + } + } + } + + if (this.furnaceCookTime == 0 && !cookedflag) { + for(a = 0; a < this.getSizeInventory(); ++a) { + if (this.furnaceItemStacks[a] != null && this.canSmelt(a)) { + this.furnaceMaxCookTime = this.calcCookTime(); + this.furnaceCookTime = this.furnaceMaxCookTime; + break; + } + } + } + } + + } + + /** + * @author tilera + * @reason Add flux to aura + */ + @Overwrite(remap = false) + public void ejectItem(ItemStack items, ItemStack furnaceItemStack) { + if (items != null) { + ItemStack bit = items.copy(); + int bellows = this.getBellows(); + float lx = 0.5F; + lx += (float)this.facingX * 1.2F; + float lz = 0.5F; + lz += (float)this.facingZ * 1.2F; + float mx = this.facingX == 0 ? (super.worldObj.rand.nextFloat() - super.worldObj.rand.nextFloat()) * 0.03F : (float)this.facingX * 0.13F; + float mz = this.facingZ == 0 ? (super.worldObj.rand.nextFloat() - super.worldObj.rand.nextFloat()) * 0.03F : (float)this.facingZ * 0.13F; + EntityItem entityitem = new EntityItem(super.worldObj, (double)((float)super.xCoord + lx), (double)((float)super.yCoord + 0.4F), (double)((float)super.zCoord + lz), items); + entityitem.motionX = (double)mx; + entityitem.motionZ = (double)mz; + entityitem.motionY = 0.0D; + super.worldObj.spawnEntityInWorld(entityitem); + if (ThaumcraftApi.getSmeltingBonus(furnaceItemStack) != null) { + ItemStack bonus = ThaumcraftApi.getSmeltingBonus(furnaceItemStack).copy(); + if (bonus != null) { + if (bellows == 0) { + if (super.worldObj.rand.nextInt(4) == 0) { + ++bonus.stackSize; + } + } else { + for(int a = 0; a < bellows; ++a) { + if (super.worldObj.rand.nextFloat() < 0.44F) { + ++bonus.stackSize; + } + } + } + } + + if (bonus != null && bonus.stackSize > 0) { + mx = this.facingX == 0 ? (super.worldObj.rand.nextFloat() - super.worldObj.rand.nextFloat()) * 0.03F : (float)this.facingX * 0.13F; + mz = this.facingZ == 0 ? (super.worldObj.rand.nextFloat() - super.worldObj.rand.nextFloat()) * 0.03F : (float)this.facingZ * 0.13F; + EntityItem entityitem2 = new EntityItem(super.worldObj, (double)((float)super.xCoord + lx), (double)((float)super.yCoord + 0.4F), (double)((float)super.zCoord + lz), bonus); + entityitem2.motionX = (double)mx; + entityitem2.motionZ = (double)mz; + entityitem2.motionY = 0.0D; + super.worldObj.spawnEntityInWorld(entityitem2); + } + } + if (this.worldObj.rand.nextInt(15 + bellows * 5) == 0) { + AuraManager.addFluxToClosest(this.worldObj, this.xCoord, this.yCoord, this.zCoord, this.worldObj.rand.nextBoolean() ? new AspectList().add(Aspect.FIRE, 1) : new AspectList().add(Aspects.EVIL, 1)); + } + int var2 = items.stackSize; + float var3 = FurnaceRecipes.smelting().func_151398_b(bit); + int var4; + if (var3 == 0.0F) { + var2 = 0; + } else if (var3 < 1.0F) { + var4 = MathHelper.floor_float((float)var2 * var3); + if (var4 < MathHelper.ceiling_float_int((float)var2 * var3) && (float)Math.random() < (float)var2 * var3 - (float)var4) { + ++var4; + } + + var2 = var4; + } + + while(var2 > 0) { + var4 = EntityXPOrb.getXPSplit(var2); + var2 -= var4; + EntityXPOrb xp = new EntityXPOrb(super.worldObj, (double)((float)super.xCoord + lx), (double)((float)super.yCoord + 0.4F), (double)((float)super.zCoord + lz), var4); + mx = this.facingX == 0 ? (super.worldObj.rand.nextFloat() - super.worldObj.rand.nextFloat()) * 0.025F : (float)this.facingX * 0.13F; + mz = this.facingZ == 0 ? (super.worldObj.rand.nextFloat() - super.worldObj.rand.nextFloat()) * 0.025F : (float)this.facingZ * 0.13F; + xp.motionX = (double)mx; + xp.motionZ = (double)mz; + xp.motionY = 0.0D; + super.worldObj.spawnEntityInWorld(xp); + } + + } + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinTileArcaneWorkbenchRenderer.java b/src/main/java/dev/tilera/auracore/mixins/MixinTileArcaneWorkbenchRenderer.java new file mode 100644 index 0000000..559fa93 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinTileArcaneWorkbenchRenderer.java @@ -0,0 +1,39 @@ +package dev.tilera.auracore.mixins; + +import org.lwjgl.opengl.GL11; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import dev.tilera.auracore.api.IWand; +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.item.ItemStack; +import thaumcraft.client.renderers.tile.TileArcaneWorkbenchRenderer; +import thaumcraft.common.tiles.TileArcaneWorkbench; + +@Mixin(TileArcaneWorkbenchRenderer.class) +public abstract class MixinTileArcaneWorkbenchRenderer extends TileEntitySpecialRenderer { + + @Inject(method = "renderTileEntityAt", at = @At("TAIL"), remap = false) + protected void onRender(TileArcaneWorkbench table, double par2, double par4, double par6, float par8, CallbackInfo ci) { + if (table.getWorldObj() != null && table.getStackInSlot(10) != null && table.getStackInSlot(10).getItem() instanceof IWand) { + GL11.glPushMatrix(); + GL11.glTranslatef((float)par2 + 0.65F, (float)par4 + 1.0625F, (float)par6 + 0.25F); + GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F); //TODO: render in middle + //GL11.glRotatef(20.0F, 0.0F, 0.0F, 1.0F); + ItemStack is = table.getStackInSlot(10).copy(); + is.stackSize = 1; + EntityItem entityitem = new EntityItem(table.getWorldObj(), 0.0D, 0.0D, 0.0D, is); + entityitem.hoverStart = 0.0F; + RenderItem.renderInFrame = true; + RenderManager.instance.renderEntityWithPosYaw(entityitem, 0.0D, 0.0D, 0.0D, 0.0F, 0.0F); + RenderItem.renderInFrame = false; + GL11.glPopMatrix(); + } + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinTileCrucible.java b/src/main/java/dev/tilera/auracore/mixins/MixinTileCrucible.java new file mode 100644 index 0000000..1d7f696 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinTileCrucible.java @@ -0,0 +1,153 @@ +package dev.tilera.auracore.mixins; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import dev.tilera.auracore.api.IAlembic; +import dev.tilera.auracore.aura.AuraManager; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidTank; +import thaumcraft.api.TileThaumcraft; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.aspects.IAspectSource; +import thaumcraft.common.config.ConfigBlocks; +import thaumcraft.common.tiles.TileCrucible; + +@Mixin(TileCrucible.class) +public abstract class MixinTileCrucible extends TileThaumcraft implements IAspectSource { + + @Shadow(remap = false) + public short heat; + @Shadow(remap = false) + public AspectList aspects; + @Shadow(remap = false) + public FluidTank tank; + + /** + * @author tilera + * @reason Spill remnants to alembics and aura + */ + @Overwrite(remap = false) + public void spillRemnants() { + if (this.tank.getFluidAmount() > 0 || this.aspects.visSize() > 0) { + this.tank.setFluid(null); + this.heat = 0; + + for (int a = 2; a < 6; ++a) { + TileEntity tile = this.worldObj.getTileEntity( + this.xCoord + ForgeDirection.getOrientation((int) a).offsetX, + this.yCoord + ForgeDirection.getOrientation((int) a).offsetY, + this.zCoord + ForgeDirection.getOrientation((int) a).offsetZ); + if (tile == null || !(tile instanceof IAlembic)) + continue; + for (Aspect tag : this.aspects.getAspectsSortedAmount()) { + try { + int result; + if (tag == null || ((IAlembic) tile).containerContains(tag) <= 0 || (result = ((IAlembic) tile) + .addToContainer(tag, this.aspects.getAmount(tag))) == this.aspects.getAmount(tag)) + continue; + this.aspects.reduce(tag, this.aspects.getAmount(tag) - result); + } catch (Exception e) { + + } + } + } + for (int a = 2; a < 6; ++a) { + TileEntity tile = this.worldObj.getTileEntity( + this.xCoord + ForgeDirection.getOrientation((int) a).offsetX, + this.yCoord + ForgeDirection.getOrientation((int) a).offsetY, + this.zCoord + ForgeDirection.getOrientation((int) a).offsetZ); + if (tile == null || !(tile instanceof IAlembic)) + continue; + for (Aspect tag : this.aspects.getAspectsSortedAmount()) { + try { + int result; + if (tag == null || (result = ((IAlembic) tile).addToContainer(tag, + this.aspects.getAmount(tag))) == this.aspects.getAmount(tag)) + continue; + this.aspects.reduce(tag, this.aspects.getAmount(tag) - result); + } catch (Exception e) { + + } + } + } + AuraManager.addFluxToClosest(this.worldObj, (float) this.xCoord + 0.5f, (float) this.yCoord + 0.5f, + (float) this.zCoord + 0.5f, this.aspects); + + this.aspects = new AspectList(); + this.markDirty(); + super.worldObj.markBlockForUpdate(super.xCoord, super.yCoord, super.zCoord); + super.worldObj.addBlockEvent(super.xCoord, super.yCoord, super.zCoord, ConfigBlocks.blockMetalDevice, 2, 5); + } + + } + + /** + * @author tilera + * @reason Implement aspect container properly + */ + @Overwrite(remap = false) + public boolean takeFromContainer(Aspect tag, int amount) { + if (this.aspects.getAmount(tag) >= amount) { + this.aspects.reduce(tag, amount); + //this.spillNextTick = true; + this.markDirty(); + super.worldObj.markBlockForUpdate(super.xCoord, super.yCoord, super.zCoord); + return true; + } + return false; + } + + /** + * @author tilera + * @reason Implement aspect container properly + */ + @Overwrite(remap = false) + public boolean takeFromContainer(AspectList ot) { + if (this.doesContainerContain(ot)) { + for (Aspect tag : ot.getAspects()) { + this.aspects.reduce(tag, ot.getAmount(tag)); + //this.spillNextTick = true; + this.markDirty(); + super.worldObj.markBlockForUpdate(super.xCoord, super.yCoord, super.zCoord); + } + return true; + } + return false; + } + + /** + * @author tilera + * @reason Implement aspect container properly + */ + @Overwrite(remap = false) + public boolean doesContainerContainAmount(Aspect tag, int amount) { + return this.aspects.getAmount(tag) >= amount; + } + + /** + * @author tilera + * @reason Implement aspect container properly + */ + @Overwrite(remap = false) + public boolean doesContainerContain(AspectList ot) { + for (Aspect tag : this.aspects.getAspects()) { + if (this.aspects.getAmount(tag) > ot.getAmount(tag)) continue; + return false; + } + return true; + } + + /** + * @author tilera + * @reason Implement aspect container properly + */ + @Overwrite(remap = false) + public int containerContains(Aspect tag) { + return this.aspects.getAmount(tag); + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinTileCrystal.java b/src/main/java/dev/tilera/auracore/mixins/MixinTileCrystal.java new file mode 100644 index 0000000..bd9fe8b --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinTileCrystal.java @@ -0,0 +1,42 @@ +package dev.tilera.auracore.mixins; + +import java.util.Random; + +import org.spongepowered.asm.mixin.Mixin; + +import dev.tilera.auracore.aura.AuraManager; +import thaumcraft.api.TileThaumcraft; +import thaumcraft.common.tiles.TileCrystal; + +@Mixin(TileCrystal.class) +public abstract class MixinTileCrystal extends TileThaumcraft { + + private long count = System.currentTimeMillis() + (long)new Random().nextInt(300000); + + @Override + public boolean canUpdate() { + return true; + } + + @Override + public void updateEntity() { + super.updateEntity(); + if (this.worldObj.isRemote) { + return; + } + int md = this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord); + if (md == 7) { + return; + } + if (this.count <= System.currentTimeMillis()) { + try { + this.count = System.currentTimeMillis() + 300000L; + AuraManager.increaseLowestAuraWithLimit(this.worldObj, (float)this.xCoord + 0.5f, (float)this.yCoord + 0.5f, (float)this.zCoord + 0.5f, 1, 1.1f); + } + catch (Exception exception) { + + } + } + } + +} diff --git a/src/main/java/dev/tilera/auracore/mixins/MixinTileJarFillable.java b/src/main/java/dev/tilera/auracore/mixins/MixinTileJarFillable.java new file mode 100644 index 0000000..727e885 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/mixins/MixinTileJarFillable.java @@ -0,0 +1,30 @@ +package dev.tilera.auracore.mixins; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import dev.tilera.auracore.api.IEssenceContainer; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.common.tiles.TileJar; +import thaumcraft.common.tiles.TileJarFillable; + +@Mixin(TileJarFillable.class) +public abstract class MixinTileJarFillable extends TileJar implements IEssenceContainer { + + @Shadow(remap = false) + public Aspect aspect; + @Shadow(remap = false) + public int amount; + + @Override + public Aspect getAspect() { + return aspect; + } + + @Override + public int getAmount() { + return amount; + } + +} + diff --git a/src/main/java/dev/tilera/auracore/network/AuraDeletePacket.java b/src/main/java/dev/tilera/auracore/network/AuraDeletePacket.java new file mode 100644 index 0000000..1d2a3d8 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/network/AuraDeletePacket.java @@ -0,0 +1,27 @@ +package dev.tilera.auracore.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import dev.tilera.auracore.api.AuraNode; +import io.netty.buffer.ByteBuf; + +public class AuraDeletePacket implements IMessage { + + int key; + + public AuraDeletePacket() {} + + public AuraDeletePacket(AuraNode node) { + this.key = node.key; + } + + @Override + public void fromBytes(ByteBuf buf) { + key = buf.readInt(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(key); + } + +} diff --git a/src/main/java/dev/tilera/auracore/network/AuraDeletePacketHandler.java b/src/main/java/dev/tilera/auracore/network/AuraDeletePacketHandler.java new file mode 100644 index 0000000..3b9c4c0 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/network/AuraDeletePacketHandler.java @@ -0,0 +1,17 @@ +package dev.tilera.auracore.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import dev.tilera.auracore.client.AuraManagerClient; + +public class AuraDeletePacketHandler implements IMessageHandler { + + @Override + public IMessage onMessage(AuraDeletePacket message, MessageContext ctx) { + AuraManagerClient.auraClientList.remove(message.key); + AuraManagerClient.auraClientHistory.remove(message.key); + return null; + } + +} diff --git a/src/main/java/dev/tilera/auracore/network/AuraPacket.java b/src/main/java/dev/tilera/auracore/network/AuraPacket.java new file mode 100644 index 0000000..540ca07 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/network/AuraPacket.java @@ -0,0 +1,59 @@ +package dev.tilera.auracore.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import dev.tilera.auracore.api.AuraNode; +import io.netty.buffer.ByteBuf; + +public class AuraPacket implements IMessage { + + public int key; + public double x; + public double y; + public double z; + public short level; + public short base; + public int flux; + public boolean lock; + public byte type; + + public AuraPacket() {} + + public AuraPacket(AuraNode node) { + this.key = node.key; + this.x = node.xPos; + this.y = node.yPos; + this.z = node.zPos; + this.level = node.level; + this.base = node.baseLevel; + this.flux = node.flux.visSize(); + this.lock = node.locked; + this.type = (byte) node.type.ordinal(); + } + + @Override + public void fromBytes(ByteBuf buf) { + this.key = buf.readInt(); + this.x = buf.readDouble(); + this.y = buf.readDouble(); + this.z = buf.readDouble(); + this.level = buf.readShort(); + this.base = buf.readShort(); + this.flux = buf.readInt(); + this.lock = buf.readBoolean(); + this.type = buf.readByte(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(key); + buf.writeDouble(x); + buf.writeDouble(y); + buf.writeDouble(z); + buf.writeShort(level); + buf.writeShort(base); + buf.writeInt(flux); + buf.writeBoolean(lock); + buf.writeByte(type); + } + +} diff --git a/src/main/java/dev/tilera/auracore/network/AuraPacketHandler.java b/src/main/java/dev/tilera/auracore/network/AuraPacketHandler.java new file mode 100644 index 0000000..9cd70f8 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/network/AuraPacketHandler.java @@ -0,0 +1,27 @@ +package dev.tilera.auracore.network; + +import cpw.mods.fml.client.FMLClientHandler; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import dev.tilera.auracore.client.AuraManagerClient; +import dev.tilera.auracore.client.AuraManagerClient.NodeHistoryStats; +import dev.tilera.auracore.client.AuraManagerClient.NodeStats; +import net.minecraft.world.World; + +public class AuraPacketHandler implements IMessageHandler { + + @Override + public IMessage onMessage(AuraPacket message, MessageContext ctx) { + World world = FMLClientHandler.instance().getWorldClient(); + if (AuraManagerClient.auraClientHistory.get(message.key) != null) { + AuraManagerClient.auraClientHistory.put(message.key, new NodeHistoryStats(AuraManagerClient.auraClientList.get(message.key))); + } + AuraManagerClient.auraClientList.put(message.key, new NodeStats(message, world.provider.dimensionId)); + if (AuraManagerClient.auraClientHistory.get(message.key) == null) { + AuraManagerClient.auraClientHistory.put(message.key, new NodeHistoryStats(message.level, message.flux)); + } + return null; + } + +} diff --git a/src/main/java/dev/tilera/auracore/network/AuraTransferFXPacket.java b/src/main/java/dev/tilera/auracore/network/AuraTransferFXPacket.java new file mode 100644 index 0000000..351ff4f --- /dev/null +++ b/src/main/java/dev/tilera/auracore/network/AuraTransferFXPacket.java @@ -0,0 +1,47 @@ +package dev.tilera.auracore.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import dev.tilera.auracore.api.AuraNode; +import io.netty.buffer.ByteBuf; + +public class AuraTransferFXPacket implements IMessage { + + double x; + double y; + double z; + double targetX; + double targetY; + double targetZ; + + public AuraTransferFXPacket() {} + + public AuraTransferFXPacket(AuraNode node, AuraNode targetNode) { + this.x = node.xPos; + this.y = node.yPos; + this.z = node.zPos; + this.targetX = targetNode.xPos; + this.targetY = targetNode.yPos; + this.targetZ = targetNode.zPos; + } + + @Override + public void fromBytes(ByteBuf buf) { + x = buf.readDouble(); + y = buf.readDouble(); + z = buf.readDouble(); + targetX = buf.readDouble(); + targetY = buf.readDouble(); + targetZ = buf.readDouble(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeDouble(x); + buf.writeDouble(y); + buf.writeDouble(z); + buf.writeDouble(targetX); + buf.writeDouble(targetY); + buf.writeDouble(targetZ); + } + +} diff --git a/src/main/java/dev/tilera/auracore/network/AuraTransferFXPacketHandler.java b/src/main/java/dev/tilera/auracore/network/AuraTransferFXPacketHandler.java new file mode 100644 index 0000000..5814020 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/network/AuraTransferFXPacketHandler.java @@ -0,0 +1,32 @@ +package dev.tilera.auracore.network; + +import cpw.mods.fml.client.FMLClientHandler; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import dev.tilera.auracore.client.FXSparkle; +import dev.tilera.auracore.helper.Utils; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.MathHelper; + +public class AuraTransferFXPacketHandler implements IMessageHandler { + + @Override + public IMessage onMessage(AuraTransferFXPacket message, MessageContext ctx) { + EntityPlayer player = FMLClientHandler.instance().getClientPlayerEntity(); + if (Utils.hasGoggles(player)) { + double var7 = message.x - message.targetX; + double var9 = message.y - message.targetY; + double var11 = message.z - message.targetZ; + int distance = (int)MathHelper.sqrt_double((double)(var7 * var7 + var9 * var9 + var11 * var11)); + FXSparkle fx = new FXSparkle(player.worldObj, message.x, message.y, message.z, message.targetX, message.targetY, message.targetZ, 2.5f, 0, distance / 2); + fx.slowdown = false; + fx.noClip = true; + fx.leyLineEffect = true; + fx.shrink = false; + FMLClientHandler.instance().getClient().effectRenderer.addEffect(fx); + } + return null; + } + +} diff --git a/src/main/java/dev/tilera/auracore/network/NodeZapPacket.java b/src/main/java/dev/tilera/auracore/network/NodeZapPacket.java new file mode 100644 index 0000000..84a20a6 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/network/NodeZapPacket.java @@ -0,0 +1,39 @@ +package dev.tilera.auracore.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.Entity; + +public class NodeZapPacket implements IMessage { + + public double x; + public double y; + public double z; + public int entityID; + + public NodeZapPacket() {} + + public NodeZapPacket(double x, double y, double z, Entity target) { + this.x = x; + this.y = y; + this.z = z; + this.entityID = target.getEntityId(); + } + + @Override + public void fromBytes(ByteBuf buf) { + this.x = buf.readDouble(); + this.y = buf.readDouble(); + this.z = buf.readDouble(); + this.entityID = buf.readInt(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeDouble(x); + buf.writeDouble(y); + buf.writeDouble(z); + buf.writeInt(entityID); + } + +} diff --git a/src/main/java/dev/tilera/auracore/network/NodeZapPacketHandler.java b/src/main/java/dev/tilera/auracore/network/NodeZapPacketHandler.java new file mode 100644 index 0000000..7017be2 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/network/NodeZapPacketHandler.java @@ -0,0 +1,26 @@ +package dev.tilera.auracore.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.world.World; +import thaumcraft.client.fx.bolt.FXLightningBolt; + +public class NodeZapPacketHandler implements IMessageHandler { + + @Override + public IMessage onMessage(NodeZapPacket message, MessageContext ctx) { + World world = Minecraft.getMinecraft().theWorld; + Entity targetedEntity = world.getEntityByID(message.entityID); + if (targetedEntity != null) { + FXLightningBolt bolt = new FXLightningBolt(world, message.x, message.y, message.z, targetedEntity.posX, targetedEntity.posY, targetedEntity.posZ, world.rand.nextLong(), 10, 2.0f, 5); + bolt.defaultFractal(); + bolt.setType(3); + bolt.finalizeBolt(); + } + return null; + } + +} diff --git a/src/main/java/dev/tilera/auracore/world/WorldGenSilverwoodTreesOld.java b/src/main/java/dev/tilera/auracore/world/WorldGenSilverwoodTreesOld.java new file mode 100644 index 0000000..c01ac41 --- /dev/null +++ b/src/main/java/dev/tilera/auracore/world/WorldGenSilverwoodTreesOld.java @@ -0,0 +1,312 @@ +package dev.tilera.auracore.world; + +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; +import thaumcraft.common.config.ConfigBlocks; + +public class WorldGenSilverwoodTreesOld extends WorldGenerator { + static final byte[] otherCoordPairs = new byte[]{2, 0, 0, 1, 2, 1}; + Random rand = new Random(); + World worldObj; + int[] basePos = new int[]{0, 0, 0}; + int heightLimit = 0; + int height; + double heightAttenuation = 0.618; + double branchDensity = 1.0; + double branchSlope = -0.3; + double scaleWidth = 1.0; + double leafDensity = 1.5; + int trunkSize = 1; + int heightLimitLimit = 5; + int leafDistanceLimit = 4; + int[][] leafNodes; + + public WorldGenSilverwoodTreesOld(boolean par1) { + super(par1); + } + + void generateLeafNodeList() { + int var1; + this.height = (int)((double)this.heightLimit * this.heightAttenuation); + if (this.height >= this.heightLimit) { + this.height = this.heightLimit - 1; + } + if ((var1 = (int)(1.382 + Math.pow(this.leafDensity * (double)this.heightLimit / 13.0, 2.0))) < 1) { + var1 = 1; + } + int[][] var2 = new int[var1 * this.heightLimit][4]; + int var3 = this.basePos[1] + this.heightLimit - this.leafDistanceLimit; + int var4 = 1; + int var5 = this.basePos[1] + this.height; + int var6 = var3 - this.basePos[1]; + var2[0][0] = this.basePos[0]; + var2[0][1] = var3--; + var2[0][2] = this.basePos[2]; + var2[0][3] = var5; + while (var6 >= 0) { + float var8 = this.layerSize(var6); + if (var8 < 0.0f) { + --var3; + --var6; + continue; + } + double var9 = 0.5; + for (int var7 = 0; var7 < var1; ++var7) { + double var11 = this.scaleWidth * (double)var8 * ((double)this.rand.nextFloat() + 0.328); + double var13 = (double)this.rand.nextFloat() * 2.0 * Math.PI; + int var15 = MathHelper.floor_double((double)(var11 * Math.sin(var13) + (double)this.basePos[0] + var9)); + int var16 = MathHelper.floor_double((double)(var11 * Math.cos(var13) + (double)this.basePos[2] + var9)); + int[] var17 = new int[]{var15, var3, var16}; + int[] var18 = new int[]{var15, var3 + this.leafDistanceLimit, var16}; + if (this.checkBlockLine(var17, var18) != -1) continue; + int[] var19 = new int[]{this.basePos[0], this.basePos[1], this.basePos[2]}; + double var20 = Math.sqrt(Math.pow(Math.abs(this.basePos[0] - var17[0]), 2.0) + Math.pow(Math.abs(this.basePos[2] - var17[2]), 2.0)); + double var22 = var20 * this.branchSlope; + var19[1] = (double)var17[1] - var22 > (double)var5 ? var5 : (int)((double)var17[1] - var22); + if (this.checkBlockLine(var19, var17) != -1) continue; + var2[var4][0] = var15; + var2[var4][1] = var3; + var2[var4][2] = var16; + var2[var4][3] = var19[1]; + ++var4; + } + --var3; + --var6; + } + this.leafNodes = new int[var4][4]; + System.arraycopy(var2, 0, this.leafNodes, 0, var4); + } + + void genTreeLayer(int par1, int par2, int par3, float par4, byte par5, Block par6) { + int var7 = (int)((double)par4 + 0.618); + byte var8 = otherCoordPairs[par5]; + byte var9 = otherCoordPairs[par5 + 3]; + int[] var10 = new int[]{par1, par2, par3}; + int[] var11 = new int[]{0, 0, 0}; + int var13 = -var7; + var11[par5] = var10[par5]; + for (int var12 = -var7; var12 <= var7; ++var12) { + var11[var8] = var10[var8] + var12; + var13 = -var7; + while (var13 <= var7) { + double var15 = Math.pow((double)Math.abs(var12) + 0.5, 2.0) + Math.pow((double)Math.abs(var13) + 0.5, 2.0); + if (var15 > (double)(par4 * par4)) { + ++var13; + continue; + } + var11[var9] = var10[var9] + var13; + Block block = this.worldObj.getBlock(var11[0], var11[1], var11[2]); + if (!(block != Blocks.air && block != ConfigBlocks.blockMagicalLeaves || block != null && !block.canBeReplacedByLeaves(this.worldObj, var11[0], var11[1], var11[2]))) { + this.setBlockAndNotifyAdequately(this.worldObj, var11[0], var11[1], var11[2], par6, 1); + } + ++var13; + } + } + } + + float layerSize(int par1) { + if ((double)par1 < (double)this.heightLimit * 0.3) { + return -1.618f; + } + float var2 = (float)this.heightLimit / 2.0f; + float var3 = (float)this.heightLimit / 2.0f - (float)par1; + float var4 = var3 == 0.0f ? var2 : (Math.abs(var3) >= var2 ? 0.0f : (float)Math.sqrt(Math.pow(Math.abs(var2), 2.0) - Math.pow(Math.abs(var3), 2.0))); + return var4 *= 0.5f; + } + + float leafSize(int par1) { + return par1 >= 0 && par1 < this.leafDistanceLimit ? (par1 != 0 && par1 != this.leafDistanceLimit - 1 ? 3.0f : 2.0f) : -1.0f; + } + + void generateLeafNode(int par1, int par2, int par3) { + int var5 = par2 + this.leafDistanceLimit; + for (int var4 = par2; var4 < var5; ++var4) { + float var6 = this.leafSize(var4 - par2); + this.genTreeLayer(par1, var4, par3, var6, (byte)1, ConfigBlocks.blockMagicalLeaves); + } + } + + void placeBlockLine(int[] par1ArrayOfInteger, int[] par2ArrayOfInteger, Block par3) { + int[] var4 = new int[]{0, 0, 0}; + int var6 = 0; + for (int var5 = 0; var5 < 3; var5 = (int)((byte)(var5 + 1))) { + var4[var5] = par2ArrayOfInteger[var5] - par1ArrayOfInteger[var5]; + if (Math.abs(var4[var5]) <= Math.abs(var4[var6])) continue; + var6 = var5; + } + if (var4[var6] != 0) { + byte var7 = otherCoordPairs[var6]; + byte var8 = otherCoordPairs[var6 + 3]; + int var9 = var4[var6] > 0 ? 1 : -1; + double var10 = (double)var4[var7] / (double)var4[var6]; + double var12 = (double)var4[var8] / (double)var4[var6]; + int[] var14 = new int[]{0, 0, 0}; + int var16 = var4[var6] + var9; + for (int var15 = 0; var15 != var16; var15 += var9) { + int var19; + var14[var6] = MathHelper.floor_double((double)((double)(par1ArrayOfInteger[var6] + var15) + 0.5)); + var14[var7] = MathHelper.floor_double((double)((double)par1ArrayOfInteger[var7] + (double)var15 * var10 + 0.5)); + var14[var8] = MathHelper.floor_double((double)((double)par1ArrayOfInteger[var8] + (double)var15 * var12 + 0.5)); + int var17 = 0; + int var18 = Math.abs(var14[0] - par1ArrayOfInteger[0]); + int var20 = Math.max(var18, var19 = Math.abs(var14[2] - par1ArrayOfInteger[2])); + if (var20 > 0) { + if (var18 == var20) { + var17 = 4; + } else if (var19 == var20) { + var17 = 8; + } + } + this.setBlockAndNotifyAdequately(this.worldObj, var14[0], var14[1], var14[2], par3, var17 + 1); + } + } + } + + void generateLeaves() { + int var2 = this.leafNodes.length; + for (int var1 = 0; var1 < var2; ++var1) { + int var3 = this.leafNodes[var1][0]; + int var4 = this.leafNodes[var1][1]; + int var5 = this.leafNodes[var1][2]; + this.generateLeafNode(var3, var4, var5); + } + } + + boolean leafNodeNeedsBase(int par1) { + return (double)par1 >= (double)this.heightLimit * 0.2; + } + + void generateTrunk() { + int var1 = this.basePos[0]; + int var2 = this.basePos[1]; + int var3 = this.basePos[1] + this.height; + int var4 = this.basePos[2]; + int[] var5 = new int[]{var1, var2, var4}; + int[] var6 = new int[]{var1, var3, var4}; + this.placeBlockLine(var5, var6, ConfigBlocks.blockMagicalLog); + if (this.trunkSize == 2) { + var5[0] = var5[0] + 1; + var6[0] = var6[0] + 1; + this.placeBlockLine(var5, var6, ConfigBlocks.blockMagicalLog); + var5[2] = var5[2] + 1; + var6[2] = var6[2] + 1; + this.placeBlockLine(var5, var6, ConfigBlocks.blockMagicalLog); + var5[0] = var5[0] + -1; + var6[0] = var6[0] + -1; + this.placeBlockLine(var5, var6, ConfigBlocks.blockMagicalLog); + } + } + + void generateLeafNodeBases() { + int var2 = this.leafNodes.length; + int[] var3 = new int[]{this.basePos[0], this.basePos[1], this.basePos[2]}; + for (int var1 = 0; var1 < var2; ++var1) { + int[] var4 = this.leafNodes[var1]; + int[] var5 = new int[]{var4[0], var4[1], var4[2]}; + var3[1] = var4[3]; + int var6 = var3[1] - this.basePos[1]; + if (!this.leafNodeNeedsBase(var6)) continue; + this.placeBlockLine(var3, var5, ConfigBlocks.blockMagicalLog); + } + } + + int checkBlockLine(int[] par1ArrayOfInteger, int[] par2ArrayOfInteger) { + int var14; + int[] var3 = new int[]{0, 0, 0}; + int var5 = 0; + for (int var4 = 0; var4 < 3; var4 = (int)((byte)(var4 + 1))) { + var3[var4] = par2ArrayOfInteger[var4] - par1ArrayOfInteger[var4]; + if (Math.abs(var3[var4]) <= Math.abs(var3[var5])) continue; + var5 = var4; + } + if (var3[var5] == 0) { + return -1; + } + byte var6 = otherCoordPairs[var5]; + byte var7 = otherCoordPairs[var5 + 3]; + int var8 = var3[var5] > 0 ? 1 : -1; + double var9 = (double)var3[var6] / (double)var3[var5]; + double var11 = (double)var3[var7] / (double)var3[var5]; + int[] var13 = new int[]{0, 0, 0}; + int var15 = var3[var5] + var8; + for (var14 = 0; var14 != var15; var14 += var8) { + var13[var5] = par1ArrayOfInteger[var5] + var14; + var13[var6] = MathHelper.floor_double((double)((double)par1ArrayOfInteger[var6] + (double)var14 * var9)); + var13[var7] = MathHelper.floor_double((double)((double)par1ArrayOfInteger[var7] + (double)var14 * var11)); + Block var16 = this.worldObj.getBlock(var13[0], var13[1], var13[2]); + if (var16 != Blocks.air && var16 != ConfigBlocks.blockMagicalLeaves) break; + } + return var14 == var15 ? -1 : Math.abs(var14); + } + + boolean validTreeLocation(int x, int z) { + int[] var1 = new int[]{this.basePos[0] + x, this.basePos[1], this.basePos[2] + z}; + int[] var2 = new int[]{this.basePos[0] + x, this.basePos[1] + this.heightLimit - 1, this.basePos[2] + z}; + Block var3 = this.worldObj.getBlock(this.basePos[0] + x, this.basePos[1] - 1, this.basePos[2] + z); + if (var3 != Blocks.grass && var3 != Blocks.dirt) { + return false; + } + int var4 = this.checkBlockLine(var1, var2); + if (var4 == -1) { + return true; + } + if (var4 < 6) { + return false; + } + this.heightLimit = var4; + return true; + } + + public void setScale(double par1, double par3, double par5) { + this.heightLimitLimit = (int)(par1 * 12.0); + if (par1 > 0.5) { + this.leafDistanceLimit = 5; + } + this.scaleWidth = par3; + this.leafDensity = par5; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + this.worldObj = par1World; + long var6 = par2Random.nextLong(); + this.rand.setSeed(var6); + this.basePos[0] = par3; + this.basePos[1] = par4; + this.basePos[2] = par5; + if (this.heightLimit == 0) { + this.heightLimit = this.heightLimitLimit + this.rand.nextInt(this.heightLimitLimit); + } + int x = 0; + int z = 0; + for (x = 0; x < this.trunkSize; ++x) { + for (z = 0; z < this.trunkSize; ++z) { + if (this.validTreeLocation(x, z)) continue; + return false; + } + } + this.generateLeafNodeList(); + this.generateLeaves(); + this.generateTrunk(); + this.generateLeafNodeBases(); + this.basePos[0] = par3; + this.basePos[1] = par4 + this.height; + this.basePos[2] = par5; + this.generateLeafNodeList(); + this.generateLeaves(); + this.generateTrunk(); + this.generateLeafNodeBases(); + this.basePos[0] = par3; + this.basePos[1] = par4 + this.height * 2; + this.basePos[2] = par5; + this.generateLeafNodeList(); + this.generateLeaves(); + this.generateTrunk(); + this.generateLeafNodeBases(); + return true; + } +} diff --git a/src/main/java/dev/tilera/auracore/world/WorldGenerator.java b/src/main/java/dev/tilera/auracore/world/WorldGenerator.java new file mode 100644 index 0000000..7b48f6f --- /dev/null +++ b/src/main/java/dev/tilera/auracore/world/WorldGenerator.java @@ -0,0 +1,165 @@ +package dev.tilera.auracore.world; + +import java.util.HashMap; +import java.util.Random; + +import cpw.mods.fml.common.IWorldGenerator; +import dev.tilera.auracore.api.EnumNodeType; +import dev.tilera.auracore.aura.AuraManager; +import dev.tilera.auracore.aura.NodeIdStorage; +import dev.tilera.auracore.helper.Utils; +import net.minecraft.init.Blocks; +import net.minecraft.util.MathHelper; +import net.minecraft.world.ChunkPosition; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.IChunkProvider; +import net.minecraft.world.gen.structure.MapGenScatteredFeature; +import thaumcraft.common.config.ConfigBlocks; +import thaumcraft.common.lib.world.WorldGenHilltopStones; +import thaumcraft.common.lib.world.WorldGenMound; + +public class WorldGenerator implements IWorldGenerator { + + HashMap structureNode = new HashMap<>(); + + @Override + public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) { + this.worldGeneration(random, chunkX, chunkZ, world, true); + } + + public void worldGeneration(Random random, int chunkX, int chunkZ, World world, boolean newGen) { + if (AuraManager.nodeIdStore == null) { + AuraManager.nodeIdStore = new NodeIdStorage(world.getSaveHandler()); + } + switch (world.provider.dimensionId) { + case -1: { + this.generateNether(world, random, chunkX, chunkZ, newGen); + break; + } + case 1: { + break; + } + default: { + this.generateSurface(world, random, chunkX, chunkZ, newGen); + } + } + if (!newGen) { + world.getChunkFromChunkCoords(chunkX, chunkZ).setChunkModified(); + } + } + + private void generateSurface(World world, Random random, int chunkX, int chunkZ, boolean newGen) { + boolean auraGen = false; + if (!world.getWorldInfo().getTerrainType().getWorldTypeName().startsWith("flat") && newGen) { + int randPosX2 = chunkX * 16 + random.nextInt(16); + int randPosZ2 = chunkZ * 16 + random.nextInt(16); + int randPosY = world.getHeightValue(randPosX2, randPosZ2) - 9; + Chunk var1 = world.getChunkFromBlockCoords(MathHelper.floor_double((double)randPosX2), MathHelper.floor_double((double)randPosZ2)); + WorldGenMound mound = new WorldGenMound(); + if (var1.getRandomWithSeed(957234911L).nextInt(100) == 0 && !AuraManager.specificAuraTypeNearby(world.provider.dimensionId, randPosX2 + 9, randPosY + 8, randPosZ2 + 9, EnumNodeType.DARK, 250)) { + if (mound.generate(world, random, randPosX2, randPosY, randPosZ2)) { + auraGen = true; + int value = random.nextInt(200) + 400; + AuraManager.registerAuraNode(world, (short)value, EnumNodeType.DARK, world.provider.dimensionId, randPosX2 + 9, randPosY + 8, randPosZ2 + 9); + } + } else { + WorldGenHilltopStones hilltopStones = new WorldGenHilltopStones(); + if (random.nextInt(3) == 0 && !AuraManager.specificAuraTypeNearby(world.provider.dimensionId, randPosX2, randPosY += 9, randPosZ2, EnumNodeType.UNSTABLE, 250) && hilltopStones.generate(world, random, randPosX2, randPosY, randPosZ2)) { + auraGen = true; + int value = random.nextInt(200) + 400; + AuraManager.registerAuraNode(world, (short)value, EnumNodeType.UNSTABLE, world.provider.dimensionId, randPosX2, randPosY + 5, randPosZ2); + } + } + } + if (newGen) { + ChunkPosition var7 = (new MapGenScatteredFeature()).func_151545_a(world, chunkX * 16 + 8, world.getHeightValue(chunkX * 16 + 8, chunkZ * 16 + 8), chunkZ * 16 + 8); + if (var7 != null && !this.structureNode.containsKey(var7.hashCode())) { + auraGen = true; + this.structureNode.put(var7.hashCode(), true); + int value = random.nextInt(200) + 800; + AuraManager.registerAuraNode(world, (short)value, EnumNodeType.NORMAL, world.provider.dimensionId, var7.chunkPosX, world.getHeightValue(var7.chunkPosX, var7.chunkPosZ) + 3, var7.chunkPosZ); + } + auraGen = this.generateAura(world, random, chunkX, chunkZ, auraGen, newGen); + } + } + + private void generateNether(World world, Random random, int chunkX, int chunkZ, boolean newGen) { + if (newGen) { + this.generateAura(world, random, chunkX, chunkZ, false, newGen); + } + } + + private boolean generateAura(World world, Random random, int chunkX, int chunkZ, boolean auraGen, boolean newGen) { + if (random.nextInt(/*Config.nodeRarity*/23) == 0 && !auraGen) { + int y; + int p; + int z; + int q; + int x = chunkX * 16 + random.nextInt(16); + if (world.isAirBlock(x, (q = Utils.getFirstUncoveredY(world, x, z = chunkZ * 16 + random.nextInt(16))) + 1, z)) { + ++q; + } + if (world.isAirBlock(x, q + (p = random.nextInt(6)), z)) { + q += p; + if (p == 5) { + p = random.nextInt(5); + } + if (world.isAirBlock(x, q + p, z)) { + q += p; + } + } + if (AuraManager.auraNearby(world.provider.dimensionId, x, y = q, z, 64)) { + return false; + } + BiomeGenBase bg = world.getBiomeGenForCoords(x, z); + boolean bbase = false; + int value = random.nextInt(/*BiomeHandler.getBiomeAura(bg)*/400 / 2) + /*BiomeHandler.getBiomeAura(bg)*/400 / 2; + EnumNodeType type = EnumNodeType.NORMAL; + if (random.nextInt(/*Config.specialNodeRarity*/75) == 0) { + switch (random.nextInt(3)) { + case 0: { + type = EnumNodeType.PURE; + break; + } + case 1: { + type = EnumNodeType.DARK; + break; + } + case 2: { + type = EnumNodeType.UNSTABLE; + } + } + } + if (newGen && random.nextInt(type != EnumNodeType.NORMAL ? 2 : (world.provider.dimensionId == -1 ? 2 : 6)) == 0) { + int topy; + int n = topy = world.provider.dimensionId == -1 ? Utils.getFirstUncoveredY(world, x, z) - 1 : world.getHeightValue(x, z) - 1; + if (world.getBlock(x, topy, z) != null && world.getBlock(x, topy, z).isLeaves(world, x, topy, z)) { + while (world.getBlock(x, --topy, z) != Blocks.grass && topy > 40) { + } + } + if (world.getBlock(x, topy, z) == Blocks.snow_layer || world.getBlock(x, topy, z) == Blocks.tallgrass) { + --topy; + } + if (world.getBlock(x, topy, z) == Blocks.grass || world.getBlock(x, topy, z) == Blocks.sand || world.getBlock(x, topy, z) == Blocks.dirt || world.getBlock(x, topy, z) == Blocks.stone || world.getBlock(x, topy, z) == Blocks.netherrack) { + int count; + for (count = 1; (world.isAirBlock(x, topy + count, z) || world.getBlock(x, topy, z) == Blocks.snow_layer || world.getBlock(x, topy, z) == Blocks.tallgrass) && count < 3; ++count) { + } + if (count >= 2) { + world.setBlock(x, topy, z, ConfigBlocks.blockCosmeticSolid, 1, 3); + for (count = 1; (world.isAirBlock(x, topy + count, z) || world.getBlock(x, topy, z) == Blocks.snow_layer || world.getBlock(x, topy, z) == Blocks.tallgrass) && count < 5; ++count) { + world.setBlock(x, topy + count, z, ConfigBlocks.blockCosmeticSolid, 0, 3); + if (count <= 1 || random.nextInt(4) != 0) continue; + count = 5; + } + } + } + } + AuraManager.registerAuraNode(world, (short)value, type, world.provider.dimensionId, x, y, z); + return true; + } + return false; + } + +} diff --git a/src/main/resources/assets/auracore/lang/en_US.lang b/src/main/resources/assets/auracore/lang/en_US.lang new file mode 100644 index 0000000..9558926 --- /dev/null +++ b/src/main/resources/assets/auracore/lang/en_US.lang @@ -0,0 +1,6 @@ +item.ItemShard.7.name=Vis Shard +item.ItemShard.8.name=Dull Shard +item.ItemShard.9.name=Tainted Shard +tile.blockCustomOre.8.name=Vis Infused Ore +tile.blockCustomOre.9.name=Dull Ore +tile.blockCustomOre.10.name=Tainted Ore \ No newline at end of file diff --git a/src/main/resources/assets/auracore/textures/aspects/14.png b/src/main/resources/assets/auracore/textures/aspects/14.png new file mode 100644 index 0000000..f2c7488 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/14.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/41.png b/src/main/resources/assets/auracore/textures/aspects/41.png new file mode 100644 index 0000000..bc966b3 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/41.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/51.png b/src/main/resources/assets/auracore/textures/aspects/51.png new file mode 100644 index 0000000..a98e439 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/51.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/aer.png b/src/main/resources/assets/auracore/textures/aspects/aer.png new file mode 100644 index 0000000..5e67692 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/aer.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/alienis.png b/src/main/resources/assets/auracore/textures/aspects/alienis.png new file mode 100644 index 0000000..38f3b2b Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/alienis.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/animus.png b/src/main/resources/assets/auracore/textures/aspects/animus.png new file mode 100644 index 0000000..cb649d8 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/animus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/aqua.png b/src/main/resources/assets/auracore/textures/aspects/aqua.png new file mode 100644 index 0000000..164f5d3 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/aqua.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/aura.png b/src/main/resources/assets/auracore/textures/aspects/aura.png new file mode 100644 index 0000000..8619549 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/aura.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/bestia.png b/src/main/resources/assets/auracore/textures/aspects/bestia.png new file mode 100644 index 0000000..32ee000 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/bestia.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/bestiola.png b/src/main/resources/assets/auracore/textures/aspects/bestiola.png new file mode 100644 index 0000000..5653bb2 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/bestiola.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/carus.png b/src/main/resources/assets/auracore/textures/aspects/carus.png new file mode 100644 index 0000000..39ead29 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/carus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/cognitio.png b/src/main/resources/assets/auracore/textures/aspects/cognitio.png new file mode 100644 index 0000000..9b64d41 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/cognitio.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/corpus.png b/src/main/resources/assets/auracore/textures/aspects/corpus.png new file mode 100644 index 0000000..dc015b6 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/corpus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/fabrico.png b/src/main/resources/assets/auracore/textures/aspects/fabrico.png new file mode 100644 index 0000000..d90389b Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/fabrico.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/flos.png b/src/main/resources/assets/auracore/textures/aspects/flos.png new file mode 100644 index 0000000..3fbd387 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/flos.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/fractus.png b/src/main/resources/assets/auracore/textures/aspects/fractus.png new file mode 100644 index 0000000..ab8e5c7 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/fractus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/fungus.png b/src/main/resources/assets/auracore/textures/aspects/fungus.png new file mode 100644 index 0000000..a885d0f Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/fungus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/gelum.png b/src/main/resources/assets/auracore/textures/aspects/gelum.png new file mode 100644 index 0000000..e059582 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/gelum.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/herba.png b/src/main/resources/assets/auracore/textures/aspects/herba.png new file mode 100644 index 0000000..6ed3fe5 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/herba.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/ignis.png b/src/main/resources/assets/auracore/textures/aspects/ignis.png new file mode 100644 index 0000000..b144a53 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/ignis.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/imperito.png b/src/main/resources/assets/auracore/textures/aspects/imperito.png new file mode 100644 index 0000000..71c494e Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/imperito.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/instrumentum.png b/src/main/resources/assets/auracore/textures/aspects/instrumentum.png new file mode 100644 index 0000000..0949fb7 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/instrumentum.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/lignum.png b/src/main/resources/assets/auracore/textures/aspects/lignum.png new file mode 100644 index 0000000..7777d53 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/lignum.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/lux.png b/src/main/resources/assets/auracore/textures/aspects/lux.png new file mode 100644 index 0000000..d682121 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/lux.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/machina.png b/src/main/resources/assets/auracore/textures/aspects/machina.png new file mode 100644 index 0000000..74ef613 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/machina.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/malum.png b/src/main/resources/assets/auracore/textures/aspects/malum.png new file mode 100644 index 0000000..b206740 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/malum.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/messis.png b/src/main/resources/assets/auracore/textures/aspects/messis.png new file mode 100644 index 0000000..fb75556 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/messis.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/metallum.png b/src/main/resources/assets/auracore/textures/aspects/metallum.png new file mode 100644 index 0000000..8be1088 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/metallum.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/mortuus.png b/src/main/resources/assets/auracore/textures/aspects/mortuus.png new file mode 100644 index 0000000..71abb19 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/mortuus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/motus.png b/src/main/resources/assets/auracore/textures/aspects/motus.png new file mode 100644 index 0000000..401e462 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/motus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/mutatio.png b/src/main/resources/assets/auracore/textures/aspects/mutatio.png new file mode 100644 index 0000000..4c2ed36 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/mutatio.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/pannus.png b/src/main/resources/assets/auracore/textures/aspects/pannus.png new file mode 100644 index 0000000..1e403e1 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/pannus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/permutatio.png b/src/main/resources/assets/auracore/textures/aspects/permutatio.png new file mode 100644 index 0000000..ed2dd71 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/permutatio.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/potentia.png b/src/main/resources/assets/auracore/textures/aspects/potentia.png new file mode 100644 index 0000000..e951337 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/potentia.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/praecantatio.png b/src/main/resources/assets/auracore/textures/aspects/praecantatio.png new file mode 100644 index 0000000..7ed387d Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/praecantatio.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/purus.png b/src/main/resources/assets/auracore/textures/aspects/purus.png new file mode 100644 index 0000000..e3d6307 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/purus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/sano.png b/src/main/resources/assets/auracore/textures/aspects/sano.png new file mode 100644 index 0000000..e8d7055 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/sano.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/saxum.png b/src/main/resources/assets/auracore/textures/aspects/saxum.png new file mode 100644 index 0000000..665b58a Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/saxum.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/solum.png b/src/main/resources/assets/auracore/textures/aspects/solum.png new file mode 100644 index 0000000..6c91bb5 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/solum.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/sonus.png b/src/main/resources/assets/auracore/textures/aspects/sonus.png new file mode 100644 index 0000000..b8e2ac6 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/sonus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/telum.png b/src/main/resources/assets/auracore/textures/aspects/telum.png new file mode 100644 index 0000000..b5a9ce7 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/telum.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/tempus.png b/src/main/resources/assets/auracore/textures/aspects/tempus.png new file mode 100644 index 0000000..4d66a05 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/tempus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/tenebris.png b/src/main/resources/assets/auracore/textures/aspects/tenebris.png new file mode 100644 index 0000000..cb03f6b Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/tenebris.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/tutamen.png b/src/main/resources/assets/auracore/textures/aspects/tutamen.png new file mode 100644 index 0000000..ef427fd Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/tutamen.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/vacuos.png b/src/main/resources/assets/auracore/textures/aspects/vacuos.png new file mode 100644 index 0000000..61443e9 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/vacuos.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/venenum.png b/src/main/resources/assets/auracore/textures/aspects/venenum.png new file mode 100644 index 0000000..1e7eef8 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/venenum.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/victus.png b/src/main/resources/assets/auracore/textures/aspects/victus.png new file mode 100644 index 0000000..03bb8c9 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/victus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/vinculum.png b/src/main/resources/assets/auracore/textures/aspects/vinculum.png new file mode 100644 index 0000000..ba0aa36 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/vinculum.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/visum.png b/src/main/resources/assets/auracore/textures/aspects/visum.png new file mode 100644 index 0000000..65558ee Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/visum.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/vitreus.png b/src/main/resources/assets/auracore/textures/aspects/vitreus.png new file mode 100644 index 0000000..d711718 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/vitreus.png differ diff --git a/src/main/resources/assets/auracore/textures/aspects/volito.png b/src/main/resources/assets/auracore/textures/aspects/volito.png new file mode 100644 index 0000000..a245bb7 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/aspects/volito.png differ diff --git a/src/main/resources/assets/auracore/textures/gui/gui_arcaneworkbench.png b/src/main/resources/assets/auracore/textures/gui/gui_arcaneworkbench.png new file mode 100644 index 0000000..7adaf70 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/gui/gui_arcaneworkbench.png differ diff --git a/src/main/resources/assets/auracore/textures/gui/guiresearchtable.png b/src/main/resources/assets/auracore/textures/gui/guiresearchtable.png new file mode 100644 index 0000000..91ffb09 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/gui/guiresearchtable.png differ diff --git a/src/main/resources/assets/auracore/textures/misc/aura_1.png b/src/main/resources/assets/auracore/textures/misc/aura_1.png new file mode 100644 index 0000000..4a2e7be Binary files /dev/null and b/src/main/resources/assets/auracore/textures/misc/aura_1.png differ diff --git a/src/main/resources/assets/auracore/textures/misc/aura_2.png b/src/main/resources/assets/auracore/textures/misc/aura_2.png new file mode 100644 index 0000000..4349def Binary files /dev/null and b/src/main/resources/assets/auracore/textures/misc/aura_2.png differ diff --git a/src/main/resources/assets/auracore/textures/misc/aura_3.png b/src/main/resources/assets/auracore/textures/misc/aura_3.png new file mode 100644 index 0000000..c206ade Binary files /dev/null and b/src/main/resources/assets/auracore/textures/misc/aura_3.png differ diff --git a/src/main/resources/assets/auracore/textures/misc/aura_lock.png b/src/main/resources/assets/auracore/textures/misc/aura_lock.png new file mode 100644 index 0000000..2d6f35d Binary files /dev/null and b/src/main/resources/assets/auracore/textures/misc/aura_lock.png differ diff --git a/src/main/resources/assets/auracore/textures/misc/chaos.png b/src/main/resources/assets/auracore/textures/misc/chaos.png new file mode 100644 index 0000000..9afbb82 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/misc/chaos.png differ diff --git a/src/main/resources/assets/auracore/textures/misc/particles.png b/src/main/resources/assets/auracore/textures/misc/particles.png new file mode 100644 index 0000000..85857ce Binary files /dev/null and b/src/main/resources/assets/auracore/textures/misc/particles.png differ diff --git a/src/main/resources/assets/auracore/textures/misc/pure.png b/src/main/resources/assets/auracore/textures/misc/pure.png new file mode 100644 index 0000000..42fac63 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/misc/pure.png differ diff --git a/src/main/resources/assets/auracore/textures/misc/vortex.png b/src/main/resources/assets/auracore/textures/misc/vortex.png new file mode 100644 index 0000000..04b7470 Binary files /dev/null and b/src/main/resources/assets/auracore/textures/misc/vortex.png differ diff --git a/src/main/resources/auracore.mixins.json b/src/main/resources/auracore.mixins.json new file mode 100644 index 0000000..446fb4f --- /dev/null +++ b/src/main/resources/auracore.mixins.json @@ -0,0 +1,27 @@ +{ + "package": "dev.tilera.auracore.mixins", + "refmap": "auracore.refmap.json", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "MixinItemShard", + "MixinItemEssence", + "MixinTileCrystal", + "MixinTileCrucible", + "MixinTileArcaneFurnace", + "MixinTileJarFillable", + "MixinTileAlembic", + "MixinBlockCustomPlant", + "MixinBlockCustomOre", + "MixinEventHandlerEntity", + "MixinSlotLimitedByWand", + "MixinThaumcraftWorldGenerator" + ], + "client": [ + "MixinBlockCustomOreRenderer", + "MixinTileArcaneWorkbenchRenderer" + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file