1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-07-04 02:52:56 +00:00

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
This commit is contained in:
SquidDev 2017-05-05 02:07:11 +01:00
parent 5a4375f6ac
commit 8ba5edb6e4
5 changed files with 178 additions and 161 deletions

View File

@ -15,25 +15,25 @@ import java.util.Map;
public interface IPocketAccess 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 @Nullable
Entity getEntity(); 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. * 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) * @see #setLight(int)
*/ */
int getLight(); 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 * Colours take the form of an integer between 0 and 15, using the opposite order to those in
* {@link <a href="http://www.computercraft.info/wiki/Colors_(API)#Colors">The colors API</a>} - so 0 being black, * {@link <a href="http://www.computercraft.info/wiki/Colors_(API)#Colors">The colors API</a>} - so 0 being black,
@ -45,31 +45,32 @@ public interface IPocketAccess
void setLight( int value ); 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() * @see #updateUpgradeNBTData()
*/ */
@Nonnull @Nonnull
NBTTagCompound getUpgradeNBTData(); NBTTagCompound getUpgradeNBTData();
/** /**
* Mark the upgrade specific NBT as dirty * Mark the upgrade-specific NBT as dirty.
* *
* @see #getUpgradeNBTData() * @see #getUpgradeNBTData()
*/ */
void updateUpgradeNBTData(); void updateUpgradeNBTData();
/** /**
* Remove the current peripheral and create a new one. You * Remove the current peripheral and create a new one. You may wish to do this if the methods available change.
* may wish to do this if the methods available change.
*/ */
void invalidatePeripheral(); 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 @Nonnull
Map<ResourceLocation, IPeripheral> getUpgrades(); Map<ResourceLocation, IPeripheral> getUpgrades();

View File

@ -2,9 +2,7 @@ package dan200.computercraft.api.pocket;
import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleSide;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -14,18 +12,20 @@ import javax.annotation.Nullable;
/** /**
* Additional peripherals for pocket computers. * Additional peripherals for pocket computers.
* <p> *
* This is similar to {@link dan200.computercraft.api.turtle.ITurtleUpgrade}. * This is similar to {@link dan200.computercraft.api.turtle.ITurtleUpgrade}.
*/ */
public interface IPocketUpgrade public interface IPocketUpgrade
{ {
/** /**
* Gets a unique identifier representing this type of turtle upgrade. eg: "computercraft:wireless_modem" or "my_mod:my_upgrade". * Gets a unique identifier representing this type of turtle upgrade. eg: "computercraft:wireless_modem" or
* You should use a unique resource domain to ensure this upgrade is uniquely identified. * "my_mod:my_upgrade".
* The peripheral will fail registration if an already used ID is specified.
* *
* @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 IPocketUpgrade#getUpgradeID()
* @see ComputerCraftAPI#registerPocketUpgrade(IPocketUpgrade) * @see ComputerCraftAPI#registerPocketUpgrade(IPocketUpgrade)
*/ */
@ -33,54 +33,59 @@ public interface IPocketUpgrade
ResourceLocation getUpgradeID(); ResourceLocation getUpgradeID();
/** /**
* Return a String to describe this type of turtle in turtle item names. * Return an unlocalised string to describe the type of pocket computer this upgrade provides.
* An example of built-in adjectives is "Wireless".
* *
* @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() * @see ITurtleUpgrade#getUnlocalisedAdjective()
*/ */
@Nonnull @Nonnull
String getUnlocalisedAdjective(); String getUnlocalisedAdjective();
/** /**
* Return an item stack representing the type of item that a turtle must be crafted * Return an item stack representing the type of item that a pocket computer must be crafted with to create a
* with to create a turtle which holds this upgrade. This item stack is also used * pocket computer which holds this upgrade. This item stack is also used to determine the upgrade given by
* to determine the upgrade given by turtle.equip() * {@code pocket.equip()}/{@code pocket.unequip()}.
* *
* @return The item stack used for crafting. This can be {@code null} if crafting is disabled. * @return The item stack used for crafting. This can be {@code null} if crafting is disabled.
* @see ITurtleUpgrade#getCraftingItem()
*/ */
@Nullable @Nullable
ItemStack getCraftingItem(); ItemStack getCraftingItem();
/** /**
* Creates a peripheral for the pocket computer. * Creates a peripheral for the pocket computer.
* <p>
* 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. * @return The newly created peripheral.
* @see ITurtleUpgrade#createPeripheral(ITurtleAccess, TurtleSide) * @see #update(IPocketAccess, IPeripheral)
*/ */
@Nullable @Nullable
IPeripheral createPeripheral( @Nonnull IPocketAccess access ); 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 access The access object for the pocket item stack.
* @param peripheral The peripheral for this upgrade * @param peripheral The peripheral for this upgrade.
* @see #createPeripheral(IPocketAccess)
*/ */
void update( @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ); 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 world The world the computer is in.
* @param access The access object for the pocket item stack * @param access The access object for the pocket item stack.
* @param peripheral The peripheral for this upgrade * @param peripheral The peripheral for this upgrade.
* @return {@code true} to stop the gui from opening, otherwise false. * @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 ); boolean onRightClick( @Nonnull World world, @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral );
} }

View File

@ -8,11 +8,11 @@ package dan200.computercraft.shared.pocket.apis;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.ILuaTask;
import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.core.apis.ILuaAPI; import dan200.computercraft.core.apis.ILuaAPI;
import dan200.computercraft.shared.pocket.core.PocketServerComputer; 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.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil; import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@ -61,19 +61,22 @@ public class PocketAPI implements ILuaAPI
} }
@Override @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 ) switch( method )
{ {
case 0: case 0:
{
// equipBack // equipBack
return context.executeMainThreadTask( new ILuaTask()
{
@Override
public Object[] execute() throws LuaException
{
if( !(m_computer.getEntity() instanceof EntityPlayer) ) if( !(m_computer.getEntity() instanceof EntityPlayer) )
{ {
throw new LuaException( "Cannot find player" ); throw new LuaException( "Cannot find player" );
} }
ItemStack pocketStack = m_computer.getStack();
EntityPlayer player = (EntityPlayer) m_computer.getEntity(); EntityPlayer player = (EntityPlayer) m_computer.getEntity();
InventoryPlayer inventory = player.inventory; InventoryPlayer inventory = player.inventory;
@ -82,7 +85,10 @@ public class PocketAPI implements ILuaAPI
// Attempt to find the upgrade, starting in the main segment, and then looking in the opposite // 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. // 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 ); IPocketUpgrade newUpgrade = findUpgrade( inventory.mainInventory, inventory.currentItem, previousUpgrade );
if( newUpgrade == null ) newUpgrade = findUpgrade( inventory.offHandInventory, 0, previousUpgrade ); if( newUpgrade == null )
{
newUpgrade = findUpgrade( inventory.offHandInventory, 0, previousUpgrade );
}
if( newUpgrade == null ) throw new LuaException( "Cannot find a valid upgrade" ); if( newUpgrade == null ) throw new LuaException( "Cannot find a valid upgrade" );
// Remove the current upgrade // Remove the current upgrade
@ -100,23 +106,24 @@ public class PocketAPI implements ILuaAPI
} }
// Set the new upgrade // Set the new upgrade
ItemPocketComputer.setUpgrade( pocketStack, newUpgrade );
m_computer.setUpgrade( newUpgrade ); m_computer.setUpgrade( newUpgrade );
inventory.markDirty();
return null; return null;
} }
} );
case 1: case 1:
{
// unequipBack // unequipBack
return context.executeMainThreadTask( new ILuaTask()
{
@Override
public Object[] execute() throws LuaException
{
if( !(m_computer.getEntity() instanceof EntityPlayer) ) if( !(m_computer.getEntity() instanceof EntityPlayer) )
{ {
throw new LuaException( "Cannot find player" ); throw new LuaException( "Cannot find player" );
} }
ItemStack pocketStack = m_computer.getStack();
EntityPlayer player = (EntityPlayer) m_computer.getEntity(); EntityPlayer player = (EntityPlayer) m_computer.getEntity();
InventoryPlayer inventory = player.inventory; InventoryPlayer inventory = player.inventory;
@ -124,7 +131,6 @@ public class PocketAPI implements ILuaAPI
if( previousUpgrade == null ) throw new LuaException( "Nothing to unequip" ); if( previousUpgrade == null ) throw new LuaException( "Nothing to unequip" );
ItemPocketComputer.setUpgrade( pocketStack, null );
m_computer.setUpgrade( null ); m_computer.setUpgrade( null );
ItemStack stack = previousUpgrade.getCraftingItem(); ItemStack stack = previousUpgrade.getCraftingItem();
@ -139,6 +145,7 @@ public class PocketAPI implements ILuaAPI
return null; return null;
} }
} );
default: default:
return null; return null;
} }

View File

@ -13,7 +13,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -26,10 +25,9 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
private Entity m_entity; private Entity m_entity;
private ItemStack m_stack; 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 ); super( world, computerID, label, instanceID, family, ComputerCraft.terminalWidth_pocketComputer, ComputerCraft.terminalHeight_pocketComputer );
update( entity, stack );
} }
@Nullable @Nullable
@ -63,30 +61,7 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
@Override @Override
public NBTTagCompound getUpgradeNBTData() public NBTTagCompound getUpgradeNBTData()
{ {
NBTTagCompound tag; return ComputerCraft.Items.pocketComputer.getUpgradeInfo( m_stack );
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 @Override
@ -120,39 +95,47 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
} }
} }
public ItemStack getStack()
{
return m_stack;
}
public IPocketUpgrade getUpgrade() public IPocketUpgrade getUpgrade()
{ {
return m_upgrade; return m_upgrade;
} }
public void update( Entity entity, ItemStack stack ) /**
{ * Set the upgrade for this pocket computer, also updating the item stack.
if( m_entity != null ) setPosition( entity.getPosition() ); *
m_entity = entity; * Note this method is not thread safe - it must be called from the server thread.
m_stack = stack; *
} * @param upgrade The new upgrade to set it to, may be {@code null}.
*/
public synchronized void setUpgrade( IPocketUpgrade upgrade ) public void setUpgrade( IPocketUpgrade upgrade )
{ {
if( this.m_upgrade == upgrade ) return; if( this.m_upgrade == upgrade ) return;
// Clear the old upgrade NBT synchronized (this)
if( m_stack.hasTagCompound() )
{ {
NBTTagCompound tag = m_stack.getTagCompound(); ComputerCraft.Items.pocketComputer.setUpgrade( m_stack, upgrade );
if( tag.hasKey( "upgrade_info", 10 ) ) if( m_entity instanceof EntityPlayer ) ((EntityPlayer) m_entity).inventory.markDirty();
{
tag.removeTag( "upgrade_info" );
updateUpgradeNBTData();
}
}
this.m_upgrade = upgrade; this.m_upgrade = upgrade;
invalidatePeripheral(); invalidatePeripheral();
} }
} }
public synchronized void updateValues( Entity entity, ItemStack stack, IPocketUpgrade upgrade )
{
if( entity != null )
{
setWorld( entity.getEntityWorld() );
setPosition( entity.getPosition() );
}
m_entity = entity;
m_stack = stack;
if( this.m_upgrade != upgrade )
{
this.m_upgrade = upgrade;
invalidatePeripheral();
}
}
}

View File

@ -104,10 +104,12 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia
PocketServerComputer computer = createServerComputer( world, inventory, entity, stack ); PocketServerComputer computer = createServerComputer( world, inventory, entity, stack );
if( computer != null ) if( computer != null )
{ {
IPocketUpgrade upgrade = getUpgrade( stack );
// Ping computer // Ping computer
computer.keepAlive(); computer.keepAlive();
computer.setWorld( world ); computer.setWorld( world );
computer.update( entity, stack ); computer.updateValues( entity, stack, upgrade );
// Sync ID // Sync ID
int id = computer.getID(); int id = computer.getID();
@ -131,8 +133,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia
} }
} }
// Update modem // Update pocket upgrade
IPocketUpgrade upgrade = getUpgrade( stack );
if( upgrade != null ) if( upgrade != null )
{ {
upgrade.update( computer, computer.getPeripheral( 2 ) ); upgrade.update( computer, computer.getPeripheral( 2 ) );
@ -165,6 +166,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia
IPocketUpgrade upgrade = getUpgrade( stack ); IPocketUpgrade upgrade = getUpgrade( stack );
if( upgrade != null ) if( upgrade != null )
{ {
computer.updateValues( player, stack, upgrade );
stop = upgrade.onRightClick( world, computer, computer.getPeripheral( 2 ) ); stop = upgrade.onRightClick( world, computer, computer.getPeripheral( 2 ) );
} }
} }
@ -258,12 +260,10 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia
computerID, computerID,
getLabel( stack ), getLabel( stack ),
instanceID, instanceID,
getFamily( stack ), getFamily( stack )
stack,
entity
); );
computer.updateValues( entity, stack, getUpgrade( stack ) );
computer.addAPI( new PocketAPI( computer ) ); computer.addAPI( new PocketAPI( computer ) );
computer.setUpgrade( getUpgrade( stack ) );
ComputerCraft.serverComputerRegistry.add( instanceID, computer ); ComputerCraft.serverComputerRegistry.add( instanceID, computer );
if( inventory != null ) if( inventory != null )
{ {
@ -461,7 +461,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia
return 0; return 0;
} }
public static IPocketUpgrade getUpgrade( ItemStack stack ) public IPocketUpgrade getUpgrade( ItemStack stack )
{ {
NBTTagCompound compound = stack.getTagCompound(); NBTTagCompound compound = stack.getTagCompound();
if( compound != null ) if( compound != null )
@ -484,7 +484,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia
return null; return null;
} }
public static void setUpgrade( ItemStack stack, IPocketUpgrade upgrade ) public void setUpgrade( ItemStack stack, IPocketUpgrade upgrade )
{ {
NBTTagCompound compound = stack.getTagCompound(); NBTTagCompound compound = stack.getTagCompound();
if( compound == null ) stack.setTagCompound( compound = new NBTTagCompound() ); if( compound == null ) stack.setTagCompound( compound = new NBTTagCompound() );
@ -500,4 +500,25 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia
compound.removeTag( "upgrade_info" ); 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;
}
}
} }