mirror of
https://github.com/GTNewHorizons/ThaumicBases.git
synced 2026-10-26 14:24:08 +00:00
Merge remote-tracking branch 'felixfour/patch-1' into dev
This commit is contained in:
15 files changed
+260
-94
No files matched your search
+7
-4
@@ -1,13 +1,16 @@
|
||||
// Add your dependencies here
|
||||
|
||||
dependencies {
|
||||
api("com.github.GTNewHorizons:GTNHLib:0.9.47:dev")
|
||||
api('thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev')
|
||||
api('com.github.GTNewHorizons:DummyCore:1.20.0:dev')
|
||||
|
||||
compileOnly('com.github.GTNewHorizons:GT5-Unofficial:5.09.52.95:dev') {transitive=false}
|
||||
compileOnly('com.github.GTNewHorizons:GT5-Unofficial:5.09.52.341:dev') {transitive=false}
|
||||
compileOnly('curse.maven:automagy-222153:2285272')
|
||||
compileOnly('com.github.GTNewHorizons:EnderIO:2.10.21:dev')
|
||||
|
||||
runtimeOnly("com.github.GTNewHorizons:NotEnoughItems:2.8.26-GTNH:dev")
|
||||
runtimeOnly("com.github.GTNewHorizons:waila:1.9.7:dev")
|
||||
runtimeOnly("com.github.GTNewHorizons:NotEnoughItems:2.8.73-GTNH:dev")
|
||||
runtimeOnly("com.github.GTNewHorizons:waila:1.19.22:dev")
|
||||
runtimeOnly('com.github.GTNewHorizons:Baubles-Expanded:2.2.9-GTNH:dev')
|
||||
runtimeOnly('com.github.GTNewHorizons:CodeChickenCore:1.4.7:dev') // Required to allow dummycore to run in dev
|
||||
runtimeOnly('com.github.GTNewHorizons:CodeChickenCore:1.4.11:dev') // Required to allow dummycore to run in dev
|
||||
}
|
||||
+30
-3
@@ -39,9 +39,33 @@ remoteMappings = https\://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/co
|
||||
# `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE.
|
||||
developmentEnvironmentUserName = Developer
|
||||
|
||||
# Enables using modern Java syntax (up to version 17) via Jabel, while still targeting JVM 8.
|
||||
# See https://github.com/bsideup/jabel for details on how this works.
|
||||
enableModernJavaSyntax = true
|
||||
# Enables modern Java syntax support. Valid values:
|
||||
# - false: No modern syntax, Java 8 only
|
||||
# - jabel: Jabel syntax-only support, compiles to J8 bytecode
|
||||
# - jvmDowngrader: Full modern Java via JVM Downgrader (syntax + stdlib APIs)
|
||||
# - modern: Native modern Java bytecode, no downgrading
|
||||
enableModernJavaSyntax = jabel
|
||||
|
||||
# If set, ignores the above setting and compiles with the given toolchain. This may cause unexpected issues,
|
||||
# and should *not* be used in most situations. -1 disables this.
|
||||
# forceToolchainVersion = -1
|
||||
|
||||
# Target JVM version for JVM Downgrader bytecode downgrading.
|
||||
# Only used when enableModernJavaSyntax = jvmDowngrader
|
||||
# downgradeTargetVersion = 8
|
||||
|
||||
# Comma-separated list of Java versions for multi-release jar support (JVM Downgrader only).
|
||||
# Classes will be available in META-INF/versions/N/ for each version N in this list.
|
||||
# Default: "21,25" (J25+ gets native classes, J21-24 gets partial downgrade, J8-20 gets full downgrade).
|
||||
# jvmDowngraderMultiReleaseVersions = 21,25
|
||||
|
||||
# Specifies how JVM Downgrader API stubs are provided. Options:
|
||||
# - shade: Shade minimized stubs into the jar
|
||||
# - gtnhlib: GTNHLib provides stubs at runtime (adds version constraint)
|
||||
# - external: Another dependency provides stubs (no constraint, no warning)
|
||||
# - (empty): Warning reminding you to configure stubs
|
||||
# Note: 'shade' option requires you to verify license compliance, see: https://github.com/unimined/JvmDowngrader/blob/main/LICENSE.md
|
||||
# jvmDowngraderStubsProvider =
|
||||
|
||||
# Enables injecting missing generics into the decompiled source code for a better coding experience.
|
||||
# Turns most publicly visible List, Map, etc. into proper List<E>, Map<K, V> types.
|
||||
@@ -209,3 +233,6 @@ customArchiveBaseName = Thaumic-Based
|
||||
# This is meant to be set in $HOME/.gradle/gradle.properties.
|
||||
# ideaCheckSpotlessOnBuild = true
|
||||
|
||||
# Non-GTNH properties
|
||||
org.gradle.configuration-cache = true
|
||||
org.gradle.parallel = true
|
||||
@@ -0,0 +1,12 @@
|
||||
#This file is generated by updateDaemonJvm
|
||||
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/1630f7ebef05444cb27a2709ea0249b3/redirect
|
||||
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/5ee463876563a46fff651cce1bc53a4c/redirect
|
||||
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/1630f7ebef05444cb27a2709ea0249b3/redirect
|
||||
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/cd495626d2ee49a75447e3fdc6afb287/redirect
|
||||
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/d4fd992c9557644e637ebe98263e0ae7/redirect
|
||||
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/59a9771cad43219260d9aac9a8ec4d6a/redirect
|
||||
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/c5ee947fbfb70bc347d8d531e3a578c4/redirect
|
||||
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/5ee463876563a46fff651cce1bc53a4c/redirect
|
||||
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/a4c09dd2e2d7079373d30e524bbc2829/redirect
|
||||
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/b96cb7670c095245220e7d01d5927b58/redirect
|
||||
toolchainVersion=25
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright © 2015 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -57,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -114,7 +114,6 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -172,7 +171,6 @@ fi
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
|
||||
Vendored
+1
-2
@@ -70,11 +70,10 @@ goto fail
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.48'
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.24'
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,26 @@ public class BlockOverchanter extends BlockContainer {
|
||||
return new TileOverchanter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborBlockChange(World worldIn, int x, int y, int z, Block neighbor) {
|
||||
boolean powered = worldIn.isBlockIndirectlyGettingPowered(x, y, z)
|
||||
|| worldIn.isBlockIndirectlyGettingPowered(x, y - 1, z);
|
||||
int meta = worldIn.getBlockMetadata(x, y, z);
|
||||
boolean metaUnpowered = (meta & 8) == 0;
|
||||
|
||||
if (powered && metaUnpowered) {
|
||||
if (worldIn.getTileEntity(x, y, z) instanceof TileOverchanter teo && teo.canStartEnchanting()) {
|
||||
teo.isEnchantingStarted = true;
|
||||
teo.syncTimer = 0;
|
||||
worldIn.playSoundEffect(x, y, z, "thaumcraft:craftstart", 0.5F, 1.0F);
|
||||
}
|
||||
worldIn.setBlockMetadataWithNotify(x, y, z, meta | 8, 4);
|
||||
return;
|
||||
}
|
||||
if (powered || metaUnpowered) return;
|
||||
worldIn.setBlockMetadataWithNotify(x, y, z, meta & -9, 4);
|
||||
}
|
||||
|
||||
public void breakBlock(World w, int x, int y, int z, Block b, int meta) {
|
||||
MiscUtils.dropItemsOnBlockBreak(w, x, y, z, b, meta);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package tb.common.tile;
|
||||
|
||||
import static tb.core.TBCore.isAutomagyLoaded;
|
||||
import static tb.core.TBCore.isEioLoaded;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -7,7 +10,7 @@ import java.util.Set;
|
||||
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.ISidedInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
@@ -19,18 +22,23 @@ import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.geometry.CubeIterator;
|
||||
|
||||
import DummyCore.Utils.MathUtils;
|
||||
import DummyCore.Utils.MiscUtils;
|
||||
import crazypants.enderio.machine.obelisk.xp.TileExperienceObelisk;
|
||||
import crazypants.enderio.xp.ExperienceContainer;
|
||||
import thaumcraft.api.aspects.Aspect;
|
||||
import thaumcraft.api.wands.IWandable;
|
||||
import thaumcraft.common.lib.events.EssentiaHandler;
|
||||
import tuhljin.automagy.tiles.TileEntityJarXP;
|
||||
|
||||
public class TileOverchanter extends TileEntity implements IInventory, IWandable {
|
||||
public class TileOverchanter extends TileEntity implements ISidedInventory, IWandable {
|
||||
|
||||
public ItemStack inventory;
|
||||
|
||||
public int enchantingTime;
|
||||
public boolean xpAbsorbed;
|
||||
public int enchantingTicks;
|
||||
public int xpToAbsorb;
|
||||
public boolean isEnchantingStarted;
|
||||
public int syncTimer;
|
||||
|
||||
@@ -48,87 +56,70 @@ public class TileOverchanter extends TileEntity implements IInventory, IWandable
|
||||
if (syncTimer <= 0) {
|
||||
syncTimer = 100;
|
||||
NBTTagCompound tg = new NBTTagCompound();
|
||||
tg.setInteger("0", enchantingTime);
|
||||
tg.setBoolean("1", xpAbsorbed);
|
||||
tg.setInteger("0", enchantingTicks);
|
||||
tg.setInteger("1", xpToAbsorb);
|
||||
tg.setBoolean("2", isEnchantingStarted);
|
||||
tg.setInteger("x", xCoord);
|
||||
tg.setInteger("y", yCoord);
|
||||
tg.setInteger("z", zCoord);
|
||||
MiscUtils.syncTileEntity(tg, 0);
|
||||
} else--syncTimer;
|
||||
} else {
|
||||
--syncTimer;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.inventory == null) {
|
||||
isEnchantingStarted = false;
|
||||
xpAbsorbed = false;
|
||||
enchantingTime = 0;
|
||||
xpToAbsorb = 825; // 30 levels
|
||||
enchantingTicks = 0;
|
||||
// renderedLightning = null;
|
||||
} else {
|
||||
if (this.isEnchantingStarted) {
|
||||
if (this.worldObj.getTotalWorldTime() % 20 == 0) {
|
||||
// renderedLightning = new Lightning(this.worldObj.rand, new Coord3D(0,0,0), new
|
||||
// Coord3D(MathUtils.randomDouble(this.worldObj.rand)/50,MathUtils.randomDouble(this.worldObj.rand)/50,MathUtils.randomDouble(this.worldObj.rand)/50),
|
||||
// 0.3F, 1,0,1);
|
||||
this.worldObj
|
||||
.playSoundEffect(this.xCoord, this.yCoord, this.zCoord, "thaumcraft:infuserstart", 1F, 1.0F);
|
||||
if (EssentiaHandler.drainEssentia(this, Aspect.MAGIC, ForgeDirection.UNKNOWN, 8, false)) {
|
||||
++enchantingTime;
|
||||
if (enchantingTime >= 16 && !this.xpAbsorbed) {
|
||||
List<EntityPlayer> players = this.worldObj.getEntitiesWithinAABB(
|
||||
EntityPlayer.class,
|
||||
AxisAlignedBB.getBoundingBox(xCoord, yCoord, zCoord, xCoord + 1, yCoord + 1, zCoord + 1)
|
||||
.expand(6, 3, 6));
|
||||
if (!players.isEmpty()) {
|
||||
for (int i = 0; i < players.size(); ++i) {
|
||||
EntityPlayer p = players.get(i);
|
||||
if (p.experienceLevel >= 30) {
|
||||
p.attackEntityFrom(DamageSource.magic, 8);
|
||||
this.worldObj
|
||||
.playSoundEffect(p.posX, p.posY, p.posZ, "thaumcraft:zap", 1F, 1.0F);
|
||||
p.experienceLevel -= 30;
|
||||
xpAbsorbed = true;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (this.isEnchantingStarted) {
|
||||
if (enchantingTicks % 20 == 0) {
|
||||
// renderedLightning = new Lightning(this.worldObj.rand, new Coord3D(0,0,0), new
|
||||
// Coord3D(MathUtils.randomDouble(this.worldObj.rand)/50,MathUtils.randomDouble(this.worldObj.rand)/50,MathUtils.randomDouble(this.worldObj.rand)/50),
|
||||
// 0.3F, 1,0,1);
|
||||
this.worldObj
|
||||
.playSoundEffect(this.xCoord, this.yCoord, this.zCoord, "thaumcraft:infuserstart", 1F, 1.0F);
|
||||
if (EssentiaHandler.drainEssentia(this, Aspect.MAGIC, ForgeDirection.UNKNOWN, 8, false)) {
|
||||
if ((enchantingTicks >= 320 && xpToAbsorb != 0 && absorbXP() || xpToAbsorb == 0)
|
||||
&& enchantingTicks >= 620) {
|
||||
int enchId = this.findEnchantment(inventory);
|
||||
NBTTagList nbttaglist = this.inventory.getEnchantmentTagList();
|
||||
for (int i = 0; i < nbttaglist.tagCount(); ++i) {
|
||||
NBTTagCompound tag = nbttaglist.getCompoundTagAt(i);
|
||||
if (tag != null && tag.getShort("id") == enchId) {
|
||||
tag.setShort(
|
||||
"lvl",
|
||||
(short) Math.max(1, Math.min(tag.getShort("lvl") + 1, Short.MAX_VALUE)));
|
||||
NBTTagCompound stackTag = MiscUtils.getStackTag(inventory);
|
||||
if (!stackTag.hasKey("overchants")) {
|
||||
stackTag.setIntArray("overchants", new int[] { enchId });
|
||||
} else {
|
||||
int[] arrayInt = stackTag.getIntArray("overchants");
|
||||
int[] newArrayInt = new int[arrayInt.length + 1];
|
||||
System.arraycopy(arrayInt, 0, newArrayInt, 0, arrayInt.length);
|
||||
newArrayInt[newArrayInt.length - 1] = enchId;
|
||||
|
||||
stackTag.setIntArray("overchants", newArrayInt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (xpAbsorbed && enchantingTime >= 32) {
|
||||
int enchId = this.findEnchantment(inventory);
|
||||
NBTTagList nbttaglist = this.inventory.getEnchantmentTagList();
|
||||
for (int i = 0; i < nbttaglist.tagCount(); ++i) {
|
||||
NBTTagCompound tag = nbttaglist.getCompoundTagAt(i);
|
||||
if (tag != null && Integer.valueOf(tag.getShort("id")) == enchId) {
|
||||
tag.setShort("lvl", (short) (Integer.valueOf(tag.getShort("lvl")) + 1));
|
||||
NBTTagCompound stackTag = MiscUtils.getStackTag(inventory);
|
||||
if (!stackTag.hasKey("overchants")) {
|
||||
stackTag.setIntArray("overchants", new int[] { enchId });
|
||||
} else {
|
||||
int[] arrayInt = stackTag.getIntArray("overchants");
|
||||
int[] newArrayInt = new int[arrayInt.length + 1];
|
||||
for (int j = 0; j < arrayInt.length; ++j) {
|
||||
newArrayInt[j] = arrayInt[j];
|
||||
}
|
||||
newArrayInt[newArrayInt.length - 1] = enchId;
|
||||
|
||||
stackTag.setIntArray("overchants", newArrayInt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
isEnchantingStarted = false;
|
||||
xpAbsorbed = false;
|
||||
enchantingTime = 0;
|
||||
// renderedLightning = null;
|
||||
this.worldObj
|
||||
.playSoundEffect(this.xCoord, this.yCoord, this.zCoord, "thaumcraft:wand", 1F, 1F);
|
||||
}
|
||||
|
||||
} else {
|
||||
--enchantingTime;
|
||||
isEnchantingStarted = false;
|
||||
xpToAbsorb = 825;
|
||||
enchantingTicks = 0;
|
||||
// renderedLightning = null;
|
||||
this.worldObj.playSoundEffect(this.xCoord, this.yCoord, this.zCoord, "thaumcraft:wand", 1F, 1F);
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
enchantingTicks -= 20;
|
||||
}
|
||||
}
|
||||
enchantingTicks += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,10 +159,10 @@ public class TileOverchanter extends TileEntity implements IInventory, IWandable
|
||||
}
|
||||
|
||||
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
|
||||
enchantingTime = pkt.func_148857_g()
|
||||
enchantingTicks = pkt.func_148857_g()
|
||||
.getInteger("0");
|
||||
xpAbsorbed = pkt.func_148857_g()
|
||||
.getBoolean("1");
|
||||
xpToAbsorb = pkt.func_148857_g()
|
||||
.getInteger("1");
|
||||
isEnchantingStarted = pkt.func_148857_g()
|
||||
.getBoolean("2");
|
||||
}
|
||||
@@ -259,15 +250,32 @@ public class TileOverchanter extends TileEntity implements IInventory, IWandable
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int slot, ItemStack stk) {
|
||||
// return stk.hasTagCompound() && stk.getEnchantmentTagList() != null;
|
||||
return false;
|
||||
return stk.hasTagCompound() && stk.getEnchantmentTagList() != null
|
||||
&& stk.getEnchantmentTagList()
|
||||
.tagCount() > 0
|
||||
&& findEnchantment(stk) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtractItem(int slot, ItemStack item, int side) {
|
||||
return !isItemValidForSlot(0, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInsertItem(int slot, ItemStack item, int side) {
|
||||
return isItemValidForSlot(0, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getAccessibleSlotsFromSide(int side) {
|
||||
return new int[] { 0 };
|
||||
}
|
||||
|
||||
public void readFromNBT(NBTTagCompound tag) {
|
||||
super.readFromNBT(tag);
|
||||
|
||||
enchantingTime = tag.getInteger("enchTime");
|
||||
xpAbsorbed = tag.getBoolean("xpAbsorbed");
|
||||
enchantingTicks = tag.getInteger("enchTime");
|
||||
xpToAbsorb = tag.getInteger("xpToAbsorb");
|
||||
isEnchantingStarted = tag.getBoolean("enchStarted");
|
||||
|
||||
if (tag.hasKey("itm")) inventory = ItemStack.loadItemStackFromNBT(tag.getCompoundTag("itm"));
|
||||
@@ -276,8 +284,8 @@ public class TileOverchanter extends TileEntity implements IInventory, IWandable
|
||||
public void writeToNBT(NBTTagCompound tag) {
|
||||
super.writeToNBT(tag);
|
||||
|
||||
tag.setInteger("enchTime", enchantingTime);
|
||||
tag.setBoolean("xpAbsorbed", xpAbsorbed);
|
||||
tag.setInteger("enchTime", enchantingTicks);
|
||||
tag.setInteger("xpToAbsorb", xpToAbsorb);
|
||||
tag.setBoolean("enchStarted", isEnchantingStarted);
|
||||
|
||||
if (inventory != null) {
|
||||
@@ -310,4 +318,97 @@ public class TileOverchanter extends TileEntity implements IInventory, IWandable
|
||||
|
||||
@Override
|
||||
public void onWandStoppedUsing(ItemStack wandstack, World world, EntityPlayer player, int count) {}
|
||||
|
||||
public boolean absorbXP() {
|
||||
// note that the drain functions shouldnt be in a non remote test b/c of player damage fallback
|
||||
if (isAutomagyLoaded) {
|
||||
this.xpToAbsorb = this.drainXPJarsInRange(this.xpToAbsorb, 8);
|
||||
// This scans a 17x17x17 cube centered around the TE (radius 8), matching the range of Thaumcraft's Infusion
|
||||
// Altar
|
||||
// It prioritizes coordinates closest to the controller to avoid it from "stealing" from far jars
|
||||
if (xpToAbsorb == 0) return true;
|
||||
}
|
||||
if (isEioLoaded) {
|
||||
this.xpToAbsorb = this.drainEIOObelisksInRange(this.xpToAbsorb, 8);
|
||||
if (xpToAbsorb == 0) return true;
|
||||
}
|
||||
List<EntityPlayer> players = this.worldObj.getEntitiesWithinAABB(
|
||||
EntityPlayer.class,
|
||||
AxisAlignedBB.getBoundingBox(xCoord, yCoord, zCoord, xCoord + 1, yCoord + 1, zCoord + 1)
|
||||
.expand(6, 3, 6));
|
||||
if (!players.isEmpty()) {
|
||||
int lvlsleft = (int) Math
|
||||
.round(xpToAbsorb > 255 ? (59 + Math.sqrt(24 * xpToAbsorb - 5159)) / 6 : xpToAbsorb / 17d);
|
||||
// it's a double in the second branch so that both branches use the same Math.sqrt
|
||||
for (EntityPlayer p : players) {
|
||||
if (p.experienceLevel >= lvlsleft) {
|
||||
p.attackEntityFrom(DamageSource.magic, 8);
|
||||
this.worldObj.playSoundEffect(p.posX, p.posY, p.posZ, "thaumcraft:zap", 1F, 1.0F);
|
||||
p.experienceLevel -= lvlsleft;
|
||||
this.xpToAbsorb = 0;
|
||||
// if anyone else wants to implement the exact formula for experience
|
||||
// draining, you can
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int drainXPJarsInRange(int xp, int range) {
|
||||
if (xp <= 0) return xp;
|
||||
CubeIterator cubeIter = new CubeIterator(range);
|
||||
int jarxp;
|
||||
while (cubeIter.hasNext()) {
|
||||
cubeIter.next();
|
||||
if (this.worldObj.getTileEntity(
|
||||
cubeIter.n + this.xCoord,
|
||||
cubeIter.l + this.yCoord,
|
||||
cubeIter.m + this.zCoord) instanceof TileEntityJarXP jar) {
|
||||
jarxp = jar.getXP();
|
||||
if (jarxp < xp) {
|
||||
if (!worldObj.isRemote) jar.setXP(0);
|
||||
xp -= jarxp;
|
||||
continue;
|
||||
}
|
||||
if (!worldObj.isRemote) jar.setXP(jarxp - xp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return xp;
|
||||
// This algorithm drains each jar it comes across sequentially without regard to how full they are. If you would
|
||||
// rather it prioritize emptying barely filled jars within a certain radius, and then emptying non-full jars,
|
||||
// then instead have a counter sinceLastPrioJar that starts at 0 and increments each iteration, and cache the
|
||||
// most recent "priority" jar (lowest non-full jar with jarxp > xp argument); reset that counter per each jar
|
||||
// with jarxp under xp argument, and drain each jar with jarxp under xp argument, stopping once the counter
|
||||
// reaches an arbitrary count of blocks searched without draining a jar, and then drain the cached lowest-filled
|
||||
// jar. The TC EssentiaHandler would be so much better if it worked that way as well.
|
||||
}
|
||||
|
||||
// EIO version (separated so that it prioritizes the magic jars, feel free to switch this to being in sync instead)
|
||||
public int drainEIOObelisksInRange(int xp, int range) {
|
||||
if (xp <= 0) return xp;
|
||||
CubeIterator cubeIter = new CubeIterator(range);
|
||||
int jarxp;
|
||||
while (cubeIter.hasNext()) {
|
||||
cubeIter.next();
|
||||
if (this.worldObj.getTileEntity(
|
||||
cubeIter.n + this.xCoord,
|
||||
cubeIter.l + this.yCoord,
|
||||
cubeIter.m + this.zCoord) instanceof TileExperienceObelisk obelisk) {
|
||||
ExperienceContainer cont = obelisk.getContainer();
|
||||
jarxp = cont.getExperienceTotal();
|
||||
// goddamn private fields with no good setters
|
||||
if (!worldObj.isRemote) {
|
||||
cont.drain(null, Integer.MAX_VALUE, true);
|
||||
cont.addExperience(Math.max(0, jarxp - xp));
|
||||
}
|
||||
// if this causes desyncs, remove the !worldObj.isRemote test or add an additional multiplayer test
|
||||
xp -= jarxp;
|
||||
if (xp <= 0) return 0;
|
||||
}
|
||||
}
|
||||
return xp;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,6 +48,9 @@ public class TBCore {
|
||||
|
||||
public static final TBConfig cfg = new TBConfig();
|
||||
|
||||
public static final boolean isAutomagyLoaded = cpw.mods.fml.common.Loader.isModLoaded("Automagy");
|
||||
public static final boolean isEioLoaded = cpw.mods.fml.common.Loader.isModLoaded("EnderIO");
|
||||
|
||||
@SidedProxy(serverSide = serverProxy, clientSide = clientProxy)
|
||||
public static TBServer proxy;
|
||||
|
||||
|
||||
@@ -1394,6 +1394,7 @@ public class TBThaumonomicon {
|
||||
new ResearchPage("tb.rec.overchanter.page.0"),
|
||||
new ResearchPage("tb.rec.overchanter.page.1"),
|
||||
new ResearchPage("tb.rec.overchanter.page.2"),
|
||||
new ResearchPage("tb.rec.overchanter.page.3"),
|
||||
new ResearchPage(overchanterRec))
|
||||
.registerResearchItem();
|
||||
|
||||
|
||||
@@ -22,4 +22,5 @@ public class TBTiles {
|
||||
GameRegistry.registerTileEntity(TileCampfire.class, "tb.campfire");
|
||||
GameRegistry.registerTileEntity(TileBrazier.class, "tb.brazier");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -426,6 +426,7 @@ tc.research_text.TB.Overchanter=Pushing the limits
|
||||
tb.rec.overchanter.page.0=Thaumaturges often use their magic to infuse regular mundane items with magical force, making them better. This process is called enchanting. Thaumaturges have also discovered a way to do the same with an Infusion Altar, using it to make items stronger. However, there always seems to be a limit to the magic infused into the item... You have managed to push that limit a little bit further. You have managed to create an Overchanting table, which is able to increase the level of enchantments on the item by one. Not only could it get items closer to the desired level, it can do more - it can increase the level beyond maximum, allowing enchantments like Fortune IV, or Sharpness VI.
|
||||
tb.rec.overchanter.page.1=The device will improve the first enchantment on the item. The order is the same as displayed in the item's description. Previously buffed enchantments will be skipped - the device is not quite powerful enough to do things like Sharpness VII. It does not take the enchantment into account, so things like Silk Touch II are possible, yet useless. To infuse the item just put it in the only slot available and start the overchanting process by using your wand on the table twice. Then the Praecantatio essentia will be drawn from nearby jars into the table - you will need 32 Praecantatio in total. The table also requires a player nearby, since in the middle of the process it will use 30 levels from the player in range of 6 blocks!
|
||||
tb.rec.overchanter.page.2=Overchanting can be stopped in any time just by taking the item from the table, but the levels and the essentia will be wasted then. The table will draw Praecantatio from the range of 8 blocks, mirrors will also do the job just fine. Upon sapping experience the table will skip players with level before 30, so having multiple people with total level of 30 will not work. Any item with enchantments can be overchanted. Putting a non-enchanted item in the Overchanting table does nothing.
|
||||
tb.rec.overchanter.page.3=You can also automate the Overchanter with redstone, hoppers, and an XP container from the mods Automagy and EnderIO. Redstone input to the table will start overchanting, and overchanted items can be inserted and non-overchanted items extracted via hopper. It will only be able to extract fully overchanted items, so there is no need to lock hoppers! XP can be sourced from Automagy XP jars (first priority) or EnderIO XP obelisks (second priority) within a 17x17x17 cube centered on the table, prioritizing closer sources. If XP is left over, it will consume the rest from nearby players.
|
||||
|
||||
tc.research_name.TB.EntityDec=Entity Deconstructor
|
||||
tc.research_text.TB.EntityDec=Lively knowledge
|
||||
|
||||
@@ -418,6 +418,7 @@ tc.research_text.TB.Overchanter=挑战极限
|
||||
tb.rec.overchanter.page.0=神秘使通常会向普通物品注入魔法力量来改进它们.这个过程被称为附魔.神秘使也找到了一个方法用注魔祭坛办到同样的事情.然而,给物品注入魔力总是有极限的...但是你成功将这个极限变得了更极限了一些.你成功创造了这个超吟附魔台.它能够将附魔等级上限提升一级.不仅仅是是将物品的附魔向理想状态提升一级,它甚至可以超过极限,使得时运IV或者锋利VI这种附魔得以实现.
|
||||
tb.rec.overchanter.page.1=这个设备会提升物品上的第一个附魔.这个顺序和物品中附魔描述的顺序相同.之前的强化后的附魔将会被忽略——这个设备还没有制作出锋利VII那样强力的能力.它并没有考虑这个附魔本身的特性,因此例如精准采集II这样的附魔是会出现的,虽然这并没有什么卵用.如果想给物品注入魔力只需要把它放进超吟附魔台中唯一的栏位然后用法杖点击附魔台2次.然后附魔台会从附近吸收总共32点的Praecantatio源质.这个附魔台也需要有一个玩家在附近,由于这个附魔过程中会从玩家身上抽取30级经验!
|
||||
tb.rec.overchanter.page.2=超吟附魔台可以在任何时候停止它的工作,但是吸收的经验与源质就会被浪费掉了.附魔台会在8格范围内吸收Praecantatio源质,范围之内的源质之镜也能很好的工作.附魔台会忽略等级没有达到30级的玩家,因此即便是多人的等级和超过30附魔台也不会工作.任何物品只要具有附魔就可以使用超吟附魔台,但是没有附魔的物品放上去并不会产生什么卵用.
|
||||
tb.rec.overchanter.page.3=超吟附魔台也可以通过赤石末实现自动化。激活后,附魔台还能从Automagy的罐子以及EnderIO的方尖碑中吸收经验。附魔台会在8格范围内搜索罐装附魔精华液和经验交换方尖碑。罐子的优先级高于方尖碑,剩余部分则由玩家供应。漏斗可用于把物品传入和移出。它们仅在工艺流程做成后才会进行移出,因此无需加锁。
|
||||
|
||||
tc.research_name.TB.EntityDec=实体粉碎机
|
||||
tc.research_text.TB.EntityDec=活生生的知识
|
||||
|
||||
Reference in new issue
Block a user