CC-Tweaked/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java

567 lines
17 KiB
Java

/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.pocket.items;
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.pocket.IPocketUpgrade;
import dan200.computercraft.shared.common.IColouredItem;
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.core.PocketServerComputer;
import dan200.computercraft.shared.util.StringUtil;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import java.util.List;
public class ItemPocketComputer extends Item implements IComputerItem, IMedia, IColouredItem
{
public ItemPocketComputer()
{
setMaxStackSize( 1 );
setHasSubtypes( true );
setTranslationKey( "computercraft:pocket_computer" );
setCreativeTab( ComputerCraft.mainCreativeTab );
}
public ItemStack create( int id, String label, int colour, ComputerFamily family, IPocketUpgrade upgrade )
{
// Ignore types we can't handle
if( family != ComputerFamily.Normal && family != ComputerFamily.Advanced )
{
return null;
}
// Build the stack
int damage = (family == ComputerFamily.Advanced) ? 1 : 0;
ItemStack result = new ItemStack( this, 1, damage );
if( id >= 0 || upgrade != null )
{
NBTTagCompound compound = new NBTTagCompound();
if( id >= 0 )
{
compound.setInteger( "computerID", id );
}
if( upgrade != null )
{
compound.setString( "upgrade", upgrade.getUpgradeID().toString() );
}
result.setTagCompound( compound );
}
if( label != null )
{
result.setStackDisplayName( label );
}
if( colour != -1 )
{
NBTTagCompound tag = result.getTagCompound();
if( tag == null ) result.setTagCompound( tag = new NBTTagCompound() );
tag.setInteger( "colour", colour );
}
return result;
}
@Override
public void getSubItems( @Nonnull CreativeTabs tabs, @Nonnull NonNullList<ItemStack> list )
{
if( !isInCreativeTab( tabs ) ) return;
getSubItems( list, ComputerFamily.Normal );
getSubItems( list, ComputerFamily.Advanced );
}
private void getSubItems( NonNullList<ItemStack> list, ComputerFamily family )
{
list.add( PocketComputerItemFactory.create( -1, null, -1, family, null ) );
for( IPocketUpgrade upgrade : ComputerCraft.getVanillaPocketUpgrades() )
{
list.add( PocketComputerItemFactory.create( -1, null, -1, family, upgrade ) );
}
}
@Override
public void onUpdate( ItemStack stack, World world, Entity entity, int slotNum, boolean selected )
{
if( !world.isRemote )
{
// Server side
IInventory inventory = (entity instanceof EntityPlayer) ? ((EntityPlayer) entity).inventory : null;
PocketServerComputer computer = createServerComputer( world, inventory, entity, stack );
if( computer != null )
{
IPocketUpgrade upgrade = getUpgrade( stack );
// Ping computer
computer.keepAlive();
computer.setWorld( world );
computer.updateValues( entity, stack, upgrade );
// Sync ID
int id = computer.getID();
if( id != getComputerID( stack ) )
{
setComputerID( stack, id );
if( inventory != null )
{
inventory.markDirty();
}
}
// Sync label
String label = computer.getLabel();
if( !Objects.equal( label, getLabel( stack ) ) )
{
setLabel( stack, label );
if( inventory != null )
{
inventory.markDirty();
}
}
// Update pocket upgrade
if( upgrade != null )
{
upgrade.update( computer, computer.getPeripheral( 2 ) );
}
}
}
else
{
// Client side
ClientComputer computer = createClientComputer( stack );
if( computer != null )
{
// Todo: things here?
}
}
}
@Nonnull
@Override
public ActionResult<ItemStack> onItemRightClick( World world, EntityPlayer player, @Nonnull EnumHand hand )
{
ItemStack stack = player.getHeldItem( hand );
if( !world.isRemote )
{
PocketServerComputer computer = createServerComputer( world, player.inventory, player, stack );
boolean stop = false;
if( computer != null )
{
computer.turnOn();
IPocketUpgrade upgrade = getUpgrade( stack );
if( upgrade != null )
{
computer.updateValues( player, stack, upgrade );
stop = upgrade.onRightClick( world, computer, computer.getPeripheral( 2 ) );
}
}
if( !stop ) ComputerCraft.openPocketComputerGUI( player, hand );
}
return new ActionResult<>( EnumActionResult.SUCCESS, stack );
}
@Nonnull
@Override
public String getTranslationKey( @Nonnull ItemStack stack )
{
switch( getFamily( stack ) )
{
case Normal:
default:
{
return "item.computercraft:pocket_computer";
}
case Advanced:
{
return "item.computercraft:advanced_pocket_computer";
}
}
}
@Nonnull
@Override
public String getItemStackDisplayName( @Nonnull ItemStack stack )
{
String baseString = getTranslationKey( stack );
IPocketUpgrade upgrade = getUpgrade( stack );
if( upgrade != null )
{
return StringUtil.translateToLocalFormatted(
baseString + ".upgraded.name",
StringUtil.translateToLocal( upgrade.getUnlocalisedAdjective() )
);
}
else
{
return StringUtil.translateToLocal( baseString + ".name" );
}
}
@Override
public void addInformation( @Nonnull ItemStack stack, World world, List<String> list, ITooltipFlag flag )
{
if( flag.isAdvanced() )
{
int id = getComputerID( stack );
if( id >= 0 )
{
list.add( "(Computer ID: " + id + ")" );
}
}
}
private PocketServerComputer createServerComputer( final World world, IInventory inventory, Entity entity, @Nonnull ItemStack stack )
{
if( world.isRemote )
{
return null;
}
PocketServerComputer computer;
int instanceID = getInstanceID( stack );
int sessionID = getSessionID( stack );
int correctSessionID = ComputerCraft.serverComputerRegistry.getSessionID();
if( instanceID >= 0 && sessionID == correctSessionID &&
ComputerCraft.serverComputerRegistry.contains( instanceID ) )
{
computer = (PocketServerComputer) ComputerCraft.serverComputerRegistry.get( instanceID );
}
else
{
if( instanceID < 0 || sessionID != correctSessionID )
{
instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID();
setInstanceID( stack, instanceID );
setSessionID( stack, correctSessionID );
}
int computerID = getComputerID( stack );
if( computerID < 0 )
{
computerID = ComputerCraft.createUniqueNumberedSaveDir( world, "computer" );
setComputerID( stack, computerID );
}
computer = new PocketServerComputer(
world,
computerID,
getLabel( stack ),
instanceID,
getFamily( stack )
);
computer.updateValues( entity, stack, getUpgrade( stack ) );
computer.addAPI( new PocketAPI( computer ) );
ComputerCraft.serverComputerRegistry.add( instanceID, computer );
if( inventory != null )
{
inventory.markDirty();
}
}
computer.setWorld( world );
return computer;
}
public ServerComputer getServerComputer( @Nonnull ItemStack stack )
{
int instanceID = getInstanceID( stack );
if( instanceID >= 0 )
{
return ComputerCraft.serverComputerRegistry.get( instanceID );
}
return null;
}
public ClientComputer createClientComputer( @Nonnull ItemStack stack )
{
int instanceID = getInstanceID( stack );
if( instanceID >= 0 )
{
if( !ComputerCraft.clientComputerRegistry.contains( instanceID ) )
{
ComputerCraft.clientComputerRegistry.add( instanceID, new ClientComputer( instanceID ) );
}
return ComputerCraft.clientComputerRegistry.get( instanceID );
}
return null;
}
private ClientComputer getClientComputer( @Nonnull ItemStack stack )
{
int instanceID = getInstanceID( stack );
if( instanceID >= 0 )
{
return ComputerCraft.clientComputerRegistry.get( instanceID );
}
return null;
}
// IComputerItem implementation
@Override
public int getComputerID( @Nonnull ItemStack stack )
{
NBTTagCompound compound = stack.getTagCompound();
if( compound != null && compound.hasKey( "computerID" ) )
{
return compound.getInteger( "computerID" );
}
return -1;
}
private void setComputerID( @Nonnull ItemStack stack, int computerID )
{
if( !stack.hasTagCompound() )
{
stack.setTagCompound( new NBTTagCompound() );
}
stack.getTagCompound().setInteger( "computerID", computerID );
}
@Override
public String getLabel( @Nonnull ItemStack stack )
{
if( stack.hasDisplayName() )
{
return stack.getDisplayName();
}
return null;
}
@Override
public ComputerFamily getFamily( @Nonnull ItemStack stack )
{
int damage = stack.getItemDamage();
switch( damage )
{
case 0:
default:
{
return ComputerFamily.Normal;
}
case 1:
{
return ComputerFamily.Advanced;
}
}
}
@Override
public ItemStack withFamily( @Nonnull ItemStack stack, @Nonnull ComputerFamily family )
{
return PocketComputerItemFactory.create(
getComputerID( stack ), getLabel( stack ), getColour( stack ),
family, getUpgrade( stack )
);
}
// IMedia
@Override
public boolean setLabel( @Nonnull ItemStack stack, String label )
{
if( label != null )
{
stack.setStackDisplayName( label );
}
else
{
stack.clearCustomName();
}
return true;
}
@Override
public IMount createDataMount( @Nonnull ItemStack stack, @Nonnull World world )
{
int id = getComputerID( stack );
if( id >= 0 )
{
return ComputerCraft.createSaveDirMount( world, "computer/" + id, ComputerCraft.computerSpaceLimit );
}
return null;
}
private int getInstanceID( @Nonnull ItemStack stack )
{
NBTTagCompound compound = stack.getTagCompound();
if( compound != null && compound.hasKey( "instanceID" ) )
{
return compound.getInteger( "instanceID" );
}
return -1;
}
private void setInstanceID( @Nonnull ItemStack stack, int instanceID )
{
if( !stack.hasTagCompound() )
{
stack.setTagCompound( new NBTTagCompound() );
}
stack.getTagCompound().setInteger( "instanceID", instanceID );
}
private int getSessionID( @Nonnull ItemStack stack )
{
NBTTagCompound compound = stack.getTagCompound();
if( compound != null && compound.hasKey( "sessionID" ) )
{
return compound.getInteger( "sessionID" );
}
return -1;
}
private void setSessionID( @Nonnull ItemStack stack, int sessionID )
{
if( !stack.hasTagCompound() )
{
stack.setTagCompound( new NBTTagCompound() );
}
stack.getTagCompound().setInteger( "sessionID", sessionID );
}
@SideOnly( Side.CLIENT )
public ComputerState getState( @Nonnull ItemStack stack )
{
ClientComputer computer = getClientComputer( stack );
if( computer != null && computer.isOn() )
{
return computer.isCursorDisplayed() ? ComputerState.Blinking : ComputerState.On;
}
return ComputerState.Off;
}
@SideOnly( Side.CLIENT )
public int getLightState( @Nonnull ItemStack stack )
{
ClientComputer computer = getClientComputer( stack );
if( computer != null && computer.isOn() )
{
NBTTagCompound computerNBT = computer.getUserData();
if( computerNBT != null && computerNBT.hasKey( "modemLight", Constants.NBT.TAG_ANY_NUMERIC ) )
{
return computerNBT.getInteger( "modemLight" );
}
}
return -1;
}
public IPocketUpgrade getUpgrade( @Nonnull ItemStack stack )
{
NBTTagCompound compound = stack.getTagCompound();
if( compound != null )
{
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 null;
}
public void setUpgrade( @Nonnull 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" );
}
public NBTTagCompound getUpgradeInfo( @Nonnull 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;
}
}
@Override
public int getColour( ItemStack stack )
{
NBTTagCompound tag = stack.getTagCompound();
return tag != null && tag.hasKey( "colour", Constants.NBT.TAG_ANY_NUMERIC ) ? tag.getInteger( "colour" ) : -1;
}
@Override
public ItemStack setColour( ItemStack stack, int colour )
{
ItemStack copy = stack.copy();
setColourDirect( copy, colour );
return copy;
}
public void setColourDirect( ItemStack stack, int colour )
{
NBTTagCompound tag = stack.getTagCompound();
if( colour == -1 )
{
if( tag != null ) tag.removeTag( "colour" );
}
else
{
if( tag == null ) stack.setTagCompound( tag = new NBTTagCompound() );
tag.setInteger( "colour", colour );
}
}
}