Backpacks with style.
Fixed SMP packet crash. Fixed potential golem hook crash and added levels of interaction. Added golem backpack skins.
No files matched your search
@@ -1,8 +1,15 @@
|
||||
01/22/2016 1.0.0.0 - Beta
|
||||
01/23/2016 1.0.0.0 - Beta
|
||||
Fixed SMP packet crash.
|
||||
Fixed potential golem hook crash.
|
||||
Added levels of interaction.
|
||||
Added golem backpack skins.
|
||||
|
||||
01/22/2016 1.0.0.0 - Beta
|
||||
Bumped version to 1.0.0.0
|
||||
Fixes #213: Added backpack lore and recipe.
|
||||
Added backpack config option.
|
||||
Updated mod info file.
|
||||
Fixed several SMP crashes.
|
||||
|
||||
01/21/2016 0.10.0.0 - Beta
|
||||
Fixed multiple issues with the Arcane assembler: GUI desync, invalid network state.
|
||||
|
||||
@@ -52,6 +52,59 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
*/
|
||||
public interface IGolemHookHandler
|
||||
{
|
||||
/**
|
||||
* Defines interaction levels.
|
||||
*
|
||||
* @author Nividica
|
||||
*
|
||||
*/
|
||||
public static enum InteractionLevel
|
||||
{
|
||||
/**
|
||||
* The interaction was not handled at all.<br>
|
||||
* <ul>
|
||||
* <li>GUI will be shown, if golem has one.</li>
|
||||
* <li>customInteraction() will not be called.</li>
|
||||
* <li>Sync data will not be sent.</li>
|
||||
* <li>setupGolem() will not be called.</li>
|
||||
* </ul>
|
||||
*/
|
||||
NoInteraction,
|
||||
|
||||
/**
|
||||
* The interaction was handled, but no sync data changed, and golem does not need to be re-setup.<br>
|
||||
* <ul>
|
||||
* <li>GUI will not be shown</li>
|
||||
* <li>customInteraction() called.
|
||||
* <li>
|
||||
* <li>Sync data will not be sent.</li>
|
||||
* <li>setupGolem() will not be called.</li>
|
||||
* </ul>
|
||||
*/
|
||||
BasicInteraction,
|
||||
|
||||
/**
|
||||
* The interaction was handled and sync data changed, but the golem does not need to be re-setup<br>
|
||||
* <ul>
|
||||
* <li>GUI will not be shown</li>
|
||||
* <li>customInteraction() called.</li>
|
||||
* <li>Sync data sent.</li>
|
||||
* <li>setupGolem() will not be called.</li>
|
||||
* </ul>
|
||||
*/
|
||||
SyncInteraction,
|
||||
|
||||
/**
|
||||
* The interaction was handled and the golem needs to be re-setup.
|
||||
* <ul>
|
||||
* <li>GUI will not be shown</li>
|
||||
* <li>customInteraction() called.</li>
|
||||
* <li>Sync data sent.</li>
|
||||
* <li>setupGolem() called.</li>
|
||||
* </ul>
|
||||
*/
|
||||
FullInteraction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any data you wish to sync between the server and clients can be added here.<br/>
|
||||
@@ -87,12 +140,11 @@ public interface IGolemHookHandler
|
||||
* @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.
|
||||
* @return The level of interaction.
|
||||
*/
|
||||
public boolean canHandleInteraction( @Nonnull final EntityGolemBase golem, @Nullable Object handlerData, @Nonnull EntityPlayer player,
|
||||
@Nonnull Side side );
|
||||
@Nonnull
|
||||
public InteractionLevel 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/>
|
||||
@@ -100,17 +152,21 @@ public interface IGolemHookHandler
|
||||
* @param golem
|
||||
* @param handlerData
|
||||
* Handler data attached to the golem.
|
||||
* @param syncData
|
||||
* @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 );
|
||||
public Object customInteraction( @Nonnull final EntityGolemBase golem, @Nullable Object handlerData, @Nonnull IGolemHookSyncRegistry syncData,
|
||||
@Nonnull EntityPlayer player, @Nonnull Side side );
|
||||
|
||||
/**
|
||||
* Called when a golem receives a tick, if {@code needsDynamicUpdate} returned true during registration.
|
||||
* Called when a golem receives a tick, if {@code needsDynamicUpdate} returned true during registration.<br>
|
||||
* If setting sync data, you do not need to track if the sync data has changed yourself. The {@code syncData} class
|
||||
* tracks this internally and will only ever send updates if the data has actually changed. Although for performance reasons
|
||||
* it would be a good idea to keep a tick counter and only set the data periodically if there is any processing involved.<br>
|
||||
* Note: This is only called server side.
|
||||
*
|
||||
* @param golem
|
||||
|
||||
@@ -6,9 +6,8 @@ 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 thaumicenergistics.common.items.ItemGolemWirelessBackpack.BackpackSkins;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@@ -16,8 +15,6 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
public class ModelGolemWifiBackpack
|
||||
extends ModelBase
|
||||
{
|
||||
public static ResourceLocation TEXTURE = new ResourceLocation( ThaumicEnergistics.MOD_ID, "textures/models/golem.wifi.backpack.png" );
|
||||
|
||||
/**
|
||||
* Submodels
|
||||
*/
|
||||
@@ -182,12 +179,12 @@ public class ModelGolemWifiBackpack
|
||||
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 );
|
||||
this.render( 0.03f, f5, true, BackpackSkins.Thaumium );
|
||||
}
|
||||
|
||||
public void render( final float pearlRotation, final float f5, final boolean inRange )
|
||||
public void render( final float pearlRotation, final float f5, final boolean inRange, final BackpackSkins skin )
|
||||
{
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture( ModelGolemWifiBackpack.TEXTURE );
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture( skin.getTextureLocation() );
|
||||
this.PackBack.render( f5 );
|
||||
this.PackFront.render( f5 );
|
||||
this.Antenna.render( f5 );
|
||||
|
||||
@@ -86,6 +86,11 @@ public class ContainerDistillationPatternEncoder
|
||||
*/
|
||||
private final TheInternalInventory internalInventory;
|
||||
|
||||
/**
|
||||
* Cached versions of the source and pattern.
|
||||
*/
|
||||
private ItemStack cachedSource, cachedPattern;
|
||||
|
||||
/**
|
||||
* Slot holding the source item.
|
||||
*/
|
||||
@@ -179,20 +184,6 @@ public class ContainerDistillationPatternEncoder
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the slot needs to be sync'd
|
||||
*
|
||||
* @param slot
|
||||
* @return
|
||||
*/
|
||||
private boolean doesSlotNeedSync( final Slot slot )
|
||||
{
|
||||
ItemStack slotStack = slot.getStack();
|
||||
ItemStack invStack = (ItemStack)this.inventoryItemStacks.get( slot.slotNumber );
|
||||
|
||||
return !ItemStack.areItemStacksEqual( invStack, slotStack );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the transfer was handled.
|
||||
* Assumes that clickedslot has an itemstack.
|
||||
@@ -249,7 +240,8 @@ public class ContainerDistillationPatternEncoder
|
||||
private void loadPattern()
|
||||
{
|
||||
// Read the pattern
|
||||
this.patternHelper.readPattern( this.slotPatternEncoded.getStack() );
|
||||
this.cachedPattern = this.slotPatternEncoded.getStack();
|
||||
this.patternHelper.readPattern( this.cachedPattern );
|
||||
|
||||
// Is the pattern valid?
|
||||
if( this.patternHelper.isValid() )
|
||||
@@ -270,27 +262,21 @@ public class ContainerDistillationPatternEncoder
|
||||
*/
|
||||
private void scanSourceItem( final boolean setSelectedAspect )
|
||||
{
|
||||
if( EffectiveSide.isClientSide() )
|
||||
{
|
||||
// Ignored client side
|
||||
return;
|
||||
}
|
||||
|
||||
this.cachedSource = this.slotSourceItem.getStack();
|
||||
|
||||
// Clear aspect slots
|
||||
this.clearAspectSlots();
|
||||
|
||||
// Null?
|
||||
if( !this.slotSourceItem.getHasStack() )
|
||||
if( this.cachedSource == null )
|
||||
{
|
||||
// Done
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the itemstack
|
||||
ItemStack sourceItem = this.slotSourceItem.getDisplayStack();
|
||||
|
||||
// Get the aspects
|
||||
AspectList itemAspects = ThaumcraftApiHelper.getObjectAspects( sourceItem );
|
||||
AspectList itemAspects = ThaumcraftApiHelper.getObjectAspects( this.cachedSource );
|
||||
Aspect[] sortedAspects = null;
|
||||
|
||||
// Does the item have any aspects?
|
||||
@@ -301,7 +287,7 @@ public class ContainerDistillationPatternEncoder
|
||||
}
|
||||
|
||||
// Generate hash
|
||||
int hash = ScanManager.generateItemHash( sourceItem.getItem(), sourceItem.getItemDamage() );
|
||||
int hash = ScanManager.generateItemHash( this.cachedSource.getItem(), this.cachedSource.getItemDamage() );
|
||||
|
||||
// Get the list of scanned objects
|
||||
List<String> list = Thaumcraft.proxy.getScannedObjects().get( this.player.getCommandSenderName() );
|
||||
@@ -355,14 +341,14 @@ public class ContainerDistillationPatternEncoder
|
||||
protected boolean detectAndSendChangesMP( final EntityPlayerMP playerMP )
|
||||
{
|
||||
// Does the pattern slot need to be sync'd?
|
||||
if( this.doesSlotNeedSync( this.slotPatternEncoded ) )
|
||||
if( this.slotPatternEncoded.getStack() != this.cachedPattern )
|
||||
{
|
||||
// Load the pattern
|
||||
this.loadPattern();
|
||||
return true;
|
||||
}
|
||||
// Does the source item need to be sync'd?
|
||||
else if( this.doesSlotNeedSync( this.slotSourceItem ) )
|
||||
else if( this.slotSourceItem.getStack() != this.cachedSource )
|
||||
{
|
||||
// Scan the source item
|
||||
this.scanSourceItem( true );
|
||||
@@ -513,7 +499,16 @@ public class ContainerDistillationPatternEncoder
|
||||
ItemStack heldItem = player.inventory.getItemStack();
|
||||
|
||||
// Set the source slot
|
||||
this.slotSourceItem.putStack( heldItem );
|
||||
if( heldItem != null )
|
||||
{
|
||||
ItemStack copy = heldItem.copy();
|
||||
copy.stackSize = 1;
|
||||
this.slotSourceItem.putStack( copy );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.slotSourceItem.putStack( null );
|
||||
}
|
||||
|
||||
handled = true;
|
||||
}
|
||||
|
||||
@@ -247,10 +247,13 @@ public abstract class AIAENetworkGolem
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate the amount to inject
|
||||
int amountToInject = Math.min( amount, this.maxEssentiaRate );
|
||||
|
||||
// Attempt to inject
|
||||
long amountRejected = monitor.injectEssentia( aspect, amountToInject, Actionable.MODULATE, this.actionSource, true );
|
||||
|
||||
// Return the amount that was injected
|
||||
return amountToInject - amountRejected;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package thaumicenergistics.common.entities;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import thaumcraft.common.config.ConfigBlocks;
|
||||
import thaumcraft.common.entities.golems.EntityGolemBase;
|
||||
import thaumicenergistics.api.entities.IGolemHookHandler;
|
||||
import thaumicenergistics.api.entities.IGolemHookSyncRegistry;
|
||||
@@ -12,28 +15,42 @@ import thaumicenergistics.client.render.model.ModelGolemWifiBackpack;
|
||||
import thaumicenergistics.common.integration.tc.GolemCoreType;
|
||||
import thaumicenergistics.common.items.ItemEnum;
|
||||
import thaumicenergistics.common.items.ItemGolemWirelessBackpack;
|
||||
import thaumicenergistics.common.items.ItemGolemWirelessBackpack.BackpackSkins;
|
||||
import thaumicenergistics.common.utils.EffectiveSide;
|
||||
import appeng.api.AEApi;
|
||||
import appeng.items.parts.ItemFacade;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
public class WirelessGolemHandler
|
||||
implements IGolemHookHandler
|
||||
{
|
||||
/**
|
||||
* Data stored on the client side.
|
||||
*
|
||||
* @author Nividica
|
||||
*
|
||||
*/
|
||||
public static class WirelessClientData
|
||||
{
|
||||
public boolean isInRange = false;
|
||||
public float pearlRotation = 0.0f;
|
||||
|
||||
public WirelessClientData( final boolean inRange )
|
||||
{
|
||||
this.isInRange = inRange;
|
||||
}
|
||||
public BackpackSkins skin = BackpackSkins.Thaumium;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data stored on the server side.
|
||||
*
|
||||
* @author Nividica
|
||||
*
|
||||
*/
|
||||
public static class WirelessServerData
|
||||
{
|
||||
public final String encryptionKey;
|
||||
public int tickCounter = 0;
|
||||
public boolean isInRange = false;
|
||||
public ItemStack facade = null;
|
||||
public BackpackSkins skin = BackpackSkins.Thaumium;
|
||||
|
||||
public WirelessServerData( final String encKey )
|
||||
{
|
||||
@@ -44,16 +61,17 @@ public class WirelessGolemHandler
|
||||
private static WirelessGolemHandler INSTANCE = null;
|
||||
|
||||
/**
|
||||
* NBT key used to represent if the golem has the wifi backpack or not.
|
||||
* NBT keys
|
||||
*/
|
||||
private static final String NBTKEY_WIFI_KEY = "wifiBackpackKey";
|
||||
private static final String NBTKEY_WIFI_KEY = "wifiBackpackKey", NBTKEY_FACADE = "facade";
|
||||
|
||||
/**
|
||||
* State flags.
|
||||
*/
|
||||
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' );
|
||||
SYNCFLAG_NO_WIFI = Character.valueOf( 'n' ),
|
||||
SYNCFIELD_SKIN = 'a';
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private ModelGolemWifiBackpack addonModel;
|
||||
@@ -63,11 +81,21 @@ public class WirelessGolemHandler
|
||||
*/
|
||||
private int wifiSyncID = -1;
|
||||
|
||||
/**
|
||||
* ID of the skin sync field.
|
||||
*/
|
||||
private int skinSyncID = -1;
|
||||
|
||||
/**
|
||||
* Cache of the backpack item.
|
||||
*/
|
||||
private ItemGolemWirelessBackpack backpackItem;
|
||||
|
||||
/**
|
||||
* Item that represents a facade, or null.
|
||||
*/
|
||||
private ItemFacade facadeItem;
|
||||
|
||||
/**
|
||||
* Private constructor.
|
||||
*/
|
||||
@@ -81,6 +109,9 @@ public class WirelessGolemHandler
|
||||
|
||||
// Store a reference to the backpack item.
|
||||
this.backpackItem = (ItemGolemWirelessBackpack)ItemEnum.GOLEM_WIFI_BACKPACK.getItem();
|
||||
|
||||
// Store a reference to the facade item
|
||||
this.facadeItem = (ItemFacade)AEApi.instance().definitions().items().facade().maybeItem().orNull();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,61 +129,45 @@ public class WirelessGolemHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the wifi addon model.
|
||||
* Gets a character based on the skin.
|
||||
*
|
||||
* @param skin
|
||||
* @return
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
private void setupModel()
|
||||
private Character backpackSkinToSyncChar( final BackpackSkins skin )
|
||||
{
|
||||
this.addonModel = new ModelGolemWifiBackpack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDefaultSyncEntries( final IGolemHookSyncRegistry syncRegistry )
|
||||
{
|
||||
// Register the wifi entry
|
||||
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 )
|
||||
int id = 0;
|
||||
if( skin != null )
|
||||
{
|
||||
// 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 );
|
||||
id = skin.ordinal();
|
||||
}
|
||||
|
||||
return Character.valueOf( (char)( SYNCFIELD_SKIN + id ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canHandleInteraction( final EntityGolemBase golem, final Object handlerData, final EntityPlayer player, final Side side )
|
||||
/**
|
||||
* Han the backpack be handled?
|
||||
*
|
||||
* @param golem
|
||||
* @param handlerData
|
||||
* @param player
|
||||
* @param side
|
||||
* @return
|
||||
*/
|
||||
private InteractionLevel canHandleInteration_Backpack( 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 ) );
|
||||
|
||||
// Does the golem already have a backpack on?
|
||||
if( handlerData != null )
|
||||
{
|
||||
// Already has backpack.
|
||||
return false;
|
||||
return InteractionLevel.NoInteraction;
|
||||
}
|
||||
|
||||
// Is the core valid?
|
||||
GolemCoreType core = GolemCoreType.getCoreByID( golem.getCore() );
|
||||
if( core == null )
|
||||
{
|
||||
return false;
|
||||
return InteractionLevel.NoInteraction;
|
||||
}
|
||||
switch ( core )
|
||||
{
|
||||
@@ -166,7 +181,7 @@ public class WirelessGolemHandler
|
||||
case Sorting:
|
||||
case Use:
|
||||
default:
|
||||
return false;
|
||||
return InteractionLevel.NoInteraction;
|
||||
|
||||
// Supported cores
|
||||
case Gather:
|
||||
@@ -179,36 +194,274 @@ public class WirelessGolemHandler
|
||||
// Client side?
|
||||
if( side == Side.CLIENT )
|
||||
{
|
||||
if( isHoldingBackpack )
|
||||
{
|
||||
//Swing the item
|
||||
player.swingItem();
|
||||
}
|
||||
return false;
|
||||
//Swing the item
|
||||
player.swingItem();
|
||||
return InteractionLevel.NoInteraction;
|
||||
}
|
||||
|
||||
return isHoldingBackpack;
|
||||
return InteractionLevel.FullInteraction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the facade be handled?
|
||||
*
|
||||
* @param golem
|
||||
* @param handlerData
|
||||
* @param player
|
||||
* @param side
|
||||
* @param heldItem
|
||||
* @return
|
||||
*/
|
||||
private InteractionLevel canHandleInteration_Facade( final EntityGolemBase golem, final Object handlerData, final EntityPlayer player,
|
||||
final Side side,
|
||||
final ItemStack heldItem )
|
||||
{
|
||||
// Is the golem wearing a backpack?
|
||||
if( handlerData == null )
|
||||
{
|
||||
// No backpack to apply it to
|
||||
return InteractionLevel.NoInteraction;
|
||||
}
|
||||
|
||||
// Get the skin for the facade
|
||||
BackpackSkins skin = this.getSkinFromFacade( heldItem );
|
||||
if( skin == null )
|
||||
{
|
||||
// Unsupported facade
|
||||
return InteractionLevel.NoInteraction;
|
||||
}
|
||||
|
||||
// Client side?
|
||||
if( ( side == Side.CLIENT ) && ( handlerData instanceof WirelessClientData ) )
|
||||
{
|
||||
//Swing the item
|
||||
player.swingItem();
|
||||
|
||||
// Set the skin
|
||||
( (WirelessClientData)handlerData ).skin = skin;
|
||||
|
||||
return InteractionLevel.NoInteraction;
|
||||
}
|
||||
|
||||
return InteractionLevel.SyncInteraction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the skin associated with the facade, or null if there is not one.
|
||||
*
|
||||
* @param facade
|
||||
* @return
|
||||
*/
|
||||
private BackpackSkins getSkinFromFacade( final ItemStack facade )
|
||||
{
|
||||
Block b = this.facadeItem.getBlock( facade );
|
||||
int metaData = this.facadeItem.getMeta( facade );
|
||||
|
||||
if( b == ConfigBlocks.blockCosmeticSolid )
|
||||
{
|
||||
// Thaumium block?
|
||||
if( metaData == 4 )
|
||||
{
|
||||
return BackpackSkins.Thaumium;
|
||||
}
|
||||
// Tallow block?
|
||||
else if( metaData == 5 )
|
||||
{
|
||||
return BackpackSkins.Tallow;
|
||||
}
|
||||
}
|
||||
// Greatwood log?
|
||||
else if( ( b == ConfigBlocks.blockMagicalLog ) && ( metaData == 0 ) )
|
||||
{
|
||||
return BackpackSkins.GreatWood;
|
||||
}
|
||||
// Flesh?
|
||||
else if( ( b == ConfigBlocks.blockTaint ) && ( metaData == 2 ) )
|
||||
{
|
||||
return BackpackSkins.Flesh;
|
||||
}
|
||||
// Stone block?
|
||||
else if( b == Blocks.stone )
|
||||
{
|
||||
return BackpackSkins.Stone;
|
||||
}
|
||||
// Hay block?
|
||||
else if( b == Blocks.hay_block )
|
||||
{
|
||||
return BackpackSkins.Straw;
|
||||
}
|
||||
// Bricks?
|
||||
else if( b == Blocks.brick_block )
|
||||
{
|
||||
return BackpackSkins.Clay;
|
||||
}
|
||||
// Iron?
|
||||
else if( b == Blocks.iron_block )
|
||||
{
|
||||
return BackpackSkins.Iron;
|
||||
}
|
||||
else if( b == Blocks.gold_block )
|
||||
{
|
||||
return BackpackSkins.Gold;
|
||||
}
|
||||
else if( b == Blocks.diamond_block )
|
||||
{
|
||||
return BackpackSkins.Diamond;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the wifi addon model.
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
private void setupModel()
|
||||
{
|
||||
this.addonModel = new ModelGolemWifiBackpack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the skin based on the character
|
||||
*
|
||||
* @param skinSyncChar
|
||||
* @return
|
||||
*/
|
||||
private BackpackSkins syncCharToBackpackSkin( final char skinSyncChar )
|
||||
{
|
||||
int id = skinSyncChar - SYNCFIELD_SKIN;
|
||||
if( ( id < 0 ) || ( id > BackpackSkins.VALUES.length ) )
|
||||
{
|
||||
id = 0;
|
||||
}
|
||||
return BackpackSkins.VALUES[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDefaultSyncEntries( final IGolemHookSyncRegistry syncRegistry )
|
||||
{
|
||||
// Register the wifi entry
|
||||
this.wifiSyncID = syncRegistry.registerSyncChar( this, SYNCFLAG_NO_WIFI );
|
||||
|
||||
// Register facade item
|
||||
this.skinSyncID = syncRegistry.registerSyncChar( this, this.backpackSkinToSyncChar( BackpackSkins.Thaumium ) );
|
||||
}
|
||||
|
||||
@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 )
|
||||
{
|
||||
WirelessServerData wsd = ( (WirelessServerData)handlerData );
|
||||
|
||||
// Create a new backpack item
|
||||
ItemStack backpack = ItemEnum.GOLEM_WIFI_BACKPACK.getStack();
|
||||
|
||||
// Set the key
|
||||
this.backpackItem.setEncryptionKey( backpack, wsd.encryptionKey, null );
|
||||
|
||||
// Drop the backpack
|
||||
golem.entityDropItem( backpack, 0.5f );
|
||||
|
||||
// Is there a facade?
|
||||
if( wsd.facade != null )
|
||||
{
|
||||
// Drop the facade
|
||||
golem.entityDropItem( wsd.facade, 0.5f );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object customInteraction( final EntityGolemBase golem, final Object handlerData, final EntityPlayer player, final Side side )
|
||||
public InteractionLevel canHandleInteraction( 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 )
|
||||
// Empty hand?
|
||||
if( heldItem == null )
|
||||
{
|
||||
return InteractionLevel.NoInteraction;
|
||||
}
|
||||
|
||||
// Backpack?
|
||||
if( heldItem.getItem() == this.backpackItem )
|
||||
{
|
||||
return this.canHandleInteration_Backpack( golem, handlerData, player, side );
|
||||
}
|
||||
|
||||
// Facade?
|
||||
else if( ( this.facadeItem != null ) && ( heldItem.getItem() == this.facadeItem ) )
|
||||
{
|
||||
return this.canHandleInteration_Facade( golem, handlerData, player, side, heldItem );
|
||||
}
|
||||
|
||||
return InteractionLevel.NoInteraction;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object customInteraction( final EntityGolemBase golem, final Object handlerData, final IGolemHookSyncRegistry syncData,
|
||||
final EntityPlayer player, final Side side )
|
||||
{
|
||||
// Get the held item
|
||||
ItemStack heldItem = player.inventory.getCurrentItem();
|
||||
|
||||
// Backpack?
|
||||
if( heldItem.getItem() == this.backpackItem )
|
||||
{
|
||||
// Is the backpack linked?
|
||||
String encKey = this.backpackItem.getEncryptionKey( heldItem );
|
||||
if( encKey != null )
|
||||
{
|
||||
// Play sound
|
||||
golem.worldObj.playSoundAtEntity( golem, "thaumcraft:upgrade", 0.5F, 1.0F );
|
||||
|
||||
// Take the item
|
||||
player.inventory.setInventorySlotContents( player.inventory.currentItem, null );
|
||||
|
||||
// Create the data
|
||||
return new WirelessServerData( encKey );
|
||||
}
|
||||
}
|
||||
|
||||
// Facade?
|
||||
else if( ( this.facadeItem != null ) && ( heldItem.getItem() == this.facadeItem ) )
|
||||
{
|
||||
WirelessServerData wsd = (WirelessServerData)handlerData;
|
||||
|
||||
// Is there a facade set?
|
||||
if( ( wsd.facade != null ) && ( !player.capabilities.isCreativeMode ) )
|
||||
{
|
||||
// Drop the old facade
|
||||
golem.entityDropItem( wsd.facade, 0.5f );
|
||||
}
|
||||
|
||||
// Set facade
|
||||
wsd.facade = heldItem.copy();
|
||||
wsd.facade.stackSize = 1;
|
||||
|
||||
// Take a facade from the player
|
||||
if( !player.capabilities.isCreativeMode )
|
||||
{
|
||||
--heldItem.stackSize;
|
||||
if( heldItem.stackSize <= 0 )
|
||||
{
|
||||
player.inventory.setInventorySlotContents( player.inventory.currentItem, null );
|
||||
}
|
||||
}
|
||||
|
||||
// Set the skin
|
||||
wsd.skin = this.getSkinFromFacade( wsd.facade );
|
||||
syncData.updateSyncChar( this, this.skinSyncID, this.backpackSkinToSyncChar( wsd.skin ) );
|
||||
|
||||
// Play sound
|
||||
golem.worldObj.playSoundAtEntity( golem, "thaumcraft:upgrade", 0.5F, 1.0F );
|
||||
golem.worldObj.playSoundAtEntity( golem, "thaumcraft:cameraticks", 0.5F, 1.0F );
|
||||
|
||||
// Take the item
|
||||
player.inventory.setInventorySlotContents( player.inventory.currentItem, null );
|
||||
|
||||
// Create the data
|
||||
return new WirelessServerData( encKey );
|
||||
return wsd;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -220,9 +473,18 @@ public class WirelessGolemHandler
|
||||
// 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 ) );
|
||||
WirelessServerData wsd = (WirelessServerData)serverHandlerData;
|
||||
|
||||
// Set sync data every 18th tick
|
||||
if( ++wsd.tickCounter > 18 )
|
||||
{
|
||||
// Reset counter
|
||||
wsd.tickCounter = 0;
|
||||
|
||||
// Set sync data
|
||||
syncData.updateSyncChar( this, this.wifiSyncID, ( wsd.isInRange ? SYNCFLAG_HAS_WIFI_IN_RANGE : SYNCFLAG_HAS_WIFI_OUT_OF_RANGE ) );
|
||||
syncData.updateSyncChar( this, this.skinSyncID, this.backpackSkinToSyncChar( wsd.skin ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,15 +503,31 @@ public class WirelessGolemHandler
|
||||
@Override
|
||||
public Object readEntityFromNBT( final EntityGolemBase golem, final NBTTagCompound nbtTag )
|
||||
{
|
||||
WirelessServerData wsd = null;
|
||||
|
||||
// Does the golem have a backpack?
|
||||
if( nbtTag.hasKey( NBTKEY_WIFI_KEY ) )
|
||||
{
|
||||
// Create the data
|
||||
return new WirelessServerData( nbtTag.getString( NBTKEY_WIFI_KEY ) );
|
||||
wsd = new WirelessServerData( nbtTag.getString( NBTKEY_WIFI_KEY ) );
|
||||
|
||||
if( nbtTag.hasKey( NBTKEY_FACADE ) )
|
||||
{
|
||||
// Read the facade
|
||||
try
|
||||
{
|
||||
wsd.facade = ItemStack.loadItemStackFromNBT( nbtTag.getCompoundTag( NBTKEY_FACADE ) );
|
||||
wsd.skin = this.getSkinFromFacade( wsd.facade );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
// Invalid facade
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// No wifi
|
||||
return null;
|
||||
return wsd;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -297,7 +575,7 @@ public class WirelessGolemHandler
|
||||
GL11.glPushMatrix();
|
||||
|
||||
// Translate to the golem
|
||||
GL11.glTranslatef( (float)x, (float)y + 0.63f, (float)z );
|
||||
GL11.glTranslatef( (float)x, (float)y + 0.64f, (float)z );
|
||||
|
||||
// Rotate to face away from the golem
|
||||
float golemYaw = 270.0f;
|
||||
@@ -315,7 +593,7 @@ public class WirelessGolemHandler
|
||||
GL11.glScalef( 0.8f, 0.8f, 0.8f );
|
||||
|
||||
// Render
|
||||
this.addonModel.render( wcd.pearlRotation, 0.0625f, golemActive );
|
||||
this.addonModel.render( wcd.pearlRotation, 0.0625f, golemActive, wcd.skin );
|
||||
|
||||
// Pop the matrix
|
||||
GL11.glPopMatrix();
|
||||
@@ -405,15 +683,25 @@ public class WirelessGolemHandler
|
||||
}
|
||||
|
||||
// Has existing data?
|
||||
WirelessClientData wcd = null;
|
||||
if( clientHandlerData instanceof WirelessClientData )
|
||||
{
|
||||
// Update the data
|
||||
( (WirelessClientData)clientHandlerData ).isInRange = inRange;
|
||||
return clientHandlerData;
|
||||
wcd = (WirelessClientData)clientHandlerData;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create new data
|
||||
wcd = new WirelessClientData();
|
||||
}
|
||||
|
||||
// Create new data
|
||||
return new WirelessClientData( inRange );
|
||||
// Update the range
|
||||
wcd.isInRange = inRange;
|
||||
|
||||
// Get the skin
|
||||
char skinChar = syncData.getSyncCharOrDefault( this.skinSyncID, SYNCFIELD_SKIN );
|
||||
wcd.skin = this.syncCharToBackpackSkin( skinChar );
|
||||
|
||||
return wcd;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -422,8 +710,17 @@ public class WirelessGolemHandler
|
||||
// Does the golem have a backpack?
|
||||
if( serverHandlerData instanceof WirelessServerData )
|
||||
{
|
||||
WirelessServerData wsd = ( (WirelessServerData)serverHandlerData );
|
||||
|
||||
// Write network key
|
||||
nbtTag.setString( NBTKEY_WIFI_KEY, ( (WirelessServerData)serverHandlerData ).encryptionKey );
|
||||
nbtTag.setString( NBTKEY_WIFI_KEY, wsd.encryptionKey );
|
||||
|
||||
// Has facade?
|
||||
if( wsd.facade != null )
|
||||
{
|
||||
// Write the facade
|
||||
nbtTag.setTag( NBTKEY_FACADE, wsd.facade.writeToNBT( new NBTTagCompound() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ public class FeatureGolemBackpack
|
||||
new ResearchPage( ResearchTypes.GOLEM_BACKPACK.getPageName( 1 ) ),
|
||||
new ResearchPage( RecipeRegistry.ITEM_GOLEM_WIFI_BACKPACK ),
|
||||
new ResearchPage( ResearchTypes.GOLEM_BACKPACK.getPageName( 2 ) ),
|
||||
new ResearchPage( ResearchTypes.GOLEM_BACKPACK.getPageName( 3 ) ),
|
||||
new ResearchPage( ResearchTypes.GOLEM_BACKPACK.getPageName( "COREGATHER" ) ),
|
||||
new ResearchPage( "COREFILL", ResearchTypes.GOLEM_BACKPACK.getPageName( "COREFILL" ) ),
|
||||
new ResearchPage( "CORELIQUID", ResearchTypes.GOLEM_BACKPACK.getPageName( "CORELIQUID" ) ),
|
||||
@@ -103,7 +104,8 @@ public class FeatureGolemBackpack
|
||||
ResearchTypes.GOLEM_BACKPACK.createResearchItem( aspects, ResearchRegistry.COMPLEXITY_LARGE, icon, pages );
|
||||
|
||||
// Set parents
|
||||
ResearchTypes.GOLEM_BACKPACK.researchItem.setParents( this.getFirstValidParentKey( false ), PseudoResearchTypes.COREGATHER.getKey() );
|
||||
ResearchTypes.GOLEM_BACKPACK.researchItem.setParents( this.getFirstValidParentKey( false ), "COREGATHER",
|
||||
PseudoResearchTypes.COREGATHER.getKey() );
|
||||
|
||||
// Hide until the parent has been researched
|
||||
ResearchTypes.GOLEM_BACKPACK.researchItem.setConcealed();
|
||||
|
||||
@@ -514,14 +514,21 @@ public class EssentiaMonitor
|
||||
}
|
||||
|
||||
// Simulate the injection
|
||||
long rejectedAmount = this.injectEssentiaSafely( aspect, amount, Actionable.SIMULATE, source, essentiaGas );
|
||||
long adjustedAmount = amount - rejectedAmount;
|
||||
long injectedAmount = amount;
|
||||
long rejectedAmount = this.injectEssentiaSafely( aspect, injectedAmount, Actionable.SIMULATE, source, essentiaGas );
|
||||
injectedAmount -= rejectedAmount;
|
||||
|
||||
// Was all rejected?
|
||||
if( injectedAmount == 0 )
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
|
||||
// Is this a powered injection?
|
||||
if( powered )
|
||||
{
|
||||
// Simulate power extraction
|
||||
double powerRequest = EssentiaMonitor.AE_PER_ESSENTIA * adjustedAmount;
|
||||
double powerRequest = EssentiaMonitor.AE_PER_ESSENTIA * injectedAmount;
|
||||
double powerReceived = this.energyGrid.extractAEPower( powerRequest, Actionable.SIMULATE, PowerMultiplier.CONFIG );
|
||||
|
||||
// Was enough power extracted?
|
||||
@@ -536,18 +543,18 @@ public class EssentiaMonitor
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
// Inject
|
||||
rejectedAmount = this.injectEssentiaSafely( aspect, adjustedAmount, Actionable.MODULATE, source, essentiaGas );
|
||||
adjustedAmount -= rejectedAmount;
|
||||
rejectedAmount = this.injectEssentiaSafely( aspect, injectedAmount, Actionable.MODULATE, source, essentiaGas );
|
||||
injectedAmount -= rejectedAmount;
|
||||
|
||||
// Adjust and extract power
|
||||
if( powered )
|
||||
{
|
||||
double powerRequest = EssentiaMonitor.AE_PER_ESSENTIA * adjustedAmount;
|
||||
double powerRequest = EssentiaMonitor.AE_PER_ESSENTIA * injectedAmount;
|
||||
this.energyGrid.extractAEPower( powerRequest, Actionable.MODULATE, PowerMultiplier.CONFIG );
|
||||
}
|
||||
}
|
||||
|
||||
return rejectedAmount;
|
||||
return amount - injectedAmount;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,6 +24,86 @@ import codechicken.nei.recipe.IRecipeHandler;
|
||||
public class ModuleNEI
|
||||
{
|
||||
|
||||
/**
|
||||
* Base class for handling item overlays.
|
||||
*
|
||||
* @author Nividica
|
||||
*
|
||||
*/
|
||||
abstract class AbstractBaseOverlayHandler
|
||||
implements IOverlayHandler
|
||||
{
|
||||
/**
|
||||
* Calls on the subclass to add an ingredient to the items array.
|
||||
*
|
||||
* @param ingredient
|
||||
* @param overlayItems
|
||||
*/
|
||||
protected abstract boolean addIngredientToItems( PositionedStack ingredient, IAEItemStack[] overlayItems );
|
||||
|
||||
/**
|
||||
* Called when the items are ready to be placed in the GUI.
|
||||
*
|
||||
* @param overlayItems
|
||||
*/
|
||||
protected abstract void addItemsToGUI( IAEItemStack[] overlayItems );
|
||||
|
||||
/**
|
||||
* Checks with the subclass to see if this is a GUI it handles.
|
||||
*
|
||||
* @param gui
|
||||
* @return
|
||||
*/
|
||||
protected abstract boolean isCorrectGUI( GuiContainer gui );
|
||||
|
||||
/**
|
||||
* Called when the user has shift-clicked the [?] button in NEI
|
||||
*/
|
||||
@Override
|
||||
public final void overlayRecipe( final GuiContainer gui, final IRecipeHandler recipeHandler, final int recipeIndex, final boolean shift )
|
||||
{
|
||||
try
|
||||
{
|
||||
// Ensure the gui is correct
|
||||
if( this.isCorrectGUI( gui ) )
|
||||
{
|
||||
// List of items
|
||||
IAEItemStack[] overlayItems = new IAEItemStack[9];
|
||||
|
||||
// Assume there are no items until they are added.
|
||||
boolean hasItems = false;
|
||||
|
||||
// Get the ingredients
|
||||
List<PositionedStack> ingredients = recipeHandler.getIngredientStacks( recipeIndex );
|
||||
|
||||
// Get each item
|
||||
for( PositionedStack ingredient : ingredients )
|
||||
{
|
||||
// Skip nulls
|
||||
if( ( ingredient == null ) || ( ingredient.item == null ) || ( ingredient.item.getItem() == null ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Pass to subclass
|
||||
hasItems |= this.addIngredientToItems( ingredient, overlayItems );
|
||||
}
|
||||
|
||||
// Were any items added?
|
||||
if( hasItems )
|
||||
{
|
||||
this.addItemsToGUI( overlayItems );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
// Silently ignored.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a selected NEI recipe to the open A.C.T on the server.
|
||||
*
|
||||
@@ -178,86 +258,6 @@ public class ModuleNEI
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for handling item overlays.
|
||||
*
|
||||
* @author Nividica
|
||||
*
|
||||
*/
|
||||
abstract class AbstractBaseOverlayHandler
|
||||
implements IOverlayHandler
|
||||
{
|
||||
/**
|
||||
* Calls on the subclass to add an ingredient to the items array.
|
||||
*
|
||||
* @param ingredient
|
||||
* @param overlayItems
|
||||
*/
|
||||
protected abstract boolean addIngredientToItems( PositionedStack ingredient, IAEItemStack[] overlayItems );
|
||||
|
||||
/**
|
||||
* Called when the items are ready to be placed in the GUI.
|
||||
*
|
||||
* @param overlayItems
|
||||
*/
|
||||
protected abstract void addItemsToGUI( IAEItemStack[] overlayItems );
|
||||
|
||||
/**
|
||||
* Checks with the subclass to see if this is a GUI it handles.
|
||||
*
|
||||
* @param gui
|
||||
* @return
|
||||
*/
|
||||
protected abstract boolean isCorrectGUI( GuiContainer gui );
|
||||
|
||||
/**
|
||||
* Called when the user has shift-clicked the [?] button in NEI
|
||||
*/
|
||||
@Override
|
||||
public final void overlayRecipe( final GuiContainer gui, final IRecipeHandler recipeHandler, final int recipeIndex, final boolean shift )
|
||||
{
|
||||
try
|
||||
{
|
||||
// Ensure the gui is correct
|
||||
if( this.isCorrectGUI( gui ) )
|
||||
{
|
||||
// List of items
|
||||
IAEItemStack[] overlayItems = new IAEItemStack[9];
|
||||
|
||||
// Assume there are no items until they are added.
|
||||
boolean hasItems = false;
|
||||
|
||||
// Get the ingredients
|
||||
List<PositionedStack> ingredients = recipeHandler.getIngredientStacks( recipeIndex );
|
||||
|
||||
// Get each item
|
||||
for( PositionedStack ingredient : ingredients )
|
||||
{
|
||||
// Skip nulls
|
||||
if( ( ingredient == null ) || ( ingredient.item == null ) || ( ingredient.item.getItem() == null ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Pass to subclass
|
||||
hasItems |= this.addIngredientToItems( ingredient, overlayItems );
|
||||
}
|
||||
|
||||
// Were any items added?
|
||||
if( hasItems )
|
||||
{
|
||||
this.addItemsToGUI( overlayItems );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
// Silently ignored.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Starting X offset for slots in NEI
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,7 @@ 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.IGolemHookHandler.InteractionLevel;
|
||||
import thaumicenergistics.api.entities.IGolemHookSyncRegistry;
|
||||
import thaumicenergistics.common.utils.EffectiveSide;
|
||||
import thaumicenergistics.common.utils.ThELog;
|
||||
@@ -15,6 +16,13 @@ import thaumicenergistics.fml.ThECore;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
/**
|
||||
* Golem hook system.<br>
|
||||
* Manages golem hooks and handlers.
|
||||
*
|
||||
* @author Nividica
|
||||
*
|
||||
*/
|
||||
public class GolemHooks
|
||||
{
|
||||
private static class DummyHookHandler
|
||||
@@ -40,13 +48,15 @@ public class GolemHooks
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canHandleInteraction( final EntityGolemBase golem, final Object handlerData, final EntityPlayer player, final Side side )
|
||||
public InteractionLevel canHandleInteraction( final EntityGolemBase golem, final Object handlerData, final EntityPlayer player,
|
||||
final Side side )
|
||||
{
|
||||
return false;
|
||||
return InteractionLevel.NoInteraction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object customInteraction( final EntityGolemBase golem, final Object handlerData, final EntityPlayer player, final Side side )
|
||||
public Object customInteraction( final EntityGolemBase golem, final Object handlerData, final IGolemHookSyncRegistry syncData,
|
||||
final EntityPlayer player, final Side side )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -216,56 +226,91 @@ public class GolemHooks
|
||||
public static boolean hook_CustomInteraction( final EntityGolemBase golem, final EntityPlayer player,
|
||||
final HashMap<IGolemHookHandler, Object> golemHandlerData )
|
||||
{
|
||||
boolean interactionHandled = false;
|
||||
GolemSyncRegistry syncRegistry = ( (GolemSyncRegistry)golemHandlerData.get( internalHandler ) );
|
||||
|
||||
boolean needsSync = false;
|
||||
boolean needsSetup = false;
|
||||
boolean skipGUI = false;
|
||||
InteractionLevel handlerLevel;
|
||||
|
||||
Side side = EffectiveSide.side();
|
||||
|
||||
for( IGolemHookHandler handler : registeredHandlers )
|
||||
{
|
||||
// Get the current handler data
|
||||
Object handlerData = golemHandlerData.getOrDefault( handler, null );
|
||||
|
||||
// Call handler
|
||||
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 );
|
||||
}
|
||||
}
|
||||
handlerLevel = handler.canHandleInteraction( golem, handlerData, player, side );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
logCaughtException( "canHandleInteraction", handler, e );
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ( handlerLevel )
|
||||
{
|
||||
case NoInteraction:
|
||||
continue;
|
||||
|
||||
case BasicInteraction:
|
||||
break;
|
||||
|
||||
case SyncInteraction:
|
||||
needsSync = true;
|
||||
break;
|
||||
|
||||
case FullInteraction:
|
||||
needsSync = true;
|
||||
needsSetup = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Handled, dont show the GUI
|
||||
skipGUI = true;
|
||||
|
||||
boolean hadData = ( handlerData != null );
|
||||
try
|
||||
{
|
||||
handlerData = handler.customInteraction( golem, handlerData, syncRegistry, player, side );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
logCaughtException( "customInteraction", handler, e );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update golem
|
||||
if( handlerData == null )
|
||||
{
|
||||
if( hadData )
|
||||
{
|
||||
golemHandlerData.remove( handler );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
golemHandlerData.put( handler, handlerData );
|
||||
}
|
||||
|
||||
}
|
||||
if( interactionHandled && side == Side.SERVER )
|
||||
|
||||
if( side == Side.SERVER )
|
||||
{
|
||||
golem.setupGolem();
|
||||
if( needsSetup )
|
||||
{
|
||||
golem.setupGolem();
|
||||
}
|
||||
if( needsSync )
|
||||
{
|
||||
syncRegistry.markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
return interactionHandled;
|
||||
return skipGUI;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,7 +359,14 @@ public class GolemHooks
|
||||
else if( DATAWATCHER_ID > 0 )
|
||||
{
|
||||
// Add datawatcher field.
|
||||
watcher.addObject( DATAWATCHER_ID, localRegistry.mappingsToString() );
|
||||
try
|
||||
{
|
||||
watcher.addObject( DATAWATCHER_ID, localRegistry.mappingsToString() );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
localRegistry.markDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,7 +387,14 @@ public class GolemHooks
|
||||
// Update handlers
|
||||
for( IGolemHookHandler handler : dynamicHandlers )
|
||||
{
|
||||
handler.golemTick( golem, golemHandlerData.get( handler ), syncRegistry );
|
||||
try
|
||||
{
|
||||
handler.golemTick( golem, golemHandlerData.get( handler ), syncRegistry );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
logCaughtException( "golemTick", handler, e );
|
||||
}
|
||||
}
|
||||
|
||||
// Update data watcher
|
||||
@@ -343,7 +402,22 @@ public class GolemHooks
|
||||
{
|
||||
if( DATAWATCHER_ID > 0 )
|
||||
{
|
||||
golem.getDataWatcher().updateObject( DATAWATCHER_ID, syncRegistry.mappingsToString() );
|
||||
try
|
||||
{
|
||||
golem.getDataWatcher().updateObject( DATAWATCHER_ID, syncRegistry.mappingsToString() );
|
||||
}
|
||||
catch( NullPointerException e1 )
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
golem.getDataWatcher().addObject( DATAWATCHER_ID, syncRegistry.mappingsToString() );
|
||||
}
|
||||
catch( Exception e2 )
|
||||
{
|
||||
syncRegistry.markDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -364,10 +438,18 @@ public class GolemHooks
|
||||
syncRegistry.clientSyncTicks = 0.0f;
|
||||
|
||||
// Is the data out of sync?
|
||||
String watcherString = golem.getDataWatcher().getWatchableObjectString( DATAWATCHER_ID );
|
||||
if( !syncRegistry.hasChanged() && ( watcherString == syncRegistry.lastUpdatedFrom ) )
|
||||
String watcherString;
|
||||
try
|
||||
{
|
||||
watcherString = golem.getDataWatcher().getWatchableObjectString( DATAWATCHER_ID );
|
||||
if( !syncRegistry.hasChanged() && ( watcherString == syncRegistry.lastUpdatedFrom ) )
|
||||
{
|
||||
// Data is in sync
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
// Data is in sync
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -382,31 +464,31 @@ public class GolemHooks
|
||||
// Inform each handler
|
||||
for( IGolemHookHandler handler : handlersToUpdate )
|
||||
{
|
||||
// Get the current handler data
|
||||
Object handlerData = golemHandlerData.getOrDefault( handler, null );
|
||||
boolean hadData = ( handlerData != null );
|
||||
try
|
||||
{
|
||||
// Get the current handler data
|
||||
Object handlerData = golemHandlerData.getOrDefault( handler, null );
|
||||
boolean hadData = ( handlerData != null );
|
||||
|
||||
// Call handler
|
||||
handlerData = handler.syncDataChanged( syncRegistry, handlerData );
|
||||
|
||||
// Update golem
|
||||
if( handlerData == null )
|
||||
{
|
||||
if( hadData )
|
||||
{
|
||||
golemHandlerData.remove( handler );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
golemHandlerData.put( handler, handlerData );
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
logCaughtException( "onSyncDataChanged", handler, e );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update golem
|
||||
if( handlerData == null )
|
||||
{
|
||||
if( hadData )
|
||||
{
|
||||
golemHandlerData.remove( handler );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
golemHandlerData.put( handler, handlerData );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -562,9 +644,16 @@ public class GolemHooks
|
||||
}
|
||||
|
||||
// Update data watcher
|
||||
if( localRegistry.hasChanged() && side == Side.SERVER )
|
||||
if( localRegistry.hasChanged() && ( side == Side.SERVER ) && ( DATAWATCHER_ID > 0 ) )
|
||||
{
|
||||
golem.getDataWatcher().updateObject( DATAWATCHER_ID, localRegistry.mappingsToString() );
|
||||
try
|
||||
{
|
||||
golem.getDataWatcher().updateObject( DATAWATCHER_ID, localRegistry.mappingsToString() );
|
||||
}
|
||||
catch( NullPointerException e )
|
||||
{
|
||||
localRegistry.markDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,14 @@ class GolemSyncRegistry
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the registry as needing to be syncd.
|
||||
*/
|
||||
public void markDirty()
|
||||
{
|
||||
this.hasDataChanged = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the mappings from a string
|
||||
*
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import thaumicenergistics.common.ThaumicEnergistics;
|
||||
import thaumicenergistics.common.registries.ThEStrings;
|
||||
import appeng.api.features.INetworkEncodable;
|
||||
@@ -16,6 +17,59 @@ public class ItemGolemWirelessBackpack
|
||||
extends Item
|
||||
implements INetworkEncodable
|
||||
{
|
||||
public static enum BackpackSkins
|
||||
{
|
||||
Thaumium ("Thaum"),
|
||||
Stone ("Stone"),
|
||||
Straw ("Straw"),
|
||||
GreatWood ("Wood"),
|
||||
Flesh ("Flesh"),
|
||||
Clay ("Clay"),
|
||||
Iron ("Iron"),
|
||||
Tallow ("Tallow"),
|
||||
Gold ("Gold"),
|
||||
Diamond ("Diamond");
|
||||
|
||||
/**
|
||||
* Array of skins.
|
||||
*/
|
||||
public static final BackpackSkins VALUES[] = BackpackSkins.values();
|
||||
|
||||
/**
|
||||
* Skin texture.
|
||||
*/
|
||||
private ResourceLocation texture = null;
|
||||
|
||||
/**
|
||||
* Texture ID of the skin
|
||||
*/
|
||||
private final String texID;
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
*
|
||||
* @param ID
|
||||
*/
|
||||
private BackpackSkins( final String ID )
|
||||
{
|
||||
this.texID = ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the texture for this skin.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public ResourceLocation getTextureLocation()
|
||||
{
|
||||
if( this.texture == null )
|
||||
{
|
||||
this.texture = new ResourceLocation( ThaumicEnergistics.MOD_ID, "textures/models/golemBackpack/" + this.texID + ".png" );
|
||||
}
|
||||
return this.texture;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String NBT_ENCRYPTION_KEY = "wifiKey";
|
||||
|
||||
public ItemGolemWirelessBackpack()
|
||||
@@ -25,6 +79,8 @@ public class ItemGolemWirelessBackpack
|
||||
|
||||
// Set non stacking
|
||||
this.setMaxStackSize( 1 );
|
||||
|
||||
// Set non-damageable
|
||||
this.setMaxDamage( 0 );
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,16 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
public abstract class ThEClientPacket
|
||||
extends ThEBasePacket
|
||||
{
|
||||
@SideOnly(Side.CLIENT)
|
||||
private final void preWrap()
|
||||
{
|
||||
// Set the player
|
||||
this.player = Minecraft.getMinecraft().thePlayer;
|
||||
|
||||
// Execute the packet
|
||||
this.wrappedExecute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean includePlayerInStream()
|
||||
{
|
||||
@@ -30,11 +40,7 @@ public abstract class ThEClientPacket
|
||||
// Ensure this is client side
|
||||
if( EffectiveSide.isClientSide() )
|
||||
{
|
||||
// Get the player
|
||||
this.player = Minecraft.getMinecraft().thePlayer;
|
||||
|
||||
// Execute the packet
|
||||
this.wrappedExecute();
|
||||
this.preWrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,7 +163,8 @@ public class DistillationPatternHelper
|
||||
*/
|
||||
public void setInputItem( final ItemStack inputItem )
|
||||
{
|
||||
this.input = inputItem;
|
||||
this.input = inputItem.copy();
|
||||
this.input.stackSize = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -182,7 +182,8 @@ thaumicenergistics.research_page.TEDISTILLATIONPATTERNENCODER.1=Expanding on the
|
||||
tc.research_name.thaumicenergistics.TEGOLEMWIFIBACKPACK=Golem Wifi Backpack
|
||||
tc.research_text.thaumicenergistics.TEGOLEMWIFIBACKPACK=DigitalGolem423@ae2.net
|
||||
thaumicenergistics.research_page.TEGOLEMWIFIBACKPACK.1=After watching your golems running around depositing gathered items into a chest for you to collect and store later, you wondered if you could cut out the middle-man. Inspiration struck when you realized that you could utilize your networks wireless capabilities to do just that.<BR>After spending hours feverishly working, you created a backpack that will give your golems access to the network. The backpack does come with some limitations however. Golems must be in range of an §lAccess Point§r to communicate with the network. The fluix pearl atop the antenna serves as an indicator to whether or not the golem can communicate with the network.
|
||||
thaumicenergistics.research_page.TEGOLEMWIFIBACKPACK.2=As communicating with the network takes power, you retro-fitted a charger to draw power from two embedded Nitor. When charged the backpack will be able to transmit for only a short time before starting another charge cycle. During this window of opportunity the golem will be able to interact with the network.<LINE>As you progress with your golemancy research, check back here for potential new uses of the backpack.
|
||||
thaumicenergistics.research_page.TEGOLEMWIFIBACKPACK.2=As communicating with the network takes power, you retro-fitted a charger to draw power from two embedded Nitor. When charged the backpack will be able to transmit for only a short time before starting another charge cycle. During this window of opportunity the golem will be able to interact with the network.<BR>To link the backpack with your network, place it in the security terminal.<LINE>As you progress with your golemancy research, check back here for potential new uses of the backpack.
|
||||
thaumicenergistics.research_page.TEGOLEMWIFIBACKPACK.3=§nFacades§r<BR>Facades can be used to apply a variety of styles to the backpack: Thaumium Block(default), Greatwood Log, Bricks, Hay Bale, Tallow Block, Flesh Block, Stone, Iron Block, Gold Block and Diamond Block.<BR>Right click on a golem wearing a backpack with the facade in hand to apply it.
|
||||
thaumicenergistics.research_page.TEGOLEMWIFIBACKPACK.COREGATHER=§nGather Core Unlocked§r<IMG>thaumicenergistics:textures/gui/states.png:16:0:16:16:1.0</IMG>A golem equipped with a §lGather Core§r will be able to deposit gathered items directly into the network. The maximum number of items deposited is determined by how efficiently the golem manages each charge.
|
||||
thaumicenergistics.research_page.TEGOLEMWIFIBACKPACK.COREFILL=§nFill Core Unlocked§r<IMG>thaumicenergistics:textures/gui/states.png:32:0:16:16:1.0</IMG>A golem equipped with a §lFill Core§r will be able to extract items from the network. The maximum number of items extracted is determined by the golems GUI, and how efficiently the golem manages each charge.
|
||||
thaumicenergistics.research_page.TEGOLEMWIFIBACKPACK.CORELIQUID=§nDecanting Core Unlocked§r<IMG>thaumicenergistics:textures/gui/states.png:48:0:16:16:1.0</IMG>A golem equipped with a Decanting Core§r will be able to extract fluid from the network. The maximum amount of fluid extracted is determined by how efficiently the golem manages each charge.<LINE>Special note: Storing fluids in the AE network requires the services of another mod, such as Extra Cells 2.
|
||||
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 4.2 KiB |