Dynamism Tablet Rewrite (#65)

Co-authored-by: Martin Robertz <dream-master@gmx.net>
This commit is contained in:
sisyphussyandMartin Robertz authored and GitHub committed 2025-09-21 16:33:05 +02:00
1 parent c2cbc66645
commit 4f2618d03b
10 files changed
+637 -506

No files matched your search

+2 -2
View File
@@ -1,7 +1,7 @@
// Add your dependencies here
dependencies {
api('com.github.GTNewHorizons:Baubles-Expanded:2.1.14-GTNH:dev')
api('com.github.GTNewHorizons:Baubles-Expanded:2.1.15-GTNH:dev')
api('thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev')
api('com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-686-GTNH:api')
api('com.github.GTNewHorizons:ThaumicBoots:1.4.14:dev') {
@@ -19,7 +19,7 @@ dependencies {
compileOnly('com.github.GTNewHorizons:CodeChickenCore:1.4.7:dev') {transitive=false}
compileOnly('com.github.GTNewHorizons:OpenComputers:1.11.19-GTNH:api') {transitive=false}
compileOnly('net.industrial-craft:industrialcraft-2:2.2.828-experimental:api') {transitive=false}
compileOnly("com.github.GTNewHorizons:GT5-Unofficial:5.09.51.457:dev") {transitive=false}
compileOnly("com.github.GTNewHorizons:GT5-Unofficial:5.09.51.457:dev")
compileOnly('curse.maven:computercraft-67504:2269339')
compileOnly('curse.maven:cofh-core-69162:2388751')
+1 -1
View File
@@ -41,7 +41,7 @@ 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 = false
enableModernJavaSyntax = true
# 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.
@@ -47,12 +47,18 @@ public class RenderTileAnimationTablet extends TileEntitySpecialRenderer {
int rotation = meta == 2 ? 270 : meta == 3 ? 90 : meta == 4 ? 0 : 180;
GL11.glColor4f(1F, 1F, 1F, 1F);
GL11.glPushMatrix();
GL11.glTranslated(d0, d1, d2);
renderOverlay(tile, overlayCenter, -1, false, false, 0.65, 0.13F, 0F);
if (tile.leftClick) renderOverlay(tile, overlayLeft, 1, false, true, 1, 0.13F, 0F);
else renderOverlay(tile, overlayRight, 1, false, true, 1, 0.131F, 0F);
renderOverlay(tile, overlayIndent, 0, false, false, 0.5F, 0.13F, rotation + 90F);
GL11.glDepthMask(false);
GL11.glDisable(GL11.GL_LIGHTING);
renderOverlay(tile, overlayCenter, -1, false, 0.65, 0.13F, partialTicks);
if (tile.leftClick) renderOverlay(tile, overlayLeft, 1, true, 1, 0.13F, partialTicks);
else renderOverlay(tile, overlayRight, 1, true, 1, 0.131F, partialTicks);
renderIndents(tile, rotation + 90F);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glDepthMask(true);
GL11.glRotatef(rotation, 0F, 1F, 0F);
GL11.glTranslated(0.1, 0.2 + Math.cos(System.currentTimeMillis() / 600D) / 18F, 0.5);
@@ -60,9 +66,10 @@ public class RenderTileAnimationTablet extends TileEntitySpecialRenderer {
GL11.glTranslatef(translations[0], translations[1], translations[2]);
GL11.glScalef(0.8F, 0.8F, 0.8F);
GL11.glTranslatef(0.5F, 0F, 0.5F);
GL11.glRotatef(tile.swingProgress, 0F, 0F, 1F);
float swingProgress = tile.getRenderSwingProgress(partialTicks);
GL11.glRotatef(swingProgress, 0F, 0F, 1F);
GL11.glTranslatef(-0.5F, 0F, -0.5F);
GL11.glTranslatef(-tile.swingProgress / 250F, tile.swingProgress / 1000F, 0F);
GL11.glTranslatef(-swingProgress / 250F, swingProgress / 1000F, 0F);
GL11.glRotatef((float) Math.cos(System.currentTimeMillis() / 400F) * 5F, 1F, 0F, 1F);
renderItem(tile);
GL11.glPopMatrix();
@@ -72,6 +79,8 @@ public class RenderTileAnimationTablet extends TileEntitySpecialRenderer {
ItemStack stack = tablet.getStackInSlot(0);
if (stack != null) {
EntityItem entityitem = new EntityItem(tablet.getWorldObj(), 0.0D, 0.0D, 0.0D, stack);
entityitem.worldObj = tablet.getWorldObj();
int stackSize = entityitem.getEntityItem().stackSize;
entityitem.getEntityItem().stackSize = 1;
entityitem.hoverStart = 0.0F;
GL11.glPushMatrix();
@@ -81,25 +90,24 @@ public class RenderTileAnimationTablet extends TileEntitySpecialRenderer {
RenderItem.renderInFrame = true;
RenderManager.instance.renderEntityWithPosYaw(entityitem, 0.0D, 0.0D, 0.0D, 0.0F, 0.0F);
RenderItem.renderInFrame = false;
GL11.glPopMatrix();
entityitem.getEntityItem().stackSize = stackSize;
}
}
private void renderOverlay(TileAnimationTablet tablet, ResourceLocation texture, int rotationMod,
boolean useLighting, boolean useBlend, double size, float height, float forceDeg) {
private void renderOverlay(TileAnimationTablet tablet, ResourceLocation texture, int rotationMod, boolean useBlend,
double size, float height, float partialTicks) {
Minecraft mc = ClientHelper.minecraft();
mc.renderEngine.bindTexture(texture);
GL11.glPushMatrix();
GL11.glDepthMask(false);
if (!useLighting) GL11.glDisable(GL11.GL_LIGHTING);
if (useBlend) {
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
GL11.glTranslatef(0.5F, height, 0.5F);
float deg = rotationMod == 0 ? forceDeg : (float) (tablet.ticksExisted * rotationMod % 360F);
float deg = (tablet.getTicksExisted(partialTicks) * rotationMod % 360F);
GL11.glRotatef(deg, 0F, 1F, 0F);
GL11.glColor4f(1F, 1F, 1F, 1F);
Tessellator tess = Tessellator.instance;
double size1 = size / 2;
double size2 = -size1;
@@ -109,8 +117,33 @@ public class RenderTileAnimationTablet extends TileEntitySpecialRenderer {
tess.addVertexWithUV(size1, 0, size2, 1, 0);
tess.addVertexWithUV(size2, 0, size2, 0, 0);
tess.draw();
GL11.glDepthMask(true);
if (!useLighting) GL11.glEnable(GL11.GL_LIGHTING);
GL11.glPopMatrix();
}
private void renderIndents(TileAnimationTablet tablet, float forceDeg) {
Minecraft mc = ClientHelper.minecraft();
mc.renderEngine.bindTexture(overlayIndent);
GL11.glPushMatrix();
GL11.glTranslatef(0.5F, (float) 0.13, 0.5F);
GL11.glRotatef(forceDeg, 0F, 1F, 0F);
Tessellator tess = Tessellator.instance;
final double size1 = 0.25;
final double size2 = -0.25;
tess.startDrawingQuads();
tess.addVertexWithUV(size2, 0, size1, 0, 1);
tess.addVertexWithUV(size1, 0, size1, 1, 1);
tess.addVertexWithUV(size1, 0, size2, 1, 0);
tess.addVertexWithUV(size2, 0, size2, 0, 0);
tess.draw();
int acceleration = tablet.getWorldAcceleratorBonus();
if (acceleration != 0) {
GL11.glRotatef(90, -1, 0, 0);
GL11.glScalef(0.02f, -0.02f, 0.02f);
final String s = 'x' + Integer.toString(acceleration);
final int width = mc.fontRenderer.getStringWidth(s);
GL11.glTranslatef(-width / 2f, 10f + mc.fontRenderer.FONT_HEIGHT / 2f, 0);
mc.fontRenderer.drawString(s, 0, 0, 0xFFFFFF);
}
GL11.glPopMatrix();
}
}
@@ -57,6 +57,7 @@ public class ThaumicTinkerer {
public static TTCommonProxy proxy;
public static boolean isBootsActive = false;
public static boolean gtLoaded;
public static final String BOOTS = "thaumicboots";
public static CommonProxy tcProxy;
@@ -80,6 +81,7 @@ public class ThaumicTinkerer {
if (Loader.isModLoaded(BOOTS)) {
isBootsActive = true;
}
gtLoaded = Loader.isModLoaded("gregtech");
}
@EventHandler
@@ -44,6 +44,7 @@ import thaumic.tinkerer.common.block.tile.tablet.TileAnimationTablet;
import thaumic.tinkerer.common.lib.LibBlockNames;
import thaumic.tinkerer.common.lib.LibGuiIDs;
import thaumic.tinkerer.common.lib.LibResearch;
import thaumic.tinkerer.common.registry.TTRegistry;
import thaumic.tinkerer.common.registry.ThaumicTinkererArcaneRecipe;
import thaumic.tinkerer.common.registry.ThaumicTinkererRecipe;
import thaumic.tinkerer.common.research.IRegisterableResearch;
@@ -98,37 +99,32 @@ public class BlockAnimationTablet extends BlockModContainer {
TileAnimationTablet tablet = (TileAnimationTablet) par1World.getTileEntity(par2, par3, par4);
if (tablet != null) {
if (tablet.getIsBreaking()) {}
ItemStack itemstack = tablet.heldItem;
if (itemstack != null) {
float f = random.nextFloat() * 0.8F + 0.1F;
float f1 = random.nextFloat() * 0.8F + 0.1F;
EntityItem entityitem;
for (int j1 = 0; j1 < tablet.getSizeInventory(); ++j1) {
ItemStack itemstack = tablet.getStackInSlot(j1);
for (float f2 = random.nextFloat() * 0.8F + 0.1F; itemstack.stackSize > 0; par1World
.spawnEntityInWorld(entityitem)) {
int k1 = random.nextInt(21) + 10;
if (itemstack != null) {
float f = random.nextFloat() * 0.8F + 0.1F;
float f1 = random.nextFloat() * 0.8F + 0.1F;
EntityItem entityitem;
if (k1 > itemstack.stackSize) k1 = itemstack.stackSize;
for (float f2 = random.nextFloat() * 0.8F + 0.1F; itemstack.stackSize > 0; par1World
.spawnEntityInWorld(entityitem)) {
int k1 = random.nextInt(21) + 10;
itemstack.stackSize -= k1;
entityitem = new EntityItem(
par1World,
par2 + f,
par3 + f1,
par4 + f2,
new ItemStack(itemstack.getItem(), k1, itemstack.getItemDamage()));
float f3 = 0.05F;
entityitem.motionX = (float) random.nextGaussian() * f3;
entityitem.motionY = (float) random.nextGaussian() * f3 + 0.2F;
entityitem.motionZ = (float) random.nextGaussian() * f3;
if (k1 > itemstack.stackSize) k1 = itemstack.stackSize;
itemstack.stackSize -= k1;
entityitem = new EntityItem(
par1World,
par2 + f,
par3 + f1,
par4 + f2,
new ItemStack(itemstack.getItem(), k1, itemstack.getItemDamage()));
float f3 = 0.05F;
entityitem.motionX = (float) random.nextGaussian() * f3;
entityitem.motionY = (float) random.nextGaussian() * f3 + 0.2F;
entityitem.motionZ = (float) random.nextGaussian() * f3;
if (itemstack.hasTagCompound()) entityitem.getEntityItem()
.setTagCompound((NBTTagCompound) itemstack.getTagCompound().copy());
}
if (itemstack.hasTagCompound())
entityitem.getEntityItem().setTagCompound((NBTTagCompound) itemstack.getTagCompound().copy());
}
}
@@ -142,6 +138,8 @@ public class BlockAnimationTablet extends BlockModContainer {
@Override
public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, Block par5) {
if (par1World.isRemote) return;
TileEntity te = par1World.getTileEntity(par2, par3, par4);
if (!(te instanceof TileAnimationTablet tablet) || !tablet.redstone) return;
boolean power = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)
|| par1World.isBlockIndirectlyGettingPowered(par2, par3 + 1, par4);
@@ -162,18 +160,9 @@ public class BlockAnimationTablet extends BlockModContainer {
@Override
public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) {
TileEntity tile = par1World.getTileEntity(par2, par3, par4);
if (tile != null && tile instanceof TileAnimationTablet) {
TileAnimationTablet tablet = (TileAnimationTablet) tile;
if (tablet.redstone && tablet.swingProgress == 0) {
tablet.findEntities(tablet.getTargetLoc());
if (tile instanceof TileAnimationTablet tablet) {
if (tablet.redstone && tablet.isIdle()) {
tablet.initiateSwing();
par1World.addBlockEvent(
par2,
par3,
par4,
ThaumicTinkerer.registry.getFirstBlockFromClass(BlockAnimationTablet.class),
0,
0);
}
}
}
@@ -183,13 +172,12 @@ public class BlockAnimationTablet extends BlockModContainer {
int par6, float par7, float par8, float par9) {
if (!par1World.isRemote) {
TileEntity tile = par1World.getTileEntity(par2, par3, par4);
if (tile != null) {
TileAnimationTablet tablet = (TileAnimationTablet) tile;
if (tile instanceof TileAnimationTablet tablet) {
if (par5EntityPlayer.getCurrentEquippedItem() != null
&& par5EntityPlayer.getCurrentEquippedItem().getItem() instanceof ItemWandCasting) {
int meta = par1World.getBlockMetadata(par2, par3, par4);
boolean activated = (meta & 8) != 0;
if (!activated && !tablet.getIsBreaking() && tablet.swingProgress == 0) {
if (!activated && !tablet.getIsBreaking() && tablet.isIdle()) {
par1World.setBlockMetadataWithNotify(par2, par3, par4, meta == 5 ? 2 : meta + 1, 1 | 2);
par1World.playSoundEffect(par2, par3, par4, "thaumcraft:tool", 0.6F, 1F);
} else par5EntityPlayer
@@ -268,10 +256,9 @@ public class BlockAnimationTablet extends BlockModContainer {
-8,
2,
4,
new ItemStack(ThaumicTinkerer.registry.getFirstBlockFromClass(BlockAnimationTablet.class))).setWarp(1)
.setParents(LibResearch.KEY_MAGNETS).setPages(
new ResearchPage("0"),
ResearchHelper.arcaneRecipePage(LibResearch.KEY_ANIMATION_TABLET));
new ItemStack(TTRegistry.dynamismTablet)).setWarp(1).setParents(LibResearch.KEY_MAGNETS).setPages(
new ResearchPage("0"),
ResearchHelper.arcaneRecipePage(LibResearch.KEY_ANIMATION_TABLET));
}
@Override
@@ -279,7 +266,7 @@ public class BlockAnimationTablet extends BlockModContainer {
return new ThaumicTinkererArcaneRecipe(
LibResearch.KEY_ANIMATION_TABLET,
LibResearch.KEY_ANIMATION_TABLET,
new ItemStack(ThaumicTinkerer.registry.getFirstBlockFromClass(BlockAnimationTablet.class)),
new ItemStack(TTRegistry.dynamismTablet),
new AspectList().add(Aspect.AIR, 25).add(Aspect.ORDER, 15).add(Aspect.FIRE, 10),
"GIG",
"ICI",
@@ -13,76 +13,180 @@ package thaumic.tinkerer.common.block.tile.tablet;
import java.util.UUID;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.network.NetHandlerPlayServer;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.IChatComponent;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import com.mojang.authlib.GameProfile;
import thaumcraft.common.lib.FakeThaumcraftPlayer;
public final class TabletFakePlayer extends FakePlayer {
public class TabletFakePlayer extends FakeThaumcraftPlayer {
private final TileAnimationTablet tablet;
TileAnimationTablet tablet;
public TabletFakePlayer(TileAnimationTablet tablet) { // ,String name) {
public TabletFakePlayer(TileAnimationTablet tablet) {
super(
tablet.getWorldObj(),
(WorldServer) tablet.getWorldObj(),
new GameProfile(UUID.fromString("a8f026a0-135b-11e4-9191-0800200c9a66"), "[ThaumcraftTablet]"));
// super(tablet.getWorldObj(),"[ThaumcraftTablet]");
this.tablet = tablet;
}
@Override
public void setDead() {
inventory.clearInventory(null, -1);
super.setDead();
}
@Override
public void openGui(Object mod, int modGuiId, World world, int x, int y, int z) {
// NO-OP
this.playerNetServerHandler = new DummyNetHandlerPlayServer(MinecraftServer.getServer(), this);
this.width = 0;
this.height = 0;
this.boundingBox.setBounds(this.posX, this.posY, this.posZ, this.posX, this.posY, this.posZ);
this.rotationPitch = -15;
}
@Override
public void onUpdate() {
capabilities.isCreativeMode = false;
posX = tablet.xCoord + 0.5;
posY = tablet.yCoord + 1.6;
posZ = tablet.zCoord + 0.5;
if (riddenByEntity != null) riddenByEntity.ridingEntity = null;
if (ridingEntity != null) ridingEntity.riddenByEntity = null;
riddenByEntity = null;
ridingEntity = null;
this.posX = tablet.xCoord + 0.5f;
this.posY = tablet.yCoord + 0.5f;
this.posZ = tablet.zCoord + 0.5f;
this.inventory.currentItem = 0;
motionX = motionY = motionZ = 0;
setHealth(20);
isDead = false;
this.capabilities.isCreativeMode = false;
int meta = tablet.getBlockMetadata() & 7;
int rotation = meta == 2 ? 180 : meta == 3 ? 0 : meta == 4 ? 90 : -90;
rotationYaw = rotationYawHead = rotation;
rotationPitch = -15;
for (int i = 0; i < inventory.getSizeInventory(); i++) {
if (i != inventory.currentItem) {
ItemStack stack = inventory.getStackInSlot(i);
if (stack != null) {
entityDropItem(stack, 1.0f);
inventory.setInventorySlotContents(i, null);
}
rotationYaw = rotationYawHead = rotation;
// Drop everything except for held item
for (int i = 1; i < inventory.getSizeInventory(); i++) {
ItemStack stack = inventory.getStackInSlot(i);
if (stack != null) {
entityDropItem(stack, 0);
inventory.setInventorySlotContents(i, null);
}
}
syncSlots();
}
@Override
public void addChatMessage(IChatComponent var1) {}
public void syncSlots() {
this.inventory.mainInventory[0] = tablet.heldItem;
}
// Copied from Minecraft and PlayerControllerMP
public boolean sendUseItem(ItemStack stack) {
if (!ForgeEventFactory.onPlayerInteract(this, PlayerInteractEvent.Action.RIGHT_CLICK_AIR, 0, 0, 0, -1, worldObj)
.isCanceled()) {
int i = stack.stackSize;
ItemStack itemstack1 = stack.useItemRightClick(worldObj, this);
if (itemstack1 == stack && itemstack1.stackSize == i) {
return false;
}
inventory.mainInventory[0] = itemstack1;
if (itemstack1.stackSize <= 0) {
inventory.mainInventory[0] = null;
MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(this, itemstack1));
}
return true;
}
return false;
}
// copied from PlayerController#onPlayerRightClick
public boolean onPlayerRightClick(ItemStack stack, int x, int y, int z, int side, float f, float f1, float f2) {
Item item = stack.getItem();
if (item != null && item.onItemUseFirst(stack, this, worldObj, x, y, z, side, f, f1, f2)) {
return true;
}
Block block = worldObj.getBlock(x, y, z);
if (block.onBlockActivated(worldObj, x, y, z, this, side, f, f1, f2)) {
return true;
}
if (!stack.tryPlaceItemIntoWorld(this, worldObj, x, y, z, side, f, f1, f2)) {
return false;
}
if (stack.stackSize <= 0) {
MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(this, stack));
}
return true;
}
@Override
public ChunkCoordinates getPlayerCoordinates() {
return new ChunkCoordinates(tablet.xCoord, tablet.yCoord, tablet.zCoord);
}
@Override
protected boolean isMovementBlocked() {
return true;
}
@Override
public boolean canBePushed() {
return false;
}
@Override
public boolean canBeCollidedWith() {
return false;
}
@Override
public void setPosition(double x, double y, double z) {
// NO-OP (the position is set at creation)
}
@Override
public void setDead() {
// NO-OP (this should never happen...?)
}
@Override
public void mountEntity(Entity entityIn) {
// NO-OP
}
@Override
public void setHealth(float p_70606_1_) {
// NO-OP
}
@Override
public void onLivingUpdate() {
// NO-OP
}
@Override
public void addChatMessage(IChatComponent var1) {
// NO-OP
}
@Override
public void addChatComponentMessage(IChatComponent chatmessagecomponent) {
// NO-OP
}
private static final class DummyNetHandlerPlayServer extends NetHandlerPlayServer {
public DummyNetHandlerPlayServer(MinecraftServer server, FakePlayer player) {
super(server, new NetworkManager(false), player);
}
@Override
public void onNetworkTick() {
// NO-OP
}
@Override
public void sendPacket(Packet packetIn) {
// NO-OP
}
}
}
@@ -11,48 +11,49 @@
*/
package thaumic.tinkerer.common.block.tile.tablet;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.passive.EntityAnimal;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemReed;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.server.management.ItemInWorldManager;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import appeng.api.movable.IMovableTile;
import cpw.mods.fml.common.Optional;
import cpw.mods.fml.common.eventhandler.Event;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import gregtech.common.tileentities.machines.basic.MTEWorldAccelerator;
import li.cil.oc.api.machine.Arguments;
import li.cil.oc.api.machine.Callback;
import li.cil.oc.api.machine.Context;
import li.cil.oc.api.network.SimpleComponent;
import thaumic.tinkerer.common.ThaumicTinkerer;
import thaumic.tinkerer.common.block.BlockAnimationTablet;
import thaumic.tinkerer.common.lib.LibBlockNames;
import thaumic.tinkerer.common.registry.TTRegistry;
import thaumic.tinkerer.mixins.early.AccessorItemInWorldManager;
@Optional.InterfaceList({ @Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers"),
@Optional.Interface(iface = "dan200.computercraft.api.peripheral.IPeripheral", modid = "ComputerCraft"),
@@ -63,339 +64,343 @@ public class TileAnimationTablet extends TileEntity implements IInventory, IMova
private static final String TAG_REDSTONE = "redstone";
private static final String TAG_PROGRESS = "progress";
private static final String TAG_MOD = "mod";
private static final String TAG_OWNER = "owner";
private static final int[][] LOC_INCREASES = new int[][] { { 0, -1 }, { 0, +1 }, { -1, 0 }, { +1, 0 } };
private static final ForgeDirection[] SIDES = new ForgeDirection[] { ForgeDirection.NORTH, ForgeDirection.SOUTH,
ForgeDirection.WEST, ForgeDirection.EAST };
private static final int SWING_SPEED = 3;
private static final int MAX_DEGREE = 45;
public double ticksExisted = 0;
private static final byte SWING_SPEED = 3;
private static final byte MAX_DEGREE = 45;
private static final byte MAX_ITERATIONS = MAX_DEGREE / SWING_SPEED;
public boolean leftClick = true;
public boolean redstone = false;
public int swingProgress = 0;
List<Entity> detectedEntities = new ArrayList<>();
ItemStack[] inventorySlots = new ItemStack[1];
// public String Owner;
TabletFakePlayer player;
private int swingMod = 0;
private byte prevSwingProgress;
private byte swingProgress;
private byte swingMod;
public ItemStack heldItem;
private TabletFakePlayer player;
private boolean isBreaking = false;
private int initialDamage = 0;
private int curblockDamage = 0;
private int durabilityRemainingOnBlock;
private int ticksElapsed;
private int prevTicksElapsed;
private final Vec3 tempVec = Vec3.createVectorHelper(0, 0, 0);
private final Vec3 positionVec = Vec3.createVectorHelper(0, 0, 0);
@SideOnly(Side.CLIENT)
public final float getRenderSwingProgress(float partialTicks) {
return prevSwingProgress + (swingProgress - prevSwingProgress) * partialTicks;
}
@SideOnly(Side.CLIENT)
public final float getTicksExisted(float partialTicks) {
return prevTicksElapsed + (ticksElapsed - prevTicksElapsed) * partialTicks;
}
@SideOnly(Side.CLIENT)
public final int getWorldAcceleratorBonus() {
return (ticksElapsed - prevTicksElapsed) - 1;
}
@Override
public void updateEntity() {
// player = new TabletFakePlayer(this);//,Owner);
player.onUpdate();
player.inventory.clearInventory(null, -1);
ticksExisted++;
if (worldObj.isRemote) {
prevSwingProgress = swingProgress;
prevTicksElapsed = ticksElapsed;
int iterations = ThaumicTinkerer.gtLoaded ? MTEWorldAccelerator.getAccelerationForTEUnsafe(this) + 1 : 1;
ticksElapsed += iterations;
ItemStack stack = heldItem;
if (stack != null) {
iterations = Math.min(iterations, MAX_ITERATIONS);
for (int i = 0; i < iterations; i++) {
swingProgress += swingMod;
if (swingProgress >= MAX_DEGREE) {
swingMod = -SWING_SPEED;
} else if (swingProgress <= 0) {
stopSwinging();
}
}
} else {
stopSwinging();
}
return;
}
ItemStack stack = getStackInSlot(0);
try {
player.onUpdate();
if (stack != null) {
if (swingProgress >= MAX_DEGREE) swingHit();
ItemStack stack = heldItem;
if (stack == null) {
if (isBreaking) stopBreaking();
stopSwinging();
return;
}
swingMod = swingProgress <= 0 ? 0 : swingProgress >= MAX_DEGREE ? -SWING_SPEED : swingMod;
MovingObjectPosition hit = calculateHit();
swingProgress += swingMod;
if (swingProgress < 0) swingProgress = 0;
} else {
swingMod = 0;
swingProgress = 0;
if (swingProgress >= MAX_DEGREE) {
if (hit != null) {
swingHit(stack, hit);
}
swingMod = -SWING_SPEED;
} else if (swingProgress <= 0) {
stopSwinging();
}
if (isBreaking) stopBreaking();
}
boolean detect = detect();
if (!detect) stopBreaking();
if (detect && isBreaking) continueBreaking();
if ((!redstone || isBreaking) && detect && swingProgress == 0) {
initiateSwing();
worldObj.addBlockEvent(
xCoord,
yCoord,
zCoord,
ThaumicTinkerer.registry.getFirstBlockFromClass(BlockAnimationTablet.class),
0,
0);
}
}
public void initiateSwing() {
swingMod = SWING_SPEED;
swingProgress = 1;
}
public void swingHit() {
ChunkCoordinates coords = getTargetLoc();
ItemStack stack = getStackInSlot(0);
Item item = stack.getItem();
Block block = worldObj.getBlock(coords.posX, coords.posY, coords.posZ);
player.setCurrentItemOrArmor(0, stack);
boolean done = false;
if (leftClick) {
Entity entity = detectedEntities.isEmpty() ? null
: detectedEntities.get(worldObj.rand.nextInt(detectedEntities.size()));
if (entity != null) {
player.getAttributeMap().applyAttributeModifiers(stack.getAttributeModifiers()); // Set attack strenght
player.attackTargetEntityWithCurrentItem(entity);
done = true;
} else if (!isBreaking) {
if (block != Blocks.air && !block.isAir(worldObj, coords.posX, coords.posY, coords.posZ)
&& block.getBlockHardness(worldObj, coords.posX, coords.posY, coords.posZ) >= 0) {
isBreaking = true;
startBreaking(block, worldObj.getBlockMetadata(coords.posX, coords.posY, coords.posZ));
done = true;
if (isBreaking) {
if (hit == null || hit.typeOfHit != MovingObjectPosition.MovingObjectType.BLOCK) {
stopBreaking();
return;
}
ItemInWorldManager worldManager = player.theItemInWorldManager;
worldManager.updateBlockRemoving();
if (((AccessorItemInWorldManager) worldManager).getDurabilityRemainingOnBlock() >= 10) {
worldManager.tryHarvestBlock(hit.blockX, hit.blockY, hit.blockZ);
}
}
} else {
int side = SIDES[(getBlockMetadata() & 7) - 2].getOpposite().ordinal();
if (!(block != Blocks.air && !block.isAir(worldObj, coords.posX, coords.posY, coords.posZ))) {
coords.posY -= 1;
side = ForgeDirection.UP.ordinal();
block = worldObj.getBlock(coords.posX, coords.posY, coords.posZ);
}
try {
ForgeEventFactory.onPlayerInteract(
player,
Action.RIGHT_CLICK_AIR,
coords.posX,
coords.posY,
coords.posZ,
side,
worldObj);
Entity entity = detectedEntities.isEmpty() ? null
: detectedEntities.get(worldObj.rand.nextInt(detectedEntities.size()));
done = entity != null && entity instanceof EntityLiving
&& (item.itemInteractionForEntity(stack, player, (EntityLivingBase) entity)
|| (!(entity instanceof EntityAnimal) || ((EntityAnimal) entity).interact(player)));
if (!done) item.onItemUseFirst(
stack,
player,
worldObj,
coords.posX,
coords.posY,
coords.posZ,
side,
0F,
0F,
0F);
if (!done) done = block != null && block
.onBlockActivated(worldObj, coords.posX, coords.posY, coords.posZ, player, side, 0F, 0F, 0F);
if (!done) done = item
.onItemUse(stack, player, worldObj, coords.posX, coords.posY, coords.posZ, side, 0F, 0F, 0F);
if (!done) {
item.onItemRightClick(stack, worldObj, player);
done = true;
}
} catch (Throwable e) {
e.printStackTrace();
List list = worldObj.getEntitiesWithinAABB(
EntityPlayer.class,
AxisAlignedBB.getBoundingBox(
xCoord - 8,
yCoord - 8,
zCoord - 8,
xCoord + 8,
yCoord + 8,
zCoord + 8));
for (Object player : list) {
((EntityPlayer) player).addChatComponentMessage(
new ChatComponentText(
EnumChatFormatting.RED
+ "Something went wrong with a Tool Dynamism Tablet! Check your FML log."));
((EntityPlayer) player).addChatComponentMessage(
new ChatComponentText(
EnumChatFormatting.RED + "" + EnumChatFormatting.ITALIC + e.getMessage()));
if (isIdle() && hit != null && (!redstone || isBreaking)) {
if (hit.typeOfHit == MovingObjectPosition.MovingObjectType.MISS
&& (leftClick || !canPlaceItem(stack))) {
return;
}
initiateSwing();
}
}
if (done) {
stack = player.getCurrentEquippedItem();
if (stack == null || stack.stackSize <= 0) setInventorySlotContents(0, null);
else if (stack != getStackInSlot(0)) setInventorySlotContents(0, stack);
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
markDirty();
}
// Copied from ItemInWorldManager, seems to do the trick.
private void stopBreaking() {
isBreaking = false;
ChunkCoordinates coords = getTargetLoc();
worldObj.destroyBlockInWorldPartially(player.getEntityId(), coords.posX, coords.posY, coords.posZ, -1);
}
// Copied from ItemInWorldManager, seems to do the trick.
private void startBreaking(Block block, int meta) {
int side = SIDES[(getBlockMetadata() & 7) - 2].getOpposite().ordinal();
ChunkCoordinates coords = getTargetLoc();
PlayerInteractEvent event = ForgeEventFactory.onPlayerInteract(
player,
Action.LEFT_CLICK_BLOCK,
coords.posX,
coords.posY,
coords.posZ,
side,
worldObj);
if (event.isCanceled()) {
stopBreaking();
return;
}
initialDamage = curblockDamage;
float var5 = 1F;
if (block != null) {
if (event.useBlock != Event.Result.DENY)
block.onBlockClicked(worldObj, coords.posX, coords.posY, coords.posZ, player);
var5 = block.getPlayerRelativeBlockHardness(player, worldObj, coords.posX, coords.posY, coords.posZ);
}
if (event.useItem == Event.Result.DENY) {
stopBreaking();
return;
}
if (var5 >= 1F) {
tryHarvestBlock(coords.posX, coords.posY, coords.posZ);
stopBreaking();
} else {
int var7 = (int) (var5 * 10);
worldObj.destroyBlockInWorldPartially(player.getEntityId(), coords.posX, coords.posY, coords.posZ, var7);
durabilityRemainingOnBlock = var7;
}
}
// Copied from ItemInWorldManager, seems to do the trick.
private void continueBreaking() {
++curblockDamage;
int var1;
float var4;
int var5;
ChunkCoordinates coords = getTargetLoc();
var1 = curblockDamage - initialDamage;
Block block = worldObj.getBlock(coords.posX, coords.posY, coords.posZ);
if (block == Blocks.air) stopBreaking();
else {
var4 = block.getPlayerRelativeBlockHardness(player, worldObj, coords.posX, coords.posY, coords.posZ) * var1;
var5 = (int) (var4 * 10);
if (var5 != durabilityRemainingOnBlock) {
worldObj.destroyBlockInWorldPartially(
player.getEntityId(),
coords.posX,
coords.posY,
coords.posZ,
var5);
durabilityRemainingOnBlock = var5;
}
if (var4 >= 1F) {
tryHarvestBlock(coords.posX, coords.posY, coords.posZ);
stopBreaking();
} catch (Exception e) {
e.printStackTrace();
List<EntityPlayer> list = worldObj.getEntitiesWithinAABB(
EntityPlayer.class,
AxisAlignedBB
.getBoundingBox(xCoord - 8, yCoord - 8, zCoord - 8, xCoord + 8, yCoord + 8, zCoord + 8));
for (EntityPlayer player : list) {
player.addChatComponentMessage(
new ChatComponentText(
EnumChatFormatting.RED
+ "Something went wrong with a Tool Dynamism Tablet! Check your FML log."));
player.addChatComponentMessage(
new ChatComponentText(
EnumChatFormatting.RED.toString() + EnumChatFormatting.ITALIC + e.getMessage()));
}
}
}
// Copied from ItemInWorldManager, seems to do the trick.
public boolean tryHarvestBlock(int par1, int par2, int par3) {
ItemStack stack = getStackInSlot(0);
if (stack != null && stack.getItem().onBlockStartBreak(stack, par1, par2, par3, player)) return false;
Block block = worldObj.getBlock(par1, par2, par3);
int var5 = worldObj.getBlockMetadata(par1, par2, par3);
// worldObj.playAuxSFXAtEntity(player, 2001, par1, par2, par3, var4 + (var5 << 12));
boolean var6;
boolean var8 = false;
if (block != null) var8 = block.canHarvestBlock(player, var5);
worldObj.loadedEntityList.size();
if (stack != null) stack.getItem().onBlockDestroyed(stack, worldObj, block, par1, par2, par3, player);
var6 = removeBlock(par1, par2, par3);
if (var6 && var8) block.harvestBlock(worldObj, player, par1, par2, par3, var5);
return var6;
}
// Copied from ItemInWorldManager, seems to do the trick.
private boolean removeBlock(int par1, int par2, int par3) {
Block var4 = worldObj.getBlock(par1, par2, par3);
int var5 = worldObj.getBlockMetadata(par1, par2, par3);
if (var4 != null) var4.onBlockHarvested(worldObj, par1, par2, par3, var5, player);
boolean var6 = var4 != null && var4.removedByPlayer(worldObj, player, par1, par2, par3);
if (var4 != null && var6) var4.onBlockDestroyedByPlayer(worldObj, par1, par2, par3, var5);
return var6;
}
public boolean detect() {
ChunkCoordinates coords = getTargetLoc();
findEntities(coords);
return !worldObj.isAirBlock(coords.posX, coords.posY, coords.posZ) || !detectedEntities.isEmpty();
}
public void findEntities(ChunkCoordinates coords) {
AxisAlignedBB boundingBox = AxisAlignedBB.getBoundingBox(
coords.posX,
coords.posY,
coords.posZ,
coords.posX + 1,
coords.posY + 1,
coords.posZ + 1);
detectedEntities = worldObj.getEntitiesWithinAABB(Entity.class, boundingBox);
private boolean canPlaceItem(ItemStack stack) {
final Item item = stack.getItem();
return item instanceof ItemBlock || item instanceof ItemReed;
}
@Override
public void validate() {
super.validate();
player = new TabletFakePlayer(this);
if (!worldObj.isRemote) {
if (player == null) {
player = new TabletFakePlayer(this);
}
player.worldObj = this.worldObj;
}
}
public ChunkCoordinates getTargetLoc() {
ChunkCoordinates coords = new ChunkCoordinates(xCoord, yCoord, zCoord);
private void swingHit(ItemStack stack, MovingObjectPosition hit) {
if (leftClick) {
if (hit.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY) {
player.attackTargetEntityWithCurrentItem(hit.entityHit);
updateState();
} else if (hit.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) {
if (!isBreaking) {
int x = hit.blockX;
int y = hit.blockY;
int z = hit.blockZ;
Block block = worldObj.getBlock(x, y, z);
if (!block.isAir(worldObj, x, y, z) && block.getBlockHardness(worldObj, x, y, z) >= 0) {
isBreaking = true;
player.theItemInWorldManager.onBlockClicked(x, y, z, hit.sideHit);
updateState();
}
}
}
} else {
if (hit.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY) {
if (player.interactWith(hit.entityHit)) {
updateState();
}
return;
}
int side = hit.sideHit;
int x = hit.blockX;
int y = hit.blockY;
int z = hit.blockZ;
// Copied from Minecraft's right click logic
boolean result = !ForgeEventFactory
.onPlayerInteract(player, PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK, x, y, z, side, worldObj)
.isCanceled();
if (result) {
Vec3 hitVec = hit.hitVec;
if (player.onPlayerRightClick(
stack,
x,
y,
z,
side,
(float) hitVec.xCoord,
(float) hitVec.yCoord,
(float) hitVec.zCoord)) {
updateState();
return;
}
}
if (player.sendUseItem(stack)) {
updateState();
}
}
}
public final boolean isIdle() {
return swingMod == 0;
}
public final boolean getIsBreaking() {
return isBreaking;
}
private void stopSwinging() {
swingProgress = 0;
swingMod = 0;
}
// Copied from ItemInWorldManager, seems to do the trick.
private void stopBreaking() {
player.theItemInWorldManager.updateBlockRemoving();
isBreaking = false;
int[] increase = LOC_INCREASES[(getBlockMetadata() & 7) - 2];
int x = xCoord + increase[0];
int y = yCoord;
int z = zCoord + increase[1];
worldObj.destroyBlockInWorldPartially(player.getEntityId(), x, y, z, -1);
}
private void updateState() {
ItemStack stack = player.getHeldItem();
if (stack == null || stack.stackSize <= 0) {
this.heldItem = null;
player.syncSlots();
} else {
this.heldItem = stack;
}
markDirty();
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
/**
* Logic: Casts a ray between the player and the middle of the AABB to determine the side and hitVec. Works for both
* entities and blocks. Whichever is closer takes priority.
* <p>
* This is similar to how Minecraft calculates the MovingObjectPosition, but instead of yaw/pitch I use the middle
* of the bounding box to cover edge where blocks have a weird bounding box.
* <p>
* hit.typeOfHit will be MISS if it's targeting the block below (this is done so that placing blocks still properly
* works).
* <p>
* This is an improvement to the old system, because it properly knows whether to hit an entity or block and also
* passes in the proper parameters when interacting with a block (this has previously caused some issues with
* certain blocks).
*/
private MovingObjectPosition calculateHit() {
int meta = getBlockMetadata();
if (meta == 0) {
ThaumicTinkerer.log
.error("Metadata of a Tool Dynamism tablet is in an invalid state. This is a critical error.");
return coords;
return null;
}
int[] increase = LOC_INCREASES[(meta & 7) - 2];
coords.posX += increase[0];
coords.posZ += increase[1];
int x = xCoord + increase[0];
int y = yCoord;
int z = zCoord + increase[1];
Block block = worldObj.getBlock(x, y, z);
return coords;
MovingObjectPosition hit = null;
Vec3 position = positionVec;
position.xCoord = xCoord + 0.5f;
position.yCoord = yCoord + 0.5f;
position.zCoord = zCoord + 0.5f;
if (!worldObj.isAirBlock(x, y, z)) {
AxisAlignedBB aabb = block.getSelectedBoundingBoxFromPool(worldObj, x, y, z);
if (aabb != null) {
hit = block.collisionRayTrace(worldObj, x, y, z, position, getMiddleOfAABB(aabb));
}
}
List<Entity> entities = (List<Entity>) worldObj.getEntitiesWithinAABBExcludingEntity(
player,
AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 1, z + 1));
if (!entities.isEmpty()) {
double dist = hit == null ? Double.MAX_VALUE : position.squareDistanceTo(hit.hitVec);
Entity targetedEntity = null;
Vec3 hitVec = null;
for (Entity e : entities) {
if (e.canBeCollidedWith()) {
float borderSize = e.getCollisionBorderSize();
AxisAlignedBB aabb = e.boundingBox.expand(borderSize, borderSize, borderSize);
MovingObjectPosition intercept = aabb.calculateIntercept(position, getMiddleOfAABB(aabb));
if (aabb.isVecInside(position)) {
targetedEntity = e;
hitVec = intercept == null ? position : intercept.hitVec;
break;
}
if (intercept != null) {
double entityDist = position.squareDistanceTo(intercept.hitVec);
if (dist > entityDist) {
hitVec = intercept.hitVec;
targetedEntity = e;
dist = entityDist;
}
}
}
}
if (targetedEntity != null) {
hit = new MovingObjectPosition(targetedEntity, hitVec);
}
}
if (hit == null) {
// Use the block beneath
y--;
if (!worldObj.isAirBlock(x, y, z)) {
AxisAlignedBB aabb = block.getSelectedBoundingBoxFromPool(worldObj, x, y, z);
Vec3 vec = getMiddleOfAABB(aabb);
vec.yCoord = (aabb.maxY - y);
hit = new MovingObjectPosition(x, y, z, ForgeDirection.UP.ordinal(), vec, false);
}
}
return hit;
}
public boolean getIsBreaking() {
return isBreaking;
private Vec3 getMiddleOfAABB(AxisAlignedBB aabb) {
tempVec.xCoord = (aabb.minX + aabb.maxX) / 2f;
tempVec.yCoord = (aabb.minY + aabb.maxY) / 2f;
tempVec.zCoord = (aabb.minZ + aabb.maxZ) / 2f;
return tempVec;
}
public void initiateSwing() {
swingMod = SWING_SPEED;
worldObj.addBlockEvent(xCoord, yCoord, zCoord, TTRegistry.dynamismTablet, 0, 0);
}
@Override
public boolean receiveClientEvent(int par1, int par2) {
if (par1 == 0) {
initiateSwing();
public boolean receiveClientEvent(int id, int type) {
if (!worldObj.isRemote) return true;
if (id == 0) {
swingMod = SWING_SPEED;
swingProgress = 0;
return true;
}
@@ -403,82 +408,86 @@ public class TileAnimationTablet extends TileEntity implements IInventory, IMova
}
@Override
public void readFromNBT(NBTTagCompound par1NBTTagCompound) {
super.readFromNBT(par1NBTTagCompound);
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
swingProgress = par1NBTTagCompound.getInteger(TAG_PROGRESS);
swingProgress = tag.getByte(TAG_PROGRESS);
swingMod = tag.getByte(TAG_MOD);
readCustomNBT(par1NBTTagCompound);
readCustomNBT(tag);
}
@Override
public void writeToNBT(NBTTagCompound par1NBTTagCompound) {
super.writeToNBT(par1NBTTagCompound);
public void writeToNBT(NBTTagCompound tag) {
super.writeToNBT(tag);
par1NBTTagCompound.setInteger(TAG_PROGRESS, swingProgress);
par1NBTTagCompound.setInteger(TAG_MOD, swingMod);
// par1NBTTagCompound.setString(TAG_OWNER,Owner);
writeCustomNBT(par1NBTTagCompound);
tag.setByte(TAG_PROGRESS, swingProgress);
tag.setByte(TAG_MOD, swingMod);
writeCustomNBT(tag);
}
public void readCustomNBT(NBTTagCompound par1NBTTagCompound) {
leftClick = par1NBTTagCompound.getBoolean(TAG_LEFT_CLICK);
redstone = par1NBTTagCompound.getBoolean(TAG_REDSTONE);
NBTTagList var2 = par1NBTTagCompound.getTagList("Items", Constants.NBT.TAG_COMPOUND);
inventorySlots = new ItemStack[getSizeInventory()];
for (int var3 = 0; var3 < var2.tagCount(); ++var3) {
NBTTagCompound var4 = var2.getCompoundTagAt(var3);
byte var5 = var4.getByte("Slot");
if (var5 >= 0 && var5 < inventorySlots.length) inventorySlots[var5] = ItemStack.loadItemStackFromNBT(var4);
private void readCustomNBT(NBTTagCompound tag) {
leftClick = tag.getBoolean(TAG_LEFT_CLICK);
redstone = tag.getBoolean(TAG_REDSTONE);
if (tag.hasKey("Item")) {
NBTTagCompound itemTag = tag.getCompoundTag("Item");
heldItem = ItemStack.loadItemStackFromNBT(itemTag);
return;
}
// Legacy Compatibility (there is no reason to store it as an array)
NBTTagList tagList = tag.getTagList("Items", Constants.NBT.TAG_COMPOUND);
if (tagList.tagCount() != 0) {
heldItem = ItemStack.loadItemStackFromNBT(tagList.getCompoundTagAt(0));
}
}
public void writeCustomNBT(NBTTagCompound par1NBTTagCompound) {
par1NBTTagCompound.setBoolean(TAG_LEFT_CLICK, leftClick);
par1NBTTagCompound.setBoolean(TAG_REDSTONE, redstone);
NBTTagList var2 = new NBTTagList();
for (int var3 = 0; var3 < inventorySlots.length; ++var3) {
if (inventorySlots[var3] != null) {
NBTTagCompound var4 = new NBTTagCompound();
var4.setByte("Slot", (byte) var3);
inventorySlots[var3].writeToNBT(var4);
var2.appendTag(var4);
}
}
par1NBTTagCompound.setTag("Items", var2);
@Override
public S35PacketUpdateTileEntity getDescriptionPacket() {
NBTTagCompound tag = new NBTTagCompound();
writeCustomNBT(tag);
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, -999, tag);
}
@Override
public void onDataPacket(NetworkManager manager, S35PacketUpdateTileEntity packet) {
super.onDataPacket(manager, packet);
readCustomNBT(packet.func_148857_g());
}
private void writeCustomNBT(NBTTagCompound tag) {
tag.setBoolean(TAG_LEFT_CLICK, leftClick);
tag.setBoolean(TAG_REDSTONE, redstone);
tag.setTag("Item", heldItem == null ? new NBTTagCompound() : heldItem.writeToNBT(new NBTTagCompound()));
}
@Override
public int getSizeInventory() {
return inventorySlots.length;
return 1;
}
@Override
public ItemStack getStackInSlot(int i) {
return inventorySlots[i];
return i == 0 ? heldItem : null;
}
@Override
public ItemStack decrStackSize(int par1, int par2) {
if (inventorySlots[par1] != null) {
public ItemStack decrStackSize(int index, int count) {
if (index == 0 && heldItem != null) {
ItemStack stackAt;
if (inventorySlots[par1].stackSize <= par2) {
stackAt = inventorySlots[par1];
inventorySlots[par1] = null;
if (heldItem.stackSize <= count) {
stackAt = heldItem;
heldItem = null;
if (!worldObj.isRemote) worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
return stackAt;
} else {
stackAt = inventorySlots[par1].splitStack(par2);
stackAt = heldItem.splitStack(count);
if (inventorySlots[par1].stackSize == 0) inventorySlots[par1] = null;
if (!worldObj.isRemote) worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
return stackAt;
if (heldItem.stackSize == 0) heldItem = null;
}
if (!worldObj.isRemote) worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
return stackAt;
}
return null;
@@ -491,7 +500,8 @@ public class TileAnimationTablet extends TileEntity implements IInventory, IMova
@Override
public void setInventorySlotContents(int i, ItemStack itemstack) {
inventorySlots[i] = itemstack;
if (i != 0) return;
heldItem = itemstack;
if (!worldObj.isRemote) worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
@@ -528,19 +538,6 @@ public class TileAnimationTablet extends TileEntity implements IInventory, IMova
@Override
public void closeInventory() {}
@Override
public S35PacketUpdateTileEntity getDescriptionPacket() {
NBTTagCompound nbttagcompound = new NBTTagCompound();
writeCustomNBT(nbttagcompound);
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, -999, nbttagcompound);
}
@Override
public void onDataPacket(NetworkManager manager, S35PacketUpdateTileEntity packet) {
super.onDataPacket(manager, packet);
readCustomNBT(packet.func_148857_g());
}
@Override
public String getType() {
return "tt_animationTablet";
@@ -556,39 +553,23 @@ public class TileAnimationTablet extends TileEntity implements IInventory, IMova
@Optional.Method(modid = "ComputerCraft")
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments)
throws LuaException {
switch (method) {
case 0:
return new Object[] { redstone };
case 1:
return setRedstoneImplementation((Boolean) arguments[0]);
case 2:
return new Object[] { leftClick };
case 3:
return setLeftClickImplementation((Boolean) arguments[0]);
case 4:
return new Object[] { getBlockMetadata() - 2 };
case 5:
return setRotationImplementation((Double) arguments[0]);
case 6:
return new Object[] { getStackInSlot(0) != null };
case 7:
return triggerImplementation();
}
return null;
return switch (method) {
case 0 -> new Object[] { redstone };
case 1 -> setRedstoneImplementation((Boolean) arguments[0]);
case 2 -> new Object[] { leftClick };
case 3 -> setLeftClickImplementation((Boolean) arguments[0]);
case 4 -> new Object[] { getBlockMetadata() - 2 };
case 5 -> setRotationImplementation((Double) arguments[0]);
case 6 -> new Object[] { heldItem != null };
case 7 -> triggerImplementation();
default -> null;
};
}
private Object[] triggerImplementation() {
if (swingProgress != 0) return new Object[] { false };
if (!isIdle()) return new Object[] { false };
findEntities(getTargetLoc());
initiateSwing();
worldObj.addBlockEvent(
xCoord,
yCoord,
zCoord,
ThaumicTinkerer.registry.getFirstBlockFromClass(BlockAnimationTablet.class),
0,
0);
return new Object[] { true };
}
@@ -651,26 +632,30 @@ public class TileAnimationTablet extends TileEntity implements IInventory, IMova
@Callback(doc = "function():boolean -- Returns Whether tablet is redstone activated")
@Optional.Method(modid = "OpenComputers")
public Object[] getRedstone(Context context, Arguments args) throws Exception {
@SuppressWarnings("unused")
public Object[] getRedstone(Context context, Arguments args) {
return new Object[] { redstone };
}
@Callback(doc = "function(boolean):Nil -- Sets Whether tablet is redstone activated")
@Optional.Method(modid = "OpenComputers")
public Object[] setRedstone(Context context, Arguments args) throws Exception {
@SuppressWarnings("unused")
public Object[] setRedstone(Context context, Arguments args) {
setRedstoneImplementation(args.checkBoolean(0));
return new Object[] { redstone };
}
@Callback(doc = "function():boolean -- Returns Whether tablet Left clicks")
@Optional.Method(modid = "OpenComputers")
public Object[] getLeftClick(Context context, Arguments args) throws Exception {
@SuppressWarnings("unused")
public Object[] getLeftClick(Context context, Arguments args) {
return new Object[] { leftClick };
}
@Callback(doc = "function(boolean):Nil -- Sets Whether tablet Left Clicks")
@Optional.Method(modid = "OpenComputers")
public Object[] setLeftClick(Context context, Arguments args) throws Exception {
@SuppressWarnings("unused")
public Object[] setLeftClick(Context context, Arguments args) {
setLeftClickImplementation(args.checkBoolean(0));
return new Object[] { leftClick };
}
@@ -678,26 +663,30 @@ public class TileAnimationTablet extends TileEntity implements IInventory, IMova
// TODO {"hasItem", "trigger" };
@Callback(doc = "function():number -- Returns tablet Rotation")
@Optional.Method(modid = "OpenComputers")
public Object[] getRotation(Context context, Arguments args) throws Exception {
@SuppressWarnings("unused")
public Object[] getRotation(Context context, Arguments args) {
return new Object[] { getBlockMetadata() - 2 };
}
@Callback(doc = "function(number):Nil -- Sets tablet rotation")
@Optional.Method(modid = "OpenComputers")
public Object[] setRotation(Context context, Arguments args) throws Exception {
@SuppressWarnings("unused")
public Object[] setRotation(Context context, Arguments args) throws LuaException {
setRotationImplementation((double) args.checkInteger(0));
return new Object[] { getBlockMetadata() - 2 };
}
@Callback(doc = "function():boolean -- Returns wether tablet has an item or not")
@Optional.Method(modid = "OpenComputers")
public Object[] hasItem(Context context, Arguments args) throws Exception {
return new Object[] { getStackInSlot(0) != null };
@SuppressWarnings("unused")
public Object[] hasItem(Context context, Arguments args) {
return new Object[] { heldItem != null };
}
@Callback(doc = "function():Nil -- Triggers tablets swing")
@Optional.Method(modid = "OpenComputers")
public Object[] trigger(Context context, Arguments args) throws Exception {
@SuppressWarnings("unused")
public Object[] trigger(Context context, Arguments args) {
return triggerImplementation();
}
}
@@ -20,6 +20,7 @@ import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import thaumic.tinkerer.client.lib.LibResources;
import thaumic.tinkerer.common.ThaumicTinkerer;
import thaumic.tinkerer.common.block.BlockAnimationTablet;
import thaumic.tinkerer.common.core.handler.ModCreativeTab;
import thaumic.tinkerer.common.item.kami.ItemBlockTalisman;
import thaumic.tinkerer.common.item.kami.ItemPlacementMirror;
@@ -33,6 +34,7 @@ public class TTRegistry {
private ArrayList<Class> blockClasses = new ArrayList<>();
private HashMap<Class, ArrayList<Block>> blockRegistry = new HashMap<>();
public static Block dynamismTablet;
public static Item itemPlacementMirror;
public static Item itemBlackHoleTalisman;
@@ -177,6 +179,7 @@ public class TTRegistry {
}
}
dynamismTablet = ThaumicTinkerer.registry.getFirstBlockFromClass(BlockAnimationTablet.class);
itemBlackHoleTalisman = getFirstItemFromClass(ItemBlockTalisman.class);
itemPlacementMirror = getFirstItemFromClass(ItemPlacementMirror.class);
}
@@ -0,0 +1,13 @@
package thaumic.tinkerer.mixins.early;
import net.minecraft.server.management.ItemInWorldManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ItemInWorldManager.class)
public interface AccessorItemInWorldManager {
@Accessor
int getDurabilityRemainingOnBlock();
}
@@ -99,8 +99,8 @@ public class ThaumicTLoaderContainer extends DummyModContainer implements IFMLLo
@Override
public List<String> getMixins(Set<String> loadedCoreMods) {
if (!FMLLaunchHandler.side().isClient()) {
return Collections.emptyList();
return Collections.singletonList("AccessorItemInWorldManager");
}
return Collections.singletonList("renderer.MixinRenderBlocks");
return Arrays.asList("renderer.MixinRenderBlocks", "AccessorItemInWorldManager");
}
}