mirror of
https://github.com/GTNewHorizons/ThaumicEnergistics.git
synced 2026-10-25 20:32:27 +00:00
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:
1 parent
ae17e65313
commit
c222d94ceb
95 files changed
+3513
-434
No files matched your search
+25
-1
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
|
||||
+4
-2
@@ -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;
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+11
-1
@@ -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 )
|
||||
|
||||
+3
-3
@@ -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
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration;
|
||||
package thaumicenergistics.common.integration;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration;
|
||||
package thaumicenergistics.common.integration;
|
||||
|
||||
/**
|
||||
* Used to pass specific events to a watcher.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration;
|
||||
package thaumicenergistics.common.integration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration;
|
||||
package thaumicenergistics.common.integration;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import thaumicenergistics.api.ThEApi;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration;
|
||||
package thaumicenergistics.common.integration;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration;
|
||||
package thaumicenergistics.common.integration;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import thaumicenergistics.api.ThEApi;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration;
|
||||
package thaumicenergistics.common.integration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration;
|
||||
package thaumicenergistics.common.integration;
|
||||
|
||||
import java.util.List;
|
||||
import mcp.mobius.waila.api.IWailaConfigHandler;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration.tc;
|
||||
package thaumicenergistics.common.integration.tc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import javax.annotation.Nullable;
|
||||
+1
-1
@@ -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
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration.tc;
|
||||
package thaumicenergistics.common.integration.tc;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration.tc;
|
||||
package thaumicenergistics.common.integration.tc;
|
||||
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import thaumcraft.api.aspects.Aspect;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration.tc;
|
||||
package thaumicenergistics.common.integration.tc;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration.tc;
|
||||
package thaumicenergistics.common.integration.tc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
+1
-1
@@ -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
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration.tc;
|
||||
package thaumicenergistics.common.integration.tc;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Field;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration.tc;
|
||||
package thaumicenergistics.common.integration.tc;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration.tc;
|
||||
package thaumicenergistics.common.integration.tc;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package thaumicenergistics.integration.tc;
|
||||
package thaumicenergistics.common.integration.tc;
|
||||
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import thaumcraft.api.WorldCoordinates;
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
+1
-1
@@ -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
|
||||
{
|
||||
|
||||
+41
-254
@@ -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;
|
||||
|
||||
|
||||
+3
-3
@@ -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 |
BIN
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 |
Reference in new issue
Block a user