From 5faceac7bac76fd12cc823a2c1f225f0f0cf279c Mon Sep 17 00:00:00 2001 From: SquidDev Date: Tue, 2 May 2017 01:46:17 +0100 Subject: [PATCH 1/6] Add registry for pocket computer upgrades --- .../dan200/computercraft/ComputerCraft.java | 62 +++++++- .../computercraft/api/ComputerCraftAPI.java | 16 ++ .../api/pocket/IPocketAccess.java | 65 ++++++++ .../api/pocket/IPocketUpgrade.java | 86 +++++++++++ .../proxy/ComputerCraftProxyClient.java | 2 +- .../pocket/core/PocketServerComputer.java | 145 ++++++++++++++++++ .../pocket/items/ItemPocketComputer.java | 124 ++++++++------- .../items/PocketComputerItemFactory.java | 5 +- .../pocket/peripherals/PocketModem.java | 88 +++++++++++ .../recipes/PocketComputerUpgradeRecipe.java | 51 +++--- .../proxy/ComputerCraftProxyCommon.java | 32 +++- 11 files changed, 567 insertions(+), 109 deletions(-) create mode 100644 src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java create mode 100644 src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java create mode 100644 src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java create mode 100644 src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java diff --git a/src/main/java/dan200/computercraft/ComputerCraft.java b/src/main/java/dan200/computercraft/ComputerCraft.java index 710094ecd..d7f5edf80 100644 --- a/src/main/java/dan200/computercraft/ComputerCraft.java +++ b/src/main/java/dan200/computercraft/ComputerCraft.java @@ -14,6 +14,7 @@ import dan200.computercraft.api.media.IMediaProvider; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheralProvider; import dan200.computercraft.api.permissions.ITurtlePermissionProvider; +import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.redstone.IBundledRedstoneProvider; import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.core.filesystem.ComboMount; @@ -38,15 +39,13 @@ import dan200.computercraft.shared.peripheral.modem.BlockAdvancedModem; import dan200.computercraft.shared.peripheral.modem.WirelessNetwork; import dan200.computercraft.shared.peripheral.printer.TilePrinter; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; +import dan200.computercraft.shared.pocket.peripherals.PocketModem; import dan200.computercraft.shared.proxy.ICCTurtleProxy; import dan200.computercraft.shared.proxy.IComputerCraftProxy; import dan200.computercraft.shared.turtle.blocks.BlockTurtle; import dan200.computercraft.shared.turtle.blocks.TileTurtle; import dan200.computercraft.shared.turtle.upgrades.*; -import dan200.computercraft.shared.util.CreativeTabMain; -import dan200.computercraft.shared.util.IDAssigner; -import dan200.computercraft.shared.util.IEntityDropConsumer; -import dan200.computercraft.shared.util.WorldUtil; +import dan200.computercraft.shared.util.*; import io.netty.buffer.Unpooled; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; @@ -75,9 +74,7 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.util.*; /////////////// // UNIVERSAL // @@ -163,6 +160,12 @@ public class ComputerCraft public static TurtleModem advancedModem; } + public static class PocketUpgrades + { + public static PocketModem wirelessModem; + public static PocketModem advancedModem; + } + public static class Config { public static Configuration config; @@ -186,7 +189,6 @@ public class ComputerCraft public static Property computerSpaceLimit; public static Property floppySpaceLimit; public static Property maximumFilesOpen; - } // Registries @@ -204,6 +206,7 @@ public class ComputerCraft private static List bundledRedstoneProviders = new ArrayList(); private static List mediaProviders = new ArrayList(); private static List permissionProviders = new ArrayList(); + private static final Map pocketUpgrades = new HashMap(); // Implementation @Mod.Instance( value = "ComputerCraft" ) @@ -539,6 +542,18 @@ public class ComputerCraft return true; } + public static void registerPocketUpgrade( IPocketUpgrade upgrade ) + { + String id = upgrade.getUpgradeID().toString(); + IPocketUpgrade existing = pocketUpgrades.get( id ); + if( existing != null ) + { + throw new RuntimeException( "Error registering '" + upgrade.getUnlocalisedAdjective() + " pocket computer'. UpgradeID '" + id + "' is already registered by '" + existing.getUnlocalisedAdjective() + " pocket computer'" ); + } + + pocketUpgrades.put( id, upgrade ); + } + public static void registerPeripheralProvider( IPeripheralProvider provider ) { if( provider != null && !peripheralProviders.contains( provider ) ) @@ -659,6 +674,37 @@ public class ComputerCraft return null; } + public static IPocketUpgrade getPocketUpgrade(String id) { + return pocketUpgrades.get( id ); + } + + public static IPocketUpgrade getPocketUpgrade( ItemStack stack ) + { + if( stack == null ) return null; + + for (IPocketUpgrade upgrade : pocketUpgrades.values()) + { + ItemStack craftingStack = upgrade.getCraftingItem(); + if( craftingStack != null && InventoryUtil.areItemsStackable( stack, craftingStack ) ) + { + return upgrade; + } + } + + return null; + } + + public static Iterable getVanillaPocketUpgrades() { + List upgrades = new ArrayList(); + for(IPocketUpgrade upgrade : pocketUpgrades.values()) { + if(upgrade instanceof PocketModem) { + upgrades.add( upgrade ); + } + } + + return upgrades; + } + public static int createUniqueNumberedSaveDir( World world, String parentSubPath ) { return IDAssigner.getNextIDFromDirectory(new File(getWorldDir(world), parentSubPath)); diff --git a/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java b/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java index c88bde40e..c4194f5b2 100644 --- a/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java +++ b/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java @@ -14,6 +14,7 @@ import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheralProvider; import dan200.computercraft.api.permissions.ITurtlePermissionProvider; +import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.redstone.IBundledRedstoneProvider; import dan200.computercraft.api.turtle.ITurtleUpgrade; import net.minecraft.util.EnumFacing; @@ -270,6 +271,17 @@ public final class ComputerCraftAPI } } + public static void registerPocketUpgrade(IPocketUpgrade upgrade) { + findCC(); + if(computerCraft_registerPocketUpgrade != null) { + try { + computerCraft_registerPocketUpgrade.invoke( null, upgrade ); + } catch (Exception e) { + // It failed + } + } + } + // The functions below here are private, and are used to interface with the non-API ComputerCraft classes. // Reflection is used here so you can develop your mod without decompiling ComputerCraft and including // it in your solution, and so your mod won't crash if ComputerCraft is installed. @@ -308,6 +320,9 @@ public final class ComputerCraftAPI computerCraft_registerPermissionProvider = findCCMethod( "registerPermissionProvider", new Class[] { ITurtlePermissionProvider.class } ); + computerCraft_registerPocketUpgrade = findCCMethod( "registerPocketUpgrade", new Class[] { + IPocketUpgrade.class + } ); } catch( Exception e ) { System.out.println( "ComputerCraftAPI: ComputerCraft not found." ); } finally { @@ -342,4 +357,5 @@ public final class ComputerCraftAPI private static Method computerCraft_getDefaultBundledRedstoneOutput = null; private static Method computerCraft_registerMediaProvider = null; private static Method computerCraft_registerPermissionProvider = null; + private static Method computerCraft_registerPocketUpgrade = null; } diff --git a/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java b/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java new file mode 100644 index 000000000..f2df7ca91 --- /dev/null +++ b/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java @@ -0,0 +1,65 @@ +package dan200.computercraft.api.pocket; + +import dan200.computercraft.api.peripheral.IPeripheral; +import net.minecraft.entity.Entity; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Map; + +/** + * Wrapper class for pocket computers + */ +public interface IPocketAccess +{ + /** + * Gets the holding entity of this item + * + * @return The holding entity, may be {@code null}. + */ + @Nullable + Entity getEntity(); + + /** + * Get if the modem light is turned on + * + * @return If the modem light is turned on + */ + boolean getModemLight(); + + /** + * Turn on/off the modem light + * + * @param value If the light should be on + */ + void setModemLight( boolean value ); + + /** + * Get the upgrade specific NBT + * + * @return The upgrade's NBT + */ + @Nonnull + NBTTagCompound getUpgradeNBTData(); + + /** + * Mark the upgrade specific NBT as dirty + */ + void updateUpgradeNBTData(); + + /** + * Remove the current peripheral and create a new one. You + * may wish to do this if the methods available change. + */ + void invalidatePeripheral(); + + /** + * Get a list of all upgrades for the pocket computer + * + * @return A collection of all upgrade names + */ + @Nonnull + Map getUpgrades(); +} diff --git a/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java b/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java new file mode 100644 index 000000000..37c26912c --- /dev/null +++ b/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java @@ -0,0 +1,86 @@ +package dan200.computercraft.api.pocket; + +import dan200.computercraft.api.ComputerCraftAPI; +import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.api.turtle.ITurtleAccess; +import dan200.computercraft.api.turtle.ITurtleUpgrade; +import dan200.computercraft.api.turtle.TurtleSide; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Additional peripherals for pocket computers. + *

+ * This is similar to {@link dan200.computercraft.api.turtle.ITurtleUpgrade}. + */ +public interface IPocketUpgrade +{ + + /** + * Gets a unique identifier representing this type of turtle upgrade. eg: "computercraft:wireless_modem" or "my_mod:my_upgrade". + * You should use a unique resource domain to ensure this upgrade is uniquely identified. + * The peripheral will fail registration if an already used ID is specified. + * + * @return The id + * @see IPocketUpgrade#getUpgradeID() + * @see ComputerCraftAPI#registerPocketUpgrade(IPocketUpgrade) + */ + @Nonnull + ResourceLocation getUpgradeID(); + + /** + * Return a String to describe this type of turtle in turtle item names. + * An example of built-in adjectives is "Wireless". + * + * @return The unlocalised adjective + * @see ITurtleUpgrade#getUnlocalisedAdjective() + */ + @Nonnull + String getUnlocalisedAdjective(); + + /** + * Return an item stack representing the type of item that a turtle must be crafted + * with to create a turtle which holds this upgrade. This item stack is also used + * to determine the upgrade given by turtle.equip() + * + * @return The item stack used for crafting. This can be {@code null} if crafting is disabled. + * @see ITurtleUpgrade#getCraftingItem() + */ + @Nullable + ItemStack getCraftingItem(); + + /** + * Creates a peripheral for the pocket computer. + *

+ * The peripheral created will be stored for the lifetime of the upgrade, will have update() called + * once-per-tick, and will be attached, detached and have methods called in the same manner as a Computer peripheral. + * + * @param access The access object for the pocket item stack + * @return The newly created peripheral. + * @see ITurtleUpgrade#createPeripheral(ITurtleAccess, TurtleSide) + */ + @Nullable + IPeripheral createPeripheral( @Nonnull IPocketAccess access ); + + /** + * Called when the pocket computer item stack updates + * + * @param access The access object for the pocket item stack + * @param peripheral The peripheral for this upgrade + */ + void update( @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ); + + /** + * Called when the pocket computer is right clicked on something + * + * @param world The world the computer is in + * @param access The access object for the pocket item stack + * @param peripheral The peripheral for this upgrade + * @return {@code true} to stop the gui from opening, otherwise false. + */ + boolean onRightClick( @Nonnull World world, @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ); +} diff --git a/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java b/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java index eb3366d1e..747fef93d 100644 --- a/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java +++ b/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java @@ -129,7 +129,7 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon public ModelResourceLocation getModelLocation( ItemStack stack ) { ItemPocketComputer itemPocketComputer = (ItemPocketComputer)stack.getItem(); - boolean modemOn = itemPocketComputer.getModemState( stack ); + boolean modemOn = itemPocketComputer.getLightState( stack ); switch( itemPocketComputer.getFamily( stack ) ) { case Advanced: diff --git a/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java new file mode 100644 index 000000000..16bbce476 --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java @@ -0,0 +1,145 @@ +package dan200.computercraft.shared.pocket.core; + +import dan200.computercraft.ComputerCraft; +import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.api.pocket.IPocketAccess; +import dan200.computercraft.api.pocket.IPocketUpgrade; +import dan200.computercraft.shared.computer.core.ComputerFamily; +import dan200.computercraft.shared.computer.core.ServerComputer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraftforge.common.util.Constants; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.Map; + +public class PocketServerComputer extends ServerComputer implements IPocketAccess +{ + private IPocketUpgrade m_upgrade; + private Entity m_entity; + private ItemStack m_stack; + + public PocketServerComputer( World world, int computerID, String label, int instanceID, ComputerFamily family, ItemStack stack, Entity entity ) + { + super( world, computerID, label, instanceID, family, ComputerCraft.terminalWidth_pocketComputer, ComputerCraft.terminalHeight_pocketComputer ); + update( entity, stack ); + } + + @Nullable + @Override + public Entity getEntity() + { + return m_entity; + } + + @Override + public boolean getModemLight() + { + return getUserData().getBoolean( "modemLight" ); + } + + @Override + public void setModemLight( boolean value ) + { + NBTTagCompound tag = getUserData(); + if( tag.getBoolean( "modemLight" ) != value ) + { + tag.setBoolean( "modemLight", value ); + updateUserData(); + } + } + + @Nonnull + @Override + public NBTTagCompound getUpgradeNBTData() + { + NBTTagCompound tag; + if( m_stack.hasTagCompound() ) + { + tag = m_stack.getTagCompound(); + } + else + { + tag = new NBTTagCompound(); + m_stack.setTagCompound( tag ); + } + + if( tag.hasKey( "upgrade_info", Constants.NBT.TAG_COMPOUND ) ) + { + return tag.getCompoundTag( "upgrade_info" ); + } + else + { + NBTTagCompound sub = new NBTTagCompound(); + + tag.setTag( "upgrade_info", sub ); + updateUpgradeNBTData(); + + return sub; + } + } + + @Override + public void updateUpgradeNBTData() + { + InventoryPlayer inventory = m_entity instanceof EntityPlayer ? ((EntityPlayer) m_entity).inventory : null; + if( inventory != null ) + { + inventory.markDirty(); + } + } + + @Override + public void invalidatePeripheral() + { + IPeripheral peripheral = m_upgrade == null ? null : m_upgrade.createPeripheral( this ); + setPeripheral( 2, peripheral ); + } + + @Nonnull + @Override + public Map getUpgrades() + { + if( m_upgrade == null ) + { + return Collections.emptyMap(); + } + else + { + return Collections.singletonMap( m_upgrade.getUpgradeID(), getPeripheral( 2 ) ); + } + } + + public void update( Entity entity, ItemStack stack ) + { + if( m_entity != null ) setPosition( entity.getPosition() ); + m_entity = entity; + m_stack = stack; + } + + public synchronized void setUpgrade( IPocketUpgrade upgrade ) + { + if( this.m_upgrade == upgrade ) return; + + // Clear the old upgrade NBT + if( m_stack.hasTagCompound() ) + { + NBTTagCompound tag = m_stack.getTagCompound(); + if( tag.hasKey( "upgrade_info", 10 ) ) + { + tag.removeTag( "upgrade_info" ); + updateUpgradeNBTData(); + } + } + + this.m_upgrade = upgrade; + invalidatePeripheral(); + } +} diff --git a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java index 1044cbe37..81226baac 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java @@ -10,18 +10,17 @@ import com.google.common.base.Objects; import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.media.IMedia; -import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.shared.computer.blocks.ComputerState; import dan200.computercraft.shared.computer.core.ClientComputer; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.computer.items.IComputerItem; import dan200.computercraft.shared.pocket.apis.PocketAPI; -import dan200.computercraft.shared.pocket.peripherals.PocketModemPeripheral; +import dan200.computercraft.shared.pocket.core.PocketServerComputer; import dan200.computercraft.shared.util.StringUtil; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; @@ -32,11 +31,10 @@ import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumHand; import net.minecraft.util.SoundEvent; import net.minecraft.world.World; +import net.minecraftforge.common.util.Constants; import java.util.List; -; - public class ItemPocketComputer extends Item implements IComputerItem, IMedia { public ItemPocketComputer() @@ -47,7 +45,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia setCreativeTab( ComputerCraft.mainCreativeTab ); } - public ItemStack create( int id, String label, ComputerFamily family, boolean modem ) + public ItemStack create( int id, String label, ComputerFamily family, IPocketUpgrade upgrade ) { // Ignore types we can't handle if( family != ComputerFamily.Normal && family != ComputerFamily.Advanced ) @@ -58,16 +56,16 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia // Build the stack int damage = (family == ComputerFamily.Advanced) ? 1 : 0; ItemStack result = new ItemStack( this, 1, damage ); - if( id >= 0 || modem ) + if( id >= 0 || upgrade != null ) { NBTTagCompound compound = new NBTTagCompound(); if( id >= 0 ) { compound.setInteger( "computerID", id ); } - if( modem ) + if( upgrade != null ) { - compound.setInteger( "upgrade", 1 ); + compound.setString( "upgrade", upgrade.getUpgradeID().toString() ); } result.setTagCompound( compound ); } @@ -79,12 +77,19 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia } @Override - public void getSubItems( Item itemID, CreativeTabs tabs, List list ) + public void getSubItems( Item itemID, CreativeTabs tabs, List list ) { - list.add( PocketComputerItemFactory.create( -1, null, ComputerFamily.Normal, false ) ); - list.add( PocketComputerItemFactory.create( -1, null, ComputerFamily.Normal, true ) ); - list.add( PocketComputerItemFactory.create( -1, null, ComputerFamily.Advanced, false ) ); - list.add( PocketComputerItemFactory.create( -1, null, ComputerFamily.Advanced, true ) ); + getSubItems( list, ComputerFamily.Normal ); + getSubItems( list, ComputerFamily.Advanced ); + } + + private void getSubItems( List list, ComputerFamily family ) + { + list.add( PocketComputerItemFactory.create( -1, null, family, null ) ); + for (IPocketUpgrade upgrade : ComputerCraft.getVanillaPocketUpgrades()) + { + list.add( PocketComputerItemFactory.create( -1, null, family, upgrade ) ); + } } @Override @@ -93,13 +98,14 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia if( !world.isRemote ) { // Server side - IInventory inventory = (entity instanceof EntityPlayer) ? ((EntityPlayer)entity).inventory : null; - ServerComputer computer = createServerComputer( world, inventory, stack ); + IInventory inventory = (entity instanceof EntityPlayer) ? ((EntityPlayer) entity).inventory : null; + PocketServerComputer computer = createServerComputer( world, inventory, entity, stack ); if( computer != null ) { // Ping computer computer.keepAlive(); computer.setWorld( world ); + computer.update( entity, stack ); // Sync ID int id = computer.getID(); @@ -124,29 +130,10 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia } // Update modem - IPeripheral peripheral = computer.getPeripheral( 2 ); - if( peripheral != null && peripheral instanceof PocketModemPeripheral ) + IPocketUpgrade upgrade = getUpgrade( stack ); + if( upgrade != null ) { - // Location - PocketModemPeripheral modem = (PocketModemPeripheral)peripheral; - if( entity instanceof EntityLivingBase ) - { - EntityLivingBase player = (EntityLivingBase)entity; - modem.setLocation( world, player.posX, player.posY + player.getEyeHeight(), player.posZ ); - } - else - { - modem.setLocation( world, entity.posX, entity.posY, entity.posZ ); - } - - // Light - boolean modemLight = modem.isActive(); - NBTTagCompound modemNBT = computer.getUserData(); - if( modemNBT.getBoolean( "modemLight" ) != modemLight ) - { - modemNBT.setBoolean( "modemLight", modemLight ); - computer.updateUserData(); - } + upgrade.update( computer, computer.getPeripheral( 2 ) ); } } } @@ -166,12 +153,21 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia { if( !world.isRemote ) { - ServerComputer computer = createServerComputer( world, player.inventory, stack ); + PocketServerComputer computer = createServerComputer( world, player.inventory, player, stack ); + + boolean stop = false; if( computer != null ) { computer.turnOn(); + + IPocketUpgrade upgrade = getUpgrade( stack ); + if( upgrade != null ) + { + stop = upgrade.onRightClick( world, computer, computer.getPeripheral( 2 ) ); + } } - ComputerCraft.openPocketComputerGUI( player, hand ); + + if( !stop ) ComputerCraft.openPocketComputerGUI( player, hand ); } return new ActionResult( EnumActionResult.SUCCESS, stack ); } @@ -197,12 +193,12 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia public String getItemStackDisplayName( ItemStack stack ) { String baseString = getUnlocalizedName( stack ); - boolean modem = getHasModem( stack ); - if( modem ) + IPocketUpgrade upgrade = getUpgrade( stack ); + if( upgrade != null ) { return StringUtil.translateToLocalFormatted( baseString + ".upgraded.name", - StringUtil.translateToLocal( "upgrade.computercraft:wireless_modem.adjective" ) + StringUtil.translateToLocal( upgrade.getUnlocalisedAdjective() ) ); } else @@ -224,14 +220,14 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia } } - private ServerComputer createServerComputer( final World world, IInventory inventory, ItemStack stack ) + private PocketServerComputer createServerComputer( final World world, IInventory inventory, Entity entity, ItemStack stack ) { if( world.isRemote ) { return null; } - ServerComputer computer; + PocketServerComputer computer; int instanceID = getInstanceID( stack ); int sessionID = getSessionID( stack ); int correctSessionID = ComputerCraft.serverComputerRegistry.getSessionID(); @@ -239,7 +235,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia if( instanceID >= 0 && sessionID == correctSessionID && ComputerCraft.serverComputerRegistry.contains( instanceID ) ) { - computer = ComputerCraft.serverComputerRegistry.get( instanceID ); + computer = (PocketServerComputer) ComputerCraft.serverComputerRegistry.get( instanceID ); } else { @@ -255,20 +251,17 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia computerID = ComputerCraft.createUniqueNumberedSaveDir( world, "computer" ); setComputerID( stack, computerID ); } - computer = new ServerComputer( + computer = new PocketServerComputer( world, computerID, getLabel( stack ), instanceID, getFamily( stack ), - ComputerCraft.terminalWidth_pocketComputer, - ComputerCraft.terminalHeight_pocketComputer + stack, + entity ); computer.addAPI( new PocketAPI() ); - if( getHasModem( stack ) ) - { - computer.setPeripheral( 2, new PocketModemPeripheral( false ) ); - } + computer.setUpgrade( getUpgrade( stack ) ); ComputerCraft.serverComputerRegistry.add( instanceID, computer ); if( inventory != null ) { @@ -394,7 +387,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia @Override public IMount createDataMount( ItemStack stack, World world ) { - ServerComputer computer = createServerComputer( world, null, stack ); + ServerComputer computer = createServerComputer( world, null, null, stack ); if( computer != null ) { return computer.getRootMount(); @@ -450,7 +443,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia return ComputerState.Off; } - public boolean getModemState( ItemStack stack ) + public boolean getLightState( ItemStack stack ) { ClientComputer computer = getClientComputer( stack ); if( computer != null && computer.isOn() ) @@ -464,13 +457,26 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia return false; } - public boolean getHasModem( ItemStack stack ) + public static IPocketUpgrade getUpgrade( ItemStack stack ) { NBTTagCompound compound = stack.getTagCompound(); - if( compound != null && compound.hasKey( "upgrade" ) ) + if( compound != null ) { - return (compound.getInteger( "upgrade" ) == 1); + if( compound.hasKey( "upgrade", Constants.NBT.TAG_STRING ) ) + { + String name = compound.getString( "upgrade" ); + return ComputerCraft.getPocketUpgrade( name ); + } + else if( compound.hasKey( "upgrade", Constants.NBT.TAG_ANY_NUMERIC ) ) + { + int id = compound.getInteger( "upgrade" ); + if( id == 1 ) + { + return ComputerCraft.getPocketUpgrade( "computercraft:wireless_modem" ); + } + } } - return false; + + return null; } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItemFactory.java b/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItemFactory.java index 2b17d6555..2fa08d038 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItemFactory.java +++ b/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItemFactory.java @@ -7,12 +7,13 @@ package dan200.computercraft.shared.pocket.items; import dan200.computercraft.ComputerCraft; +import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.shared.computer.core.ComputerFamily; import net.minecraft.item.ItemStack; public class PocketComputerItemFactory { - public static ItemStack create( int id, String label, ComputerFamily family, boolean modem ) + public static ItemStack create( int id, String label, ComputerFamily family, IPocketUpgrade upgrade ) { ItemPocketComputer computer = ComputerCraft.Items.pocketComputer; switch( family ) @@ -20,7 +21,7 @@ public class PocketComputerItemFactory case Normal: case Advanced: { - return computer.create( id, label, family, modem ); + return computer.create( id, label, family, upgrade ); } } return null; diff --git a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java new file mode 100644 index 000000000..8ef40b64a --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java @@ -0,0 +1,88 @@ +package dan200.computercraft.shared.pocket.peripherals; + +import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.api.pocket.IPocketAccess; +import dan200.computercraft.api.pocket.IPocketUpgrade; +import dan200.computercraft.shared.peripheral.PeripheralType; +import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class PocketModem implements IPocketUpgrade +{ + private final boolean m_advanced; + + public PocketModem( boolean m_advanced ) + { + this.m_advanced = m_advanced; + } + + @Nonnull + @Override + public ResourceLocation getUpgradeID() + { + return m_advanced + ? new ResourceLocation( "computercraft", "advanved_modem" ) + : new ResourceLocation( "computercraft", "wireless_modem" ); + } + + @Nonnull + @Override + public String getUnlocalisedAdjective() + { + return m_advanced + ? "upgrade.computercraft:advanced_modem.adjective" + : "upgrade.computercraft:wireless_modem.adjective"; + } + + @Nullable + @Override + public ItemStack getCraftingItem() + { + return PeripheralItemFactory.create( + m_advanced ? PeripheralType.AdvancedModem : PeripheralType.WirelessModem, + null, 1 + ); + } + + @Nullable + @Override + public IPeripheral createPeripheral( @Nonnull IPocketAccess access ) + { + return new PocketModemPeripheral( m_advanced ); + } + + @Override + public void update( @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ) + { + if( peripheral instanceof PocketModemPeripheral ) + { + Entity entity = access.getEntity(); + + PocketModemPeripheral modem = (PocketModemPeripheral) peripheral; + if( entity instanceof EntityLivingBase ) + { + EntityLivingBase player = (EntityLivingBase) entity; + modem.setLocation( entity.getEntityWorld(), player.posX, player.posY + player.getEyeHeight(), player.posZ ); + } + else if( entity != null ) + { + modem.setLocation( entity.getEntityWorld(), entity.posX, entity.posY, entity.posZ ); + } + + access.setModemLight( modem.isActive() ); + } + } + + @Override + public boolean onRightClick( @Nonnull World world, @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ) + { + return false; + } +} diff --git a/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java b/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java index a78623538..7eeefef94 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java +++ b/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java @@ -6,9 +6,9 @@ package dan200.computercraft.shared.pocket.recipes; +import dan200.computercraft.ComputerCraft; +import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.shared.computer.core.ComputerFamily; -import dan200.computercraft.shared.peripheral.PeripheralType; -import dan200.computercraft.shared.peripheral.common.IPeripheralItem; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory; import net.minecraft.inventory.InventoryCrafting; @@ -31,7 +31,7 @@ public class PocketComputerUpgradeRecipe implements IRecipe @Override public ItemStack getRecipeOutput() { - return PocketComputerItemFactory.create( -1, null, ComputerFamily.Normal, true ); + return PocketComputerItemFactory.create( -1, null, ComputerFamily.Normal, null ); } @Override @@ -47,9 +47,9 @@ public class PocketComputerUpgradeRecipe implements IRecipe ItemStack computer = null; int computerX = -1; int computerY = -1; - for( int y=0; y Date: Tue, 2 May 2017 01:53:30 +0100 Subject: [PATCH 2/6] Add .equip and .unequip methods to pocket API. --- .../shared/pocket/apis/PocketAPI.java | 113 +++++++++++++++++- .../pocket/core/PocketServerComputer.java | 8 ++ .../pocket/items/ItemPocketComputer.java | 19 ++- 3 files changed, 135 insertions(+), 5 deletions(-) diff --git a/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java b/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java index b3d6cf853..9119f5042 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java +++ b/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java @@ -6,14 +6,26 @@ package dan200.computercraft.shared.pocket.apis; +import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.core.apis.ILuaAPI; +import dan200.computercraft.shared.pocket.core.PocketServerComputer; +import dan200.computercraft.shared.pocket.items.ItemPocketComputer; +import dan200.computercraft.shared.util.InventoryUtil; +import dan200.computercraft.shared.util.WorldUtil; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; public class PocketAPI implements ILuaAPI { - public PocketAPI() + private final PocketServerComputer m_computer; + + public PocketAPI( PocketServerComputer computer ) { + this.m_computer = computer; } @Override @@ -43,14 +55,107 @@ public class PocketAPI implements ILuaAPI public String[] getMethodNames() { return new String[] { - // TODO: Add some methods + "equip", + "unequip" }; } @Override public Object[] callMethod( ILuaContext context, int method, Object[] arguments ) throws LuaException { - // TODO: Add some methods - return null; + switch( method ) + { + case 0: + { + // equip + if( !(m_computer.getEntity() instanceof EntityPlayer) ) + { + throw new LuaException( "Cannot find player" ); + } + + ItemStack pocketStack = m_computer.getStack(); + EntityPlayer player = (EntityPlayer) m_computer.getEntity(); + InventoryPlayer inventory = player.inventory; + + IPocketUpgrade previousUpgrade = m_computer.getUpgrade(); + IPocketUpgrade newUpgrade = null; + + int size = inventory.getSizeInventory(), held = inventory.currentItem; + for (int i = 0; i < size; i++) + { + ItemStack invStack = inventory.getStackInSlot( (i + held) % size ); + if( invStack != null ) + { + newUpgrade = ComputerCraft.getPocketUpgrade( invStack ); + + if( newUpgrade != null && newUpgrade != previousUpgrade ) + { + // Consume an item from this stack and exit the loop + invStack = invStack.copy(); + invStack.stackSize--; + inventory.setInventorySlotContents( (i + held) % size, invStack.stackSize <= 0 ? null : invStack ); + + break; + } + } + } + + if( newUpgrade == null ) throw new LuaException( "Cannot find a valid upgrade" ); + + // Remove the current upgrade + if( previousUpgrade != null ) + { + ItemStack stack = previousUpgrade.getCraftingItem(); + if( stack != null ) + { + stack = InventoryUtil.storeItems( stack, inventory, 0, 36, inventory.currentItem ); + if( stack != null ) + { + WorldUtil.dropItemStack( stack, player.worldObj, player.posX, player.posY, player.posZ ); + } + } + } + + // Set the new upgrade + ItemPocketComputer.setUpgrade( pocketStack, newUpgrade ); + m_computer.setUpgrade( newUpgrade ); + + return null; + } + + case 1: + { + // unequip + if( !(m_computer.getEntity() instanceof EntityPlayer) ) + { + throw new LuaException( "Cannot find player" ); + } + + ItemStack pocketStack = m_computer.getStack(); + EntityPlayer player = (EntityPlayer) m_computer.getEntity(); + InventoryPlayer inventory = player.inventory; + + IPocketUpgrade previousUpgrade = m_computer.getUpgrade(); + + if( previousUpgrade == null ) throw new LuaException( "Nothing to unequip" ); + + ItemPocketComputer.setUpgrade( pocketStack, null ); + m_computer.setUpgrade( null ); + + ItemStack stack = previousUpgrade.getCraftingItem(); + if( stack != null ) + { + stack = InventoryUtil.storeItems( stack, inventory, 0, 36, inventory.currentItem ); + if( stack != null ) + { + WorldUtil.dropItemStack( stack, player.worldObj, player.posX, player.posY, player.posZ ); + } + } + + return null; + } + default: + return null; + } } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java index 16bbce476..9f01eb70c 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java @@ -117,6 +117,14 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces } } + public ItemStack getStack() { + return m_stack; + } + + public IPocketUpgrade getUpgrade() { + return m_upgrade; + } + public void update( Entity entity, ItemStack stack ) { if( m_entity != null ) setPosition( entity.getPosition() ); diff --git a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java index 81226baac..6a4c3da85 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java @@ -260,7 +260,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia stack, entity ); - computer.addAPI( new PocketAPI() ); + computer.addAPI( new PocketAPI( computer ) ); computer.setUpgrade( getUpgrade( stack ) ); ComputerCraft.serverComputerRegistry.add( instanceID, computer ); if( inventory != null ) @@ -479,4 +479,21 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia return null; } + + public static void setUpgrade( ItemStack stack, IPocketUpgrade upgrade ) + { + NBTTagCompound compound = stack.getTagCompound(); + if( compound == null ) stack.setTagCompound( compound = new NBTTagCompound() ); + + if( upgrade == null ) + { + compound.removeTag( "upgrade" ); + } + else + { + compound.setString( "upgrade", upgrade.getUpgradeID().toString() ); + } + + compound.removeTag( "upgrade_info" ); + } } From 7f8100ae0fb347b9d313c0bf5afaf771d0acdf13 Mon Sep 17 00:00:00 2001 From: SquidDev Date: Thu, 4 May 2017 23:21:26 +0100 Subject: [PATCH 3/6] Check the offhand inventory too when searching for upgrades --- .../shared/pocket/apis/PocketAPI.java | 59 +++++++++++-------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java b/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java index 9119f5042..7cfc5a064 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java +++ b/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java @@ -55,8 +55,8 @@ public class PocketAPI implements ILuaAPI public String[] getMethodNames() { return new String[] { - "equip", - "unequip" + "equipBack", + "unequipBack" }; } @@ -67,7 +67,7 @@ public class PocketAPI implements ILuaAPI { case 0: { - // equip + // equipBack if( !(m_computer.getEntity() instanceof EntityPlayer) ) { throw new LuaException( "Cannot find player" ); @@ -78,28 +78,11 @@ public class PocketAPI implements ILuaAPI InventoryPlayer inventory = player.inventory; IPocketUpgrade previousUpgrade = m_computer.getUpgrade(); - IPocketUpgrade newUpgrade = null; - - int size = inventory.getSizeInventory(), held = inventory.currentItem; - for (int i = 0; i < size; i++) - { - ItemStack invStack = inventory.getStackInSlot( (i + held) % size ); - if( invStack != null ) - { - newUpgrade = ComputerCraft.getPocketUpgrade( invStack ); - - if( newUpgrade != null && newUpgrade != previousUpgrade ) - { - // Consume an item from this stack and exit the loop - invStack = invStack.copy(); - invStack.stackSize--; - inventory.setInventorySlotContents( (i + held) % size, invStack.stackSize <= 0 ? null : invStack ); - - break; - } - } - } + // Attempt to find the upgrade, starting in the main segment, and then looking in the opposite + // one. We start from the position the item is currently in and loop round to the start. + IPocketUpgrade newUpgrade = findUpgrade( inventory.mainInventory, inventory.currentItem, previousUpgrade ); + if( newUpgrade == null ) newUpgrade = findUpgrade( inventory.offHandInventory, 0, previousUpgrade ); if( newUpgrade == null ) throw new LuaException( "Cannot find a valid upgrade" ); // Remove the current upgrade @@ -120,12 +103,14 @@ public class PocketAPI implements ILuaAPI ItemPocketComputer.setUpgrade( pocketStack, newUpgrade ); m_computer.setUpgrade( newUpgrade ); + inventory.markDirty(); + return null; } case 1: { - // unequip + // unequipBack if( !(m_computer.getEntity() instanceof EntityPlayer) ) { throw new LuaException( "Cannot find player" ); @@ -158,4 +143,28 @@ public class PocketAPI implements ILuaAPI return null; } } + + private static IPocketUpgrade findUpgrade( ItemStack[] inv, int start, IPocketUpgrade previous ) + { + for (int i = 0; i < inv.length; i++) + { + ItemStack invStack = inv[ (i + start) % inv.length ]; + if( invStack != null ) + { + IPocketUpgrade newUpgrade = ComputerCraft.getPocketUpgrade( invStack ); + + if( newUpgrade != null && newUpgrade != previous ) + { + // Consume an item from this stack and exit the loop + invStack = invStack.copy(); + invStack.stackSize--; + inv[ (i + start) % inv.length ] = invStack.stackSize <= 0 ? null : invStack; + + return newUpgrade; + } + } + } + + return null; + } } From 6020cd55b15f677b86166aca6ad7448edaae2d2d Mon Sep 17 00:00:00 2001 From: SquidDev Date: Thu, 4 May 2017 23:35:41 +0100 Subject: [PATCH 4/6] Added documentation and updated changelog/whatsnew --- .../resources/assets/computercraft/lua/rom/help/changelog | 2 ++ src/main/resources/assets/computercraft/lua/rom/help/pocket | 6 ++++++ .../resources/assets/computercraft/lua/rom/help/whatsnew | 2 ++ 3 files changed, 10 insertions(+) create mode 100644 src/main/resources/assets/computercraft/lua/rom/help/pocket diff --git a/src/main/resources/assets/computercraft/lua/rom/help/changelog b/src/main/resources/assets/computercraft/lua/rom/help/changelog index 76d4ab0b0..7b8ede788 100644 --- a/src/main/resources/assets/computercraft/lua/rom/help/changelog +++ b/src/main/resources/assets/computercraft/lua/rom/help/changelog @@ -6,6 +6,8 @@ New Features in ComputerCraft 1.80: * os.time() and os.day() now accept parameters to give the real world time. * Added os.epoch() * Monitor text now glows in the dark. +* Added a "Pocket Computer upgrde API" so mod developers can add their own pocket upgrades. +* Added pocket.equipBack()/pocket.unequipBack() to add/remove pocket upgrades. New Features in ComputerCraft 1.79: diff --git a/src/main/resources/assets/computercraft/lua/rom/help/pocket b/src/main/resources/assets/computercraft/lua/rom/help/pocket new file mode 100644 index 000000000..fc498c669 --- /dev/null +++ b/src/main/resources/assets/computercraft/lua/rom/help/pocket @@ -0,0 +1,6 @@ +pocket is an API available on pocket computers, which allows modifying its upgrades. +Functions in the pocket API: +pocket.equipBack() +pocket.unequipBack() + +When equipping upgrades, it will search your inventory for a suitable upgrade, starting in the selected slot. If one cannot be found then it will check your offhand. \ No newline at end of file diff --git a/src/main/resources/assets/computercraft/lua/rom/help/whatsnew b/src/main/resources/assets/computercraft/lua/rom/help/whatsnew index 7dc6f17ce..bd8220b3f 100644 --- a/src/main/resources/assets/computercraft/lua/rom/help/whatsnew +++ b/src/main/resources/assets/computercraft/lua/rom/help/whatsnew @@ -6,5 +6,7 @@ New Features in ComputerCraft 1.80: * os.time() and os.day() now accept parameters to give the real world time. * Added os.epoch() * Monitor text now glows in the dark. +* Added a "Pocket Computer upgrde API" so mod developers can add their own pocket upgrades. +* Added pocket.equipBack()/pocket.unequipBack() to add/remove pocket upgrades. Type "help changelog" to see the full version history. From 5a4375f6ac69a84aa662088b3b63e28d982af897 Mon Sep 17 00:00:00 2001 From: SquidDev Date: Fri, 5 May 2017 00:54:41 +0100 Subject: [PATCH 5/6] Allow changing the colour of the modem light This now uses an integer between 0 and 15 to represent a colour, rather than a simple on/off flag. --- .../api/pocket/IPocketAccess.java | 23 +++++++++--- .../proxy/ComputerCraftProxyClient.java | 35 +++++++++++------- .../pocket/core/PocketServerComputer.java | 19 ++++++---- .../pocket/items/ItemPocketComputer.java | 12 ++++-- .../pocket/peripherals/PocketModem.java | 3 +- .../advanced_pocket_computer_blinking.json | 3 +- ...ced_pocket_computer_blinking_modem_on.json | 7 ---- .../item/advanced_pocket_computer_on.json | 3 +- .../advanced_pocket_computer_on_modem_on.json | 7 ---- .../models/item/pocket_computer_blinking.json | 3 +- .../pocket_computer_blinking_modem_on.json | 7 ---- .../models/item/pocket_computer_on.json | 3 +- .../item/pocket_computer_on_modem_on.json | 7 ---- .../textures/items/pocketComputerLight.png | Bin 0 -> 246 bytes .../items/pocketComputerModemLight.png | Bin 242 -> 0 bytes 15 files changed, 68 insertions(+), 64 deletions(-) delete mode 100644 src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_blinking_modem_on.json delete mode 100644 src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_on_modem_on.json delete mode 100644 src/main/resources/assets/computercraft/models/item/pocket_computer_blinking_modem_on.json delete mode 100644 src/main/resources/assets/computercraft/models/item/pocket_computer_on_modem_on.json create mode 100644 src/main/resources/assets/computercraft/textures/items/pocketComputerLight.png delete mode 100644 src/main/resources/assets/computercraft/textures/items/pocketComputerModemLight.png diff --git a/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java b/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java index f2df7ca91..8a7b6f26b 100644 --- a/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java +++ b/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java @@ -23,29 +23,40 @@ public interface IPocketAccess Entity getEntity(); /** - * Get if the modem light is turned on + * Get the colour of the modem light. * - * @return If the modem light is turned on + * See {@link #setLight(int)} for the values this may return. + * + * @return The colour of the modem light. + * @see #setLight(int) */ - boolean getModemLight(); + int getLight(); /** - * Turn on/off the modem light + * Set the colour of the modem light. Use {@link 0} to turn it off. * - * @param value If the light should be on + * Colours take the form of an integer between 0 and 15, using the opposite order to those in + * {@link The colors API} - so 0 being black, + * 1 representing red, 2 representing green all the way up to 15 for white. + * + * @param value The colour the light should have. + * @see #getLight() */ - void setModemLight( boolean value ); + void setLight( int value ); /** * Get the upgrade specific NBT * * @return The upgrade's NBT + * @see #updateUpgradeNBTData() */ @Nonnull NBTTagCompound getUpgradeNBTData(); /** * Mark the upgrade specific NBT as dirty + * + * @see #getUpgradeNBTData() */ void updateUpgradeNBTData(); diff --git a/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java b/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java index 747fef93d..7dab83860 100644 --- a/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java +++ b/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java @@ -25,6 +25,7 @@ import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon; import dan200.computercraft.shared.turtle.blocks.TileTurtle; import dan200.computercraft.shared.turtle.entity.TurtleVisionCamera; +import dan200.computercraft.shared.util.Colour; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GlStateManager; @@ -53,7 +54,6 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import org.lwjgl.opengl.GL11; import java.io.File; import java.util.ArrayList; @@ -117,19 +117,14 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon private ModelResourceLocation pocket_computer_off = new ModelResourceLocation( "computercraft:pocketComputer", "inventory" ); private ModelResourceLocation pocket_computer_on = new ModelResourceLocation( "computercraft:pocket_computer_on", "inventory" ); private ModelResourceLocation pocket_computer_blinking = new ModelResourceLocation( "computercraft:pocket_computer_blinking", "inventory" ); - private ModelResourceLocation pocket_computer_on_modem_on = new ModelResourceLocation( "computercraft:pocket_computer_on_modem_on", "inventory" ); - private ModelResourceLocation pocket_computer_blinking_modem_on = new ModelResourceLocation( "computercraft:pocket_computer_blinking_modem_on", "inventory" ); private ModelResourceLocation advanced_pocket_computer_off = new ModelResourceLocation( "computercraft:advanced_pocket_computer_off", "inventory" ); private ModelResourceLocation advanced_pocket_computer_on = new ModelResourceLocation( "computercraft:advanced_pocket_computer_on", "inventory" ); private ModelResourceLocation advanced_pocket_computer_blinking = new ModelResourceLocation( "computercraft:advanced_pocket_computer_blinking", "inventory" ); - private ModelResourceLocation advanced_pocket_computer_on_modem_on = new ModelResourceLocation( "computercraft:advanced_pocket_computer_on_modem_on", "inventory" ); - private ModelResourceLocation advanced_pocket_computer_blinking_modem_on = new ModelResourceLocation( "computercraft:advanced_pocket_computer_blinking_modem_on", "inventory" ); @Override public ModelResourceLocation getModelLocation( ItemStack stack ) { ItemPocketComputer itemPocketComputer = (ItemPocketComputer)stack.getItem(); - boolean modemOn = itemPocketComputer.getLightState( stack ); switch( itemPocketComputer.getFamily( stack ) ) { case Advanced: @@ -143,11 +138,11 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon } case On: { - return modemOn ? advanced_pocket_computer_on_modem_on : advanced_pocket_computer_on; + return advanced_pocket_computer_on; } case Blinking: { - return modemOn ? advanced_pocket_computer_blinking_modem_on : advanced_pocket_computer_blinking; + return advanced_pocket_computer_blinking; } } } @@ -163,24 +158,36 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon } case On: { - return modemOn ? pocket_computer_on_modem_on : pocket_computer_on; + return pocket_computer_on; } case Blinking: { - return modemOn ? pocket_computer_blinking_modem_on : pocket_computer_blinking; + return pocket_computer_blinking; } } } } } }, new String[] { - "pocketComputer", "pocket_computer_on", "pocket_computer_blinking", "pocket_computer_on_modem_on", "pocket_computer_blinking_modem_on", - "advanced_pocket_computer_off", "advanced_pocket_computer_on", "advanced_pocket_computer_blinking", "advanced_pocket_computer_on_modem_on", "advanced_pocket_computer_blinking_modem_on", + "pocketComputer", "pocket_computer_on", "pocket_computer_blinking", + "advanced_pocket_computer_off", "advanced_pocket_computer_on", "advanced_pocket_computer_blinking", } ); // Setup - mc.getItemColors().registerItemColorHandler(new DiskColorHandler(ComputerCraft.Items.disk), ComputerCraft.Items.disk); - mc.getItemColors().registerItemColorHandler(new DiskColorHandler(ComputerCraft.Items.diskExpanded), ComputerCraft.Items.diskExpanded); + mc.getItemColors().registerItemColorHandler( new DiskColorHandler( ComputerCraft.Items.disk ), ComputerCraft.Items.disk ); + mc.getItemColors().registerItemColorHandler( new DiskColorHandler( ComputerCraft.Items.diskExpanded ), ComputerCraft.Items.diskExpanded ); + + mc.getItemColors().registerItemColorHandler( new IItemColor() + { + @Override + public int getColorFromItemstack( ItemStack stack, int layout ) + { + if( layout != 1 ) return 0xFFFFFF; + + Colour colour = Colour.fromInt( ComputerCraft.Items.pocketComputer.getLightState( stack ) ); + return colour == null ? Colour.Black.getHex() : colour.getHex(); + } + }, ComputerCraft.Items.pocketComputer ); // Setup renderers ClientRegistry.bindTileEntitySpecialRenderer( TileMonitor.class, new TileEntityMonitorRenderer() ); diff --git a/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java index 9f01eb70c..bccc4f371 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java @@ -40,18 +40,21 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces } @Override - public boolean getModemLight() + public int getLight() { - return getUserData().getBoolean( "modemLight" ); + int value = getUserData().getInteger( "modemLight" ); + return value >= 0 && value <= 15 ? value : 0; } @Override - public void setModemLight( boolean value ) + public void setLight( int value ) { + if( value < 0 || value > 15 ) throw new IllegalArgumentException( "Colour out of bounds" ); + NBTTagCompound tag = getUserData(); - if( tag.getBoolean( "modemLight" ) != value ) + if( tag.getInteger( "modemLight" ) != value ) { - tag.setBoolean( "modemLight", value ); + tag.setInteger( "modemLight", value ); updateUserData(); } } @@ -117,11 +120,13 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces } } - public ItemStack getStack() { + public ItemStack getStack() + { return m_stack; } - public IPocketUpgrade getUpgrade() { + public IPocketUpgrade getUpgrade() + { return m_upgrade; } diff --git a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java index 6a4c3da85..ba86bbe9e 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java @@ -32,6 +32,8 @@ import net.minecraft.util.EnumHand; import net.minecraft.util.SoundEvent; import net.minecraft.world.World; import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; @@ -433,6 +435,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia stack.getTagCompound().setInteger( "sessionID", sessionID ); } + @SideOnly(Side.CLIENT) public ComputerState getState( ItemStack stack ) { ClientComputer computer = getClientComputer( stack ); @@ -443,18 +446,19 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia return ComputerState.Off; } - public boolean getLightState( ItemStack stack ) + @SideOnly(Side.CLIENT) + public int getLightState( ItemStack stack ) { ClientComputer computer = getClientComputer( stack ); if( computer != null && computer.isOn() ) { NBTTagCompound computerNBT = computer.getUserData(); - if( computerNBT != null && computerNBT.getBoolean( "modemLight" ) ) + if( computerNBT != null ) { - return true; + return computerNBT.getInteger( "modemLight" ); } } - return false; + return 0; } public static IPocketUpgrade getUpgrade( ItemStack stack ) diff --git a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java index 8ef40b64a..8d58a8365 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java +++ b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java @@ -5,6 +5,7 @@ import dan200.computercraft.api.pocket.IPocketAccess; import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.shared.peripheral.PeripheralType; import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory; +import dan200.computercraft.shared.util.Colour; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.ItemStack; @@ -76,7 +77,7 @@ public class PocketModem implements IPocketUpgrade modem.setLocation( entity.getEntityWorld(), entity.posX, entity.posY, entity.posZ ); } - access.setModemLight( modem.isActive() ); + access.setLight( modem.isActive() ? Colour.Red.ordinal() : Colour.Black.ordinal() ); } } diff --git a/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_blinking.json b/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_blinking.json index 44d6ba418..784b5a5cd 100644 --- a/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_blinking.json +++ b/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_blinking.json @@ -1,6 +1,7 @@ { "parent": "item/generated", "textures": { - "layer0": "computercraft:items/pocketComputerBlinkAdvanced" + "layer0": "computercraft:items/pocketComputerBlinkAdvanced", + "layer1": "computercraft:items/pocketComputerLight" } } diff --git a/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_blinking_modem_on.json b/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_blinking_modem_on.json deleted file mode 100644 index e7a01ae0b..000000000 --- a/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_blinking_modem_on.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "computercraft:items/pocketComputerBlinkAdvanced", - "layer1": "computercraft:items/pocketComputerModemLight" - } -} diff --git a/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_on.json b/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_on.json index 5edc838c8..c3ce43796 100644 --- a/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_on.json +++ b/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_on.json @@ -1,6 +1,7 @@ { "parent": "item/generated", "textures": { - "layer0": "computercraft:items/pocketComputerOnAdvanced" + "layer0": "computercraft:items/pocketComputerOnAdvanced", + "layer1": "computercraft:items/pocketComputerLight" } } diff --git a/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_on_modem_on.json b/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_on_modem_on.json deleted file mode 100644 index da39d266c..000000000 --- a/src/main/resources/assets/computercraft/models/item/advanced_pocket_computer_on_modem_on.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "computercraft:items/pocketComputerOnAdvanced", - "layer1": "computercraft:items/pocketComputerModemLight" - } -} diff --git a/src/main/resources/assets/computercraft/models/item/pocket_computer_blinking.json b/src/main/resources/assets/computercraft/models/item/pocket_computer_blinking.json index 2600d8049..7309710cb 100644 --- a/src/main/resources/assets/computercraft/models/item/pocket_computer_blinking.json +++ b/src/main/resources/assets/computercraft/models/item/pocket_computer_blinking.json @@ -1,6 +1,7 @@ { "parent": "item/generated", "textures": { - "layer0": "computercraft:items/pocketComputerBlink" + "layer0": "computercraft:items/pocketComputerBlink", + "layer1": "computercraft:items/pocketComputerLight" } } diff --git a/src/main/resources/assets/computercraft/models/item/pocket_computer_blinking_modem_on.json b/src/main/resources/assets/computercraft/models/item/pocket_computer_blinking_modem_on.json deleted file mode 100644 index 47a53343b..000000000 --- a/src/main/resources/assets/computercraft/models/item/pocket_computer_blinking_modem_on.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "computercraft:items/pocketComputerBlink", - "layer1": "computercraft:items/pocketComputerModemLight" - } -} diff --git a/src/main/resources/assets/computercraft/models/item/pocket_computer_on.json b/src/main/resources/assets/computercraft/models/item/pocket_computer_on.json index 6c7c827ea..9575e139a 100644 --- a/src/main/resources/assets/computercraft/models/item/pocket_computer_on.json +++ b/src/main/resources/assets/computercraft/models/item/pocket_computer_on.json @@ -1,6 +1,7 @@ { "parent": "item/generated", "textures": { - "layer0": "computercraft:items/pocketComputerOn" + "layer0": "computercraft:items/pocketComputerOn", + "layer1": "computercraft:items/pocketComputerLight" } } diff --git a/src/main/resources/assets/computercraft/models/item/pocket_computer_on_modem_on.json b/src/main/resources/assets/computercraft/models/item/pocket_computer_on_modem_on.json deleted file mode 100644 index a08912c00..000000000 --- a/src/main/resources/assets/computercraft/models/item/pocket_computer_on_modem_on.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "computercraft:items/pocketComputerOn", - "layer1": "computercraft:items/pocketComputerModemLight" - } -} diff --git a/src/main/resources/assets/computercraft/textures/items/pocketComputerLight.png b/src/main/resources/assets/computercraft/textures/items/pocketComputerLight.png new file mode 100644 index 0000000000000000000000000000000000000000..52f186fc7ba3a286d8080d4a3d67f2ac4f48ed95 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p>QK$!8;-MT+OLG}_)Usv|~JY2j=+Oi0Mh)eV$b z&scQnQiWk4+n@jc<(-vzgx@m7v|TvQy5oa_dBWpky%DC0$rGgZun9DuG-8l2PGCs7 ie2#TVf)*ni8v|?otZC=E7L@{xXYh3Ob6Mw<&;$U{3`V~I literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/computercraft/textures/items/pocketComputerModemLight.png b/src/main/resources/assets/computercraft/textures/items/pocketComputerModemLight.png deleted file mode 100644 index 42238aafdb77b6e8d5c6093cfad78564b3ede5a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP~4;QZz_g+udBS4{gPZ!4!i_^&o3j_=fNoZ+lsbuac ze$K}X0^FMtQc_d`XHD0S=S$zbz*}#QIsf`+KbEM7*a@4t^3S(Xyrmt%J7M}n#ajY% z^nmojGpr(&jUo=Q%sxIo99a(G%@g_5{AasK>lgg`{r~xw@BjPt&N;1Nyl Date: Fri, 5 May 2017 02:07:11 +0100 Subject: [PATCH 6/6] Minor cleanup of pocket computer upgrades - General improvements of the docs. - Move all ItemStack code to the ItemPocketComputer class - Make PocketAPI execute on the server thread, rather than the computer thread --- .../api/pocket/IPocketAccess.java | 25 ++-- .../api/pocket/IPocketUpgrade.java | 59 ++++---- .../shared/pocket/apis/PocketAPI.java | 133 +++++++++--------- .../pocket/core/PocketServerComputer.java | 83 +++++------ .../pocket/items/ItemPocketComputer.java | 39 +++-- 5 files changed, 178 insertions(+), 161 deletions(-) diff --git a/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java b/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java index 8a7b6f26b..2485cacf3 100644 --- a/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java +++ b/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java @@ -15,25 +15,25 @@ import java.util.Map; public interface IPocketAccess { /** - * Gets the holding entity of this item + * Gets the entity holding this item. * - * @return The holding entity, may be {@code null}. + * @return The holding entity. This may be {@code null}. */ @Nullable Entity getEntity(); /** - * Get the colour of the modem light. + * Get the colour of the pocket computer's light. * * See {@link #setLight(int)} for the values this may return. * - * @return The colour of the modem light. + * @return The colour of the pocket computer's light. * @see #setLight(int) */ int getLight(); /** - * Set the colour of the modem light. Use {@link 0} to turn it off. + * Set the colour of the pocket computer's light. Use {@link 0} to turn it off. * * Colours take the form of an integer between 0 and 15, using the opposite order to those in * {@link The colors API} - so 0 being black, @@ -45,31 +45,32 @@ public interface IPocketAccess void setLight( int value ); /** - * Get the upgrade specific NBT + * Get the upgrade-specific NBT. * - * @return The upgrade's NBT + * This is persisted between computer reboots and chunk loads. + * + * @return The upgrade's NBT. * @see #updateUpgradeNBTData() */ @Nonnull NBTTagCompound getUpgradeNBTData(); /** - * Mark the upgrade specific NBT as dirty + * Mark the upgrade-specific NBT as dirty. * * @see #getUpgradeNBTData() */ void updateUpgradeNBTData(); /** - * Remove the current peripheral and create a new one. You - * may wish to do this if the methods available change. + * Remove the current peripheral and create a new one. You may wish to do this if the methods available change. */ void invalidatePeripheral(); /** - * Get a list of all upgrades for the pocket computer + * Get a list of all upgrades for the pocket computer. * - * @return A collection of all upgrade names + * @return A collection of all upgrade names. */ @Nonnull Map getUpgrades(); diff --git a/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java b/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java index 37c26912c..4b92ac214 100644 --- a/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java +++ b/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java @@ -2,9 +2,7 @@ package dan200.computercraft.api.pocket; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.peripheral.IPeripheral; -import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleUpgrade; -import dan200.computercraft.api.turtle.TurtleSide; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; @@ -14,18 +12,20 @@ import javax.annotation.Nullable; /** * Additional peripherals for pocket computers. - *

+ * * This is similar to {@link dan200.computercraft.api.turtle.ITurtleUpgrade}. */ public interface IPocketUpgrade { /** - * Gets a unique identifier representing this type of turtle upgrade. eg: "computercraft:wireless_modem" or "my_mod:my_upgrade". - * You should use a unique resource domain to ensure this upgrade is uniquely identified. - * The peripheral will fail registration if an already used ID is specified. + * Gets a unique identifier representing this type of turtle upgrade. eg: "computercraft:wireless_modem" or + * "my_mod:my_upgrade". * - * @return The id + * You should use a unique resource domain to ensure this upgrade is uniquely identified. The upgrade will fail + * registration if an already used ID is specified. + * + * @return The upgrade's id. * @see IPocketUpgrade#getUpgradeID() * @see ComputerCraftAPI#registerPocketUpgrade(IPocketUpgrade) */ @@ -33,54 +33,59 @@ public interface IPocketUpgrade ResourceLocation getUpgradeID(); /** - * Return a String to describe this type of turtle in turtle item names. - * An example of built-in adjectives is "Wireless". + * Return an unlocalised string to describe the type of pocket computer this upgrade provides. * - * @return The unlocalised adjective + * An example of a built-in adjectives is "Wireless" - this is converted to "Wireless Pocket Computer". + * + * @return The unlocalised adjective. * @see ITurtleUpgrade#getUnlocalisedAdjective() */ @Nonnull String getUnlocalisedAdjective(); /** - * Return an item stack representing the type of item that a turtle must be crafted - * with to create a turtle which holds this upgrade. This item stack is also used - * to determine the upgrade given by turtle.equip() + * Return an item stack representing the type of item that a pocket computer must be crafted with to create a + * pocket computer which holds this upgrade. This item stack is also used to determine the upgrade given by + * {@code pocket.equip()}/{@code pocket.unequip()}. * * @return The item stack used for crafting. This can be {@code null} if crafting is disabled. - * @see ITurtleUpgrade#getCraftingItem() */ @Nullable ItemStack getCraftingItem(); /** * Creates a peripheral for the pocket computer. - *

- * The peripheral created will be stored for the lifetime of the upgrade, will have update() called - * once-per-tick, and will be attached, detached and have methods called in the same manner as a Computer peripheral. * - * @param access The access object for the pocket item stack + * The peripheral created will be stored for the lifetime of the upgrade, will be passed an argument to + * {@link #update(IPocketAccess, IPeripheral)} and will be attached, detached and have methods called in the same + * manner as an ordinary peripheral. + * + * @param access The access object for the pocket item stack. * @return The newly created peripheral. - * @see ITurtleUpgrade#createPeripheral(ITurtleAccess, TurtleSide) + * @see #update(IPocketAccess, IPeripheral) */ @Nullable IPeripheral createPeripheral( @Nonnull IPocketAccess access ); /** - * Called when the pocket computer item stack updates + * Called when the pocket computer item stack updates. * - * @param access The access object for the pocket item stack - * @param peripheral The peripheral for this upgrade + * @param access The access object for the pocket item stack. + * @param peripheral The peripheral for this upgrade. + * @see #createPeripheral(IPocketAccess) */ void update( @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ); /** - * Called when the pocket computer is right clicked on something + * Called when the pocket computer is right clicked. * - * @param world The world the computer is in - * @param access The access object for the pocket item stack - * @param peripheral The peripheral for this upgrade - * @return {@code true} to stop the gui from opening, otherwise false. + * @param world The world the computer is in. + * @param access The access object for the pocket item stack. + * @param peripheral The peripheral for this upgrade. + * @return {@code true} to stop the GUI from opening, otherwise false. You should always provide some code path + * which returns {@code false}, such as requiring the player to be sneaking - otherwise they will be unable to + * access the GUI. + * @see #createPeripheral(IPocketAccess) */ boolean onRightClick( @Nonnull World world, @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ); } diff --git a/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java b/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java index 7cfc5a064..8ef404c0f 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java +++ b/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java @@ -8,11 +8,11 @@ package dan200.computercraft.shared.pocket.apis; import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.lua.ILuaContext; +import dan200.computercraft.api.lua.ILuaTask; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.core.apis.ILuaAPI; import dan200.computercraft.shared.pocket.core.PocketServerComputer; -import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.WorldUtil; import net.minecraft.entity.player.EntityPlayer; @@ -61,84 +61,91 @@ public class PocketAPI implements ILuaAPI } @Override - public Object[] callMethod( ILuaContext context, int method, Object[] arguments ) throws LuaException + public Object[] callMethod( ILuaContext context, int method, Object[] arguments ) throws LuaException, InterruptedException { switch( method ) { case 0: - { // equipBack - if( !(m_computer.getEntity() instanceof EntityPlayer) ) + return context.executeMainThreadTask( new ILuaTask() { - throw new LuaException( "Cannot find player" ); - } - - ItemStack pocketStack = m_computer.getStack(); - EntityPlayer player = (EntityPlayer) m_computer.getEntity(); - InventoryPlayer inventory = player.inventory; - - IPocketUpgrade previousUpgrade = m_computer.getUpgrade(); - - // Attempt to find the upgrade, starting in the main segment, and then looking in the opposite - // one. We start from the position the item is currently in and loop round to the start. - IPocketUpgrade newUpgrade = findUpgrade( inventory.mainInventory, inventory.currentItem, previousUpgrade ); - if( newUpgrade == null ) newUpgrade = findUpgrade( inventory.offHandInventory, 0, previousUpgrade ); - if( newUpgrade == null ) throw new LuaException( "Cannot find a valid upgrade" ); - - // Remove the current upgrade - if( previousUpgrade != null ) - { - ItemStack stack = previousUpgrade.getCraftingItem(); - if( stack != null ) + @Override + public Object[] execute() throws LuaException { - stack = InventoryUtil.storeItems( stack, inventory, 0, 36, inventory.currentItem ); - if( stack != null ) + if( !(m_computer.getEntity() instanceof EntityPlayer) ) { - WorldUtil.dropItemStack( stack, player.worldObj, player.posX, player.posY, player.posZ ); + throw new LuaException( "Cannot find player" ); } + + EntityPlayer player = (EntityPlayer) m_computer.getEntity(); + InventoryPlayer inventory = player.inventory; + + IPocketUpgrade previousUpgrade = m_computer.getUpgrade(); + + // Attempt to find the upgrade, starting in the main segment, and then looking in the opposite + // one. We start from the position the item is currently in and loop round to the start. + IPocketUpgrade newUpgrade = findUpgrade( inventory.mainInventory, inventory.currentItem, previousUpgrade ); + if( newUpgrade == null ) + { + newUpgrade = findUpgrade( inventory.offHandInventory, 0, previousUpgrade ); + } + if( newUpgrade == null ) throw new LuaException( "Cannot find a valid upgrade" ); + + // Remove the current upgrade + if( previousUpgrade != null ) + { + ItemStack stack = previousUpgrade.getCraftingItem(); + if( stack != null ) + { + stack = InventoryUtil.storeItems( stack, inventory, 0, 36, inventory.currentItem ); + if( stack != null ) + { + WorldUtil.dropItemStack( stack, player.worldObj, player.posX, player.posY, player.posZ ); + } + } + } + + // Set the new upgrade + m_computer.setUpgrade( newUpgrade ); + + return null; } - } - - // Set the new upgrade - ItemPocketComputer.setUpgrade( pocketStack, newUpgrade ); - m_computer.setUpgrade( newUpgrade ); - - inventory.markDirty(); - - return null; - } + } ); case 1: - { // unequipBack - if( !(m_computer.getEntity() instanceof EntityPlayer) ) + return context.executeMainThreadTask( new ILuaTask() { - throw new LuaException( "Cannot find player" ); - } - - ItemStack pocketStack = m_computer.getStack(); - EntityPlayer player = (EntityPlayer) m_computer.getEntity(); - InventoryPlayer inventory = player.inventory; - - IPocketUpgrade previousUpgrade = m_computer.getUpgrade(); - - if( previousUpgrade == null ) throw new LuaException( "Nothing to unequip" ); - - ItemPocketComputer.setUpgrade( pocketStack, null ); - m_computer.setUpgrade( null ); - - ItemStack stack = previousUpgrade.getCraftingItem(); - if( stack != null ) - { - stack = InventoryUtil.storeItems( stack, inventory, 0, 36, inventory.currentItem ); - if( stack != null ) + @Override + public Object[] execute() throws LuaException { - WorldUtil.dropItemStack( stack, player.worldObj, player.posX, player.posY, player.posZ ); - } - } + if( !(m_computer.getEntity() instanceof EntityPlayer) ) + { + throw new LuaException( "Cannot find player" ); + } - return null; - } + EntityPlayer player = (EntityPlayer) m_computer.getEntity(); + InventoryPlayer inventory = player.inventory; + + IPocketUpgrade previousUpgrade = m_computer.getUpgrade(); + + if( previousUpgrade == null ) throw new LuaException( "Nothing to unequip" ); + + m_computer.setUpgrade( null ); + + ItemStack stack = previousUpgrade.getCraftingItem(); + if( stack != null ) + { + stack = InventoryUtil.storeItems( stack, inventory, 0, 36, inventory.currentItem ); + if( stack != null ) + { + WorldUtil.dropItemStack( stack, player.worldObj, player.posX, player.posY, player.posZ ); + } + } + + return null; + } + } ); default: return null; } diff --git a/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java index bccc4f371..bd0d9470c 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java @@ -13,7 +13,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; -import net.minecraftforge.common.util.Constants; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -26,10 +25,9 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces private Entity m_entity; private ItemStack m_stack; - public PocketServerComputer( World world, int computerID, String label, int instanceID, ComputerFamily family, ItemStack stack, Entity entity ) + public PocketServerComputer( World world, int computerID, String label, int instanceID, ComputerFamily family ) { super( world, computerID, label, instanceID, family, ComputerCraft.terminalWidth_pocketComputer, ComputerCraft.terminalHeight_pocketComputer ); - update( entity, stack ); } @Nullable @@ -63,30 +61,7 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces @Override public NBTTagCompound getUpgradeNBTData() { - NBTTagCompound tag; - if( m_stack.hasTagCompound() ) - { - tag = m_stack.getTagCompound(); - } - else - { - tag = new NBTTagCompound(); - m_stack.setTagCompound( tag ); - } - - if( tag.hasKey( "upgrade_info", Constants.NBT.TAG_COMPOUND ) ) - { - return tag.getCompoundTag( "upgrade_info" ); - } - else - { - NBTTagCompound sub = new NBTTagCompound(); - - tag.setTag( "upgrade_info", sub ); - updateUpgradeNBTData(); - - return sub; - } + return ComputerCraft.Items.pocketComputer.getUpgradeInfo( m_stack ); } @Override @@ -120,39 +95,47 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces } } - public ItemStack getStack() - { - return m_stack; - } - public IPocketUpgrade getUpgrade() { return m_upgrade; } - public void update( Entity entity, ItemStack stack ) - { - if( m_entity != null ) setPosition( entity.getPosition() ); - m_entity = entity; - m_stack = stack; - } - - public synchronized void setUpgrade( IPocketUpgrade upgrade ) + /** + * Set the upgrade for this pocket computer, also updating the item stack. + * + * Note this method is not thread safe - it must be called from the server thread. + * + * @param upgrade The new upgrade to set it to, may be {@code null}. + */ + public void setUpgrade( IPocketUpgrade upgrade ) { if( this.m_upgrade == upgrade ) return; - // Clear the old upgrade NBT - if( m_stack.hasTagCompound() ) + synchronized (this) { - NBTTagCompound tag = m_stack.getTagCompound(); - if( tag.hasKey( "upgrade_info", 10 ) ) - { - tag.removeTag( "upgrade_info" ); - updateUpgradeNBTData(); - } + ComputerCraft.Items.pocketComputer.setUpgrade( m_stack, upgrade ); + if( m_entity instanceof EntityPlayer ) ((EntityPlayer) m_entity).inventory.markDirty(); + + this.m_upgrade = upgrade; + invalidatePeripheral(); + } + } + + public synchronized void updateValues( Entity entity, ItemStack stack, IPocketUpgrade upgrade ) + { + if( entity != null ) + { + setWorld( entity.getEntityWorld() ); + setPosition( entity.getPosition() ); } - this.m_upgrade = upgrade; - invalidatePeripheral(); + m_entity = entity; + m_stack = stack; + + if( this.m_upgrade != upgrade ) + { + this.m_upgrade = upgrade; + invalidatePeripheral(); + } } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java index ba86bbe9e..0199f92b1 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java @@ -104,10 +104,12 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia PocketServerComputer computer = createServerComputer( world, inventory, entity, stack ); if( computer != null ) { + IPocketUpgrade upgrade = getUpgrade( stack ); + // Ping computer computer.keepAlive(); computer.setWorld( world ); - computer.update( entity, stack ); + computer.updateValues( entity, stack, upgrade ); // Sync ID int id = computer.getID(); @@ -131,8 +133,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia } } - // Update modem - IPocketUpgrade upgrade = getUpgrade( stack ); + // Update pocket upgrade if( upgrade != null ) { upgrade.update( computer, computer.getPeripheral( 2 ) ); @@ -165,6 +166,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia IPocketUpgrade upgrade = getUpgrade( stack ); if( upgrade != null ) { + computer.updateValues( player, stack, upgrade ); stop = upgrade.onRightClick( world, computer, computer.getPeripheral( 2 ) ); } } @@ -258,12 +260,10 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia computerID, getLabel( stack ), instanceID, - getFamily( stack ), - stack, - entity + getFamily( stack ) ); + computer.updateValues( entity, stack, getUpgrade( stack ) ); computer.addAPI( new PocketAPI( computer ) ); - computer.setUpgrade( getUpgrade( stack ) ); ComputerCraft.serverComputerRegistry.add( instanceID, computer ); if( inventory != null ) { @@ -461,7 +461,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia return 0; } - public static IPocketUpgrade getUpgrade( ItemStack stack ) + public IPocketUpgrade getUpgrade( ItemStack stack ) { NBTTagCompound compound = stack.getTagCompound(); if( compound != null ) @@ -484,7 +484,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia return null; } - public static void setUpgrade( ItemStack stack, IPocketUpgrade upgrade ) + public void setUpgrade( ItemStack stack, IPocketUpgrade upgrade ) { NBTTagCompound compound = stack.getTagCompound(); if( compound == null ) stack.setTagCompound( compound = new NBTTagCompound() ); @@ -500,4 +500,25 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia compound.removeTag( "upgrade_info" ); } + + public NBTTagCompound getUpgradeInfo( ItemStack stack ) + { + NBTTagCompound tag = stack.getTagCompound(); + if( tag == null ) + { + tag = new NBTTagCompound(); + stack.setTagCompound( tag ); + } + + if( tag.hasKey( "upgrade_info", Constants.NBT.TAG_COMPOUND ) ) + { + return tag.getCompoundTag( "upgrade_info" ); + } + else + { + NBTTagCompound sub = new NBTTagCompound(); + tag.setTag( "upgrade_info", sub ); + return sub; + } + } }