Backpacks & Integration

Added wifi backpack for Gather, Decanting, and Fill cores.
Fixes #265: Restored API call and marked as deprecated.
Fixed broken integration core.
This commit is contained in:
Chris committed 2016-01-19 11:11:13 -05:00
1 parent c222d94ceb
commit 373415c4c5
16 files changed
+659 -221

No files matched your search

+3
View File
@@ -1,6 +1,9 @@
01/18/2016 0.10.0.0 - Beta
Fixed bug where DPE would eat item stacks.
Refactored golem network code.
Added wifi backpack for Gather, Decanting, and Fill cores.
Fixes #265: Restored API call and marked as deprecated.
Fixed broken integration core.
01/17/2016 0.10.0.0 - Beta
Cleaned up backpack render code.
@@ -2,7 +2,9 @@ package thaumicenergistics.api;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.api.entities.IGolemHookHandler;
import thaumicenergistics.api.storage.IAspectStack;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -28,6 +30,15 @@ public interface IThEInteractionHelper
*/
public abstract long convertFluidAmountToEssentiaAmount( long milibuckets );
/**
* Creates a new instance of an aspect stack.
*
* @param aspect
* @param stackSize
* @return
*/
public IAspectStack createAspectStack( Aspect aspect, long stackSize );
/**
* Returns the Arcane Crafting Terminals GUI class.
*/
@@ -43,6 +54,18 @@ public interface IThEInteractionHelper
*/
public abstract void openWirelessTerminalGui( final EntityPlayer player );
/**
* The {@code IThEWirelessEssentiaTerminal} is assumed to be the item the player is holding, and is no longer needs to be passed in.
*
*
* @param player
* @param terminalInterface
* is now ignored
* @see #openWirelessTerminalGui(EntityPlayer)
*/
@Deprecated
public abstract void openWirelessTerminalGui( final EntityPlayer player, final IThEWirelessEssentiaTerminal terminalInterface );
/**
* Registers a handler to receive golem events.
*
@@ -61,6 +61,23 @@ public interface IGolemHookHandler
*/
public void addDefaultSyncEntries( @Nonnull IGolemHookSyncRegistry syncRegistry );
/**
* 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 bellLeftClicked( @Nonnull final EntityGolemBase golem, @Nullable Object handlerData, @Nonnull ItemStack itemGolemPlacer,
@Nonnull EntityPlayer player, boolean dismantled, @Nonnull Side side );
/**
* Return true if you can handle this interaction.<br/>
*
@@ -92,6 +109,23 @@ public interface IGolemHookHandler
public Object customInteraction( @Nonnull final EntityGolemBase golem, @Nullable Object handlerData, @Nonnull EntityPlayer player,
@Nonnull Side side );
/**
* Called when a golem receives a tick, if {@code needsDynamicUpdate} returned true during registration.
* Note: This is only called server side.
*
* @param golem
* @param serverHandlerData
* @param syncData
*/
public void golemTick( @Nonnull EntityGolemBase golem, @Nullable Object serverHandlerData, @Nonnull IGolemHookSyncRegistry syncData );
/**
* Return true if your handler wants to be called each time the golem gets a tick from the server.
*
* @return
*/
public boolean needsDynamicUpdates();
/**
* Return true if your handler wants to be called when a golem is rendered.<br/>
* Note: This is called only once during registration.
@@ -100,45 +134,16 @@ public interface IGolemHookHandler
*/
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 );
public Object readEntityFromNBT( @Nonnull final EntityGolemBase golem, @Nonnull NBTTagCompound nbtTag );
/**
* Called when a golem is being rendered, if {@code needsRenderer} returned true during registration.
@@ -184,6 +189,17 @@ public interface IGolemHookHandler
@Nullable
public Object spawnGolemFromItemStack( @Nonnull final EntityGolemBase golem, @Nonnull ItemStack itemGolemPlacer, @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 syncDataChanged( @Nonnull IGolemHookSyncRegistry syncData, @Nullable Object clientHandlerData );
/**
* 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.
@@ -48,8 +48,14 @@ public class ModelGolemWifiAddon
*/
private float pearlRotation = 0.0f;
/**
* True if the pearl display list is compiled
*/
private boolean isPearlCompiled = false;
/**
* ID of the pearl display list.
*/
private int pearlDispListID = -1;
public ModelGolemWifiAddon()
@@ -147,17 +153,25 @@ public class ModelGolemWifiAddon
tess.draw();
}
private void renderPearl( final float partialElapsedTick )
private void renderPearl( final float partialElapsedTick, final boolean inRange )
{
// Apply Y rotation
if( !Minecraft.getMinecraft().isGamePaused() )
if( inRange )
{
this.pearlRotation += ( partialElapsedTick * 2.0f );
if( this.pearlRotation >= 360.0f )
// Apply Y rotation
if( !Minecraft.getMinecraft().isGamePaused() )
{
this.pearlRotation -= 360.0f;
}
this.pearlRotation += ( partialElapsedTick * 2.0f );
if( this.pearlRotation >= 360.0f )
{
this.pearlRotation -= 360.0f;
}
}
}
else
{
// Set red
GL11.glColor3f( 1.0f, 0.0f, 0.0f );
}
GL11.glRotatef( this.pearlRotation, 0.0f, 1.0f, 0.0f );
@@ -181,14 +195,20 @@ public class ModelGolemWifiAddon
}
@Override
public void render( final Entity entity, final float partialElapsedTick, final float f1, final float f2, final float f3, final float f4,
public void render( final Entity entity, final float f, final float f1, final float f2, final float f3, final float f4,
final float f5 )
{
this.render( 0.03f, f5, true );
}
public void render( final float partialElapsedTick, final float f5, final boolean inRange )
{
Minecraft.getMinecraft().renderEngine.bindTexture( ModelGolemWifiAddon.TEXTURE );
this.PackBack.render( f5 );
this.PackFront.render( f5 );
this.Antenna.render( f5 );
this.renderPearl( partialElapsedTick );
this.renderPearl( partialElapsedTick, inRange );
}
}
@@ -3,68 +3,61 @@ package thaumicenergistics.common.entities;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import thaumcraft.common.entities.golems.EntityGolemBase;
import thaumicenergistics.common.grid.WirelessAELink;
import thaumicenergistics.common.integration.tc.GolemUpgradeTypes;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.data.IAEFluidStack;
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;
private final int maxItemRate;
/**
* The maximum amount of fluid, in mb, the golem can inject/extract per update.
*/
private final int maxFluids;
private final int maxFluidRate;
/**
* The maximum amount of essentia the golem can inject/extract per update.
*/
private final int maxEssentia;
private final int maxEssentiaRate;
/**
* How many ticks until the golem can interact with the network again.
* Data associated with the wireless state of the backpack.
*/
private int actionTimer = 0;
public final WirelessGolemHandler.WirelessServerData wirelessStateData;
public NetworkHandler( final String encryptionKey, final int maxItems, final int maxFluids, final int maxEssentia )
public NetworkHandler( final WirelessGolemHandler.WirelessServerData wsd, final int maxItems, final int maxFluids, final int maxEssentia )
{
// Call super
super( null, encryptionKey );
super( null, wsd.encryptionKey );
// Set maximums
this.maxItems = maxItems;
this.maxFluids = maxFluids;
this.maxEssentia = maxEssentia;
}
this.maxItemRate = maxItems;
this.maxFluidRate = maxFluids;
this.maxEssentiaRate = maxEssentia;
/**
* Gets the item monitor if possible.
*
* @return
*/
private IMEMonitor<IAEItemStack> getNetworkItems()
{
// Check connectivity
if( !this.canInteractWithNetwork() )
{
return null;
}
// Set state data
this.wirelessStateData = wsd;
// Attempt to connect to AP
this.isConnected();
// Get the item monitor
return this.getItemInventory();
}
@Override
@@ -99,49 +92,15 @@ public abstract class AIAENetworkGolem
}
/**
* Checks if the network can be interacted with.
* Attempts to deposit the itemstack into the AE system.
* The {@code stack.stacksize} will change according to how many items were left over after the deposit.
*
* @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.
* @param stack
*/
public void depositStack( final ItemStack stack )
{
// Get the item monitor
IMEMonitor<IAEItemStack> monitor = this.getNetworkItems();
IMEMonitor<IAEItemStack> monitor = this.getItemInventory();
if( monitor == null )
{
return;
@@ -151,11 +110,11 @@ public abstract class AIAENetworkGolem
IAEItemStack aeStack = AEApi.instance().storage().createItemStack( stack );
// Set size
int depositSize = Math.min( stack.stackSize, this.maxItems );
int depositSize = Math.min( stack.stackSize, this.maxItemRate );
aeStack.setStackSize( depositSize );
// Deposit
IAEItemStack rejected = monitor.injectItems( aeStack, Actionable.MODULATE, this.actionSource );
IAEItemStack rejected = AEApi.instance().storage().poweredInsert( this.getEnergyGrid(), monitor, aeStack, this.actionSource );
if( rejected != null )
{
depositSize -= (int)rejected.getStackSize();
@@ -163,13 +122,115 @@ public abstract class AIAENetworkGolem
// Reduce stack by number of items deposited
stack.stackSize -= depositSize;
}
// Reset network timer
this.actionTimer = NETWORK_COOLDOWN;
/**
* Extracts fluids from the network.
*
* @param target
* @return
*/
public FluidStack extractFluid( final FluidStack target )
{
// Get the fluid monitor
IMEMonitor<IAEFluidStack> monitor = this.getFluidInventory();
if( monitor == null )
{
return null;
}
// Get power grid
IEnergyGrid eGrid = this.getEnergyGrid();
if( eGrid == null )
{
return null;
}
// Calculate request size
long requestSize = Math.min( target.amount, this.maxFluidRate );
// Calculate power required
double pwrReq = requestSize / 100;
if( eGrid.extractAEPower( pwrReq, Actionable.SIMULATE, PowerMultiplier.CONFIG ) < pwrReq )
{
// Not enough power
return null;
}
// Create the fluid stack
IAEFluidStack aeRequest = AEApi.instance().storage().createFluidStack( target );
// Set size
aeRequest.setStackSize( requestSize );
// Extract
IAEFluidStack extracted = monitor.extractItems( aeRequest, Actionable.MODULATE, this.actionSource );
if( extracted == null )
{
return null;
}
// Take power
pwrReq = extracted.getStackSize() / 100;
eGrid.extractAEPower( pwrReq, Actionable.MODULATE, PowerMultiplier.CONFIG );
return extracted.getFluidStack();
}
/**
* Extracts items from the network.
*
* @param target
* @return Extracted stack.
*/
public ItemStack extractStack( final ItemStack target )
{
// Get the item monitor
IMEMonitor<IAEItemStack> monitor = this.getItemInventory();
if( monitor == null )
{
return null;
}
// Create the AE stack
IAEItemStack aeRequest = AEApi.instance().storage().createItemStack( target );
// Set size
aeRequest.setStackSize( Math.min( target.stackSize, this.maxItemRate ) );
// Extract
IAEItemStack extracted = AEApi.instance().storage().poweredExtraction( this.getEnergyGrid(), monitor, aeRequest, this.actionSource );
if( extracted == null )
{
return null;
}
return extracted.getItemStack();
}
/**
* Checks if the network can be interacted with.
*
* @return
*/
@Override
public boolean isConnected()
{
// Connected to network?
this.wirelessStateData.isInRange = super.isConnected();
return this.wirelessStateData.isInRange;
}
}
private static final int NETWORK_COOLDOWN = 15;
/**
* How many ticks until the golem can interact with the network again.
*/
private int actionTimer = 0;
/**
* Handles AE network communication.
*/
@@ -204,7 +265,7 @@ public abstract class AIAENetworkGolem
*/
private static final int[] ESS_RATES = new int[] { 8, 24, 32 };
public AIAENetworkGolem( final EntityGolemBase golem, final String encKey )
public AIAENetworkGolem( final EntityGolemBase golem, final WirelessGolemHandler.WirelessServerData wsd )
{
// Set the golem
this.golem = golem;
@@ -229,7 +290,31 @@ public abstract class AIAENetworkGolem
int maxFluids = FLUID_RATES[orderUpgrades] * rateMult;
// Create the network handler
this.network = new NetworkHandler( encKey, maxItems, maxFluids, maxEssentia );
this.network = new NetworkHandler( wsd, maxItems, maxFluids, maxEssentia );
}
/**
* Called to decrement the action timer.
*
* @return True if cooled down.
*/
private boolean cooldownTick()
{
if( this.actionTimer > 0 )
{
--this.actionTimer;
return false;
}
return true;
}
/**
*
*/
private void restartNetworkCooldown()
{
// Reset network timer
this.actionTimer = NETWORK_COOLDOWN;
}
/**
@@ -237,17 +322,27 @@ public abstract class AIAENetworkGolem
*
* @return
*/
protected abstract boolean needsNetworkInteraction();
protected abstract boolean needsNetworkNow();
@Override
public final boolean shouldExecute()
{
// Check the network timer
if( this.network.cooldownTick() )
if( this.cooldownTick() )
{
return this.needsNetworkInteraction();
this.restartNetworkCooldown();
// IsConnected needs to be checked before needsNetwork
// This ensures the wireless state data is kept up-to-date
if( this.network.isConnected() )
{
return this.needsNetworkNow();
}
}
return false;
}
@Override
public abstract void updateTask();
}
@@ -0,0 +1,39 @@
package thaumicenergistics.common.entities;
import net.minecraft.item.ItemStack;
import thaumcraft.common.entities.golems.EntityGolemBase;
public class AIGolemWifiFill
extends AIAENetworkGolem
{
public AIGolemWifiFill( final EntityGolemBase golem, final WirelessGolemHandler.WirelessServerData wsd )
{
super( golem, wsd );
}
@Override
protected boolean needsNetworkNow()
{
// Is the golem watching for anything?
return( this.golem.itemWatched != null );
}
@Override
public void updateTask()
{
// Get the stack the golem is watching for.
ItemStack watched = this.golem.itemWatched;
if( watched != null )
{
// Attempt extraction
ItemStack extracted = this.network.extractStack( watched );
if( extracted != null )
{
this.golem.setCarried( extracted );
this.golem.itemWatched = null;
}
}
}
}
@@ -6,13 +6,13 @@ import thaumcraft.common.entities.golems.EntityGolemBase;
public class AIGolemWifiGather
extends AIAENetworkGolem
{
public AIGolemWifiGather( final EntityGolemBase golem, final String encKey )
public AIGolemWifiGather( final EntityGolemBase golem, final WirelessGolemHandler.WirelessServerData wsd )
{
super( golem, encKey );
super( golem, wsd );
}
@Override
public boolean needsNetworkInteraction()
public boolean needsNetworkNow()
{
// Execute when the golem is holding something
return( this.golem.getCarried() != null );
@@ -0,0 +1,80 @@
package thaumicenergistics.common.entities;
import java.util.ArrayList;
import net.minecraftforge.fluids.FluidStack;
import thaumcraft.common.entities.golems.EntityGolemBase;
import thaumcraft.common.entities.golems.GolemHelper;
import thaumicenergistics.common.entities.WirelessGolemHandler.WirelessServerData;
public class AIGolemWifiLiquid
extends AIAENetworkGolem
{
private FluidStack wantedFluid;
public AIGolemWifiLiquid( final EntityGolemBase golem, final WirelessServerData wsd )
{
super( golem, wsd );
}
@Override
protected boolean needsNetworkNow()
{
// Is the golem in-need of a fluid?
ArrayList<FluidStack> fluids = GolemHelper.getMissingLiquids( this.golem );
// Don't bother if the golem is asking for EVERY fluid, only if there is a specific request.
if( ( fluids != null ) && ( fluids.size() == 1 ) )
{
// Set the wanted fluid
this.wantedFluid = fluids.get( 0 ).copy();
// Verify that the golem is carrying the fluid, or nothing
if( ( this.golem.fluidCarried == null ) || ( this.golem.fluidCarried.getFluid() == this.wantedFluid.getFluid() ) )
{
return true;
}
this.wantedFluid = null;
}
return false;
}
@Override
public void updateTask()
{
if( this.wantedFluid == null )
{
return;
}
// Is the golem carrying the fluid?
int existingSize = 0;
if( this.golem.fluidCarried != null )
{
existingSize = this.golem.fluidCarried.amount;
}
// Calculate maximum request size
this.wantedFluid.amount = 1000 - existingSize;
// Attempt extraction
FluidStack extracted = this.network.extractFluid( this.wantedFluid );
if( extracted == null )
{
return;
}
// Add to existing?
if( existingSize > 0 )
{
this.golem.fluidCarried.amount += extracted.amount;
}
else
{
this.golem.fluidCarried = extracted;
}
this.wantedFluid = null;
}
}
@@ -8,6 +8,7 @@ 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.integration.tc.GolemCoreType;
import thaumicenergistics.common.items.ItemEnum;
import thaumicenergistics.common.items.ItemGolemWirelessBackpack;
import thaumicenergistics.common.utils.EffectiveSide;
@@ -17,6 +18,27 @@ import cpw.mods.fml.relauncher.SideOnly;
public class WirelessGolemHandler
implements IGolemHookHandler
{
public static class WirelessClientData
{
public boolean isInRange = false;
public WirelessClientData( final boolean inRange )
{
this.isInRange = inRange;
}
}
public static class WirelessServerData
{
public final String encryptionKey;
public boolean isInRange = false;
public WirelessServerData( final String encKey )
{
this.encryptionKey = encKey;
}
}
private static WirelessGolemHandler INSTANCE = null;
/**
@@ -25,15 +47,11 @@ public class WirelessGolemHandler
private static final String NBTKEY_WIFI_KEY = "wifiBackpackKey";
/**
* Core types
* State flags.
*/
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' );
private static final Character SYNCFLAG_HAS_WIFI_IN_RANGE = Character.valueOf( 'i' ),
SYNCFLAG_HAS_WIFI_OUT_OF_RANGE = Character.valueOf( 'o' ),
SYNCFLAG_NO_WIFI = Character.valueOf( 'n' );
@SideOnly(Side.CLIENT)
private ModelGolemWifiAddon addonModel;
@@ -90,7 +108,26 @@ public class WirelessGolemHandler
public void addDefaultSyncEntries( final IGolemHookSyncRegistry syncRegistry )
{
// Register the wifi entry
this.wifiSyncID = syncRegistry.registerSyncChar( this, SYNC_FLAG_NO_WIFI );
this.wifiSyncID = syncRegistry.registerSyncChar( this, SYNCFLAG_NO_WIFI );
}
@Override
public void bellLeftClicked( 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 instanceof WirelessServerData )
{
// Create a new backpack item
ItemStack backpack = ItemEnum.GOLEM_WIFI_BACKPACK.getStack();
// Set the key
this.backpackItem.setEncryptionKey( backpack, ( (WirelessServerData)handlerData ).encryptionKey, null );
// Drop the backpack
golem.entityDropItem( backpack, 0.5f );
}
}
@Override
@@ -120,7 +157,34 @@ public class WirelessGolemHandler
return false;
}
return isHoldingBackpack;
// Is the core valid?
GolemCoreType core = GolemCoreType.getCoreByID( golem.getCore() );
if( core == null )
{
return false;
}
switch ( core )
{
// Unsupported cores
case Butcher:
case Empty:
case Essentia: // TODO, complex no doubt
case Fish: // TODO?
case Guard:
case Harvest:
case Lumber:
case Sorting:
case Use:
default:
return false;
// Supported cores
case Gather:
case Fill:
case Liquid:
return isHoldingBackpack;
}
}
@Override
@@ -136,13 +200,31 @@ public class WirelessGolemHandler
// Take the item
player.inventory.setInventorySlotContents( player.inventory.currentItem, null );
// Store the key
return encKey;
// Create the data
return new WirelessServerData( encKey );
}
return null;
}
@Override
public void golemTick( final EntityGolemBase golem, final Object serverHandlerData, final IGolemHookSyncRegistry syncData )
{
// Has backpack?
if( serverHandlerData instanceof WirelessServerData )
{
// Update clients
syncData.updateSyncChar( this, this.wifiSyncID, ( ( (WirelessServerData)serverHandlerData ).isInRange ? SYNCFLAG_HAS_WIFI_IN_RANGE
: SYNCFLAG_HAS_WIFI_OUT_OF_RANGE ) );
}
}
@Override
public boolean needsDynamicUpdates()
{
return true;
}
@Override
public boolean needsRenderer()
{
@@ -150,48 +232,13 @@ public class WirelessGolemHandler
}
@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 )
public Object readEntityFromNBT( final EntityGolemBase golem, 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 );
// Create the data
return new WirelessServerData( nbtTag.getString( NBTKEY_WIFI_KEY ) );
}
// No wifi
@@ -203,7 +250,7 @@ public class WirelessGolemHandler
public void renderGolem( final EntityGolemBase golem, final Object clientHandlerData, final double x, final double y, final double z,
final float partialElaspsedTick )
{
if( clientHandlerData == null )
if( !( clientHandlerData instanceof WirelessClientData ) )
{
return;
}
@@ -242,7 +289,7 @@ public class WirelessGolemHandler
GL11.glScalef( 0.8f, 0.8f, 0.8f );
// Render
this.addonModel.render( null, partialElaspsedTick, 0.0f, -0.1f, 0.0f, 0.0f, 0.0625f );
this.addonModel.render( partialElaspsedTick, 0.0625f, ( (WirelessClientData)clientHandlerData ).isInRange );
// Pop the matrix
GL11.glPopMatrix();
@@ -252,32 +299,48 @@ public class WirelessGolemHandler
@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 )
if( handlerData instanceof WirelessServerData )
{
// Get the golems core
byte core = golem.getCore();
WirelessServerData wsd = (WirelessServerData)handlerData;
// Gather core?
if( core == CORE_GATHER )
// Get the golems core
GolemCoreType core = GolemCoreType.getCoreByID( golem.getCore() );
if( core != null )
{
// Add AI Script
golem.tasks.addTask( 1, new AIGolemWifiGather( golem, (String)handlerData ) );
switch ( core )
{
case Gather:
// Add Gather AI script
golem.tasks.addTask( 1, new AIGolemWifiGather( golem, wsd ) );
break;
case Fill:
// Add Fill AI script
golem.tasks.addTask( 3, new AIGolemWifiFill( golem, wsd ) );
break;
case Liquid:
// Add liquid AI script
golem.tasks.addTask( 2, new AIGolemWifiLiquid( golem, wsd ) );
break;
default:
break;
}
}
// Update the sync data
syncData.updateSyncChar( this, this.wifiSyncID, SYNC_FLAG_HAS_WIFI );
syncData.updateSyncChar( this, this.wifiSyncID, ( wsd.isInRange ? SYNCFLAG_HAS_WIFI_IN_RANGE : SYNCFLAG_HAS_WIFI_OUT_OF_RANGE ) );
}
else
{
// Update the sync data
syncData.updateSyncChar( this, this.wifiSyncID, SYNC_FLAG_NO_WIFI );
syncData.updateSyncChar( this, this.wifiSyncID, SYNCFLAG_NO_WIFI );
}
return handlerData;
@@ -286,17 +349,51 @@ public class WirelessGolemHandler
@Override
public Object spawnGolemFromItemStack( final EntityGolemBase golem, final ItemStack itemGolemPlacer, final Side side )
{
golem.advanced = true;
return null;
}
@Override
@SideOnly(Side.CLIENT)
public Object syncDataChanged( final IGolemHookSyncRegistry syncData, final Object clientHandlerData )
{
// Does the golem have on a backpack?
char syncFlag = syncData.getSyncCharOrDefault( this.wifiSyncID, SYNCFLAG_NO_WIFI );
boolean inRange;
if( syncFlag == SYNCFLAG_HAS_WIFI_IN_RANGE )
{
inRange = true;
}
else if( syncFlag == SYNCFLAG_HAS_WIFI_OUT_OF_RANGE )
{
inRange = false;
}
else
{
// No backpack.
return null;
}
// Has existing data?
if( clientHandlerData instanceof WirelessClientData )
{
// Update the data
( (WirelessClientData)clientHandlerData ).isInRange = inRange;
return clientHandlerData;
}
// Create new data
return new WirelessClientData( inRange );
}
@Override
public void writeEntityNBT( final EntityGolemBase golem, final Object serverHandlerData, final NBTTagCompound nbtTag )
{
// Does the golem have a backpack?
if( serverHandlerData instanceof String )
if( serverHandlerData instanceof WirelessServerData )
{
// Write network key
nbtTag.setString( NBTKEY_WIFI_KEY, (String)serverHandlerData );
nbtTag.setString( NBTKEY_WIFI_KEY, ( (WirelessServerData)serverHandlerData ).encryptionKey );
}
}
@@ -13,6 +13,7 @@ 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.energy.IEnergyGrid;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.security.PlayerSource;
@@ -43,11 +44,6 @@ public abstract class WirelessAELink
*/
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.
*/
@@ -243,7 +239,7 @@ public abstract class WirelessAELink
if( this.accessPoint.isActive() )
{
// In range?
return isAPInRange( this.apLocation, this.apTransmitRange, this.getUserWorld(),
return isAPInRange( this.apLocation, this.accessPoint.getRange(), this.getUserWorld(),
this.getUserPositionX(), this.getUserPositionY(), this.getUserPositionZ() );
}
}
@@ -321,9 +317,6 @@ public abstract class WirelessAELink
// 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();
@@ -373,6 +366,27 @@ public abstract class WirelessAELink
*/
protected abstract boolean hasPowerToCommunicate();
public IEnergyGrid getEnergyGrid()
{
// Check AP
if( this.accessPoint == null )
{
return null;
}
try
{
// Get the energy grid
return this.accessPoint.getActionableNode().getGrid().getCache( IEnergyGrid.class );
}
catch( Exception e )
{
// Ignored
}
return null;
}
/**
* Gets the essentia inventory.
*
@@ -380,7 +394,8 @@ public abstract class WirelessAELink
*/
public IMEEssentiaMonitor getEssentiaInventory()
{
if( this.accessPoint == null )
// Check connectivity
if( ( this.accessPoint == null ) || !this.isConnected() )
{
return null;
}
@@ -399,7 +414,8 @@ public abstract class WirelessAELink
@Override
public IMEMonitor<IAEFluidStack> getFluidInventory()
{
if( this.accessPoint == null )
// Check connectivity
if( ( this.accessPoint == null ) || !this.isConnected() )
{
return null;
}
@@ -423,7 +439,8 @@ public abstract class WirelessAELink
@Override
public IMEMonitor<IAEItemStack> getItemInventory()
{
if( this.accessPoint == null )
// Check connectivity
if( ( this.accessPoint == null ) || !this.isConnected() )
{
return null;
}
@@ -17,7 +17,7 @@ public final class IntegrationCore
/**
* Class path to all integration modules
*/
private static final String CLASS_PATH = ThaumicEnergistics.MOD_ID + ".integration.Module";
private static final String CLASS_PATH = ThaumicEnergistics.MOD_ID + ".common.integration.Module";
/**
* Module ID for Waila
@@ -1,4 +1,4 @@
package thaumicenergistics.common.entities;
package thaumicenergistics.common.integration.tc;
import javax.annotation.Nullable;
@@ -30,6 +30,14 @@ public class GolemHooks
}
@Override
public void bellLeftClicked( final EntityGolemBase golem, final Object handlerData, final ItemStack itemGolemPlacer,
final EntityPlayer player, final boolean dismantled,
final Side side )
{
}
@Override
public boolean canHandleInteraction( final EntityGolemBase golem, final Object handlerData, final EntityPlayer player, final Side side )
{
@@ -42,6 +50,17 @@ public class GolemHooks
return null;
}
@Override
public void golemTick( final EntityGolemBase golem, final Object serverHandlerData, final IGolemHookSyncRegistry syncData )
{
}
@Override
public boolean needsDynamicUpdates()
{
return false;
}
@Override
public boolean needsRenderer()
{
@@ -49,21 +68,7 @@ public class GolemHooks
}
@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 )
public Object readEntityFromNBT( final EntityGolemBase golem, final NBTTagCompound nbtTag )
{
return null;
}
@@ -87,6 +92,12 @@ public class GolemHooks
return null;
}
@Override
public Object syncDataChanged( final IGolemHookSyncRegistry syncData, final Object clientHandlerData )
{
return null;
}
@Override
public void writeEntityNBT( final EntityGolemBase golem, final Object serverHandlerData, final NBTTagCompound nbtTag )
{
@@ -115,6 +126,11 @@ public class GolemHooks
*/
protected static final HashSet<IGolemHookHandler> registeredHandlers = new HashSet<IGolemHookHandler>();
/**
* Handlers that need to be called during tick event.
*/
protected static final HashSet<IGolemHookHandler> dynamicHandlers = new HashSet<IGolemHookHandler>();
/**
* Handlers that need to be called during render.
*/
@@ -177,7 +193,7 @@ public class GolemHooks
// Call handler
handler.onBellLeftClick( golem, handlerData, dropped, player, dismantled, side );
handler.bellLeftClicked( golem, handlerData, dropped, player, dismantled, side );
}
catch( Exception e )
{
@@ -282,14 +298,25 @@ public class GolemHooks
*/
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 );
if( EffectiveSide.isServerSide() )
{
// Update handlers
for( IGolemHookHandler handler : dynamicHandlers )
{
handler.golemTick( golem, golemHandlerData.get( handler ), syncRegistry );
}
// Update data watcher
if( syncRegistry.hasChanged() )
{
golem.getDataWatcher().updateObject( DATAWATCHER_ID, syncRegistry.mappingsToString() );
}
return;
}
// Update sync ticks
++syncRegistry.clientSyncTicks;
@@ -325,7 +352,7 @@ public class GolemHooks
boolean hadData = ( handlerData != null );
// Call handler
handlerData = handler.onSyncDataChanged( syncRegistry, handlerData );
handlerData = handler.syncDataChanged( syncRegistry, handlerData );
// Update golem
if( handlerData == null )
@@ -397,9 +424,6 @@ public class GolemHooks
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 )
{
@@ -409,7 +433,7 @@ public class GolemHooks
Object handlerData = golemHandlerData.getOrDefault( handler, null );
// Call handler
handlerData = handler.readEntityFromNBT( golem, localSyncRegistry, nbt );
handlerData = handler.readEntityFromNBT( golem, nbt );
// Update golem
if( handlerData == null )
@@ -550,6 +574,12 @@ public class GolemHooks
renderHandlers.add( handler );
}
// Needs tick?
if( handler.needsDynamicUpdates() )
{
dynamicHandlers.add( handler );
}
// Register sync data
defaultSyncRegistry.canRegister = true;
handler.addDefaultSyncEntries( defaultSyncRegistry );
@@ -1,4 +1,4 @@
package thaumicenergistics.common.entities;
package thaumicenergistics.common.integration.tc;
import javax.annotation.Nullable;
@@ -14,6 +14,7 @@ public class VisProviderProxy
{
/**
* How far vis can travel from the source. I think >.>
* TODO: Test vis range
*/
private static final int VIS_RANGE = 1;
@@ -5,9 +5,11 @@ import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.FakePlayer;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.api.IThEInteractionHelper;
import thaumicenergistics.api.IThEWirelessEssentiaTerminal;
import thaumicenergistics.api.entities.IGolemHookHandler;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.client.gui.GuiArcaneCraftingTerminal;
import thaumicenergistics.common.ThEGuiHandler;
import thaumicenergistics.common.grid.WirelessAELink;
@@ -15,6 +17,7 @@ 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.common.storage.AspectStack;
import appeng.api.AEApi;
import appeng.api.implementations.tiles.IWirelessAccessPoint;
import appeng.api.storage.data.IAEItemStack;
@@ -38,6 +41,12 @@ public class ThEInteractionHelper
return EssentiaConversionHelper.INSTANCE.convertFluidAmountToEssentiaAmount( milibuckets );
}
@Override
public IAspectStack createAspectStack( final Aspect aspect, final long stackSize )
{
return new AspectStack( aspect, stackSize );
}
@Override
@SideOnly(Side.CLIENT)
public Class getArcaneCraftingTerminalGUIClass()
@@ -121,6 +130,14 @@ public class ThEInteractionHelper
}
@Deprecated
@Override
public void openWirelessTerminalGui( final EntityPlayer player, final IThEWirelessEssentiaTerminal terminalInterface )
{
this.openWirelessTerminalGui( player );
}
@Override
public void registerGolemHookHandler( final IGolemHookHandler handler )
{