Much Golem

Added Core Mod.
Added Golem hook system and API.
Added Golem Wifi Backpack, #213
Fixed bug: A.C.T. didn't copy item on middle click when in creative
mode.
Fixed bug: D.P.E. would eat item stacks on shift+click.
This commit is contained in:
Chris committed 2016-01-19 01:48:09 -05:00
1 parent ae17e65313
commit c222d94ceb
95 files changed
+3513 -434

No files matched your search

+25 -1
View File
@@ -1,4 +1,28 @@
01/11/2016 0.10.0.0 - Beta
01/18/2016 0.10.0.0 - Beta
Fixed bug where DPE would eat item stacks.
Refactored golem network code.
01/17/2016 0.10.0.0 - Beta
Cleaned up backpack render code.
Cleaned up and documented IGolemHookHandler interface.
Added AE network capabilities to golem backpack.
01/16/2016 0.10.0.0 - Beta
Work on golem hooks & sync
Work on item and wifi backpack.
Fixed bug: A.C.T. didn't copy item on middle click when in creative mode.
01/15/2016 0.10.0.0 - Beta
Work on golem hooks
Work on item and wifi backpack.
01/14/2016 0.10.0.0 - Beta
Work on golem hooks
01/13/2016 0.10.0.0 - Beta
Began looking into #213
01/11/2016 0.10.0.0 - Beta
Fixed occasional crash when the Knowledge Inscriber GUI was clicked.
Added locked/unlocked texture & indicator to storage monitors.
Fixed bug where autocrafting gui didn't always show the item being crafted.
+6
View File
@@ -19,3 +19,9 @@ Compile
1. Get [AE2 API](http://ae-mod.info/Downloads/), [CoFHCore API](http://minecraft.curseforge.com/mc-mods/69162-cofhcore/files), and [Thaumcraft API](http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/1292130-thaumcraft-4-2-3-5-updated-2015-2-17) and put it in a new folder "libs/"
2. Run ./gradlew setupDecompWorkspace build
3. Your build shall be in build/libs/
Debug
-------
1) Do step 1 of compile
2) Add "-Dfml.coreMods.load=thaumicenergistics.fml.ThECore", without quotes, to your run & debug configuration.
In Eclipse, Menu: Run > Run|Debug Configurations > Arguments Tab > VM Arguments.
+7
View File
@@ -83,3 +83,10 @@ processResources
exclude 'mcmod.info'
}
}
jar {
manifest {
attributes 'FMLCorePlugin': 'thaumicenergistics.fml.ThECore',
'FMLCorePluginContainsFMLMod': 'true'
}
}
@@ -2,6 +2,7 @@ package thaumicenergistics.api;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import thaumicenergistics.api.entities.IGolemHookHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -42,6 +43,13 @@ public interface IThEInteractionHelper
*/
public abstract void openWirelessTerminalGui( final EntityPlayer player );
/**
* Registers a handler to receive golem events.
*
* @param handler
*/
public abstract void registerGolemHookHandler( IGolemHookHandler handler );
/**
* Attempts to set the Arcane Crafting Terminals recipe to the items
* specified for the current player.
@@ -33,4 +33,6 @@ public abstract class IThEItems
public IThEItemDescription KnowledgeCore;
public IThEItemDescription WandFocusAEWrench;
public IThEItemDescription GolemWifiBackpack;
}
@@ -0,0 +1,196 @@
package thaumicenergistics.api.entities;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import thaumcraft.common.entities.golems.EntityGolemBase;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* Defines the methods required to interact with the golem hook system.</br>
* The {@code handlerData} object can be anything that you would like and will never be touched by anything
* other than the {@code IGolemHookHandler} that created it. It simply serves as a means to attach instance
* data to a golem.<br/>
* <hr/>
* <strong>Keeping data synchronized.</strong><br/>
* If you have data you need to send to the client, you can register that data when {@link #addDefaultSyncEntries} is called. In order to reduce the
* amount of data that is sent to clients, you can only register individual characters of data.<br/>
* Keep in mind that the handlerData on the server-side will not automatically match the handlerData on the client side. You must perform the
* synchronization yourself. The only data shared between the server and client are the registered sync characters.<br/>
* <strong>Example situation</strong>
* <ol>
* <li>[BothSides] Handler receives call to {@link #addDefaultSyncEntries}<br/>
* Registers character with default value of 'n'<br/>
* Receives ID of 13.</li>
* <li>[Server] Handler receives call to {@link #customInteraction} an creates a complex object as its handler data.</li>
* <li>[Server] Handler receives call to {@link #setupGolem}.<br/>
* Handler sees that it's handlerData is not null, and verifies the data.<br/>
* Handler then sets character ID 13 to 'y'</li>
* <li>Data is sync'd and both sides have a value of 'y' in character ID 13.</li>
* <li>[Client] Handler receives call to {@link #onSyncDataChanged}<br/>
* Handlers sees that character ID 13 has a value of 'y'<br/>
* Handler then sets its handlerData to String("Active")</li>
* <li>[Client] Handler receives call to {@link #renderGolem}<br/>
* Handler sees that its handlerData is not null, verifies that it equals String("Active")<br/>
* Handler then performs its render.</li>
* </ol>
* In the above situation, the handlerData on both sides differs, but the complex object is only need on the server side. The client only needs to
* know that the server-side handler has placed a 'y'(yes) value in the sync data, and therefore the server expects all clients to perform the special
* render.<br/>
* Following the above situation, if later during a call to setupGolem the server-side handler sets the sync character to 'n'(no), when the client
* receives the update, the client-side handlerData can be set to, for example, null. This will let the handler know to not perform the special
* render.<br/>
* </br> If you want to see an example of a class that implements this, lookup my {@code WirelessGolemHandler} class on the ThE github.
*
* @author Nividica
*
* @see IGolemHookSyncRegistry
*
*/
public interface IGolemHookHandler
{
/**
* Any data you wish to sync between the server and clients can be added here.<br/>
* The added bytes are considered the default state, and will be added to all golems in that state.
*
* @param syncRegistry
*/
public void addDefaultSyncEntries( @Nonnull IGolemHookSyncRegistry syncRegistry );
/**
* Return true if you can handle this interaction.<br/>
*
* @param golem
* @param handlerData
* Handler data attached to the golem.
* @param player
* @param side
* Server or Client
* @return True will cause customInteraction to be called.<br>
* If any handlers return true, the setupGolem method will be called once all handlers
* have finished the interaction.
*/
public boolean canHandleInteraction( @Nonnull final EntityGolemBase golem, @Nullable Object handlerData, @Nonnull EntityPlayer player,
@Nonnull Side side );
/**
* Called when the golem has been interacted with and it hasn't been handled by Thaumcraft.<br/>
*
* @param golem
* @param handlerData
* Handler data attached to the golem.
* @param player
* @param side
* Server or Client
* @return Return the handler data you wish to attach to the golem, or null to clear any attached data.
*/
@Nullable
public Object customInteraction( @Nonnull final EntityGolemBase golem, @Nullable Object handlerData, @Nonnull EntityPlayer player,
@Nonnull Side side );
/**
* Return true if your handler wants to be called when a golem is rendered.<br/>
* Note: This is called only once during registration.
*
* @return
*/
public boolean needsRenderer();
/**
* Called when the golem was left clicked by a player holding the Golemancers Bell.
*
* @param golem
* @param handlerData
* Handler data attached to the golem.
* @param itemGolemPlacer
* Itemstack that will be used to hold the golem.
* @param player
* @param dismantled
* True if the golem will drop its core and upgrades.
* @param side
* Server or Client @Nonnull Side side
*/
public void onBellLeftClick( @Nonnull final EntityGolemBase golem, @Nullable Object handlerData, @Nonnull ItemStack itemGolemPlacer,
@Nonnull EntityPlayer player, boolean dismantled, @Nonnull Side side );
/**
* Called when sync data has changed.
*
* @param syncData
* @param clientHandlerData
* Handler data attached to the golem on the client side.
* @return Return the handler data you wish to attach to the golem, or null to clear any attached data.
*/
@SideOnly(Side.CLIENT)
public Object onSyncDataChanged( @Nonnull IGolemHookSyncRegistry syncData, @Nullable Object clientHandlerData );
/**
* Called when reading the golem's NBT.<br />
* Note: Called during a world load, not when the golem is placed via its item.
*
* @param golem
* @param syncData
* @param nbtTag
* @return Return the handler data you wish to attach to the golem, or null to clear any attached data.
*/
@Nullable
public Object readEntityFromNBT( @Nonnull final EntityGolemBase golem, @Nonnull IGolemHookSyncRegistry syncData, @Nonnull NBTTagCompound nbtTag );
/**
* Called when a golem is being rendered, if {@code needsRenderer} returned true during registration.
*
* @param golem
* @param clientHandlerData
* @param x
* @param y
* @param z
* @param partialElaspsedTick
*/
@SideOnly(Side.CLIENT)
public void renderGolem( @Nonnull EntityGolemBase golem, @Nullable Object clientHandlerData, double x, double y, double z,
float partialElaspsedTick );
/**
* Called just before the golem has finished setting up.<br/>
* If you are adding an AI script(s) to the golem, be aware that Thaumcraft clears all of the golems scripts at the beginning of this call. You
* will need to add the script(s) each time this is called, but you do not need to worry about removing them.<br/>
* Note: The golems inventory may not be ready.
*
* @param golem
* @param handlerData
* Handler data attached to the golem.
* @param side
* Server or Client
* @return Return the handler data you wish to attach to the golem, or null to clear any attached data.
*/
@Nullable
public Object setupGolem( @Nonnull final EntityGolemBase golem, @Nullable Object handlerData, @Nonnull IGolemHookSyncRegistry syncData,
@Nonnull Side side );
/**
* Called when a golem is being spawned via it's item.<br/>
* Note: This is not called if the item has no NBT data.
*
* @param golem
* @param itemGolemPlacer
* @param side
* Server or Client
* @return Return the handler data you wish to attach to the golem, or null to clear any attached data.
*/
@Nullable
public Object spawnGolemFromItemStack( @Nonnull final EntityGolemBase golem, @Nonnull ItemStack itemGolemPlacer, @Nonnull Side side );
/**
* Called when saving the golem's NBT.<br />
* Note: Called during a world save, not when the golem is being turned into an item via Golemancer's Bell.
*
* @param golem
* @param serverHandlerData
* @param nbtTag
*/
public void writeEntityNBT( @Nonnull final EntityGolemBase golem, @Nullable Object serverHandlerData, @Nonnull NBTTagCompound nbtTag );
}
@@ -0,0 +1,39 @@
package thaumicenergistics.api.entities;
/**
* Allows a hook handler to register data to be synchronized between the server and clients.<br/>
*
* @author Nividica
*
*/
public interface IGolemHookSyncRegistry
{
/**
* Returns the sync char if it is mapped, returns {@code defaultChar} otherwise.
*
* @param id
* @param defaultChar
* @return
*/
char getSyncCharOrDefault( int id, char defaultChar );
/**
* Registers a new sync byte, and returns the ID that maps to it.<br/>
* Note: This can only be called during registration, will throw exception otherwise.
*
* @param handler
* @param c
* Initial value of the char.
* @return The ID of the char.
*/
int registerSyncChar( IGolemHookHandler handler, char c );
/**
* Updates the sync char.
*
* @param handler
* @param id
* @param c
*/
void updateSyncChar( IGolemHookHandler handler, int id, char c );
}
@@ -22,11 +22,11 @@ import thaumicenergistics.client.textures.AEStateIconsEnum;
import thaumicenergistics.client.textures.GuiTextureManager;
import thaumicenergistics.common.container.ContainerPartArcaneCraftingTerminal;
import thaumicenergistics.common.container.ContainerPartArcaneCraftingTerminal.ArcaneCrafingCost;
import thaumicenergistics.common.integration.tc.MEItemAspectBridgeContainer;
import thaumicenergistics.common.network.packet.server.Packet_S_ArcaneCraftingTerminal;
import thaumicenergistics.common.parts.PartArcaneCraftingTerminal;
import thaumicenergistics.common.registries.ThEStrings;
import thaumicenergistics.common.utils.ThEUtils;
import thaumicenergistics.integration.tc.MEItemAspectBridgeContainer;
import appeng.api.config.*;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
@@ -435,13 +435,12 @@ public class GuiArcaneCraftingTerminal
if( ( widgetStack.isCraftable() ) && ( mouseButton != ThEGuiHelper.MOUSE_BUTTON_RIGHT ) )
{
Packet_S_ArcaneCraftingTerminal.sendAutoCraft( this.player, widgetStack );
return;
}
}
else
{
// Let the server know the user is requesting an itemstack.
Packet_S_ArcaneCraftingTerminal.sendExtract( this.player, widgetStack, mouseButton, GuiScreen.isShiftKeyDown() );
}
// Let the server know the user is requesting an itemstack.
Packet_S_ArcaneCraftingTerminal.sendExtract( this.player, widgetStack, mouseButton, GuiScreen.isShiftKeyDown() );
}
// Stop searching
@@ -15,10 +15,10 @@ import thaumicenergistics.client.gui.widget.WidgetAspectSlot;
import thaumicenergistics.client.textures.AEStateIconsEnum;
import thaumicenergistics.client.textures.GuiTextureManager;
import thaumicenergistics.common.container.ContainerEssentiaCellWorkbench;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.network.packet.server.Packet_S_EssentiaCellWorkbench;
import thaumicenergistics.common.registries.ThEStrings;
import thaumicenergistics.common.tiles.TileEssentiaCellWorkbench;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -15,12 +15,12 @@ import thaumicenergistics.client.gui.widget.ThEWidget;
import thaumicenergistics.client.gui.widget.WidgetAspectSlot;
import thaumicenergistics.client.textures.GuiTextureManager;
import thaumicenergistics.common.container.ContainerPartEssentiaIOBus;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.network.packet.server.Packet_S_EssentiaIOBus;
import thaumicenergistics.common.parts.PartEssentiaExportBus;
import thaumicenergistics.common.parts.PartEssentiaImportBus;
import thaumicenergistics.common.parts.ThEPartEssentiaIOBus_Base;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import appeng.api.config.RedstoneMode;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -14,10 +14,10 @@ import thaumicenergistics.client.gui.widget.DigitTextField;
import thaumicenergistics.client.gui.widget.WidgetAspectSlot;
import thaumicenergistics.client.textures.GuiTextureManager;
import thaumicenergistics.common.container.ContainerPartEssentiaLevelEmitter;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.network.packet.server.Packet_S_EssentiaEmitter;
import thaumicenergistics.common.parts.PartEssentiaLevelEmitter;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import appeng.api.config.RedstoneMode;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -19,11 +19,11 @@ import thaumicenergistics.client.textures.AEStateIconsEnum;
import thaumicenergistics.client.textures.GuiTextureManager;
import thaumicenergistics.common.ThEGuiHandler;
import thaumicenergistics.common.container.ContainerPartEssentiaStorageBus;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.network.packet.server.Packet_S_ChangeGui;
import thaumicenergistics.common.network.packet.server.Packet_S_EssentiaStorageBus;
import thaumicenergistics.common.parts.PartEssentiaStorageBus;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -212,12 +212,6 @@ public class ModelGearbox
@Override
public void render( final Entity entity, final float f, final float f1, final float f2, final float f3, final float f4, final float f5 )
{
// Call super
super.render( entity, f, f1, f2, f3, f4, f5 );
// Set the angles
this.setRotationAngles( f, f1, f2, f3, f4, f5, entity );
// Render the transmission
this.Transmission.render( f5 );
@@ -233,12 +227,6 @@ public class ModelGearbox
}
@Override
public void setRotationAngles( final float f, final float f1, final float f2, final float f3, final float f4, final float f5, final Entity entity )
{
super.setRotationAngles( f, f1, f2, f3, f4, f5, entity );
}
/**
* Updates the model to match the tile entity data.
*
@@ -0,0 +1,194 @@
package thaumicenergistics.client.render.model;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import thaumicenergistics.common.ThaumicEnergistics;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ModelGolemWifiAddon
extends ModelBase
{
public static ResourceLocation TEXTURE = new ResourceLocation( ThaumicEnergistics.MOD_ID, "textures/models/golem.wifi.addon.png" );
/**
* Submodels
*/
private final ModelRenderer Antenna, PackBack, PackFront;
/**
* Pearl UV coords.
*/
private final float pearl_MinU, pearl_MaxU, pearl_MinV, pearl_MaxV;
/**
* Scale of the fluix pearls
*/
private final float pearlScale = 0.2f;
/**
* Distance from edge to edge of the antenna
*/
private final float antennaWidth = 0.32f;
/**
* Distance from the antenna to render the pearl faces
*/
private final float pearl_FaceDistance, pearl_2FD;
/**
* Rotation of the pearls
*/
private float pearlRotation = 0.0f;
private boolean isPearlCompiled = false;
private int pearlDispListID = -1;
public ModelGolemWifiAddon()
{
this.textureWidth = 16;
this.textureHeight = 16;
this.Antenna = new ModelRenderer( this, 10, 0 );
this.Antenna.addBox( -0.5f, -6f, -0.5f, 1, 3, 1 );
this.Antenna.setRotationPoint( 0, 0, 0f );
this.Antenna.setTextureSize( this.textureWidth, this.textureHeight );
this.Antenna.mirror = true;
this.setSubmodelRotation( this.Antenna, 3.14f, 0, 0 );
this.PackBack = new ModelRenderer( this, 0, 0 );
this.PackBack.addBox( -1f, -3f, -3f, 2, 6, 6 );
this.PackBack.setRotationPoint( 0, 0, 0f );
this.PackBack.setTextureSize( this.textureWidth, this.textureHeight );
this.PackBack.mirror = true;
this.setSubmodelRotation( this.PackBack, 3.14f, 0, 0 );
this.PackFront = new ModelRenderer( this, 2, 0 );
this.PackFront.addBox( -1.5f, -1f, -2f, 1, 2, 4 );
this.PackFront.setRotationPoint( 0, 0, 0f );
this.PackFront.setTextureSize( this.textureWidth, this.textureHeight );
this.PackFront.mirror = true;
this.setSubmodelRotation( this.PackFront, 3.14f, 0, 0 );
this.pearl_MinU = 8.0f / this.textureWidth;
this.pearl_MaxU = 13.5f / this.textureWidth;
this.pearl_MinV = 6.0f / this.textureHeight;
this.pearl_MaxV = 11.5f / this.textureHeight;
this.pearl_FaceDistance = -0.013f / this.pearlScale;
this.pearl_2FD = this.pearl_FaceDistance + this.pearl_FaceDistance;
}
private void compilePearl()
{
// Create a new list
this.pearlDispListID = GLAllocation.generateDisplayLists( 1 );
GL11.glNewList( this.pearlDispListID, GL11.GL_COMPILE );
// Get the tesselator
Tessellator tess = Tessellator.instance;
// Move to the left of the antenna
GL11.glTranslatef( -0.0955f, 0.275f, -0.045f );
// Scale down
GL11.glScalef( this.pearlScale, this.pearlScale, this.pearlScale );
// Draw left
this.drawPearlFaces( tess, this.pearl_MinU, this.pearl_MaxU );
// Move to the right of the antenna
GL11.glTranslatef( 0.0f, 0.0f, this.antennaWidth - this.pearl_2FD );
// Draw right
this.drawPearlFaces( tess, this.pearl_MaxU, this.pearl_MinU );
// Rotate 90
GL11.glRotatef( 90.0f, 0.0f, 1.0f, 0.0f );
// Move to the front of the antenna
GL11.glTranslatef( -this.antennaWidth - this.pearl_FaceDistance, 0.0f, this.antennaWidth + this.pearl_FaceDistance );
// Draw front
this.drawPearlFaces( tess, this.pearl_MaxU, this.pearl_MinU );
// Move to the back of the antenna
GL11.glTranslatef( 0.0f, 0.0f, this.antennaWidth - this.pearl_2FD );
// Draw back
this.drawPearlFaces( tess, this.pearl_MinU, this.pearl_MaxU );
// End the list
GL11.glEndList();
this.isPearlCompiled = true;
}
private void drawPearlFaces( final Tessellator tess, final float minU, final float maxU )
{
tess.startDrawingQuads();
// Face
tess.addVertexWithUV( 0.0D, 0.0D, 0.0D, maxU, this.pearl_MaxV );
tess.addVertexWithUV( 1.0D, 0.0D, 0.0D, minU, this.pearl_MaxV );
tess.addVertexWithUV( 1.0D, 1.0D, 0.0D, minU, this.pearl_MinV );
tess.addVertexWithUV( 0.0D, 1.0D, 0.0D, maxU, this.pearl_MinV );
// Back-face
tess.addVertexWithUV( 0.0D, 1.0D, 0.0D, maxU, this.pearl_MinV );
tess.addVertexWithUV( 1.0D, 1.0D, 0.0D, minU, this.pearl_MinV );
tess.addVertexWithUV( 1.0D, 0.0D, 0.0D, minU, this.pearl_MaxV );
tess.addVertexWithUV( 0.0D, 0.0D, 0.0D, maxU, this.pearl_MaxV );
tess.draw();
}
private void renderPearl( final float partialElapsedTick )
{
// Apply Y rotation
if( !Minecraft.getMinecraft().isGamePaused() )
{
this.pearlRotation += ( partialElapsedTick * 2.0f );
if( this.pearlRotation >= 360.0f )
{
this.pearlRotation -= 360.0f;
}
}
GL11.glRotatef( this.pearlRotation, 0.0f, 1.0f, 0.0f );
// Is the pearl compiled?
if( !this.isPearlCompiled )
{
// Compile the pearl
compilePearl();
}
// Draw the pearl
GL11.glCallList( this.pearlDispListID );
}
private void setSubmodelRotation( final ModelRenderer model, final float x, final float y, final float z )
{
model.rotateAngleX = x;
model.rotateAngleY = y;
model.rotateAngleZ = z;
}
@Override
public void render( final Entity entity, final float partialElapsedTick, final float f1, final float f2, final float f3, final float f4,
final float f5 )
{
Minecraft.getMinecraft().renderEngine.bindTexture( ModelGolemWifiAddon.TEXTURE );
this.PackBack.render( f5 );
this.PackFront.render( f5 );
this.Antenna.render( f5 );
this.renderPearl( partialElapsedTick );
}
}
@@ -2,10 +2,10 @@ package thaumicenergistics.common;
import net.minecraftforge.oredict.OreDictionary;
import thaumicenergistics.common.fluids.GaseousEssentia;
import thaumicenergistics.common.items.ItemEnum;
import thaumicenergistics.common.items.ItemMaterial;
import thaumicenergistics.common.registries.BlockEnum;
import thaumicenergistics.common.registries.FeatureRegistry;
import thaumicenergistics.common.registries.ItemEnum;
import thaumicenergistics.common.registries.TileEnum;
import appeng.api.AEApi;
import appeng.api.movable.IMovableRegistry;
@@ -6,13 +6,14 @@ import net.minecraft.item.ItemStack;
import thaumicenergistics.api.IThEConfig;
import thaumicenergistics.api.ThEApi;
import thaumicenergistics.api.grid.IEssentiaGrid;
import thaumicenergistics.common.entities.WirelessGolemHandler;
import thaumicenergistics.common.grid.GridEssentiaCache;
import thaumicenergistics.common.integration.IntegrationCore;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.integration.tc.EssentiaTileContainerHelper;
import thaumicenergistics.common.network.NetworkHandler;
import thaumicenergistics.common.registries.AEAspectRegister;
import thaumicenergistics.common.utils.ThELog;
import thaumicenergistics.integration.IntegrationCore;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.integration.tc.EssentiaTileContainerHelper;
import appeng.api.AEApi;
import cpw.mods.fml.common.*;
import cpw.mods.fml.common.Mod.EventHandler;
@@ -114,6 +115,9 @@ public class ThaumicEnergistics
// Register the essentia grid cache
AEApi.instance().registries().gridCache().registerGridCache( IEssentiaGrid.class, GridEssentiaCache.class );
// Register the wireless golem handler
ThEApi.instance().interact().registerGolemHookHandler( WirelessGolemHandler.getInstance() );
// Mark that ThE has finished Init
ThELog.endSection( "Load", startTime );
ThaumicEnergistics.ThEState = LoaderState.INITIALIZATION;
@@ -16,7 +16,7 @@ import thaumicenergistics.api.storage.IInventoryUpdateReceiver;
import thaumicenergistics.common.container.slot.SlotRestrictive;
import thaumicenergistics.common.inventory.TheInternalInventory;
import thaumicenergistics.common.items.ItemCraftingAspect;
import thaumicenergistics.common.registries.ItemEnum;
import thaumicenergistics.common.items.ItemEnum;
import thaumicenergistics.common.tiles.TileDistillationPatternEncoder;
import thaumicenergistics.common.utils.DistillationPatternHelper;
import thaumicenergistics.common.utils.EffectiveSide;
@@ -220,7 +220,9 @@ public class ContainerDistillationPatternEncoder
return this.mergeItemStack( slotStack, this.slotPatternEncoded.slotNumber, this.slotPatternEncoded.slotNumber + 1, false );
}
// Set the source slot
this.slotSourceItem.putStack( slotStack );
ItemStack copy = slotStack.copy();
copy.stackSize = 1;
this.slotSourceItem.putStack( copy );
return true;
}
@@ -12,6 +12,8 @@ import thaumicenergistics.api.grid.IMEEssentiaMonitor;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.grid.EssentiaMonitor;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper.AspectItemType;
import thaumicenergistics.common.inventory.HandlerItemEssentiaCell;
import thaumicenergistics.common.inventory.TheInternalInventory;
import thaumicenergistics.common.items.ItemEssentiaCell;
@@ -19,8 +21,6 @@ import thaumicenergistics.common.network.packet.client.Packet_C_EssentiaCellTerm
import thaumicenergistics.common.network.packet.server.Packet_S_EssentiaCellTerminal;
import thaumicenergistics.common.storage.AspectStackComparator.AspectStackComparatorMode;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper.AspectItemType;
import appeng.api.config.Settings;
import appeng.api.config.ViewItems;
import appeng.api.networking.IGrid;
@@ -18,6 +18,8 @@ import thaumicenergistics.api.gui.ICraftingIssuerContainer;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.api.storage.IEssentiaRepo;
import thaumicenergistics.common.container.slot.SlotRestrictive;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper.AspectItemType;
import thaumicenergistics.common.network.packet.client.Packet_C_EssentiaCellTerminal;
import thaumicenergistics.common.network.packet.client.Packet_C_Sync;
import thaumicenergistics.common.network.packet.server.Packet_S_EssentiaCellTerminal;
@@ -25,8 +27,6 @@ import thaumicenergistics.common.storage.AspectStack;
import thaumicenergistics.common.storage.EssentiaRepo;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.common.utils.ThEUtils;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper.AspectItemType;
import appeng.api.config.Actionable;
import appeng.api.config.SecurityPermissions;
import appeng.api.networking.IGrid;
@@ -7,10 +7,10 @@ import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.common.container.slot.SlotRestrictive;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.network.packet.client.Packet_C_AspectSlot;
import thaumicenergistics.common.tiles.TileEssentiaCellWorkbench;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
public class ContainerEssentiaCellWorkbench
extends ContainerWithPlayerInventory
@@ -14,14 +14,14 @@ import thaumcraft.api.crafting.IArcaneRecipe;
import thaumcraft.api.crafting.ShapedArcaneRecipe;
import thaumcraft.api.crafting.ShapelessArcaneRecipe;
import thaumicenergistics.common.container.slot.SlotRestrictive;
import thaumicenergistics.common.integration.tc.ArcaneCraftingPattern;
import thaumicenergistics.common.integration.tc.ArcaneRecipeHelper;
import thaumicenergistics.common.inventory.HandlerKnowledgeCore;
import thaumicenergistics.common.inventory.TheInternalInventory;
import thaumicenergistics.common.items.ItemKnowledgeCore;
import thaumicenergistics.common.network.packet.client.Packet_C_KnowledgeInscriber;
import thaumicenergistics.common.tiles.TileKnowledgeInscriber;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.integration.tc.ArcaneCraftingPattern;
import thaumicenergistics.integration.tc.ArcaneRecipeHelper;
import appeng.api.storage.data.IAEItemStack;
import appeng.container.slot.SlotFake;
import appeng.container.slot.SlotFakeCraftingMatrix;
@@ -25,12 +25,12 @@ import thaumicenergistics.common.ThEGuiHandler;
import thaumicenergistics.common.container.slot.SlotArcaneCraftingResult;
import thaumicenergistics.common.container.slot.SlotArmor;
import thaumicenergistics.common.container.slot.SlotRestrictive;
import thaumicenergistics.common.integration.tc.ArcaneRecipeHelper;
import thaumicenergistics.common.network.packet.client.Packet_C_ArcaneCraftingTerminal;
import thaumicenergistics.common.network.packet.client.Packet_C_Sync;
import thaumicenergistics.common.parts.PartArcaneCraftingTerminal;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.common.utils.ThEUtils;
import thaumicenergistics.integration.tc.ArcaneRecipeHelper;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.SortDir;
@@ -1260,6 +1260,16 @@ public class ContainerPartArcaneCraftingTerminal
}
break;
case ThEGuiHelper.MOUSE_BUTTON_WHEEL:
if( player.capabilities.isCreativeMode )
{
ItemStack creativeCopy = requestedStack.getItemStack();
creativeCopy.stackSize = creativeCopy.getMaxStackSize();
player.inventory.setItemStack( creativeCopy );
Packet_C_Sync.sendPlayerHeldItem( player, creativeCopy );
}
break;
case ThEGuiHelper.MOUSE_WHEEL_MOTION:
// Shift must be held
if( isShiftHeld )
@@ -10,6 +10,8 @@ import thaumicenergistics.api.grid.ICraftingIssuerHost;
import thaumicenergistics.api.grid.IMEEssentiaMonitor;
import thaumicenergistics.common.ThEGuiHandler;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper.AspectItemType;
import thaumicenergistics.common.inventory.HandlerWirelessEssentiaTerminal;
import thaumicenergistics.common.inventory.TheInternalInventory;
import thaumicenergistics.common.items.ItemCraftingAspect;
@@ -17,8 +19,6 @@ import thaumicenergistics.common.network.packet.client.Packet_C_EssentiaCellTerm
import thaumicenergistics.common.network.packet.server.Packet_S_EssentiaCellTerminal;
import thaumicenergistics.common.storage.AspectStackComparator.AspectStackComparatorMode;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper.AspectItemType;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.Settings;
@@ -129,7 +129,7 @@ public class ContainerWirelessEssentiaTerminal
@Override
protected IMEEssentiaMonitor getNewMonitor()
{
return this.handler.getEssentiaMonitor();
return this.handler.getEssentiaInventory();
}
@Override
@@ -0,0 +1,253 @@
package thaumicenergistics.common.entities;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import thaumcraft.common.entities.golems.EntityGolemBase;
import thaumicenergistics.common.grid.WirelessAELink;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.data.IAEItemStack;
public abstract class AIAENetworkGolem
extends EntityAIBase
{
protected class NetworkHandler
extends WirelessAELink
{
private static final int NETWORK_COOLDOWN = 15;
/**
* The maximum number of items the golem can inject/extract per update.
*/
private final int maxItems;
/**
* The maximum amount of fluid, in mb, the golem can inject/extract per update.
*/
private final int maxFluids;
/**
* The maximum amount of essentia the golem can inject/extract per update.
*/
private final int maxEssentia;
/**
* How many ticks until the golem can interact with the network again.
*/
private int actionTimer = 0;
public NetworkHandler( final String encryptionKey, final int maxItems, final int maxFluids, final int maxEssentia )
{
// Call super
super( null, encryptionKey );
// Set maximums
this.maxItems = maxItems;
this.maxFluids = maxFluids;
this.maxEssentia = maxEssentia;
}
/**
* Gets the item monitor if possible.
*
* @return
*/
private IMEMonitor<IAEItemStack> getNetworkItems()
{
// Check connectivity
if( !this.canInteractWithNetwork() )
{
return null;
}
// Get the item monitor
return this.getItemInventory();
}
@Override
protected int getUserPositionX()
{
return (int)AIAENetworkGolem.this.golem.posX;
}
@Override
protected int getUserPositionY()
{
return (int)AIAENetworkGolem.this.golem.posY;
}
@Override
protected int getUserPositionZ()
{
return (int)AIAENetworkGolem.this.golem.posZ;
}
@Override
protected World getUserWorld()
{
return AIAENetworkGolem.this.golem.worldObj;
}
@Override
protected boolean hasPowerToCommunicate()
{
// MAGIC GOLEM POWER! YEAH!!
return true;
}
/**
* Checks if the network can be interacted with.
*
* @return
*/
public boolean canInteractWithNetwork()
{
// Is the interaction timer cooling down?
if( this.actionTimer > 0 )
{
return false;
}
// Connected to network?
if( !this.isConnected() )
{
return false;
}
return true;
}
/**
* Called to decrement the action timer.
*
* @return True if cooled down.
*/
public boolean cooldownTick()
{
if( this.actionTimer > 0 )
{
--this.actionTimer;
return false;
}
return true;
}
/**
* Deposits the itemstack into the AE system.
*/
public void depositStack( final ItemStack stack )
{
// Get the item monitor
IMEMonitor<IAEItemStack> monitor = this.getNetworkItems();
if( monitor == null )
{
return;
}
// Create the AE stack
IAEItemStack aeStack = AEApi.instance().storage().createItemStack( stack );
// Set size
int depositSize = Math.min( stack.stackSize, this.maxItems );
aeStack.setStackSize( depositSize );
// Deposit
IAEItemStack rejected = monitor.injectItems( aeStack, Actionable.MODULATE, this.actionSource );
if( rejected != null )
{
depositSize -= (int)rejected.getStackSize();
}
// Reduce stack by number of items deposited
stack.stackSize -= depositSize;
// Reset network timer
this.actionTimer = NETWORK_COOLDOWN;
}
}
/**
* Handles AE network communication.
*/
public final NetworkHandler network;
/**
* The golem the script is attached to.
*/
protected final EntityGolemBase golem;
/**
* <PRE>
* Base 100, 250, 500
* Advanced 200, 500, 1000
* </PRE>
*/
private static final int[] FLUID_RATES = new int[] { 100, 250, 500 };
/**
* <PRE>
* Base 8, 24, 32
* Advanced 16, 48, 64
* </PRE>
*/
private static final int[] ITEM_RATES = new int[] { 8, 24, 32 };
/**
* <PRE>
* Base 8, 24, 32
* Advanced 16, 48, 64
* </PRE>
*/
private static final int[] ESS_RATES = new int[] { 8, 24, 32 };
public AIAENetworkGolem( final EntityGolemBase golem, final String encKey )
{
// Set the golem
this.golem = golem;
// Get rate multiplier
int rateMult = ( golem.advanced ? 2 : 1 );
// Get number of order upgrades
int orderUpgrades = this.golem.getUpgradeAmount( GolemUpgradeTypes.Order.upgradeID );
if( orderUpgrades > 2 )
{
orderUpgrades = 2;
}
else if( orderUpgrades < 0 )
{
orderUpgrades = 0;
}
// Set interaction maximums
int maxItems = ITEM_RATES[orderUpgrades] * rateMult;
int maxEssentia = ESS_RATES[orderUpgrades] * rateMult;
int maxFluids = FLUID_RATES[orderUpgrades] * rateMult;
// Create the network handler
this.network = new NetworkHandler( encKey, maxItems, maxFluids, maxEssentia );
}
/**
* Return true if network interaction is required this update.
*
* @return
*/
protected abstract boolean needsNetworkInteraction();
@Override
public final boolean shouldExecute()
{
// Check the network timer
if( this.network.cooldownTick() )
{
return this.needsNetworkInteraction();
}
return false;
}
}
@@ -0,0 +1,44 @@
package thaumicenergistics.common.entities;
import net.minecraft.item.ItemStack;
import thaumcraft.common.entities.golems.EntityGolemBase;
public class AIGolemWifiGather
extends AIAENetworkGolem
{
public AIGolemWifiGather( final EntityGolemBase golem, final String encKey )
{
super( golem, encKey );
}
@Override
public boolean needsNetworkInteraction()
{
// Execute when the golem is holding something
return( this.golem.getCarried() != null );
}
@Override
public void updateTask()
{
ItemStack heldItem = this.golem.getCarried();
// Ensure the golem is holding something.
if( heldItem != null )
{
// Deposit the item
this.network.depositStack( heldItem );
// Was the stack drained?
if( heldItem.stackSize == 0 )
{
// Clear what the golem is holding
this.golem.setCarried( null );
// Throw his arms up for good measure.
this.golem.startActionTimer();
}
}
}
}
@@ -0,0 +1,55 @@
package thaumicenergistics.common.entities;
import javax.annotation.Nullable;
public enum GolemCoreType
{
Fill (0),
Empty (1),
Gather (2),
Harvest (3),
Guard (4),
Liquid (5),
Essentia (6),
Lumber (7),
Use (8),
Butcher (9),
Sorting (10),
Fish (11);
/**
* Array of cores sorted by ID.
*/
public static final GolemCoreType allCores[];
static
{
GolemCoreType[] values = GolemCoreType.values();
// Setup the array
allCores = new GolemCoreType[values.length];
for( GolemCoreType core : values )
{
allCores[core.coreID] = core;
}
}
/**
* Thaumcraft core ID
*/
public final byte coreID;
private GolemCoreType( final int ID )
{
this.coreID = (byte)ID;
}
@Nullable
public static GolemCoreType getCoreByID( final byte ID )
{
if( ID >= 0 && ID < allCores.length )
{
return allCores[ID];
}
return null;
}
}
@@ -0,0 +1,49 @@
package thaumicenergistics.common.entities;
import javax.annotation.Nullable;
public enum GolemUpgradeTypes
{
Air (0),
Earth (1),
Fire (2),
Water (3),
Order (4),
Entropy (5);
/**
* Array of upgrades sorted by ID.
*/
public static final GolemUpgradeTypes allUpgrades[];
static
{
GolemUpgradeTypes[] values = GolemUpgradeTypes.values();
// Setup the array
allUpgrades = new GolemUpgradeTypes[values.length];
for( GolemUpgradeTypes upgrade : values )
{
allUpgrades[upgrade.upgradeID] = upgrade;
}
}
/**
* Thaumcraft ID for the upgrade.
*/
public final byte upgradeID;
private GolemUpgradeTypes( final int ID )
{
this.upgradeID = (byte)ID;
}
@Nullable
public static GolemUpgradeTypes getUpgradeByID( final byte ID )
{
if( ID >= 0 && ID < allUpgrades.length )
{
return allUpgrades[ID];
}
return null;
}
}
@@ -0,0 +1,303 @@
package thaumicenergistics.common.entities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import org.lwjgl.opengl.GL11;
import thaumcraft.common.entities.golems.EntityGolemBase;
import thaumicenergistics.api.entities.IGolemHookHandler;
import thaumicenergistics.api.entities.IGolemHookSyncRegistry;
import thaumicenergistics.client.render.model.ModelGolemWifiAddon;
import thaumicenergistics.common.items.ItemEnum;
import thaumicenergistics.common.items.ItemGolemWirelessBackpack;
import thaumicenergistics.common.utils.EffectiveSide;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class WirelessGolemHandler
implements IGolemHookHandler
{
private static WirelessGolemHandler INSTANCE = null;
/**
* NBT key used to represent if the golem has the wifi backpack or not.
*/
private static final String NBTKEY_WIFI_KEY = "wifiBackpackKey";
/**
* Core types
*/
private static final byte CORE_GATHER = 2;
/**
* On/Off flags
*/
private static final Character SYNC_FLAG_HAS_WIFI = Character.valueOf( 'y' ),
SYNC_FLAG_NO_WIFI = Character.valueOf( 'n' );
@SideOnly(Side.CLIENT)
private ModelGolemWifiAddon addonModel;
/**
* ID of the wifi sync field.
*/
private int wifiSyncID = -1;
/**
* Cache of the backpack item.
*/
private ItemGolemWirelessBackpack backpackItem;
/**
* Private constructor.
*/
private WirelessGolemHandler()
{
// Setup the backpack model if client side
if( EffectiveSide.isClientSide() )
{
this.setupModel();
}
// Store a reference to the backpack item.
this.backpackItem = (ItemGolemWirelessBackpack)ItemEnum.GOLEM_WIFI_BACKPACK.getItem();
}
/**
* Returns the instance of the handler
*
* @return
*/
public static WirelessGolemHandler getInstance()
{
if( INSTANCE == null )
{
INSTANCE = new WirelessGolemHandler();
}
return INSTANCE;
}
/**
* Creates the wifi addon model.
*/
@SideOnly(Side.CLIENT)
private void setupModel()
{
this.addonModel = new ModelGolemWifiAddon();
}
@Override
public void addDefaultSyncEntries( final IGolemHookSyncRegistry syncRegistry )
{
// Register the wifi entry
this.wifiSyncID = syncRegistry.registerSyncChar( this, SYNC_FLAG_NO_WIFI );
}
@Override
public boolean canHandleInteraction( final EntityGolemBase golem, final Object handlerData, final EntityPlayer player, final Side side )
{
// Get the held item
ItemStack heldItem = player.inventory.getCurrentItem();
// Check for backpack
boolean isHoldingBackpack = ( ( heldItem != null ) && ( heldItem.getItem() == this.backpackItem ) );
// Client side?
if( side == Side.CLIENT )
{
if( isHoldingBackpack )
{
//Swing the item
player.swingItem();
}
return false;
}
// Does the golem already have a backpack on?
if( handlerData != null )
{
// Already has backpack.
return false;
}
return isHoldingBackpack;
}
@Override
public Object customInteraction( final EntityGolemBase golem, final Object handlerData, final EntityPlayer player, final Side side )
{
// Get the held item
ItemStack heldItem = player.inventory.getCurrentItem();
// Is the backpack linked?
String encKey = this.backpackItem.getEncryptionKey( heldItem );
if( encKey != null )
{
// Take the item
player.inventory.setInventorySlotContents( player.inventory.currentItem, null );
// Store the key
return encKey;
}
return null;
}
@Override
public boolean needsRenderer()
{
return true;
}
@Override
public void onBellLeftClick( final EntityGolemBase golem, final Object handlerData, final ItemStack itemGolemPlacer, final EntityPlayer player,
final boolean dismantled, final Side side )
{
// Goes the golem have a backpack on?
if( handlerData != null && side == Side.SERVER )
{
// Create a new backpack item
ItemStack backpack = ItemEnum.GOLEM_WIFI_BACKPACK.getStack();
// Set the key
this.backpackItem.setEncryptionKey( backpack, (String)handlerData, null );
// Drop the backpack
golem.entityDropItem( backpack, 0.5f );
}
}
@Override
@SideOnly(Side.CLIENT)
public Object onSyncDataChanged( final IGolemHookSyncRegistry syncData, final Object clientHandlerData )
{
// Does the golem have on a backpack?
if( syncData.getSyncCharOrDefault( this.wifiSyncID, SYNC_FLAG_NO_WIFI ) == SYNC_FLAG_HAS_WIFI )
{
return "HasBackpack";
}
return null;
}
@Override
public Object readEntityFromNBT( final EntityGolemBase golem, final IGolemHookSyncRegistry syncData, final NBTTagCompound nbtTag )
{
// Does the golem have a backpack?
if( nbtTag.hasKey( NBTKEY_WIFI_KEY ) )
{
// Update the sync data
syncData.updateSyncChar( this, this.wifiSyncID, SYNC_FLAG_HAS_WIFI );
// Read encryption key
return nbtTag.getString( NBTKEY_WIFI_KEY );
}
// No wifi
return null;
}
@Override
@SideOnly(Side.CLIENT)
public void renderGolem( final EntityGolemBase golem, final Object clientHandlerData, final double x, final double y, final double z,
final float partialElaspsedTick )
{
if( clientHandlerData == null )
{
return;
}
if( golem.hurtTime > 0 )
{
// Red tint
GL11.glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );
}
else if( golem.healing > 0 )
{
// Green tint
GL11.glColor3f( 0.5f, 1.0f, 0.5f );
}
else
{
// Full white
GL11.glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
}
// Push the matrix
GL11.glPushMatrix();
// Translate to the golem
GL11.glTranslatef( (float)x, (float)y + 0.63f, (float)z );
// Rotate with the golem
float golemYaw = 270.0f;
golemYaw -= ( ( golem.renderYawOffset * partialElaspsedTick ) + ( golem.prevRenderYawOffset * ( 1.0f - partialElaspsedTick ) ) );
GL11.glRotatef( golemYaw, 0.0f, 1.0f, 0.0f );
// Translate just behind the golem
GL11.glTranslatef( -0.16f, 0.0f, 0.0f );
// Scale
GL11.glScalef( 0.8f, 0.8f, 0.8f );
// Render
this.addonModel.render( null, partialElaspsedTick, 0.0f, -0.1f, 0.0f, 0.0f, 0.0625f );
// Pop the matrix
GL11.glPopMatrix();
}
@Override
public Object setupGolem( final EntityGolemBase golem, final Object handlerData, final IGolemHookSyncRegistry syncData, final Side side )
{
// Ignored on the client side
if( side == Side.CLIENT )
{
return handlerData;
}
// Does the golem have a backpack?
if( handlerData instanceof String )
{
// Get the golems core
byte core = golem.getCore();
// Gather core?
if( core == CORE_GATHER )
{
// Add AI Script
golem.tasks.addTask( 1, new AIGolemWifiGather( golem, (String)handlerData ) );
}
// Update the sync data
syncData.updateSyncChar( this, this.wifiSyncID, SYNC_FLAG_HAS_WIFI );
}
else
{
// Update the sync data
syncData.updateSyncChar( this, this.wifiSyncID, SYNC_FLAG_NO_WIFI );
}
return handlerData;
}
@Override
public Object spawnGolemFromItemStack( final EntityGolemBase golem, final ItemStack itemGolemPlacer, final Side side )
{
return null;
}
@Override
public void writeEntityNBT( final EntityGolemBase golem, final Object serverHandlerData, final NBTTagCompound nbtTag )
{
// Does the golem have a backpack?
if( serverHandlerData instanceof String )
{
// Write network key
nbtTag.setString( NBTKEY_WIFI_KEY, (String)serverHandlerData );
}
}
}
@@ -7,11 +7,11 @@ import thaumcraft.api.aspects.AspectList;
import thaumcraft.api.research.ResearchPage;
import thaumicenergistics.api.IThEConfig;
import thaumicenergistics.api.ThEApi;
import thaumicenergistics.common.integration.tc.VisCraftingHelper;
import thaumicenergistics.common.registries.*;
import thaumicenergistics.common.registries.ResearchRegistry.PseudoResearchTypes;
import thaumicenergistics.common.registries.ResearchRegistry.ResearchTypes;
import thaumicenergistics.common.tiles.TileArcaneAssembler;
import thaumicenergistics.integration.tc.VisCraftingHelper;
import appeng.core.AEConfig;
import appeng.core.features.AEFeature;
@@ -89,7 +89,7 @@ public class GaseousEssentia
gasList.put( aspect, newGas );
// Log info
ThELog.info( "Created fluid for aspect %s.", aspect.getTag() );
// ThELog.info( "Created fluid for aspect %s.", aspect.getTag() );
}
else
{
@@ -9,9 +9,9 @@ import thaumicenergistics.api.grid.IMEEssentiaMonitorReceiver;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.api.storage.IEssentiaRepo;
import thaumicenergistics.common.fluids.GaseousEssentia;
import thaumicenergistics.common.integration.tc.EssentiaConversionHelper;
import thaumicenergistics.common.storage.AspectStack;
import thaumicenergistics.common.storage.EssentiaRepo;
import thaumicenergistics.integration.tc.EssentiaConversionHelper;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.networking.energy.IEnergyGrid;
@@ -7,7 +7,7 @@ import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.api.grid.*;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.common.items.ItemCraftingAspect;
import thaumicenergistics.common.registries.ItemEnum;
import thaumicenergistics.common.items.ItemEnum;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.networking.IGrid;
@@ -0,0 +1,470 @@
package thaumicenergistics.common.grid;
import java.util.ArrayList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import thaumicenergistics.api.grid.IEssentiaGrid;
import thaumicenergistics.api.grid.IMEEssentiaMonitor;
import appeng.api.AEApi;
import appeng.api.implementations.tiles.IWirelessAccessPoint;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IMachineSet;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.security.PlayerSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IStorageMonitorable;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.DimensionalCoord;
import appeng.tile.misc.TileSecurity;
import appeng.tile.networking.TileWireless;
public abstract class WirelessAELink
implements IStorageMonitorable
{
/**
* The player who owns this link.
*/
protected final EntityPlayer player;
/**
* Encryption key used to access the network.
*/
protected final String encryptionKey;
/**
* Access point used to communicate with the AE network.
*/
protected IWirelessAccessPoint accessPoint;
/**
* Cached value of the range of the access point, squared.
*/
protected double apTransmitRange = 0;
/**
* Where in the world is the access point.
*/
protected DimensionalCoord apLocation = null;
/**
* Network source representing the player
*/
protected BaseActionSource actionSource;
public WirelessAELink( final @Nullable EntityPlayer player, @Nonnull final String encryptionKey )
{
// Set the player
this.player = player;
// Set the enc key
this.encryptionKey = encryptionKey;
// Link with the AP
this.linkWithNewAP();
}
/**
* Checks if the AP at the specified location and has the specified range,
* is close enough to communicate with.
*
* @param APLocation
* @param APRange
* @param world
* @param x
* @param y
* @param z
* @return
*/
private static boolean isAPInRange( final DimensionalCoord APLocation, final double APRange, final World world, final int x, final int y,
final int z )
{
// Is the AP in the same world?
if( !APLocation.isInWorld( world ) )
{
return false;
}
// Calculate the square distance
double squareDistance = getSquaredDistanceFromAP( APLocation, x, y, z );
// Return if close enough to use AP
return squareDistance <= ( APRange * APRange );
}
/**
* @param world
* @param x
* @param y
* @param z
* @param grid
* @return
*/
private static ArrayList<IWirelessAccessPoint> locateAPsInRange( final World world, final int x, final int y, final int z, final IGrid grid )
{
// Get all AP's on the grid
IMachineSet accessPoints = grid.getMachines( TileWireless.class );
if( accessPoints.isEmpty() )
{
return null;
}
// Create the list
ArrayList<IWirelessAccessPoint> aps = new ArrayList<IWirelessAccessPoint>();
// Loop over AP's and see if any are close enough to communicate with
for( IGridNode APNode : accessPoints )
{
// Get the AP
IWirelessAccessPoint AP = (IWirelessAccessPoint)APNode.getMachine();
// Is the AP active?
if( AP.isActive() )
{
// Close enough to the AP?
if( isAPInRange( AP.getLocation(), AP.getRange(), world, x, y, z ) )
{
aps.add( AP );
}
}
}
return aps;
}
/**
* Returns the squared distance the specified coords are from the Access Point.
*
* @param locationAP
* @param x
* @param y
* @param z
* @return
*/
protected static double getSquaredDistanceFromAP( final DimensionalCoord locationAP, final int x, final int y, final int z )
{
if( locationAP == null )
{
return Double.MAX_VALUE;
}
// Calculate the distance from the AP
int dX = locationAP.x - x, dY = locationAP.y - y, dZ = locationAP.z - z;
// Calculate the square distance
return( ( dX * dX ) + ( dY * dY ) + ( dZ * dZ ) );
}
/**
* Returns an unsorted list of AP's in range.
*
* @param world
* @param x
* @param y
* @param z
* @param encryptionKey
* @return Null on error, list of AP's in range otherwise.
*/
public static ArrayList<IWirelessAccessPoint> locateAPsInRange( final World world, final int x, final int y, final int z,
final String encryptionKey )
{
// Get the encryption key
long encryptionValue;
try
{
encryptionValue = Long.parseLong( encryptionKey );
}
catch( NumberFormatException e )
{
// Invalid security key
return null;
}
// Get the linked source
Object source = AEApi.instance().registries().locatable().getLocatableBy( encryptionValue );
// Ensure it is a security terminal
if( !( source instanceof TileSecurity ) )
{
// Invalid security terminal
return null;
}
// Get the terminal
TileSecurity securityHost = (TileSecurity)source;
// Get the grid
IGrid grid;
try
{
grid = securityHost.getGridNode( ForgeDirection.UNKNOWN ).getGrid();
}
catch( Exception e )
{
// Can not find the grid
return null;
}
return locateAPsInRange( world, x, y, z, grid );
}
/**
* Returns an unsorted list of AP's in range.
*
* @param player
* @param encryptionKey
* @return Null on error, list of AP's in range otherwise.
*/
public static ArrayList<IWirelessAccessPoint> locateAPsInRangeOfPlayer( final EntityPlayer player, final String encryptionKey )
{
return locateAPsInRange( player.worldObj,
(int)Math.floor( player.posX ),
(int)Math.floor( player.posY ),
(int)Math.floor( player.posZ ), encryptionKey );
}
/**
* Checks if the AP is still active and in range.
*
* @return
*/
private boolean isAPInRangeAndActive()
{
// Has AP?
if( this.accessPoint != null )
{
// Is active?
if( this.accessPoint.isActive() )
{
// In range?
return isAPInRange( this.apLocation, this.apTransmitRange, this.getUserWorld(),
this.getUserPositionX(), this.getUserPositionY(), this.getUserPositionZ() );
}
}
return false;
}
/**
* Locates the closest AP in range and links with it.
*
* @return True if AP linked with.
*/
private boolean linkWithNewAP()
{
World w = this.getUserWorld();
int x = this.getUserPositionX();
int y = this.getUserPositionY();
int z = this.getUserPositionZ();
IGrid grid = null;
if( this.accessPoint != null )
{
try
{
grid = this.accessPoint.getGrid();
}
catch( Exception e )
{
}
}
// Get a list of AP's in range
ArrayList<IWirelessAccessPoint> apList;
if( grid != null )
{
apList = locateAPsInRange( w, x, y, z, grid );
}
else
{
apList = locateAPsInRange( w, x, y, z, this.encryptionKey );
}
if( ( apList == null ) || ( apList.isEmpty() ) )
{
// No valid AP's found
this.accessPoint = null;
return false;
}
// Get the closest
IWirelessAccessPoint closest = null;
double closestDistance = Double.MAX_VALUE;
for( IWirelessAccessPoint ap : apList )
{
double dist = getSquaredDistanceFromAP( ap.getLocation(), x, y, z );
if( dist < closestDistance )
{
closestDistance = dist;
closest = ap;
}
}
// Set the closest as the AP to use
this.setAP( closest );
return true;
}
/**
* Set's the access point used for communication.
*
* @param accessPoint
*/
private void setAP( final IWirelessAccessPoint accessPoint )
{
// Set the access point
this.accessPoint = accessPoint;
// Get the range of the access point
this.apTransmitRange = this.accessPoint.getRange();
// Get the location of the access point
this.apLocation = this.accessPoint.getLocation();
// Create the action source
if( this.player != null )
{
this.actionSource = new PlayerSource( this.player, this.accessPoint );
}
else
{
this.actionSource = new MachineSource( this.accessPoint );
}
}
/**
* Return the x position of the user.
*
* @return
*/
protected abstract int getUserPositionX();
/**
* Return the y position of the user.
*
* @return
*/
protected abstract int getUserPositionY();
/**
* Return the z position of the user.
*
* @return
*/
protected abstract int getUserPositionZ();
/**
* Return the world the user is in.
*
* @return
*/
protected abstract World getUserWorld();
/**
* Is there enough local power to communicate with the AP?
*
* @return
*/
protected abstract boolean hasPowerToCommunicate();
/**
* Gets the essentia inventory.
*
* @return
*/
public IMEEssentiaMonitor getEssentiaInventory()
{
if( this.accessPoint == null )
{
return null;
}
try
{
// Get the network essentia monitor
return( (IMEEssentiaMonitor)this.accessPoint.getGrid().getCache( IEssentiaGrid.class ) );
}
catch( Exception e )
{
return null;
}
}
@Override
public IMEMonitor<IAEFluidStack> getFluidInventory()
{
if( this.accessPoint == null )
{
return null;
}
try
{
// Get the storage grid
IStorageGrid storageGrid = this.accessPoint.getActionableNode().getGrid().getCache( IStorageGrid.class );
// Return the monitor
return storageGrid.getFluidInventory();
}
catch( Exception e )
{
// Ignored
}
return null;
}
@Override
public IMEMonitor<IAEItemStack> getItemInventory()
{
if( this.accessPoint == null )
{
return null;
}
try
{
// Get the storage grid
IStorageGrid storageGrid = this.accessPoint.getActionableNode().getGrid().getCache( IStorageGrid.class );
// Return the monitor
return storageGrid.getItemInventory();
}
catch( Exception e )
{
// Ignored
}
return null;
}
/**
* Checks if the AP is still connected.
*
* @return
*/
public boolean isConnected()
{
// Is there power?
if( !this.hasPowerToCommunicate() )
{
return false;
}
// Is the current AP still good?
if( this.isAPInRangeAndActive() )
{
// Current AP is still connected.
return true;
}
// Attempt to link with a new AP
return this.linkWithNewAP();
}
}
@@ -1,4 +1,4 @@
package thaumicenergistics.integration;
package thaumicenergistics.common.integration;
import java.lang.ref.WeakReference;
import java.util.*;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration;
package thaumicenergistics.common.integration;
/**
* Used to pass specific events to a watcher.
@@ -1,4 +1,4 @@
package thaumicenergistics.integration;
package thaumicenergistics.common.integration;
import java.util.List;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration;
package thaumicenergistics.common.integration;
import net.minecraft.nbt.NBTTagCompound;
import thaumicenergistics.api.ThEApi;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration;
package thaumicenergistics.common.integration;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration;
package thaumicenergistics.common.integration;
import java.lang.reflect.Method;
import thaumicenergistics.api.ThEApi;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration;
package thaumicenergistics.common.integration;
import java.util.ArrayList;
import java.util.List;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration;
package thaumicenergistics.common.integration;
import java.util.List;
import mcp.mobius.waila.api.IWailaConfigHandler;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration.tc;
package thaumicenergistics.common.integration.tc;
import java.util.ArrayList;
import javax.annotation.Nullable;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration.tc;
package thaumicenergistics.common.integration.tc;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration.tc;
package thaumicenergistics.common.integration.tc;
import java.lang.ref.WeakReference;
import net.minecraft.nbt.NBTTagCompound;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration.tc;
package thaumicenergistics.common.integration.tc;
import net.minecraftforge.fluids.FluidStack;
import thaumcraft.api.aspects.Aspect;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration.tc;
package thaumicenergistics.common.integration.tc;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration.tc;
package thaumicenergistics.common.integration.tc;
import java.util.ArrayList;
import java.util.List;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration.tc;
package thaumicenergistics.common.integration.tc;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
@@ -0,0 +1,559 @@
package thaumicenergistics.common.integration.tc;
import java.util.HashMap;
import java.util.HashSet;
import net.minecraft.entity.DataWatcher;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import thaumcraft.common.entities.golems.EntityGolemBase;
import thaumicenergistics.api.entities.IGolemHookHandler;
import thaumicenergistics.api.entities.IGolemHookSyncRegistry;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.common.utils.ThELog;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class GolemHooks
{
private static class DummyHookHandler
implements IGolemHookHandler
{
public DummyHookHandler()
{
}
@Override
public void addDefaultSyncEntries( final IGolemHookSyncRegistry syncRegistry )
{
}
@Override
public boolean canHandleInteraction( final EntityGolemBase golem, final Object handlerData, final EntityPlayer player, final Side side )
{
return false;
}
@Override
public Object customInteraction( final EntityGolemBase golem, final Object handlerData, final EntityPlayer player, final Side side )
{
return null;
}
@Override
public boolean needsRenderer()
{
return false;
}
@Override
public void onBellLeftClick( final EntityGolemBase golem, final Object handlerData, final ItemStack itemGolemPlacer,
final EntityPlayer player, final boolean dismantled,
final Side side )
{
}
@Override
public Object onSyncDataChanged( final IGolemHookSyncRegistry syncData, final Object clientHandlerData )
{
return null;
}
@Override
public Object readEntityFromNBT( final EntityGolemBase golem, final IGolemHookSyncRegistry syncData, final NBTTagCompound nbtTag )
{
return null;
}
@Override
public void renderGolem( final EntityGolemBase golem, final Object clientHandlerData, final double x, final double y, final double z,
final float partialElaspsedTick )
{
}
@Override
public Object setupGolem( final EntityGolemBase golem, final Object handlerData, final IGolemHookSyncRegistry syncData, final Side side )
{
return null;
}
@Override
public Object spawnGolemFromItemStack( final EntityGolemBase golem, final ItemStack itemGolemPlacer, final Side side )
{
return null;
}
@Override
public void writeEntityNBT( final EntityGolemBase golem, final Object serverHandlerData, final NBTTagCompound nbtTag )
{
}
}
/**
* ID of the datawatcher field.
*/
private static final int DATAWATCHER_ID = 4;
/**
* Default sync values.
*/
private static final GolemSyncRegistry defaultSyncRegistry = new GolemSyncRegistry();
/**
* Internal handler used to track sync data.
*/
private static final DummyHookHandler internalHandler = new DummyHookHandler();
/**
* All hook handlers
*/
protected static final HashSet<IGolemHookHandler> registeredHandlers = new HashSet<IGolemHookHandler>();
/**
* Handlers that need to be called during render.
*/
protected static final HashSet<IGolemHookHandler> renderHandlers = new HashSet<IGolemHookHandler>();
/**
* Logs an exception when it occurs.
*
* @param hook
* @param handler
* @param e
*/
private static void logCaughtException( final String hook, final IGolemHookHandler handler, final Exception e )
{
if( handler != null )
{
if( e != null )
{
ThELog.warning( "Caught Exception During call to '" + hook + "' for handler '%s':", handler.getClass().getCanonicalName() );
ThELog.warning( e.toString() );
}
else
{
ThELog.warning( "Caught Unknown Exception During call to '" + hook + "' for handler '%s'", handler.getClass().getCanonicalName() );
}
}
else if( e != null )
{
ThELog.warning( "Caught Exception During call to null handler '" + hook + "':" );
ThELog.warning( e.toString() );
}
else
{
ThELog.warning( "Caught Unknown Exception During call to null handler '" + hook + "'" );
}
}
/**
* Hook for ItemGolemBell.onLeftClickEntity
*
* @param golem
* @param dropped
* @param player
* @param golemHandlerData
*/
public static void hook_Bell_OnLeftClickGolem( final EntityGolemBase golem, final ItemStack dropped, final EntityPlayer player,
final HashMap<IGolemHookHandler, Object> golemHandlerData )
{
// Get the dismantled status
boolean dismantled = player.isSneaking();
Side side = EffectiveSide.side();
for( IGolemHookHandler handler : registeredHandlers )
{
try
{
// Get the current handler data
Object handlerData = golemHandlerData.getOrDefault( handler, null );
// Call handler
handler.onBellLeftClick( golem, handlerData, dropped, player, dismantled, side );
}
catch( Exception e )
{
logCaughtException( "onBellLeftClick", handler, e );
}
}
}
/**
* Hook for EntityGolemBase.customInteraction
*
* @param golem
* @param player
* @param golemHandlerData
* @return
*/
public static boolean hook_CustomInteraction( final EntityGolemBase golem, final EntityPlayer player,
final HashMap<IGolemHookHandler, Object> golemHandlerData )
{
boolean interactionHandled = false;
Side side = EffectiveSide.side();
for( IGolemHookHandler handler : registeredHandlers )
{
try
{
// Get the current handler data
Object handlerData = golemHandlerData.getOrDefault( handler, null );
boolean hadData = ( handlerData != null );
// Call handler
interactionHandled |= handler.canHandleInteraction( golem, handlerData, player, side );
if( interactionHandled )
{
try
{
handlerData = handler.customInteraction( golem, handlerData, player, side );
// Update golem
if( handlerData == null )
{
if( hadData )
{
golemHandlerData.remove( handler );
}
}
else
{
golemHandlerData.put( handler, handlerData );
}
}
catch( Exception e )
{
logCaughtException( "customInteraction", handler, e );
}
}
}
catch( Exception e )
{
logCaughtException( "canHandleInteraction", handler, e );
}
}
if( interactionHandled && side == Side.SERVER )
{
golem.setupGolem();
}
return interactionHandled;
}
/**
* Hook for EntityGolemBase.entityInit
*
* @param golem
* @param golemHandlerData
*/
public static void hook_EntityInit( final EntityGolemBase golem, final HashMap<IGolemHookHandler, Object> golemHandlerData )
{
// Create a new sync registry
GolemSyncRegistry localRegistry = new GolemSyncRegistry();
localRegistry.copyDefaults( defaultSyncRegistry );
// Add to the handlers
golemHandlerData.put( internalHandler, localRegistry );
// Get the datawatcher
DataWatcher watcher = golem.getDataWatcher();
// Add datawatcher field.
watcher.addObject( DATAWATCHER_ID, localRegistry.mappingsToString() );
}
/**
* Hook for EntityGolemBase.onEntityUpdate.
* Keeps client handlers updated.
*
* @param golem
* @param golemHandlerData
*/
public static void hook_onEntityUpdate( final EntityGolemBase golem, final HashMap<IGolemHookHandler, Object> golemHandlerData )
{
if( EffectiveSide.isServerSide() )
{
return;
}
// Get the sync registry
GolemSyncRegistry syncRegistry = (GolemSyncRegistry)golemHandlerData.get( internalHandler );
// Update sync ticks
++syncRegistry.clientSyncTicks;
// Have 20 ticks passed? (Roughly a full second if the game is not lagging)
if( syncRegistry.clientSyncTicks >= 20.0f )
{
// Reset the counter
syncRegistry.clientSyncTicks = 0.0f;
// Is the data out of sync?
String watcherString = golem.getDataWatcher().getWatchableObjectString( DATAWATCHER_ID );
if( !syncRegistry.hasChanged() && ( watcherString == syncRegistry.lastUpdatedFrom ) )
{
// Data is in sync
return;
}
// Read the sync data, and get the list of handlers to update
HashSet<IGolemHookHandler> handlersToUpdate = syncRegistry.readFromString( watcherString );
if( handlersToUpdate == null )
{
// No handlers to update
return;
}
// Inform each handler
for( IGolemHookHandler handler : handlersToUpdate )
{
try
{
// Get the current handler data
Object handlerData = golemHandlerData.getOrDefault( handler, null );
boolean hadData = ( handlerData != null );
// Call handler
handlerData = handler.onSyncDataChanged( syncRegistry, handlerData );
// Update golem
if( handlerData == null )
{
if( hadData )
{
golemHandlerData.remove( handler );
}
}
else
{
golemHandlerData.put( handler, handlerData );
}
}
catch( Exception e )
{
logCaughtException( "onSyncDataChanged", handler, e );
}
}
}
}
/**
* Hook for ItemGolemPlacer.spawnCreature
*
* @param golem
* @param itemGolemPlacer
* @param golemHandlerData
*/
public static void hook_Placer_SpawnGolem( final EntityGolemBase golem, final ItemStack itemGolemPlacer,
final HashMap<IGolemHookHandler, Object> golemHandlerData )
{
// Ensure the stack has an NBT tag
if( !itemGolemPlacer.hasTagCompound() )
{
return;
}
Side side = EffectiveSide.side();
// Inform each handler
for( IGolemHookHandler handler : registeredHandlers )
{
try
{
// Call handler
Object handlerData = handler.spawnGolemFromItemStack( golem, itemGolemPlacer, side );
// Update golem
if( handlerData != null )
{
golemHandlerData.put( handler, handlerData );
}
}
catch( Exception e )
{
logCaughtException( "spawnGolemFromItemStack", handler, e );
}
}
}
/**
* Hook for EntityGolemBase.readEntityFromNBT
*
* @param golem
* @param golemHandlerData
* @param nbt
*/
public static void hook_ReadEntityFromNBT( final EntityGolemBase golem, final HashMap<IGolemHookHandler, Object> golemHandlerData,
final NBTTagCompound nbt )
{
// Get the sync data
GolemSyncRegistry localSyncRegistry = (GolemSyncRegistry)golemHandlerData.get( internalHandler );
// Inform each handler
for( IGolemHookHandler handler : registeredHandlers )
{
try
{
// Get the current handler data
Object handlerData = golemHandlerData.getOrDefault( handler, null );
// Call handler
handlerData = handler.readEntityFromNBT( golem, localSyncRegistry, nbt );
// Update golem
if( handlerData == null )
{
golemHandlerData.remove( handler );
}
else
{
golemHandlerData.put( handler, handlerData );
}
}
catch( Exception e )
{
logCaughtException( "readEntityFromNBT", handler, e );
}
}
}
/**
* Hook for RenderGolemBase.render
*
* @param golem
* @param x
* @param y
* @param z
* @param partialElaspsedTick
*/
@SideOnly(Side.CLIENT)
public static void hook_RenderGolem( final EntityGolemBase golem, final HashMap<IGolemHookHandler, Object> golemHandlerData, final double x,
final double y, final double z, final float partialElaspsedTick )
{
// Call each render handler
for( IGolemHookHandler handler : renderHandlers )
{
try
{
handler.renderGolem( golem, golemHandlerData.get( handler ), x, y, z, partialElaspsedTick );
}
catch( Exception e )
{
logCaughtException( "renderGolem", handler, e );
}
}
}
/**
* Hook for EntityGolemBase.setupGolem
*
* @param golem
* @param golemHandlerData
*/
public static void hook_SetupGolem( final EntityGolemBase golem, final HashMap<IGolemHookHandler, Object> golemHandlerData )
{
// Get the sync data
GolemSyncRegistry localRegistry = (GolemSyncRegistry)golemHandlerData.get( internalHandler );
Side side = EffectiveSide.side();
// Inform each handler
for( IGolemHookHandler handler : registeredHandlers )
{
try
{
// Get the current handler data
Object handlerData = golemHandlerData.getOrDefault( handler, null );
boolean hadData = ( handlerData != null );
// Call handler
handlerData = handler.setupGolem( golem, handlerData, localRegistry, side );
// Update golem
if( handlerData == null )
{
if( hadData )
{
golemHandlerData.remove( handler );
}
}
else
{
golemHandlerData.put( handler, handlerData );
}
}
catch( Exception e )
{
logCaughtException( "setupGolem", handler, e );
}
}
// Update data watcher
if( localRegistry.hasChanged() && side == Side.SERVER )
{
golem.getDataWatcher().updateObject( DATAWATCHER_ID, localRegistry.mappingsToString() );
}
}
/**
* Hook for EntityGolemBase.writeEntityToNBT
*
* @param golem
* @param golemHandlerData
* @param nbt
*/
public static void hook_WriteEntityToNBT( final EntityGolemBase golem, final HashMap<IGolemHookHandler, Object> golemHandlerData,
final NBTTagCompound nbt )
{
// Inform each handler
for( IGolemHookHandler handler : registeredHandlers )
{
try
{
// Get the current handler data
Object handlerData = golemHandlerData.getOrDefault( handler, null );
// Call handler
handler.writeEntityNBT( golem, handlerData, nbt );
}
catch( Exception e )
{
logCaughtException( "writeEntityNBT", handler, e );
}
}
}
/**
* Registers a handler.
*
* @param handler
*/
public static void registerHandler( final IGolemHookHandler handler )
{
// Add the handler
registeredHandlers.add( handler );
// Needs render?
if( handler.needsRenderer() )
{
renderHandlers.add( handler );
}
// Register sync data
defaultSyncRegistry.canRegister = true;
handler.addDefaultSyncEntries( defaultSyncRegistry );
defaultSyncRegistry.canRegister = false;
}
}
@@ -0,0 +1,246 @@
package thaumicenergistics.common.integration.tc;
import java.io.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import thaumicenergistics.api.entities.IGolemHookHandler;
import thaumicenergistics.api.entities.IGolemHookSyncRegistry;
import thaumicenergistics.common.utils.ThELog;
import com.google.common.base.Charsets;
class GolemSyncRegistry
implements IGolemHookSyncRegistry
{
/**
* Maps ID => Handler
*/
private static final HashMap<Integer, IGolemHookHandler> handlerMappings = new HashMap<Integer, IGolemHookHandler>();
/**
* Maps ID => Data
*/
private final HashMap<Integer, Character> dataMappings = new HashMap<Integer, Character>();
/**
* Next ID
*/
private Integer uuid = Integer.valueOf( 13 );
/**
* True if the data has changed.
*/
private boolean hasDataChanged = false;
/**
* True if new values can be added.
*/
public boolean canRegister = false;
/**
* The string that the mappings were read from.
*/
public String lastUpdatedFrom = null;
/**
* Tracks the number of ticks since the last sync on the client side.
*/
public float clientSyncTicks = 0.0f;
public void copyDefaults( final GolemSyncRegistry defaults )
{
// Clear the maps
this.dataMappings.clear();
// Copy the defaults
this.dataMappings.putAll( defaults.dataMappings );
this.hasDataChanged = true;
}
@Override
public char getSyncCharOrDefault( final int id, final char defaultChar )
{
return this.dataMappings.getOrDefault( Integer.valueOf( id ), defaultChar );
}
/**
* True if the data has changed since the last sync.
*
* @return
*/
public boolean hasChanged()
{
return this.hasDataChanged;
}
/**
* Converts the mappings into a string.
*
* @return
*/
public String mappingsToString()
{
this.hasDataChanged = false;
ByteArrayOutputStream baos = null;
DataOutputStream stream = null;
try
{
baos = new ByteArrayOutputStream( ( this.dataMappings.size() * 6 ) + 4 );
stream = new DataOutputStream( baos );
// Write count
stream.writeInt( this.dataMappings.size() );
for( Entry<Integer, Character> entry : this.dataMappings.entrySet() )
{
// Write the ID
stream.writeInt( entry.getKey() );
// Write the char
stream.writeChar( entry.getValue() );
}
stream.close();
// Return the string
return baos.toString( Charsets.UTF_8.name() );
}
catch( IOException e )
{
ThELog.warning( "Unable to send golem sync data" );
try
{
stream.close();
}
catch( IOException e1 )
{
}
}
return "";
}
/**
* Reads the mappings from a string
*
* @param data
*/
public HashSet<IGolemHookHandler> readFromString( final String data )
{
if( ( data == null ) || ( data.length() < 4 ) )
{
ThELog.warning( "Incomplete golem sync data received" );
return null;
}
HashSet<IGolemHookHandler> handlersToUpdate = new HashSet<IGolemHookHandler>();
// Mark the data as valid
this.hasDataChanged = false;
// Save the string
this.lastUpdatedFrom = data;
// Read the data
ByteArrayInputStream bais = null;
DataInputStream stream = null;
try
{
bais = new ByteArrayInputStream( data.getBytes( Charsets.UTF_8.name() ) );
stream = new DataInputStream( bais );
// Read the count
int count = stream.readInt();
for( int i = 0; i < count; ++i )
{
// Read the ID
Integer id = Integer.valueOf( stream.readInt() );
// Read the char
Character c = Character.valueOf( stream.readChar() );
// Add to the mapping
this.dataMappings.put( id, c );
// Mark for update
handlersToUpdate.add( GolemSyncRegistry.handlerMappings.get( id ) );
}
// Close the stream
stream.close();
}
catch( Exception e )
{
ThELog.warning( "Malformed golem sync data received" );
try
{
if( stream != null )
{
stream.close();
}
}
catch( IOException e1 )
{
}
}
// Update handlers
if( !handlersToUpdate.isEmpty() )
{
return handlersToUpdate;
}
return null;
}
@Override
public int registerSyncChar( final IGolemHookHandler handler, final char c )
{
if( !this.canRegister )
{
throw new UnsupportedOperationException( "Can not register new sync data at this location." );
}
// Add the mappings
this.dataMappings.put( this.uuid, Character.valueOf( c ) );
GolemSyncRegistry.handlerMappings.put( this.uuid, handler );
this.hasDataChanged = true;
// Get the id
int id = this.uuid;
// Increment the uuid
this.uuid = Integer.valueOf( id + 1 );
return id;
}
@Override
public void updateSyncChar( final IGolemHookHandler handler, final int id, final char c )
{
// Get the id
Integer ID = Integer.valueOf( id );
// Does the map have this id?
if( !this.dataMappings.containsKey( ID ) )
{
throw new UnsupportedOperationException( "Unable to update sync byte '" + Integer.toString( id ) + "', that ID is not mapped" );
}
// Get the registered handler
IGolemHookHandler registeredHandler = handlerMappings.get( ID );
if( registeredHandler != handler )
{
throw new UnsupportedOperationException( "Unable to update sync byte '" + Integer.toString( id ) + "', that ID does not belong to you." );
}
// Update
Character newValue = Character.valueOf( c );
if( this.dataMappings.put( ID, newValue ) != newValue )
{
this.hasDataChanged = true;
}
}
}
@@ -1,4 +1,4 @@
package thaumicenergistics.integration.tc;
package thaumicenergistics.common.integration.tc;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration.tc;
package thaumicenergistics.common.integration.tc;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration.tc;
package thaumicenergistics.common.integration.tc;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
@@ -1,4 +1,4 @@
package thaumicenergistics.integration.tc;
package thaumicenergistics.common.integration.tc;
import net.minecraftforge.common.util.ForgeDirection;
import thaumcraft.api.WorldCoordinates;
@@ -3,8 +3,8 @@ package thaumicenergistics.common.inventory;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.fluids.FluidStack;
import thaumicenergistics.common.fluids.GaseousEssentia;
import thaumicenergistics.common.integration.tc.EssentiaConversionHelper;
import thaumicenergistics.common.parts.PartEssentiaStorageBus;
import thaumicenergistics.integration.tc.EssentiaConversionHelper;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.networking.IGridNode;
@@ -12,9 +12,9 @@ import thaumcraft.common.tiles.TileEssentiaReservoir;
import thaumcraft.common.tiles.TileJarFillableVoid;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.common.fluids.GaseousEssentia;
import thaumicenergistics.common.integration.tc.EssentiaConversionHelper;
import thaumicenergistics.common.integration.tc.EssentiaTileContainerHelper;
import thaumicenergistics.common.parts.PartEssentiaStorageBus;
import thaumicenergistics.integration.tc.EssentiaConversionHelper;
import thaumicenergistics.integration.tc.EssentiaTileContainerHelper;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.networking.IGridNode;
@@ -8,12 +8,12 @@ import net.minecraftforge.fluids.Fluid;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.common.fluids.GaseousEssentia;
import thaumicenergistics.common.integration.tc.EssentiaConversionHelper;
import thaumicenergistics.common.items.ItemEnum;
import thaumicenergistics.common.items.ItemEssentiaCell;
import thaumicenergistics.common.registries.EnumCache;
import thaumicenergistics.common.registries.ItemEnum;
import thaumicenergistics.common.storage.AspectStack;
import thaumicenergistics.common.storage.AspectStackComparator.AspectStackComparatorMode;
import thaumicenergistics.integration.tc.EssentiaConversionHelper;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.ViewItems;
@@ -6,8 +6,8 @@ import net.minecraft.item.ItemStack;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.common.fluids.GaseousEssentia;
import thaumicenergistics.common.integration.tc.EssentiaConversionHelper;
import thaumicenergistics.common.storage.AspectStack;
import thaumicenergistics.integration.tc.EssentiaConversionHelper;
import appeng.api.config.Actionable;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.ISaveProvider;
@@ -5,8 +5,8 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.Constants;
import thaumicenergistics.common.integration.tc.ArcaneCraftingPattern;
import thaumicenergistics.common.items.ItemKnowledgeCore;
import thaumicenergistics.integration.tc.ArcaneCraftingPattern;
public class HandlerKnowledgeCore
{
@@ -4,45 +4,37 @@ import java.util.Set;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import thaumicenergistics.api.IThEWirelessEssentiaTerminal;
import thaumicenergistics.api.ThEApi;
import thaumicenergistics.api.grid.ICraftingIssuerHost;
import thaumicenergistics.api.grid.IEssentiaGrid;
import thaumicenergistics.api.grid.IMEEssentiaMonitor;
import thaumicenergistics.common.grid.EssentiaPassThroughMonitor;
import thaumicenergistics.common.grid.WirelessAELink;
import thaumicenergistics.common.items.ItemEnum;
import thaumicenergistics.common.items.ItemWirelessEssentiaTerminal;
import thaumicenergistics.common.network.packet.server.Packet_S_ChangeGui;
import thaumicenergistics.common.registries.EnumCache;
import thaumicenergistics.common.registries.ItemEnum;
import thaumicenergistics.common.storage.AspectStackComparator.AspectStackComparatorMode;
import thaumicenergistics.common.utils.EffectiveSide;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.ViewItems;
import appeng.api.implementations.guiobjects.IGuiItemObject;
import appeng.api.implementations.tiles.IWirelessAccessPoint;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IGridStorage;
import appeng.api.networking.IMachineSet;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.IActionHost;
import appeng.api.networking.security.PlayerSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.api.util.IConfigManager;
import appeng.core.AEConfig;
import appeng.tile.networking.TileWireless;
public class HandlerWirelessEssentiaTerminal
implements IActionHost, ICraftingIssuerHost, ITerminalHost, IGuiItemObject
extends WirelessAELink
implements IActionHost, ICraftingIssuerHost, IGuiItemObject
{
/**
* Redirects power requests to the wireless terminal.
@@ -188,32 +180,6 @@ public class HandlerWirelessEssentiaTerminal
*/
private final IThEWirelessEssentiaTerminal wirelessTerminal;
/**
* Access point used to communicate with the AE network.
*/
private IWirelessAccessPoint accessPoint;
/**
* Cached value of the range of the access point, squared.
*/
private double apTransmitRange;
/**
* Where in the world is the access point.
*/
private DimensionalCoord apLocation;
/**
* Player who is using the wireless terminal.
*/
private EntityPlayer player;
/**
* Network source representing the player who is interacting with the
* container.
*/
private PlayerSource playerSource = null;
/**
* The itemstack that represents this terminal.
*/
@@ -224,68 +190,18 @@ public class HandlerWirelessEssentiaTerminal
*/
private double wirelessPowerMultiplier = 1.0D;
public HandlerWirelessEssentiaTerminal( final EntityPlayer player, final IWirelessAccessPoint accessPoint,
public HandlerWirelessEssentiaTerminal( final EntityPlayer player, final String encryptionKey,
final IThEWirelessEssentiaTerminal wirelessTerminalInterface,
final ItemStack wirelessTerminalItemstack )
{
// Set the player
this.player = player;
// Call super
super( player, encryptionKey );
// Set the terminal interface
this.wirelessTerminal = wirelessTerminalInterface;
// Set the itemstack
this.wirelessItemstack = wirelessTerminalItemstack;
// Set the access point
this.setAccessPoint( accessPoint );
}
/**
* Gets the distance the specified player is from the AP.
*
* @param APLocation
* @param player
* @return
*/
private static double getSquaredPlayerDistanceFromAP( final DimensionalCoord APLocation, final EntityPlayer player )
{
// Get the player position
int pX = (int)Math.floor( player.posX ), pY = (int)Math.floor( player.posY ), pZ = (int)Math.floor( player.posZ );
// Calculate the distance from the AP
int dX = APLocation.x - pX, dY = APLocation.y - pY, dZ = APLocation.z - pZ;
// Calculate the square distance
int squareDistance = ( dX * dX ) + ( dY * dY ) + ( dZ * dZ );
return squareDistance;
}
/**
* Checks if the AP at the specified location and has the specified range,
* is close enough to communicate with.
*
* @param APLocation
* @param APRange
* @param X
* @param Y
* @param Z
* @return
*/
public static boolean isAPInRangeOfPlayer( final DimensionalCoord APLocation, final double APRange, final EntityPlayer player )
{
// Is the AP and the player in the same world?
if( !APLocation.isInWorld( player.worldObj ) )
{
return false;
}
// Calculate the square distance
double squareDistance = HandlerWirelessEssentiaTerminal.getSquaredPlayerDistanceFromAP( APLocation, player );
// Return if close enough to use AP
return squareDistance <= ( APRange * APRange );
}
/**
@@ -299,47 +215,28 @@ public class HandlerWirelessEssentiaTerminal
return( !wirelessTerminal.getEncryptionKey( wirelessTerminalItemstack ).isEmpty() );
}
/**
* Checks if the AP is still active and in range.
*
* @return
*/
private boolean isAPInRangeAndActive()
@Override
protected int getUserPositionX()
{
if( this.accessPoint != null )
{
return( ( this.accessPoint.isActive() ) && ( HandlerWirelessEssentiaTerminal.isAPInRangeOfPlayer( this.apLocation,
this.apTransmitRange, this.player ) ) );
}
return false;
return (int)this.player.posX;
}
/**
* Set's the access point used for communication.
*
* @param accessPoint
*/
private void setAccessPoint( final IWirelessAccessPoint accessPoint )
@Override
protected int getUserPositionY()
{
// Set the access point
this.accessPoint = accessPoint;
if( accessPoint == null )
{
// Most likely on the client side.
return;
}
return (int)this.player.posY;
}
// Get the range of the access point
this.apTransmitRange = this.accessPoint.getRange();
@Override
protected int getUserPositionZ()
{
return (int)this.player.posZ;
}
// Get the location of the access point
this.apLocation = this.accessPoint.getLocation();
// Create the action source
if( this.player != null )
{
this.playerSource = new PlayerSource( this.player, this.accessPoint );
}
@Override
protected World getUserWorld()
{
return this.player.worldObj;
}
/**
@@ -396,7 +293,7 @@ public class HandlerWirelessEssentiaTerminal
*/
public BaseActionSource getActionHost()
{
return this.playerSource;
return this.actionSource;
}
@Override
@@ -417,53 +314,23 @@ public class HandlerWirelessEssentiaTerminal
*
* @return
*/
public IMEEssentiaMonitor getEssentiaMonitor()
{
if( this.accessPoint == null )
{
return null;
}
try
{
// Get the network essentia monitor
IMEEssentiaMonitor essMonitor = ( (IMEEssentiaMonitor)this.accessPoint.getGrid().getCache( IEssentiaGrid.class ) );
// Create the power redirector
PowerRedirector pr = new PowerRedirector();
// Create and return the essentia monitor
IMEEssentiaMonitor monitor = new EssentiaPassThroughMonitor( essMonitor, pr );
return monitor;
}
catch( Exception e )
{
return null;
}
}
@Override
public IMEMonitor<IAEFluidStack> getFluidInventory()
public IMEEssentiaMonitor getEssentiaInventory()
{
if( this.accessPoint == null )
// Get the network essentia monitor
IMEEssentiaMonitor essMonitor = super.getEssentiaInventory();
if( essMonitor == null )
{
return null;
}
try
{
// Get the storage grid
IStorageGrid storageGrid = this.accessPoint.getActionableNode().getGrid().getCache( IStorageGrid.class );
// Create the power redirector
PowerRedirector pr = new PowerRedirector();
// Return the monitor
return storageGrid.getFluidInventory();
}
catch( Exception e )
{
// Ignored
}
return null;
// Create and return the passthrough essentia monitor
IMEEssentiaMonitor monitor = new EssentiaPassThroughMonitor( essMonitor, pr );
return monitor;
}
@Override
@@ -478,30 +345,6 @@ public class HandlerWirelessEssentiaTerminal
return ItemEnum.WIRELESS_TERMINAL.getStack();
}
@Override
public IMEMonitor<IAEItemStack> getItemInventory()
{
if( this.accessPoint == null )
{
return null;
}
try
{
// Get the storage grid
IStorageGrid storageGrid = this.accessPoint.getActionableNode().getGrid().getCache( IStorageGrid.class );
// Return the monitor
return storageGrid.getItemInventory();
}
catch( Exception e )
{
// Ignored
}
return null;
}
@Override
public ItemStack getItemStack()
{
@@ -557,71 +400,12 @@ public class HandlerWirelessEssentiaTerminal
*
* @return
*/
public boolean hasPower()
@Override
public boolean hasPowerToCommunicate()
{
return( this.wirelessTerminal.getAECurrentPower( this.wirelessItemstack ) > 0 );
}
/**
* Checks if the terminal is connected to the network.
*
* @return True if the terminal is connected, false otherwise.
*/
public boolean isConnected()
{
if( this.accessPoint == null )
{
return false;
}
// Does the terminal have power?
if( !this.hasPower() )
{
// Terminal is dead.
return false;
}
// Is the current AP still good?
if( this.isAPInRangeAndActive() )
{
// Current AP is still connected.
return true;
}
// Get all AP's on the grid
IMachineSet accessPoints = this.accessPoint.getGrid().getMachines( TileWireless.class );
// Loop over AP's and see if any are close enough to communicate with
for( IGridNode APNode : accessPoints )
{
// Get the AP
IWirelessAccessPoint AP = (IWirelessAccessPoint)APNode.getMachine();
// Skip if current AP
if( AP.equals( this.accessPoint ) )
{
continue;
}
// Is the AP active?
if( AP.isActive() )
{
// Is the player close enough to the AP?
if( HandlerWirelessEssentiaTerminal.isAPInRangeOfPlayer( AP.getLocation(), AP.getRange(), this.player ) )
{
// Set the new AP
this.setAccessPoint( AP );
// Found usable AP
return true;
}
}
}
// No AP's in range.
return false;
}
@Override
public void launchGUI( final EntityPlayer player )
{
@@ -673,7 +457,10 @@ public class HandlerWirelessEssentiaTerminal
public void updatePowerMultiplier()
{
// Get the squared distance
double distance = HandlerWirelessEssentiaTerminal.getSquaredPlayerDistanceFromAP( this.apLocation, this.player );
double distance = WirelessAELink.getSquaredDistanceFromAP( this.apLocation,
this.getUserPositionX(),
this.getUserPositionY(),
this.getUserPositionZ() );
// Calculate the distance
distance = Math.sqrt( distance );
@@ -13,7 +13,6 @@ import net.minecraft.util.StatCollector;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.common.Thaumcraft;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.registries.ItemEnum;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -1,9 +1,8 @@
package thaumicenergistics.common.registries;
package thaumicenergistics.common.items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.items.*;
public enum ItemEnum
{
@@ -15,7 +14,8 @@ public enum ItemEnum
WIRELESS_TERMINAL ("wireless.essentia.terminal", new ItemWirelessEssentiaTerminal()),
KNOWLEDGE_CORE ("knowledge.core", new ItemKnowledgeCore()),
FOCUS_AEWRENCH ("focus.aewrench", new ItemFocusAEWrench()),
CRAFTING_ASPECT ("crafting.aspect", new ItemCraftingAspect());
CRAFTING_ASPECT ("crafting.aspect", new ItemCraftingAspect()),
GOLEM_WIFI_BACKPACK ("golem.wifi.backpack", new ItemGolemWirelessBackpack());
/**
* Internal name of the item.
@@ -21,7 +21,6 @@ import thaumicenergistics.common.ThEGuiHandler;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.inventory.HandlerItemEssentiaCell;
import thaumicenergistics.common.inventory.HandlerItemEssentiaCellCreative;
import thaumicenergistics.common.registries.ItemEnum;
import thaumicenergistics.common.registries.ThEStrings;
import thaumicenergistics.common.storage.AspectStackComparator;
import thaumicenergistics.common.storage.EnumEssentiaStorageTypes;
@@ -0,0 +1,83 @@
package thaumicenergistics.common.items;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.registries.ThEStrings;
import appeng.api.features.INetworkEncodable;
import appeng.core.localization.GuiText;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class ItemGolemWirelessBackpack
extends Item
implements INetworkEncodable
{
private static final String NBT_ENCRYPTION_KEY = "wifiKey";
public ItemGolemWirelessBackpack()
{
// Set the texture
this.setTextureName( ThaumicEnergistics.MOD_ID + ":golem.wifi.backpack" );
// Set non stacking
this.setMaxStackSize( 1 );
this.setMaxDamage( 0 );
}
@Override
@SideOnly(Side.CLIENT)
public void addInformation( final ItemStack stack, final EntityPlayer player, final List list, final boolean advancedInfo )
{
if( stack.hasTagCompound() )
{
list.add( GuiText.Linked.getLocal() );
}
else
{
list.add( GuiText.Unlinked.getLocal() );
}
}
@Override
public String getEncryptionKey( final ItemStack stack )
{
if( stack.hasTagCompound() && stack.stackTagCompound.hasKey( NBT_ENCRYPTION_KEY ) )
{
return stack.stackTagCompound.getString( NBT_ENCRYPTION_KEY );
}
return null;
}
@Override
public String getUnlocalizedName()
{
return ThEStrings.Item_Golem_Wifi_Backpack.getUnlocalized();
}
@Override
public String getUnlocalizedName( final ItemStack itemStack )
{
return this.getUnlocalizedName();
}
@Override
public void setEncryptionKey( final ItemStack stack, final String encKey, final String name )
{
NBTTagCompound tag;
if( !stack.hasTagCompound() )
{
tag = new NBTTagCompound();
stack.stackTagCompound = tag;
}
else
{
tag = stack.stackTagCompound;
}
tag.setString( NBT_ENCRYPTION_KEY, encKey );
}
}
@@ -8,7 +8,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.registries.ItemEnum;
import thaumicenergistics.common.registries.ThEStrings;
public class ItemMaterial
@@ -24,12 +24,12 @@ import thaumicenergistics.client.textures.BlockTextureManager;
import thaumicenergistics.common.ThEGuiHandler;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.container.ContainerPartArcaneCraftingTerminal;
import thaumicenergistics.common.integration.tc.DigiVisSourceData;
import thaumicenergistics.common.network.packet.server.Packet_S_ChangeGui;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.common.registries.EnumCache;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.common.utils.ThEUtils;
import thaumicenergistics.integration.tc.DigiVisSourceData;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
@@ -12,11 +12,11 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.api.grid.IMEEssentiaMonitor;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper.AspectItemType;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.common.storage.AspectStack;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper.AspectItemType;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.SecurityPermissions;
@@ -10,8 +10,8 @@ import thaumcraft.api.aspects.Aspect;
import thaumcraft.common.tiles.TileJarFillableVoid;
import thaumicenergistics.api.grid.IMEEssentiaMonitor;
import thaumicenergistics.client.textures.BlockTextureManager;
import thaumicenergistics.common.integration.tc.EssentiaTileContainerHelper;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.integration.tc.EssentiaTileContainerHelper;
import appeng.api.config.Actionable;
import appeng.api.config.SecurityPermissions;
import appeng.api.parts.IPartCollisionHelper;
@@ -7,8 +7,8 @@ import net.minecraftforge.common.util.ForgeDirection;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.api.grid.IMEEssentiaMonitor;
import thaumicenergistics.client.textures.BlockTextureManager;
import thaumicenergistics.common.integration.tc.EssentiaTileContainerHelper;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.integration.tc.EssentiaTileContainerHelper;
import appeng.api.config.Actionable;
import appeng.api.config.SecurityPermissions;
import appeng.api.parts.IPartCollisionHelper;
@@ -20,11 +20,11 @@ import thaumicenergistics.api.grid.IMEEssentiaMonitor;
import thaumicenergistics.client.gui.GuiEssentiaLevelEmitter;
import thaumicenergistics.client.textures.BlockTextureManager;
import thaumicenergistics.common.container.ContainerPartEssentiaLevelEmitter;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.network.IAspectSlotPart;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.common.registries.EnumCache;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import appeng.api.config.RedstoneMode;
import appeng.api.config.SecurityPermissions;
import appeng.api.parts.IPartCollisionHelper;
@@ -16,12 +16,12 @@ import thaumicenergistics.client.gui.GuiEssentiaStorageBus;
import thaumicenergistics.client.textures.BlockTextureManager;
import thaumicenergistics.common.container.ContainerPartEssentiaStorageBus;
import thaumicenergistics.common.grid.EssentiaMonitor;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.inventory.HandlerEssentiaStorageBusBase;
import thaumicenergistics.common.inventory.HandlerEssentiaStorageBusDuality;
import thaumicenergistics.common.network.IAspectSlotPart;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
@@ -28,11 +28,11 @@ import thaumicenergistics.api.grid.IMEEssentiaMonitor;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.client.textures.BlockTextureManager;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper.AspectItemType;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.common.storage.AspectStack;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper.AspectItemType;
import appeng.api.AEApi;
import appeng.api.implementations.IPowerChannelState;
import appeng.api.implementations.parts.IPartStorageMonitor;
@@ -18,14 +18,14 @@ import thaumicenergistics.common.ThEGuiHandler;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.container.ContainerEssentiaCellTerminalBase;
import thaumicenergistics.common.container.ContainerEssentiaTerminal;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper.AspectItemType;
import thaumicenergistics.common.inventory.TheInternalInventory;
import thaumicenergistics.common.network.packet.server.Packet_S_ChangeGui;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.common.registries.EnumCache;
import thaumicenergistics.common.storage.AspectStackComparator.AspectStackComparatorMode;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper.AspectItemType;
import appeng.api.config.Settings;
import appeng.api.config.ViewItems;
import appeng.api.parts.IPartCollisionHelper;
@@ -17,9 +17,9 @@ import thaumcraft.api.visnet.VisNetHandler;
import thaumcraft.common.tiles.TileVisRelay;
import thaumicenergistics.api.grid.IDigiVisSource;
import thaumicenergistics.client.textures.BlockTextureManager;
import thaumicenergistics.common.integration.tc.DigiVisSourceData;
import thaumicenergistics.common.integration.tc.VisProviderProxy;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.integration.tc.DigiVisSourceData;
import thaumicenergistics.integration.tc.VisProviderProxy;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.implementations.items.IMemoryCard;
@@ -12,13 +12,13 @@ import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.IAspectContainer;
import thaumicenergistics.client.gui.GuiEssentiaIO;
import thaumicenergistics.common.container.ContainerPartEssentiaIOBus;
import thaumicenergistics.common.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.common.network.IAspectSlotPart;
import thaumicenergistics.common.network.packet.client.Packet_C_AspectSlot;
import thaumicenergistics.common.network.packet.client.Packet_C_EssentiaIOBus;
import thaumicenergistics.common.registries.AEPartsEnum;
import thaumicenergistics.common.registries.EnumCache;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import appeng.api.AEApi;
import appeng.api.config.RedstoneMode;
import appeng.api.config.SecurityPermissions;
@@ -808,7 +808,7 @@ public class AEAspectRegister
// Still could not register on pass 2.
if( !this.displayName.isEmpty() )
{
ThELog.info( "'%s' was not registered for TC scanning.", this.displayName );
ThELog.info( "Could not register \"%s\" for TC scanning.", this.displayName );
}
}
return;
@@ -1172,7 +1172,7 @@ public class AEAspectRegister
// Were the cells registered?
if( ( aeCell == null ) || ( cellAspects == null ) )
{
ThELog.info( "'%s' was not registered for TC scanning.", "Essentia Cells" );
ThELog.info( "Could not register \"%s\" for TC scanning.", "Essentia Cells" );
}
// Set the aspects for the iron gearbox
@@ -7,6 +7,7 @@ import net.minecraft.util.MathHelper;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.items.ItemEnum;
import thaumicenergistics.common.parts.*;
import appeng.api.config.Upgrades;
@@ -3,6 +3,7 @@ package thaumicenergistics.common.registries;
import net.minecraftforge.client.MinecraftForgeClient;
import thaumicenergistics.api.ThEApi;
import thaumicenergistics.client.render.*;
import thaumicenergistics.common.items.ItemEnum;
import thaumicenergistics.common.tiles.TileArcaneAssembler;
import thaumicenergistics.common.tiles.TileGearBox;
import cpw.mods.fml.client.registry.ClientRegistry;
@@ -5,7 +5,7 @@ import thaumcraft.api.aspects.AspectList;
import thaumcraft.api.research.ResearchItem;
import thaumcraft.api.research.ResearchPage;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.integration.tc.PseudoResearchItem;
import thaumicenergistics.common.integration.tc.PseudoResearchItem;
public class ResearchRegistry
{
@@ -54,6 +54,7 @@ public enum ThEStrings
Item_KnowledgeCore ("item.knowledge.core", true),
Item_FocusAEWrench ("item.focus.aewrench", true),
Item_FocusAEWrench_Disabled ("item.focus.aewrench.disabled", true),
Item_Golem_Wifi_Backpack ("item.golem.wifi.backpack", true),
// Tooltips
Tooltip_ItemStackDetails ("tooltip.itemstack.details", false),
@@ -2,7 +2,7 @@ package thaumicenergistics.common.storage;
import net.minecraft.item.EnumRarity;
import net.minecraft.item.ItemStack;
import thaumicenergistics.common.registries.ItemEnum;
import thaumicenergistics.common.items.ItemEnum;
import thaumicenergistics.common.registries.ThEStrings;
/**
@@ -21,14 +21,14 @@ import thaumicenergistics.api.ThEApi;
import thaumicenergistics.api.grid.IDigiVisSource;
import thaumicenergistics.client.gui.ThEGuiHelper;
import thaumicenergistics.common.blocks.BlockArcaneAssembler;
import thaumicenergistics.common.integration.IWailaSource;
import thaumicenergistics.common.integration.tc.ArcaneCraftingPattern;
import thaumicenergistics.common.integration.tc.DigiVisSourceData;
import thaumicenergistics.common.integration.tc.VisCraftingHelper;
import thaumicenergistics.common.inventory.HandlerKnowledgeCore;
import thaumicenergistics.common.inventory.TheInternalInventory;
import thaumicenergistics.common.items.ItemKnowledgeCore;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.integration.IWailaSource;
import thaumicenergistics.integration.tc.ArcaneCraftingPattern;
import thaumicenergistics.integration.tc.DigiVisSourceData;
import thaumicenergistics.integration.tc.VisCraftingHelper;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
@@ -10,9 +10,9 @@ import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.IEssentiaTransport;
import thaumicenergistics.api.ThEApi;
import thaumicenergistics.api.tiles.IEssentiaTransportWithSimulate;
import thaumicenergistics.common.integration.IEssentiaProviderWatcher;
import thaumicenergistics.common.integration.tc.EssentiaTransportHelper;
import thaumicenergistics.common.tiles.abstraction.TileProviderBase;
import thaumicenergistics.integration.IEssentiaProviderWatcher;
import thaumicenergistics.integration.tc.EssentiaTransportHelper;
import appeng.api.config.Actionable;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
@@ -10,12 +10,12 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntityFurnace;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.common.container.ContainerEssentiaVibrationChamber;
import thaumicenergistics.common.integration.IWailaSource;
import thaumicenergistics.common.integration.tc.EssentiaTransportHelper;
import thaumicenergistics.common.network.ThEBasePacket;
import thaumicenergistics.common.registries.ThEStrings;
import thaumicenergistics.common.storage.AspectStack;
import thaumicenergistics.common.tiles.abstraction.TileEVCBase;
import thaumicenergistics.integration.IWailaSource;
import thaumicenergistics.integration.tc.EssentiaTransportHelper;
import appeng.api.config.Actionable;
import appeng.api.networking.IGridNode;
import appeng.api.networking.energy.IEnergyGrid;
@@ -11,9 +11,9 @@ import net.minecraftforge.common.util.ForgeDirection;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.api.grid.IEssentiaGrid;
import thaumicenergistics.api.grid.IMEEssentiaMonitor;
import thaumicenergistics.common.integration.IWailaSource;
import thaumicenergistics.common.registries.EnumCache;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.integration.IWailaSource;
import appeng.api.config.Actionable;
import appeng.api.implementations.tiles.IColorableTile;
import appeng.api.networking.GridFlags;
@@ -1,6 +1,7 @@
package thaumicenergistics.common.utils;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
public final class EffectiveSide
{
@@ -28,4 +29,14 @@ public final class EffectiveSide
{
return FCH.getEffectiveSide().isServer();
}
/**
* Returns the effective side for the context in the game.
*
* @return
*/
public static final Side side()
{
return FCH.getEffectiveSide();
}
}
@@ -0,0 +1,691 @@
package thaumicenergistics.fml;
import net.minecraft.launchwrapper.IClassTransformer;
import org.apache.logging.log4j.Level;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
/**
* <strong>Modifications made by the transformer:</strong></br>
* Thaumcraft class <em>EntityGolemBase</em>
* <ul>
* <li>Adds field <em>hookHandlers</em> of type HashMap</li>
* <li>Adds hook to method <em>setupGolem</em></li>
* <li>Adds hook to method <em>customInteraction</em></li>
* <li>Adds hook to method <em>writeEntityNBT</em></li>
* <li>Adds hook to method <em>readEntityFromNBT</em></li>
* <li>Adds hook to method <em>func_70088_a | entityInit</em></li>
* <li>Adds hook to method <em>func_70030_z | onEntityUpdate<em></li>
* </ul>
* Thaumcraft class <em>ItemGolemBell</em>
* <ul>
* <li>Adds hook to method <em>onLeftClickEntity</em></li>
* </ul>
*
* Thaumcraft class <em>ItemGolemPlacer</em>
* <ul>
* <li>TODO: Adds hook to method <em>func_77624_a | addInformation</em></li>
* <li>Adds hook to method <em>spawnCreature</em></li>
* </ul>
*
* Thaumcraft class <em>RenderGolemBase</em>
* <ul>
* <li>Adds hook to method <em>render</em></li>
* </ul>
*
* @author Nividica
*
*/
public class ASMTransformer
implements IClassTransformer
{
private static final String CLASS_EntityGolemBase = "thaumcraft/common/entities/golems/EntityGolemBase";
private static final String CLASS_GolemHooks = "thaumicenergistics/common/integration/tc/GolemHooks";
private static final String INTERFACE_IGolemHookHandler = "thaumicenergistics/api/entities/IGolemHookHandler";
private static final String FIELD_EntityGolemBase_hookHandlers = "hookHandlers";
private static final String FIELDTYPE_EntityGolemBase_hookHandlers = "java/util/HashMap";
/**
* Adds a reference to a golems dataWatcher field to the stack.
*
* @param instructionList
* @param golemVar
* @param checkCast
* If the var specified is not type EntityGolemBase(such as just Entity or EntityLiving) a cast check must be performed.
*/
private void addGetField_hookHandlers( final InsnList instructionList, final int golemVar, final boolean checkCast )
{
instructionList.add( new VarInsnNode( Opcodes.ALOAD, golemVar ) );
if( checkCast )
{
instructionList.add( new TypeInsnNode( Opcodes.CHECKCAST, CLASS_EntityGolemBase ) );
}
instructionList.add( new FieldInsnNode( Opcodes.GETFIELD,
CLASS_EntityGolemBase,
FIELD_EntityGolemBase_hookHandlers, "L" + FIELDTYPE_EntityGolemBase_hookHandlers + ";" ) );
}
/**
* Locates the first occurrence of the specified opcode.
*
* @param instructions
* @param opcode
* @return
*/
private AbstractInsnNode findFirstOpCode( final InsnList instructions, final int opcode )
{
for( int index = 0; index < instructions.size(); ++index )
{
if( instructions.get( index ).getOpcode() == opcode )
{
return instructions.get( index );
}
}
return null;
}
/**
* Locates the last occurrence of the specified opcode.
*
* @param instructions
* @param opcode
* @return
*/
private AbstractInsnNode findLastOpCode( final InsnList instructions, final int opcode )
{
for( int index = instructions.size() - 1; index > 0; --index )
{
if( instructions.get( index ).getOpcode() == opcode )
{
return instructions.get( index );
}
}
return null;
}
/**
* Locates the last occurrence of the specified type.
*
* @param instructions
* @param type
* @param number
* of occurrences to skip
* @return
*/
private AbstractInsnNode findLastType( final InsnList instructions, final int type, int skip )
{
for( int index = instructions.size() - 1; index > 0; --index )
{
if( instructions.get( index ).getType() == type )
{
if( --skip < 0 )
{
return instructions.get( index );
}
}
}
return null;
}
/**
* Locates a sequence of instructions.
*
* @param instructions
* @param opSequence
* @param skipNons
* If true all -1 instructions will be skipped
* @return The last instruction in the sequence.
*/
private AbstractInsnNode findSequence( final InsnList instructions, final int opSequence[], final boolean skipNons )
{
int seqIndex = 0;
AbstractInsnNode insertionPoint = null;
for( int index = 0; index < instructions.size(); ++index )
{
// Get the instruction
AbstractInsnNode ins = instructions.get( index );
if( skipNons && ( ins.getOpcode() == -1 ) )
{
continue;
}
// Does it match the sequence?
if( ins.getOpcode() == opSequence[seqIndex] )
{
// Has the full sequence been found?
if( ++seqIndex == opSequence.length )
{
// Found the full sequence
insertionPoint = ins;
break;
}
}
else if( ins.getOpcode() == opSequence[0] )
{
// Restart sequence
seqIndex = 1;
}
else
{
// Reset sequence
seqIndex = 0;
}
}
return insertionPoint;
}
private void insertMethod_GolemBase_onEntityUpdate( final ClassNode classNode, final boolean isObf )
{
// Create the onEntityUpdate() method
String oEU_Name = ( isObf ? "func_70030_z" : "onEntityUpdate" );
MethodNode onEntityUpdate = new MethodNode( Opcodes.ACC_PUBLIC,
oEU_Name, "()V", null, null );
// super.onEntityUpdate()
onEntityUpdate.instructions.add( new VarInsnNode( Opcodes.ALOAD, 0 ) );
onEntityUpdate.instructions.add( new MethodInsnNode( Opcodes.INVOKESPECIAL,
"net/minecraft/entity/monster/EntityGolem", oEU_Name, "()V", false ) );
// GolemHooks.hook_onEntityUpdate( this, this.hookHandlers )
// this
onEntityUpdate.instructions.add( new VarInsnNode( Opcodes.ALOAD, 0 ) );
// this.hookHandlers
this.addGetField_hookHandlers( onEntityUpdate.instructions, 0, false );
// GolemHooks.hook_onEntityUpdate( EntityGolemBase, Hashmap )
onEntityUpdate.instructions.add( new MethodInsnNode( Opcodes.INVOKESTATIC,
CLASS_GolemHooks, "hook_onEntityUpdate",
"(L" + CLASS_EntityGolemBase + ";L" + FIELDTYPE_EntityGolemBase_hookHandlers + ";)V", false ) );
// return
onEntityUpdate.instructions.add( new InsnNode( Opcodes.RETURN ) );
// Add the method to the class
classNode.methods.add( onEntityUpdate );
}
/**
* Adds an entry to the log.
*
* @param text
*/
private void log( final String text )
{
FMLRelaunchLog.log( "ThE-Core", Level.INFO, text );
}
private byte[] transformClass_GolemBase( final byte[] classBytes )
{
// Create the class node and read in the class
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader( classBytes );
classReader.accept( classNode, 0 );
// Add the handlers field
// public HashMap<IGolemHookHandler, Object> hookHandlers;
classNode.fields.add( new FieldNode( Opcodes.ACC_PUBLIC,
FIELD_EntityGolemBase_hookHandlers,
"L" + FIELDTYPE_EntityGolemBase_hookHandlers + ";",
"L" + FIELDTYPE_EntityGolemBase_hookHandlers + "<L" + INTERFACE_IGolemHookHandler + ";Ljava/lang/Object;>;",
null ) );
boolean isObf = false;
// Transform methods
for( MethodNode method : classNode.methods )
{
// Look for an obfuscated method
if( method.name.equals( "func_70014_b" ) )
{
isObf = true;
}
// Setup golem
if( method.name.equals( "setupGolem" ) )
{
this.transformMethod_GolemBase_SetupGolem( method );
}
// Custom interaction
else if( method.name.equals( "customInteraction" ) )
{
this.transformMethod_GolemBase_CustomInteraction( method );
}
// Write entity NBT
else if( method.name.equals( "func_70014_b" ) || method.name.equals( "writeEntityToNBT" ) )
{
this.transformMethod_GolemBase_WriteEntityToNBT( method );
}
// Read entity from NBT
else if( method.name.equals( "func_70037_a" ) || method.name.equals( "readEntityFromNBT" ) )
{
this.transformMethod_GolemBase_ReadEntityFromNBT( method );
}
// Entity Init
else if( method.name.equals( "func_70088_a" ) || method.name.equals( "entityInit" ) )
{
this.transformMethod_GolemBase_EntityInit( method );
}
}
// Add the onEntityUpdate method.
insertMethod_GolemBase_onEntityUpdate( classNode, isObf );
// Create the writer
ClassWriter writer = new ClassWriter( ClassWriter.COMPUTE_MAXS );
classNode.accept( writer );
// Return the modified class
return writer.toByteArray();
}
private byte[] transformClass_ItemGolemBell( final byte[] classBytes )
{
// Create the class node and read in the class
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader( classBytes );
classReader.accept( classNode, 0 );
// Transform methods
for( MethodNode method : classNode.methods )
{
// Left click entity
if( method.name.equals( "onLeftClickEntity" ) )
{
this.transformMethod_ItemGolemBell_OnLeftClickEntity( method );
}
}
// Create the writer
ClassWriter writer = new ClassWriter( ClassWriter.COMPUTE_MAXS );
classNode.accept( writer );
// Return the modified class
return writer.toByteArray();
}
private byte[] transformClass_ItemGolemPlacer( final byte[] classBytes )
{
// Create the class node and read in the class
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader( classBytes );
classReader.accept( classNode, 0 );
// Transform methods
for( MethodNode method : classNode.methods )
{
// Spawn creature
if( method.name.equals( "spawnCreature" ) )
{
this.transformMethod_ItemGolemPlacer_SpawnCreature( method );
}
}
// Create the writer
ClassWriter writer = new ClassWriter( ClassWriter.COMPUTE_MAXS );
classNode.accept( writer );
// Return the modified class
return writer.toByteArray();
}
private byte[] transformClass_RenderGolemBase( final byte[] classBytes )
{
// Create the class node and read in the class
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader( classBytes );
classReader.accept( classNode, 0 );
boolean isObf = false;
MethodNode render = null;
// Transform methods
for( MethodNode method : classNode.methods )
{
if( method.name.equals( "func_76986_a" ) )
{
isObf = true;
}
// Render
else if( method.name.equals( "render" ) )
{
render = method;
}
}
// Render
this.transformMethod_RenderGolemBase_Render( render, isObf );
// Create the writer
ClassWriter writer = new ClassWriter( ClassWriter.COMPUTE_MAXS );
classNode.accept( writer );
// Return the modified class
return writer.toByteArray();
}
private void transformMethod_GolemBase_CustomInteraction( final MethodNode method )
{
int opSequence[] = new int[] { Opcodes.ALOAD, Opcodes.INVOKEVIRTUAL, Opcodes.ICONST_M1 };
AbstractInsnNode insertionPoint = this.findSequence( method.instructions, opSequence, false );
// Go two back
insertionPoint = insertionPoint.getPrevious().getPrevious();
// Find the last label
LabelNode lastLabel = (LabelNode)this.findLastType( method.instructions, AbstractInsnNode.LABEL, 1 );
// Insert the hook
// GolemHooks.hook_CustomInteraction( this, player, this.hookHandlers );
InsnList instructionList = new InsnList();
// this
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 0 ) );
// player
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 1 ) );
// this.hookHandlers
this.addGetField_hookHandlers( instructionList, 0, false );
// GolemHooks.setupGolemHook( EntityGolemBase, Hashmap )
instructionList.add( new MethodInsnNode( Opcodes.INVOKESTATIC,
CLASS_GolemHooks, "hook_CustomInteraction",
"(L" + CLASS_EntityGolemBase + ";Lnet/minecraft/entity/player/EntityPlayer;L"
+ FIELDTYPE_EntityGolemBase_hookHandlers + ";)Z",
false ) );
// Insert the return check
instructionList.add( new JumpInsnNode( Opcodes.IFNE, lastLabel ) );
// Insert the static call
method.instructions.insertBefore( insertionPoint, instructionList );
}
private void transformMethod_GolemBase_EntityInit( final MethodNode method )
{
// Locate the return statement
AbstractInsnNode insertionPoint = this.findLastOpCode( method.instructions, Opcodes.RETURN );
// Insert the hookHandlers initializer
// hookHandlers = new HashMap<IGolemHookHandler, Object>();
InsnList instructionList = new InsnList();
// this
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 0 ) );
// new HashMap
instructionList.add( new TypeInsnNode( Opcodes.NEW, FIELDTYPE_EntityGolemBase_hookHandlers ) );
instructionList.add( new InsnNode( Opcodes.DUP ) );
// Hashmap.<init>
instructionList.add( new MethodInsnNode( Opcodes.INVOKESPECIAL,
FIELDTYPE_EntityGolemBase_hookHandlers, "<init>", "()V", false ) );
// .hookHandlers =
instructionList.add( new FieldInsnNode( Opcodes.PUTFIELD, CLASS_EntityGolemBase,
FIELD_EntityGolemBase_hookHandlers, "L" + FIELDTYPE_EntityGolemBase_hookHandlers + ";" ) );
// Insert the hook
// GolemHooks.hook_EntityInit( this, this.hookHandlers );
// this
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 0 ) );
// this.hookHandlers
this.addGetField_hookHandlers( instructionList, 0, false );
// GolemHooks.hook_EntityInit( EntityGolemBase, Hashmap )
instructionList.add( new MethodInsnNode( Opcodes.INVOKESTATIC,
CLASS_GolemHooks, "hook_EntityInit",
"(L" + CLASS_EntityGolemBase + ";L" + FIELDTYPE_EntityGolemBase_hookHandlers + ";)V", false ) );
// Insert the static call
method.instructions.insertBefore( insertionPoint, instructionList );
}
private void transformMethod_GolemBase_ReadEntityFromNBT( final MethodNode method )
{
// Locate the super call
AbstractInsnNode insertionPoint = this.findFirstOpCode( method.instructions, Opcodes.INVOKESTATIC );
// Insert the hook
// GolemHooks.hook_ReadEntityFromNBT( this, this.hookHandlers, nbt);
InsnList instructionList = new InsnList();
// this
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 0 ) );
// this.hookHandlers
this.addGetField_hookHandlers( instructionList, 0, false );
// nbt
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 1 ) );
// GolemHooks.hook_ReadEntityFromNBT( EntityGolemBase, Hashmap, NBTTagCompound )
instructionList.add( new MethodInsnNode( Opcodes.INVOKESTATIC,
CLASS_GolemHooks, "hook_ReadEntityFromNBT",
"(L" + CLASS_EntityGolemBase + ";L" + FIELDTYPE_EntityGolemBase_hookHandlers + ";"
+ "Lnet/minecraft/nbt/NBTTagCompound;" + ")V", false ) );
// Insert the static call
method.instructions.insert( insertionPoint, instructionList );
}
private void transformMethod_GolemBase_SetupGolem( final MethodNode method )
{
// Set the insertion point to the instruction before return
// Previous node is important, since the method returns a value, the previous
// instruction is what sets that return value.
AbstractInsnNode insertionPoint = this.findLastOpCode( method.instructions, Opcodes.IRETURN );
insertionPoint = insertionPoint.getPrevious();
// Insert the hook
// GolemHooks.setupGolemHook( this, this.hookHandlers );
InsnList instructionList = new InsnList();
// this
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 0 ) );
// this.hookHandlers
this.addGetField_hookHandlers( instructionList, 0, false );
// GolemHooks.setupGolemHook( EntityGolemBase, Hashmap )
instructionList.add( new MethodInsnNode( Opcodes.INVOKESTATIC,
CLASS_GolemHooks, "hook_SetupGolem",
"(L" + CLASS_EntityGolemBase + ";L" + FIELDTYPE_EntityGolemBase_hookHandlers + ";)V", false ) );
// Insert the static call
method.instructions.insertBefore( insertionPoint, instructionList );
}
private void transformMethod_GolemBase_WriteEntityToNBT( final MethodNode method )
{
// Locate the return statement
AbstractInsnNode insertionPoint = this.findLastOpCode( method.instructions, Opcodes.RETURN );
// Insert the hook
// GolemHooks.hook_WriteEntityToNBT( this, this.hookHandlers, nbt);
InsnList instructionList = new InsnList();
// this
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 0 ) );
// this.hookHandlers
this.addGetField_hookHandlers( instructionList, 0, false );
// nbt
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 1 ) );
// GolemHooks.hook_WriteEntityToNBT( EntityGolemBase, Hashmap, NBTTagCompound )
instructionList.add( new MethodInsnNode( Opcodes.INVOKESTATIC,
CLASS_GolemHooks, "hook_WriteEntityToNBT",
"(L" + CLASS_EntityGolemBase + ";L" + FIELDTYPE_EntityGolemBase_hookHandlers + ";"
+ "Lnet/minecraft/nbt/NBTTagCompound;" + ")V", false ) );
// Insert the static call
method.instructions.insertBefore( insertionPoint, instructionList );
}
private void transformMethod_ItemGolemBell_OnLeftClickEntity( final MethodNode method )
{
int opSequence[] = new int[] { Opcodes.GETSTATIC, Opcodes.ICONST_1, Opcodes.ILOAD, Opcodes.INVOKESPECIAL, Opcodes.ASTORE };
// Locate the sequence
AbstractInsnNode insertionPoint = this.findSequence( method.instructions, opSequence, true );
// Insert the hook
// GolemHooks.hook_Bell_OnLeftClickGolem( entity, dropped, player, ((EntityGolemBase)entity).hookHandlers )
InsnList instructionList = new InsnList();
// ((EntityGolemBase)entity)
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 3 ) );
instructionList.add( new TypeInsnNode( Opcodes.CHECKCAST, CLASS_EntityGolemBase ) );
// dropped
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 9 ) );
// player
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 2 ) );
// ((EntityGolemBase)entity).hookHandlers
this.addGetField_hookHandlers( instructionList, 3, true );
// GolemHooks.hook_Bell_OnLeftClickGolem( EntityGolemBase, ItemStack, EntityPlayer, Hashmap )
instructionList.add( new MethodInsnNode( Opcodes.INVOKESTATIC,
CLASS_GolemHooks, "hook_Bell_OnLeftClickGolem",
"(L" + CLASS_EntityGolemBase + ";Lnet/minecraft/item/ItemStack;Lnet/minecraft/entity/player/EntityPlayer;L"
+ FIELDTYPE_EntityGolemBase_hookHandlers + ";)V", false ) );
// Insert the static call
method.instructions.insert( insertionPoint, instructionList );
}
private void transformMethod_ItemGolemPlacer_SpawnCreature( final MethodNode method )
{
// Locate "golem.setup(side);"
int opSequence[] = new int[] { Opcodes.PUTFIELD, Opcodes.ALOAD, Opcodes.ILOAD, Opcodes.INVOKEVIRTUAL };
AbstractInsnNode insertionPoint = this.findSequence( method.instructions, opSequence, true );
// Move back to the aload
insertionPoint = insertionPoint.getPrevious().getPrevious();
// Insert the hook
// GolemHooks.hook_Placer_SpawnGolem( golem, stack, golem.hookHandlers )
InsnList instructionList = new InsnList();
// golem
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 12 ) );
// stack
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 9 ) );
// golem.hookHandlers
this.addGetField_hookHandlers( instructionList, 12, false );
// GolemHooks.hook_Placer_SpawnGolem( EntityGolemBase, ItemStack, Hashmap )
instructionList.add( new MethodInsnNode( Opcodes.INVOKESTATIC,
CLASS_GolemHooks, "hook_Placer_SpawnGolem",
"(L" + CLASS_EntityGolemBase + ";Lnet/minecraft/item/ItemStack;L" + FIELDTYPE_EntityGolemBase_hookHandlers + ";)V", false ) );
// Insert the static call
method.instructions.insertBefore( insertionPoint, instructionList );
}
private void transformMethod_RenderGolemBase_Render( final MethodNode method, final boolean isObf )
{
// Find the return
AbstractInsnNode insertionPoint = this.findLastOpCode( method.instructions, Opcodes.RETURN );
// Insert the hook
// GolemHooks.hook_RenderGolem( e, e.hookHandlers, par2, par4, par6, par9 )
InsnList instructionList = new InsnList();
// e
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 1 ) );
// e.hookHandlers
this.addGetField_hookHandlers( instructionList, 1, false );
// par2
instructionList.add( new VarInsnNode( Opcodes.DLOAD, 2 ) );
// par4
instructionList.add( new VarInsnNode( Opcodes.DLOAD, 4 ) );
// par6
instructionList.add( new VarInsnNode( Opcodes.DLOAD, 6 ) );
// par9
instructionList.add( new VarInsnNode( Opcodes.FLOAD, 9 ) );
// GolemHooks.hook_RenderGolem( EntityGolemBase, Hashmap, double, double, double, float )
instructionList.add( new MethodInsnNode( Opcodes.INVOKESTATIC,
CLASS_GolemHooks, "hook_RenderGolem",
"(L" + CLASS_EntityGolemBase + ";L" + FIELDTYPE_EntityGolemBase_hookHandlers + ";DDDF)V", false ) );
// Insert the static call
method.instructions.insertBefore( insertionPoint, instructionList );
}
@Override
public byte[] transform( final String name, final String transformedName, final byte[] basicClass )
{
if( transformedName.equals( "thaumcraft.common.entities.golems.EntityGolemBase" ) )
{
try
{
return this.transformClass_GolemBase( basicClass );
}
catch( Exception e )
{
this.log( "Unable to modify golem base class." );
}
}
else if( transformedName.equals( "thaumcraft.common.entities.golems.ItemGolemBell" ) )
{
try
{
return this.transformClass_ItemGolemBell( basicClass );
}
catch( Exception e )
{
this.log( "Unable to modify item golem bell class." );
}
}
else if( transformedName.equals( "thaumcraft.common.entities.golems.ItemGolemPlacer" ) )
{
try
{
return this.transformClass_ItemGolemPlacer( basicClass );
}
catch( Exception e )
{
this.log( "Unable to modify item golem placer class." );
}
}
else if( transformedName.equals( "thaumcraft.client.renderers.entity.RenderGolemBase" ) )
{
try
{
return this.transformClass_RenderGolemBase( basicClass );
}
catch( Exception e )
{
this.log( "Unable to modify render golem class." );
}
}
return basicClass;
}
}
@@ -0,0 +1,95 @@
package thaumicenergistics.fml;
import java.util.Map;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.LoadController;
import cpw.mods.fml.common.ModMetadata;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion;
@MCVersion("1.7.10")
public class ThECore
extends DummyModContainer
implements IFMLLoadingPlugin
{
private final ModMetadata metadata = new ModMetadata();
public ThECore()
{
this.metadata.autogenerated = false;
this.metadata.authorList.add( "Nividica" );
this.metadata.credits = "Nividica";
this.metadata.modId = this.getModId();
this.metadata.version = this.getVersion();
this.metadata.name = this.getName();
this.metadata.url = "";
this.metadata.logoFile = "";
this.metadata.description = "Embedded Coremod for Thaumic Energistics";
}
@Override
public String getAccessTransformerClass()
{
return null;
}
@Override
public String[] getASMTransformerClass()
{
return new String[] { "thaumicenergistics.fml.ASMTransformer" };
}
@Override
public String getDisplayVersion()
{
return getVersion();
}
@Override
public ModMetadata getMetadata()
{
return this.metadata;
}
@Override
public String getModContainerClass()
{
return "thaumicenergistics.fml.ThECore";
}
@Override
public String getModId()
{
return "ThE-core";
}
@Override
public String getName()
{
return "Thaumic Energistics Core";
}
@Override
public String getSetupClass()
{
return null;
}
@Override
public String getVersion()
{
return "0.10.0.0";
}
@Override
public void injectData( final Map<String, Object> data )
{
}
@Override
public boolean registerBus( final EventBus bus, final LoadController controller )
{
return true;
}
}
@@ -1,26 +1,24 @@
package thaumicenergistics.implementaion;
import java.util.ArrayList;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.ForgeDirection;
import thaumicenergistics.api.IThEInteractionHelper;
import thaumicenergistics.api.IThEWirelessEssentiaTerminal;
import thaumicenergistics.api.entities.IGolemHookHandler;
import thaumicenergistics.client.gui.GuiArcaneCraftingTerminal;
import thaumicenergistics.common.ThEGuiHandler;
import thaumicenergistics.common.grid.WirelessAELink;
import thaumicenergistics.common.integration.tc.EssentiaConversionHelper;
import thaumicenergistics.common.integration.tc.GolemHooks;
import thaumicenergistics.common.inventory.HandlerWirelessEssentiaTerminal;
import thaumicenergistics.common.network.packet.server.Packet_S_ArcaneCraftingTerminal;
import thaumicenergistics.integration.tc.EssentiaConversionHelper;
import appeng.api.AEApi;
import appeng.api.implementations.tiles.IWirelessAccessPoint;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IMachineSet;
import appeng.api.storage.data.IAEItemStack;
import appeng.core.localization.PlayerMessages;
import appeng.tile.misc.TileSecurity;
import appeng.tile.networking.TileWireless;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -99,82 +97,36 @@ public class ThEInteractionHelper
}
// Get the encryption key
long encryptionKey;
try
{
encryptionKey = Long.parseLong( terminalInterface.getEncryptionKey( wirelessTerminal ) );
}
catch( NumberFormatException e )
{
// Invalid security key
player.addChatMessage( PlayerMessages.CommunicationError.get() );
return;
}
String encKey = terminalInterface.getEncryptionKey( wirelessTerminal );
// Get the linked source
Object source = AEApi.instance().registries().locatable().getLocatableBy( encryptionKey );
// Are any AP's in range?
ArrayList<IWirelessAccessPoint> accessPoints = WirelessAELink.locateAPsInRangeOfPlayer( player, encKey );
// Ensure it is a security terminal
if( !( source instanceof TileSecurity ) )
{
// Invalid security terminal
player.addChatMessage( PlayerMessages.CommunicationError.get() );
return;
}
// Get the terminal
TileSecurity securityHost = (TileSecurity)source;
// Get the grid
IGrid hostGrid;
try
{
hostGrid = securityHost.getGridNode( ForgeDirection.UNKNOWN ).getGrid();
}
catch( Exception e )
{
// Can not find the grid
player.addChatMessage( PlayerMessages.CommunicationError.get() );
return;
}
// Get the AP's
IMachineSet accessPoints = hostGrid.getMachines( TileWireless.class );
// Loop over AP's and see if any are close enough to communicate with
for( IGridNode APNode : accessPoints )
{
// Get the AP
IWirelessAccessPoint AP = (IWirelessAccessPoint)APNode.getMachine();
// Is the AP active?
if( AP.isActive() )
{
// Is the player close enough to the AP?
if( HandlerWirelessEssentiaTerminal.isAPInRangeOfPlayer( AP.getLocation(), AP.getRange(), player ) )
{
// Launch the gui
ThEGuiHandler.launchGui( ThEGuiHandler.WIRELESS_TERMINAL_ID, player, player.worldObj, (int)player.posX, (int)player.posY,
(int)player.posZ, new Object[] { new HandlerWirelessEssentiaTerminal( player, AP, terminalInterface, wirelessTerminal ) } );
// All done.
return;
}
}
}
// No AP's were close enough
if( accessPoints.isEmpty() )
// Error occured
if( accessPoints == null )
{
player.addChatMessage( PlayerMessages.CommunicationError.get() );
}
else
// None in range
else if( accessPoints.isEmpty() )
{
player.addChatMessage( PlayerMessages.OutOfRange.get() );
}
// Launch the gui
else
{
ThEGuiHandler.launchGui( ThEGuiHandler.WIRELESS_TERMINAL_ID, player, player.worldObj, (int)player.posX, (int)player.posY,
(int)player.posZ, new Object[] { new HandlerWirelessEssentiaTerminal( player, encKey, terminalInterface, wirelessTerminal ) } );
}
}
@Override
public void registerGolemHookHandler( final IGolemHookHandler handler )
{
GolemHooks.registerHandler( handler );
}
@Override
@SideOnly(Side.CLIENT)
public void setArcaneCraftingTerminalRecipe( final ItemStack[] itemsVanilla )
@@ -1,8 +1,8 @@
package thaumicenergistics.implementaion;
import thaumicenergistics.api.IThEItems;
import thaumicenergistics.common.items.ItemEnum;
import thaumicenergistics.common.items.ItemMaterial.MaterialTypes;
import thaumicenergistics.common.registries.ItemEnum;
import thaumicenergistics.common.storage.EnumEssentiaStorageTypes;
class ThEItems
@@ -33,5 +33,6 @@ class ThEItems
this.WirelessEssentiaTerminal = new ThEItemDescription( ItemEnum.WIRELESS_TERMINAL.getStack() );
this.KnowledgeCore = new ThEItemDescription( ItemEnum.KNOWLEDGE_CORE.getStack() );
this.WandFocusAEWrench = new ThEItemDescription( ItemEnum.FOCUS_AEWRENCH.getStack() );
this.GolemWifiBackpack = new ThEItemDescription( ItemEnum.GOLEM_WIFI_BACKPACK.getStack() );
}
}
@@ -146,7 +146,7 @@ class ThETransportPermissions
if( this.tileExtractWhiteList.add( tileClass ) )
{
// Log the addition
ThELog.info( "Added %s with capacity %d to extraction whitelist.", tileClass.toString(), capacity );
ThELog.info( "Added \"%s\" with capacity (%d) to extraction whitelist.", tileClass.toString(), capacity );
}
return true;
@@ -168,7 +168,7 @@ class ThETransportPermissions
if( this.tileInjectWhiteList.add( tileClass ) )
{
// Log the addition
ThELog.info( "Added %s with capacity %d to injection whitelist.", tileClass.toString(), capacity );
ThELog.info( "Added \"%s\" with capacity (%d) to injection whitelist.", tileClass.toString(), capacity );
}
return true;
@@ -197,7 +197,7 @@ class ThETransportPermissions
}
// Log the addition
ThELog.info( "Adding %s[%d] to item whitelist.", itemClass.toString(), damageValue );
ThELog.info( "Added \"%s\"[%d] to item whitelist.", itemClass.toString(), damageValue );
}
}
@@ -45,6 +45,7 @@ thaumicenergistics.item.wireless.essentia.terminal.name=Wireless Essentia Termin
thaumicenergistics.item.knowledge.core.name=Knowledge Core
thaumicenergistics.item.focus.aewrench.name=Wand Focus: AE Wrench
thaumicenergistics.item.focus.aewrench.disabled.name=Wand Focus: AE Wrench - Wrench Mode Disabled
thaumicenergistics.item.golem.wifi.backpack.name=Wireless Golem Backpack
#Tooltips
thaumicenergistics.tooltip.itemstack.details=Hold §eshift§f for details.
@@ -54,7 +55,7 @@ thaumicenergistics.tooltip.button.void=Allow Void?
thaumicenergistics.tooltip.button.void.disabled=Do not void essentia
thaumicenergistics.tooltip.button.void.allowed=Void essentia if jar is full
thaumicenergistics.tooltip.button.void.note=Only applies to void jars
thaumicenergistics.tooltip.button.inscriber.invalid=Invalid Recipe
thaumicenergistics.tooltip.button.inscriber.invalid=Invalid Arcane Recipe
thaumicenergistics.tooltip.button.inscriber.full=Knowledge Core Is Full
thaumicenergistics.tooltip.button.inscriber.delete=Erase Pattern From Knowledge Core
thaumicenergistics.tooltip.button.inscriber.save=Save Pattern To Knowledge Core
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB