1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-15 22:17:39 +00:00

Compare commits

..

21 Commits

Author SHA1 Message Date
SquidDev
d173787a94 Another backwards compat change
Plethora only implements getPos on older versions, so we need to stub
out both.
2019-01-21 17:36:25 +00:00
SquidDev
d5aea26f3a Bump version
It's pretty soon after the previous release (10 days!) but there's a
couple of important bug fixes and some nice improvements.
2019-01-21 11:02:29 +00:00
SquidDev
2681e578c4 Merge pull request #101 from SquidDev-CC/feature/no-ticking
Make several tile entities non-ticking, hopefully reducing
server load.
2019-01-21 08:29:42 +00:00
SquidDev
1f498dcc73 Backwards compat patch for Plethora
Ughghgghghr.
2019-01-20 16:16:02 +00:00
SquidDev
83b01d35eb Make monitors non-ticking
- Convert terminals from a polling-based system to a more event-driven
   one: they now accept an onChanged callback, which marks the parent as
   dirty.
 - Schedule ticks when monitors are marked as dirty.
 - Add several missing @Overrides. This has nothing to do with the rest
   of the changes, but I'm bad at good git practice.
2019-01-20 15:39:11 +00:00
SquidDev
8a7e651c99 Several miscellaneous changes
- Merge BlockPeripheralBase and BlockPeripheral, as no other classes
   extended the former.
 - Make BlockPeripheral use ITilePeripheral instead of
   TilePeripheralBase. This allows us to use other, non-ticking tiles
   instead.
 - Convert advanced and normal modems to extend from a generic
   TileWirelessModemBase class, and thus neither now tick.
2019-01-20 14:06:41 +00:00
SquidDev
80a5759bae Make advanced modems non-ticking
- Move getPeripheralType and getLabel from IPeripheralTile to
   TilePeripheralBase. These were mostly constant on all other tiles, so
   were rather redundant.
 - Make TileAdvancedModem extend TileGeneric, and be non-ticking (using
   similar logic to all other blocks).
2019-01-20 09:34:15 +00:00
SquidDev
e8a4fbb4e3 Make TileCable non-ticking
- Move updateTick onto BlockGeneric/TileGeneric instead of the full
   wired modem, as it is used by several tiles now.
 - Make *Cable extend from *Generic, and schedule ticks instead of
   running every tick.
2019-01-19 22:25:38 +00:00
SquidDev
0ce67afcc1 Be less strict in comparing upgrade crafting items
We currently generate the crafting item once when the upgrade is first
created, and cache it for the duration of the game. As the item never
changes throughout the game, and constructing a stack is a little
expensive (we need to fire an event, etc...), the caching is worth
having.

However, some mods may register capabilities after we've constructed our
ItemStack. This means the capability will be present on other items but
not ours, meaning they are not considered equivalent, and thus the item
cannot be equipped.

In order to avoid this, we use compare items using their share-tag, like
Forge's IngredientNBT. This means the items must still be "mostly" the
same (same enchantements, etc...), but allow differing capabilities.

See NillerMedDild/Enigmatica2Expert#655 for the original bug report -
in this case, Astral Sourcery was registering the capability in init,
but we construct upgrades just before then.
2019-01-19 21:57:21 +00:00
SquidDev
a8dad23fa3 Begin investigations into reducing ticking of TEs
- Move IDirectionalTile constraint from IPeripheralTile to
   TilePeripheralBase.
 - Make *WiredModemFull no longer inherit from *PeripheralBase. While
   there is still some shared logic (namely in the syncing of "anim"),
   it's largely fine as we don't store label or direction in NBT.
 - Add a TickScheduler. This is a thread-safe version of
   World.scheduleUpdate. We simply build a set of all TEs, and schedule
   them to be updated the next tick.
 - Make ModemState receive an "onChanged" listener, which is fired
   whenever the modem changes.
 - Make WiredModemFull no longer tick, instead scheduling updates when
   it is first loaded and whenever the modem changes.
2019-01-19 10:16:41 +00:00
SquidDev
443e0f8f76 Remove FileSystemMount and rewrite JarMount
FileSystemMount was originally added to allow using ReadableByteChannels
instead of InputStreams. However, as zip files do not allow seeking,
there is no benefit of using them over the original JarMount (which we
need to preserve for backwards compatibility).

Instead of maintaining two near-identical mounts, we remove the
FileSystemMount and rewrite the JarMount implementation with several
improvements:

 - Rewrite the jar scanning algorithm to be closer to 1.13+'s data pack
   mount. This means we no longer require the jar file to have
   directories before the file (though this was not a problem in
   practice).
 - Add all JarMounts to a ReferenceQueue, closing up the ZipFile when
   they have been garbage collected (fixes #100).
 - Cache the contents of all files for 60 seconds (with some constraints
   on size). This allows us to seek on ROM files too (assuming they are
   small), by reading the whole thing into memory.
   The cache is shared across all mounts, and has a 64MiB limit, and
   thus should not have an adverse impact on memory.
2019-01-16 17:25:46 +00:00
SquidDev
a838595e1e Derive upgrade adjectives from its ID
This is done in 1.13+ for items and blocks, so we might as well do it
for upgrades now. Note we can't do it for ender pocket modems, as the
upgrade ID is spelled incorrectly there.
2019-01-14 10:42:13 +00:00
SquidDev
61daab910e Simplify placement logic of various blocks
- For those where placement is stored in the metadata (computers),
   don't also set it in onBlockPlacedBy.
 - Remove .getDefaultState(int, EnumFacing) override, as this means we
   have more control over what is passed to us (namely, placer's
   direction too).
2019-01-14 10:27:19 +00:00
SquidDev
7fd19c43e9 Try to hide CommandCopy from most completions.
"/computercraf" auto-completes to "/computercraft_copy" instead of
"/computercraft", which is rather annoying, as the former is not meant
to be used normally.
2019-01-14 10:10:52 +00:00
SquidDev
ce0685c31f Move our message model to be closer to Forge's
It's rather embarassing that it's been restructured _again_, but I think
this is a nice middle-ground. The previous implementation was written
mostly for Fabric, which doesn't always map perfectly to Forge.

 - Move the message identifier into the registration phrase. It's not
   really a property of the message itself, rather a property of the
   registry, so better suited there.

 - Move message handling into the message itself. Honestly, it was just
   ending up being rather messy mixing the logic in two places.

   This also means we can drop some proxy methods, as it's easier to
   have conditionally loaded methods.

 - Move network registry into a dedicated class, as that's what we're
   doing for everything else.
2019-01-14 10:09:22 +00:00
SquidDev
e33f852baa Store references to the registered items
This means we can avoid several rather ugly instances of getItemBlock
and a cast. We also derive the ItemBlock's registered name from the
block's name, which makes the register a little less ugly.
2019-01-12 19:01:32 +00:00
SquidDev
227d5e9e69 Fix cables not rendering the breaking steps
The fact that it's taken this long for anyone to notice this didn't work
is rather embarassing.
2019-01-12 18:35:43 +00:00
SquidDev
1c648850ab Even more proxy pruning
- Move the "world directory" getter out of the proxy - we can just use
   Forge's code here.
 - Remove the server proxies, as both were empty. We don't tend to
   register any dedicated-server specific code, so I think we can leave
   them out.
2019-01-12 18:23:22 +00:00
SquidDev
63691707fc Move registration methods into a separate class
- All "named" entries (blocks, items, recipes, TEs and pocket/turtle
   upgrades) are registeredin one place.
 - Most client side models/textures are registered in ClientRegistry -
   we can't do item colours or TEs for now, as these aren't event based.
 - A little cleanup to how we handle ItemPocketComputer models.
2019-01-12 17:51:26 +00:00
SquidDev
5d97b9c8f3 Utilise @Mod.EventBusSubscriber a little more
This offers several advantages

 - Less registration code: the subscribers are reigstered automatically,
   and we don't need to worry about sided-proxies.
 - We no longer have so many .instance() calls.
2019-01-12 16:27:40 +00:00
SquidDev
77666d7399 Some more minor cleanups
- Move SpeakerPeripheral's TileSpeaker functionality to a sub-class.
 - Use Vec3d instead of BlockPos for speaker's positions.
 - Use WorldUtil.dropItemStack to spawn in items.
 - Remove redundant lock on ModemPeripheral.
2019-01-12 15:43:18 +00:00
108 changed files with 2247 additions and 2798 deletions

View File

@@ -23,7 +23,7 @@ apply plugin: 'org.ajoberstar.grgit'
apply plugin: 'maven-publish'
apply plugin: 'maven'
version = "1.80pr1.13"
version = "1.80pr1.14"
group = "org.squiddev"
archivesBaseName = "cc-tweaked"

View File

@@ -26,7 +26,7 @@ import dan200.computercraft.core.apis.ApiFactories;
import dan200.computercraft.core.apis.http.websocket.Websocket;
import dan200.computercraft.core.filesystem.ComboMount;
import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.core.filesystem.FileSystemMount;
import dan200.computercraft.core.filesystem.JarMount;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.core.tracking.Tracking;
import dan200.computercraft.shared.*;
@@ -37,15 +37,21 @@ import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
import dan200.computercraft.shared.computer.items.ItemCommandComputer;
import dan200.computercraft.shared.computer.items.ItemComputer;
import dan200.computercraft.shared.media.items.ItemDiskExpanded;
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
import dan200.computercraft.shared.media.items.ItemPrintout;
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
import dan200.computercraft.shared.network.NetworkHandler;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.common.ItemPeripheral;
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
import dan200.computercraft.shared.peripheral.modem.wired.BlockCable;
import dan200.computercraft.shared.peripheral.modem.wired.BlockWiredModemFull;
import dan200.computercraft.shared.peripheral.modem.wired.ItemCable;
import dan200.computercraft.shared.peripheral.modem.wireless.BlockAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.ItemAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
@@ -55,6 +61,9 @@ 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.items.ItemTurtleAdvanced;
import dan200.computercraft.shared.turtle.items.ItemTurtleLegacy;
import dan200.computercraft.shared.turtle.items.ItemTurtleNormal;
import dan200.computercraft.shared.turtle.upgrades.*;
import dan200.computercraft.shared.util.CreativeTabMain;
import dan200.computercraft.shared.util.IDAssigner;
@@ -62,7 +71,7 @@ import dan200.computercraft.shared.util.IoUtil;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import dan200.computercraft.shared.wired.WiredNode;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
@@ -71,13 +80,11 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.*;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.relauncher.Side;
import org.apache.logging.log4j.Logger;
@@ -85,13 +92,9 @@ import java.io.*;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.ServiceConfigurationError;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -172,51 +175,73 @@ public class ComputerCraft
public static class Blocks
{
public static BlockComputer computer;
public static BlockPeripheral peripheral;
public static BlockCable cable;
public static BlockCommandComputer commandComputer;
public static BlockTurtle turtle;
public static BlockTurtle turtleExpanded;
public static BlockTurtle turtleAdvanced;
public static BlockCommandComputer commandComputer;
public static BlockPeripheral peripheral;
public static BlockCable cable;
public static BlockAdvancedModem advancedModem;
public static BlockWiredModemFull wiredModemFull;
}
public static class Items
{
public static ItemComputer computer;
public static ItemCommandComputer commandComputer;
public static ItemTurtleLegacy turtle;
public static ItemTurtleNormal turtleExpanded;
public static ItemTurtleAdvanced turtleAdvanced;
public static ItemPocketComputer pocketComputer;
public static ItemDiskLegacy disk;
public static ItemDiskExpanded diskExpanded;
public static ItemPrintout printout;
public static ItemTreasureDisk treasureDisk;
public static ItemPocketComputer pocketComputer;
public static ItemPrintout printout;
public static ItemPeripheral peripheral;
public static ItemAdvancedModem advancedModem;
public static ItemCable cable;
public static ItemBlock wiredModemFull;
}
public static class Upgrades
public static class TurtleUpgrades
{
public static TurtleModem wirelessModem;
public static TurtleModem advancedModem;
public static TurtleSpeaker speaker;
public static TurtleCraftingTable craftingTable;
public static TurtleSword diamondSword;
public static TurtleShovel diamondShovel;
public static TurtleTool diamondPickaxe;
public static TurtleAxe diamondAxe;
public static TurtleHoe diamondHoe;
public static TurtleModem advancedModem;
public static TurtleSpeaker turtleSpeaker;
}
public static class PocketUpgrades
{
public static PocketModem wirelessModem;
public static PocketModem advancedModem;
public static PocketSpeaker speaker;
@Deprecated
public static PocketSpeaker pocketSpeaker;
}
// Registries
public static ClientComputerRegistry clientComputerRegistry = new ClientComputerRegistry();
public static ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry();
@Deprecated
public static class Upgrades {
public static TurtleModem advancedModem;
}
// Networking
public static SimpleNetworkWrapper networkWrapper;
// Registries
public static final ClientComputerRegistry clientComputerRegistry = new ClientComputerRegistry();
public static final ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry();
// Creative
public static CreativeTabMain mainCreativeTab;
@@ -231,11 +256,17 @@ public class ComputerCraft
@Mod.Instance( value = ComputerCraft.MOD_ID )
public static ComputerCraft instance;
@SidedProxy( clientSide = "dan200.computercraft.client.proxy.ComputerCraftProxyClient", serverSide = "dan200.computercraft.server.proxy.ComputerCraftProxyServer" )
public static IComputerCraftProxy proxy;
@SidedProxy(
clientSide = "dan200.computercraft.client.proxy.ComputerCraftProxyClient",
serverSide = "dan200.computercraft.shared.proxy.ComputerCraftProxyCommon"
)
private static IComputerCraftProxy proxy;
@SidedProxy( clientSide = "dan200.computercraft.client.proxy.CCTurtleProxyClient", serverSide = "dan200.computercraft.server.proxy.CCTurtleProxyServer" )
public static ICCTurtleProxy turtleProxy;
@SidedProxy(
clientSide = "dan200.computercraft.client.proxy.CCTurtleProxyClient",
serverSide = "dan200.computercraft.shared.proxy.CCTurtleProxyCommon"
)
private static ICCTurtleProxy turtleProxy;
@Mod.EventHandler
public void preInit( FMLPreInitializationEvent event )
@@ -246,7 +277,7 @@ public class ComputerCraft
Config.load( event.getSuggestedConfigurationFile() );
// Setup network
networkWrapper = NetworkRegistry.INSTANCE.newSimpleChannel( ComputerCraft.MOD_ID );
NetworkHandler.setup();
proxy.preInit();
turtleProxy.preInit();
@@ -354,31 +385,6 @@ public class ComputerCraft
return new File( getBaseDir(), "resourcepacks" );
}
public static File getWorldDir( World world )
{
return proxy.getWorldDir( world );
}
public static void sendToPlayer( EntityPlayer player, IMessage packet )
{
networkWrapper.sendTo( packet, (EntityPlayerMP) player );
}
public static void sendToAllPlayers( IMessage packet )
{
networkWrapper.sendToAll( packet );
}
public static void sendToServer( IMessage packet )
{
networkWrapper.sendToServer( packet );
}
public static void sendToAllAround( IMessage packet, NetworkRegistry.TargetPoint point )
{
networkWrapper.sendToAllAround( packet, point );
}
public static boolean canPlayerUseCommands( EntityPlayer player )
{
MinecraftServer server = player.getServer();
@@ -455,7 +461,7 @@ public class ComputerCraft
@Deprecated
public static int createUniqueNumberedSaveDir( World world, String parentSubPath )
{
return IDAssigner.getNextIDFromDirectory( new File( getWorldDir( world ), parentSubPath ) );
return IDAssigner.getNextIDFromDirectory( parentSubPath );
}
@Deprecated
@@ -463,7 +469,7 @@ public class ComputerCraft
{
try
{
return new FileMount( new File( getWorldDir( world ), subPath ), capacity );
return new FileMount( new File( getWorldDir(), subPath ), capacity );
}
catch( Exception e )
{
@@ -496,13 +502,11 @@ public class ComputerCraft
{
try
{
FileSystem fs = FileSystems.newFileSystem( modJar.toPath(), ComputerCraft.class.getClassLoader() );
mounts.add( new FileSystemMount( fs, subPath ) );
mounts.add( new JarMount( modJar, subPath ) );
}
catch( IOException | RuntimeException | ServiceConfigurationError e )
catch( IOException | RuntimeException e )
{
ComputerCraft.log.error( "Could not load mount from mod jar", e );
// Ignore
}
}
@@ -519,21 +523,16 @@ public class ComputerCraft
if( !resourcePack.isDirectory() )
{
// Mount a resource pack from a jar
FileSystem fs = FileSystems.newFileSystem( resourcePack.toPath(), ComputerCraft.class.getClassLoader() );
if( Files.exists( fs.getPath( subPath ) ) ) mounts.add( new FileSystemMount( fs, subPath ) );
mounts.add( new JarMount( resourcePack, subPath ) );
}
else
{
// Mount a resource pack from a folder
File subResource = new File( resourcePack, subPath );
if( subResource.exists() )
{
IMount resourcePackMount = new FileMount( subResource, 0 );
mounts.add( resourcePackMount );
}
if( subResource.exists() ) mounts.add( new FileMount( subResource, 0 ) );
}
}
catch( IOException | RuntimeException | ServiceConfigurationError e )
catch( IOException | RuntimeException e )
{
ComputerCraft.log.error( "Could not load resource pack '" + resourcePackName + "'", e );
}
@@ -680,10 +679,21 @@ public class ComputerCraft
@Deprecated
public static void registerTurtleUpgrade( ITurtleUpgrade upgrade )
{
TurtleUpgrades.register( upgrade );
dan200.computercraft.shared.TurtleUpgrades.register( upgrade );
}
public static File getWorldDir()
{
return DimensionManager.getCurrentSaveRootDirectory();
}
//region Compatibility
@Deprecated
public static File getWorldDir( World world )
{
return DimensionManager.getCurrentSaveRootDirectory();
}
@Deprecated
public static IMedia getMedia( ItemStack stack )
{
@@ -699,7 +709,7 @@ public class ComputerCraft
@Deprecated
public static ITurtleUpgrade getTurtleUpgrade( ItemStack stack )
{
return TurtleUpgrades.get( stack );
return dan200.computercraft.shared.TurtleUpgrades.get( stack );
}
@Deprecated
@@ -711,7 +721,7 @@ public class ComputerCraft
@Deprecated
public static ITurtleUpgrade getTurtleUpgrade( String id )
{
return TurtleUpgrades.get( id );
return dan200.computercraft.shared.TurtleUpgrades.get( id );
}
@Deprecated

View File

@@ -0,0 +1,156 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client;
import dan200.computercraft.ComputerCraft;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelBakery;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import javax.annotation.Nonnull;
/**
* Registers textures and models for items.
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
public class ClientRegistry
{
private static final String[] TURTLE_UPGRADES = {
"turtle_modem_off_left",
"turtle_modem_on_left",
"turtle_modem_off_right",
"turtle_modem_on_right",
"turtle_crafting_table_left",
"turtle_crafting_table_right",
"advanced_turtle_modem_off_left",
"advanced_turtle_modem_on_left",
"advanced_turtle_modem_off_right",
"advanced_turtle_modem_on_right",
"turtle_speaker_upgrade_left",
"turtle_speaker_upgrade_right",
};
@SubscribeEvent
public static void registerModels( ModelRegistryEvent event )
{
// Register item models
registerUniversalItemModel( ComputerCraft.Items.computer, "computer" );
registerItemModel( ComputerCraft.Items.commandComputer, 0, "command_computer" );
registerItemModel( ComputerCraft.Items.pocketComputer, 0, "pocket_computer" );
registerItemModel( ComputerCraft.Items.pocketComputer, 1, "advanced_pocket_computer" );
registerItemModel( ComputerCraft.Items.peripheral, 0, "peripheral" );
registerItemModel( ComputerCraft.Items.peripheral, 1, "wireless_modem" );
registerItemModel( ComputerCraft.Items.peripheral, 2, "monitor" );
registerItemModel( ComputerCraft.Items.peripheral, 3, "printer" );
registerItemModel( ComputerCraft.Items.peripheral, 4, "advanced_monitor" );
registerItemModel( ComputerCraft.Items.cable, 0, "cable" );
registerItemModel( ComputerCraft.Items.cable, 1, "wired_modem" );
registerItemModel( ComputerCraft.Items.advancedModem, 0, "advanced_modem" );
registerItemModel( ComputerCraft.Items.peripheral, 5, "speaker" );
registerItemModel( ComputerCraft.Items.wiredModemFull, 0, "wired_modem_full" );
registerUniversalItemModel( ComputerCraft.Items.disk, "disk" );
registerItemModel( ComputerCraft.Items.diskExpanded, 0, "disk_expanded" );
registerItemModel( ComputerCraft.Items.treasureDisk, 0, "treasure_disk" );
registerItemModel( ComputerCraft.Items.printout, 0, "printout" );
registerItemModel( ComputerCraft.Items.printout, 1, "pages" );
registerItemModel( ComputerCraft.Items.printout, 2, "book" );
String[] extraTurtleModels = new String[] { "turtle", "turtle_advanced", "turtle_white", "turtle_elf_overlay" };
registerUniversalItemModel( ComputerCraft.Items.turtle, "turtle_dynamic", extraTurtleModels );
registerUniversalItemModel( ComputerCraft.Items.turtleExpanded, "turtle_dynamic", extraTurtleModels );
registerUniversalItemModel( ComputerCraft.Items.turtleAdvanced, "turtle_dynamic", extraTurtleModels );
}
@SubscribeEvent
public static void onTextureStitchEvent( TextureStitchEvent.Pre event )
{
// Load all textures for upgrades
TextureMap map = event.getMap();
for( String upgrade : TURTLE_UPGRADES )
{
IModel model = ModelLoaderRegistry.getModelOrMissing( new ResourceLocation( "computercraft", "block/" + upgrade ) );
for( ResourceLocation texture : model.getTextures() )
{
map.registerSprite( texture );
}
}
}
@SubscribeEvent
public static void onModelBakeEvent( ModelBakeEvent event )
{
// Load all upgrade models
for( String upgrade : TURTLE_UPGRADES )
{
loadBlockModel( event, upgrade );
}
}
private static void registerItemModel( Item item, int damage, String name )
{
ResourceLocation location = new ResourceLocation( ComputerCraft.MOD_ID, name );
final ModelResourceLocation res = new ModelResourceLocation( location, "inventory" );
ModelBakery.registerItemVariants( item, location );
ModelLoader.setCustomModelResourceLocation( item, damage, res );
}
private static void registerUniversalItemModel( Item item, String mainModel, String... extraModels )
{
ResourceLocation mainLocation = new ResourceLocation( ComputerCraft.MOD_ID, mainModel );
ResourceLocation[] modelLocations = new ResourceLocation[extraModels.length + 1];
modelLocations[0] = mainLocation;
for( int i = 0; i < extraModels.length; i++ )
{
modelLocations[i + 1] = new ResourceLocation( ComputerCraft.MOD_ID, extraModels[i] );
}
ModelBakery.registerItemVariants( item, modelLocations );
final ModelResourceLocation mainModelLocation = new ModelResourceLocation( mainLocation, "inventory" );
ModelLoader.setCustomMeshDefinition( item, new ItemMeshDefinition()
{
@Nonnull
@Override
public ModelResourceLocation getModelLocation( @Nonnull ItemStack stack )
{
return mainModelLocation;
}
} );
}
private static void loadBlockModel( ModelBakeEvent event, String name )
{
IModel model = ModelLoaderRegistry.getModelOrMissing( new ResourceLocation( ComputerCraft.MOD_ID, "block/" + name ) );
IBakedModel bakedModel = model.bake(
model.getDefaultState(), DefaultVertexFormats.ITEM,
location -> Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( location.toString() )
);
event.getModelRegistry().putObject( new ModelResourceLocation( ComputerCraft.MOD_ID + ":" + name, "inventory" ), bakedModel );
}
}

View File

@@ -6,43 +6,40 @@
package dan200.computercraft.client;
import dan200.computercraft.ComputerCraft;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.relauncher.Side;
public class FrameInfo
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
public final class FrameInfo
{
private static final FrameInfo instance = new FrameInfo();
public static FrameInfo instance()
{
return instance;
}
private int tick;
private long renderFrame;
private static int tick;
private static long renderFrame;
private FrameInfo()
{
}
public boolean getGlobalCursorBlink()
public static boolean getGlobalCursorBlink()
{
return (tick / 8) % 2 == 0;
}
public long getRenderFrame()
public static long getRenderFrame()
{
return renderFrame;
}
@SubscribeEvent
public void onTick( TickEvent.ClientTickEvent event )
public static void onTick( TickEvent.ClientTickEvent event )
{
if( event.phase == TickEvent.Phase.START ) tick++;
}
@SubscribeEvent
public void onRenderTick( TickEvent.RenderTickEvent event )
public static void onRenderTick( TickEvent.RenderTickEvent event )
{
if( event.phase == TickEvent.Phase.START ) renderFrame++;
}

View File

@@ -388,7 +388,7 @@ public class WidgetTerminal extends Widget
// Get the data from the terminal first
// Unfortunately we have to keep the lock for the whole of drawing, so the text doesn't change under us.
FixedWidthFontRenderer fontRenderer = FixedWidthFontRenderer.instance();
boolean tblink = m_focus && terminal.getCursorBlink() && FrameInfo.instance().getGlobalCursorBlink();
boolean tblink = m_focus && terminal.getCursorBlink() && FrameInfo.getGlobalCursorBlink();
int tw = terminal.getWidth();
int th = terminal.getHeight();
int tx = terminal.getCursorX();

View File

@@ -12,69 +12,22 @@ import dan200.computercraft.client.render.TurtleSmartItemModel;
import dan200.computercraft.shared.proxy.CCTurtleProxyCommon;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.items.ItemTurtleBase;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelBakery;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.color.IItemColor;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.resources.IReloadableResourceManager;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.SimpleReloadableResourceManager;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import javax.annotation.Nonnull;
public class CCTurtleProxyClient extends CCTurtleProxyCommon
{
// IComputerCraftProxy implementation
@Override
public void preInit()
{
super.preInit();
// Setup client forge handlers
registerForgeHandlers();
}
@SubscribeEvent
public void registerModels( ModelRegistryEvent event )
{
// Register item models
ItemMeshDefinition turtleMeshDefinition = new ItemMeshDefinition()
{
private ModelResourceLocation turtle_dynamic = new ModelResourceLocation( "computercraft:turtle_dynamic", "inventory" );
@Nonnull
@Override
public ModelResourceLocation getModelLocation( @Nonnull ItemStack stack )
{
return turtle_dynamic;
}
};
String[] turtleModelNames = new String[] {
"turtle_dynamic",
"turtle", "turtle_advanced",
"turtle_white",
"turtle_elf_overlay"
};
registerItemModel( ComputerCraft.Blocks.turtle, turtleMeshDefinition, turtleModelNames );
registerItemModel( ComputerCraft.Blocks.turtleExpanded, turtleMeshDefinition, turtleModelNames );
registerItemModel( ComputerCraft.Blocks.turtleAdvanced, turtleMeshDefinition, turtleModelNames );
MinecraftForge.EVENT_BUS.register( new ForgeHandlers() );
}
@Override
@@ -83,124 +36,7 @@ public class CCTurtleProxyClient extends CCTurtleProxyCommon
super.init();
// Setup turtle colours
Minecraft.getMinecraft().getItemColors().registerItemColorHandler(
new TurtleItemColour(),
ComputerCraft.Blocks.turtle, ComputerCraft.Blocks.turtleExpanded, ComputerCraft.Blocks.turtleAdvanced
);
// Setup renderers
ClientRegistry.bindTileEntitySpecialRenderer( TileTurtle.class, new TileEntityTurtleRenderer() );
}
private void registerItemModel( Block block, ItemMeshDefinition definition, String[] names )
{
registerItemModel( Item.getItemFromBlock( block ), definition, names );
}
private void registerItemModel( Item item, ItemMeshDefinition definition, String[] names )
{
ResourceLocation[] resources = new ResourceLocation[names.length];
for( int i = 0; i < names.length; i++ )
{
resources[i] = new ResourceLocation( "computercraft:" + names[i] );
}
ModelBakery.registerItemVariants( item, resources );
ModelLoader.setCustomMeshDefinition( item, definition );
}
private void registerForgeHandlers()
{
ForgeHandlers handlers = new ForgeHandlers();
MinecraftForge.EVENT_BUS.register( handlers );
}
public static class ForgeHandlers
{
private static final String[] TURTLE_UPGRADES = {
"turtle_modem_off_left",
"turtle_modem_on_left",
"turtle_modem_off_right",
"turtle_modem_on_right",
"turtle_crafting_table_left",
"turtle_crafting_table_right",
"advanced_turtle_modem_off_left",
"advanced_turtle_modem_on_left",
"advanced_turtle_modem_off_right",
"advanced_turtle_modem_on_right",
"turtle_speaker_upgrade_left",
"turtle_speaker_upgrade_right",
};
private TurtleSmartItemModel m_turtleSmartItemModel;
public ForgeHandlers()
{
m_turtleSmartItemModel = new TurtleSmartItemModel();
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
if( resourceManager instanceof SimpleReloadableResourceManager )
{
SimpleReloadableResourceManager reloadableResourceManager = (SimpleReloadableResourceManager) resourceManager;
reloadableResourceManager.registerReloadListener( m_turtleSmartItemModel );
}
}
@SubscribeEvent
public void onTextureStitchEvent( TextureStitchEvent.Pre event )
{
// Load all textures for upgrades
TextureMap map = event.getMap();
for( String upgrade : TURTLE_UPGRADES )
{
IModel model = ModelLoaderRegistry.getModelOrMissing( new ResourceLocation( "computercraft", "block/" + upgrade ) );
for( ResourceLocation texture : model.getTextures() )
{
map.registerSprite( texture );
}
}
}
@SubscribeEvent
public void onModelBakeEvent( ModelBakeEvent event )
{
// Load all upgrade models
for( String upgrade : TURTLE_UPGRADES )
{
loadModel( event, upgrade );
}
loadSmartModel( event, "turtle_dynamic", m_turtleSmartItemModel );
}
private void loadModel( ModelBakeEvent event, String name )
{
IModel model = ModelLoaderRegistry.getModelOrMissing(
new ResourceLocation( "computercraft", "block/" + name )
);
IBakedModel bakedModel = model.bake(
model.getDefaultState(),
DefaultVertexFormats.ITEM,
location -> Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( location.toString() )
);
event.getModelRegistry().putObject(
new ModelResourceLocation( "computercraft:" + name, "inventory" ),
bakedModel
);
}
private void loadSmartModel( ModelBakeEvent event, String name, IBakedModel smartModel )
{
event.getModelRegistry().putObject(
new ModelResourceLocation( "computercraft:" + name, "inventory" ),
smartModel
);
}
}
private static class TurtleItemColour implements IItemColor
{
@Override
public int colorMultiplier( @Nonnull ItemStack stack, int tintIndex )
{
Minecraft.getMinecraft().getItemColors().registerItemColorHandler( ( stack, tintIndex ) -> {
if( tintIndex == 0 )
{
ItemTurtleBase turtle = (ItemTurtleBase) stack.getItem();
@@ -209,6 +45,30 @@ public class CCTurtleProxyClient extends CCTurtleProxyCommon
}
return 0xFFFFFF;
}, ComputerCraft.Blocks.turtle, ComputerCraft.Blocks.turtleExpanded, ComputerCraft.Blocks.turtleAdvanced );
// Setup renderers
ClientRegistry.bindTileEntitySpecialRenderer( TileTurtle.class, new TileEntityTurtleRenderer() );
}
public static class ForgeHandlers
{
private final TurtleSmartItemModel m_turtleSmartItemModel = new TurtleSmartItemModel();
ForgeHandlers()
{
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
if( resourceManager instanceof IReloadableResourceManager )
{
((IReloadableResourceManager) resourceManager).registerReloadListener( m_turtleSmartItemModel );
}
}
@SubscribeEvent
public void onModelBakeEvent( ModelBakeEvent event )
{
event.getModelRegistry().putObject( new ModelResourceLocation( "computercraft:turtle_dynamic", "inventory" ), m_turtleSmartItemModel );
}
}
}

View File

@@ -7,41 +7,27 @@
package dan200.computercraft.client.proxy;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.ClientTableFormatter;
import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.client.render.*;
import dan200.computercraft.client.render.TileEntityCableRenderer;
import dan200.computercraft.client.render.TileEntityMonitorRenderer;
import dan200.computercraft.shared.command.CommandCopy;
import dan200.computercraft.shared.command.text.TableBuilder;
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
import dan200.computercraft.shared.peripheral.modem.wired.TileCable;
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
import dan200.computercraft.shared.util.Colour;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.block.model.ModelBakery;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.color.IItemColor;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.client.ClientCommandHandler;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import java.io.File;
public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
{
@@ -50,53 +36,22 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
{
super.preInit();
// Setup client forge handlers
registerForgeHandlers();
// Register any client-specific commands
ClientCommandHandler.instance.registerCommand( CommandCopy.INSTANCE );
}
@SubscribeEvent
public void registerModels( ModelRegistryEvent event )
{
// Register item models
registerItemModel( ComputerCraft.Blocks.computer, "computer" );
registerItemModel( ComputerCraft.Blocks.peripheral, 0, "peripheral" );
registerItemModel( ComputerCraft.Blocks.peripheral, 1, "wireless_modem" );
registerItemModel( ComputerCraft.Blocks.peripheral, 2, "monitor" );
registerItemModel( ComputerCraft.Blocks.peripheral, 3, "printer" );
registerItemModel( ComputerCraft.Blocks.peripheral, 4, "advanced_monitor" );
registerItemModel( ComputerCraft.Blocks.cable, 0, "cable" );
registerItemModel( ComputerCraft.Blocks.cable, 1, "wired_modem" );
registerItemModel( ComputerCraft.Blocks.commandComputer, "command_computer" );
registerItemModel( ComputerCraft.Blocks.advancedModem, "advanced_modem" );
registerItemModel( ComputerCraft.Blocks.peripheral, 5, "speaker" );
registerItemModel( ComputerCraft.Blocks.wiredModemFull, "wired_modem_full" );
registerItemModel( ComputerCraft.Items.disk, "disk" );
registerItemModel( ComputerCraft.Items.diskExpanded, "disk_expanded" );
registerItemModel( ComputerCraft.Items.treasureDisk, "treasure_disk" );
registerItemModel( ComputerCraft.Items.printout, 0, "printout" );
registerItemModel( ComputerCraft.Items.printout, 1, "pages" );
registerItemModel( ComputerCraft.Items.printout, 2, "book" );
registerItemModel( ComputerCraft.Items.pocketComputer, "pocket_computer" );
}
@Override
public void init()
{
super.init();
// Load textures
Minecraft mc = Minecraft.getMinecraft();
// 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( ( stack, layer ) ->
{
mc.getItemColors().registerItemColorHandler( ( stack, layer ) -> {
switch( layer )
{
case 0:
@@ -122,71 +77,11 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
ClientRegistry.bindTileEntitySpecialRenderer( TileCable.class, new TileEntityCableRenderer() );
}
private void registerItemModel( Block block, int damage, String name )
{
registerItemModel( Item.getItemFromBlock( block ), damage, name );
}
private void registerItemModel( Item item, int damage, String name )
{
ModelResourceLocation res = new ModelResourceLocation( "computercraft:" + name, "inventory" );
ModelBakery.registerItemVariants( item, new ResourceLocation( "computercraft", name ) );
ModelLoader.setCustomModelResourceLocation( item, damage, res );
}
private void registerItemModel( Block block, String name )
{
registerItemModel( Item.getItemFromBlock( block ), name );
}
private void registerItemModel( Item item, String name )
{
final ModelResourceLocation res = new ModelResourceLocation( "computercraft:" + name, "inventory" );
ModelBakery.registerItemVariants( item, new ResourceLocation( "computercraft", name ) );
ModelLoader.setCustomMeshDefinition( item, new ItemMeshDefinition()
{
@Nonnull
@Override
public ModelResourceLocation getModelLocation( @Nonnull ItemStack stack )
{
return res;
}
} );
}
@Override
public File getWorldDir( World world )
{
return world.getSaveHandler().getWorldDirectory();
}
private void registerForgeHandlers()
{
MinecraftForge.EVENT_BUS.register( new ForgeHandlers() );
MinecraftForge.EVENT_BUS.register( new RenderOverlayCable() );
MinecraftForge.EVENT_BUS.register( new ItemPocketRenderer() );
MinecraftForge.EVENT_BUS.register( new ItemPrintoutRenderer() );
MinecraftForge.EVENT_BUS.register( FrameInfo.instance() );
}
@Override
public void playRecordClient( BlockPos pos, SoundEvent record, String info )
{
Minecraft mc = Minecraft.getMinecraft();
mc.world.playRecord( pos, record );
if( info != null ) mc.ingameGUI.setRecordPlayingMessage( info );
}
@Override
public void showTableClient( TableBuilder table )
{
ClientTableFormatter.INSTANCE.display( table );
}
public class ForgeHandlers
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
public static class ForgeHandlers
{
@SubscribeEvent
public void onWorldUnload( WorldEvent.Unload event )
public static void onWorldUnload( WorldEvent.Unload event )
{
if( event.getWorld().isRemote )
{

View File

@@ -24,9 +24,9 @@ import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.item.ItemStack;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.event.RenderSpecificHandEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.opengl.GL11;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
@@ -35,17 +35,23 @@ import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
/**
* Emulates map rendering for pocket computers
*/
@SideOnly( Side.CLIENT )
public class ItemPocketRenderer extends ItemMapLikeRenderer
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
public final class ItemPocketRenderer extends ItemMapLikeRenderer
{
private static final ItemPocketRenderer INSTANCE = new ItemPocketRenderer();
private ItemPocketRenderer()
{
}
@SubscribeEvent
public void renderItem( RenderSpecificHandEvent event )
public static void renderItem( RenderSpecificHandEvent event )
{
ItemStack stack = event.getItemStack();
if( !(stack.getItem() instanceof ItemPocketComputer) ) return;
event.setCanceled( true );
renderItemFirstPerson( event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack() );
INSTANCE.renderItemFirstPerson( event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack() );
}
@Override
@@ -145,7 +151,7 @@ public class ItemPocketRenderer extends ItemMapLikeRenderer
// And render the cursor;
int tx = terminal.getCursorX(), ty = terminal.getCursorY();
if( terminal.getCursorBlink() && FrameInfo.instance().getGlobalCursorBlink() &&
if( terminal.getCursorBlink() && FrameInfo.getGlobalCursorBlink() &&
tx >= 0 && ty >= 0 && tx < tw && ty < th )
{
TextBuffer cursorColour = new TextBuffer( "0123456789abcdef".charAt( terminal.getTextColour() ), 1 );

View File

@@ -12,7 +12,9 @@ import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.item.ItemStack;
import net.minecraftforge.client.event.RenderItemInFrameEvent;
import net.minecraftforge.client.event.RenderSpecificHandEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
@@ -20,17 +22,27 @@ import static dan200.computercraft.client.render.PrintoutRenderer.*;
import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE;
import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH;
public class ItemPrintoutRenderer extends ItemMapLikeRenderer
/**
* Emulates map and item-frame rendering for prinouts
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
{
private static final ItemPrintoutRenderer INSTANCE = new ItemPrintoutRenderer();
private ItemPrintoutRenderer()
{
}
@SubscribeEvent
public void onRenderInHand( RenderSpecificHandEvent event )
public static void onRenderInHand( RenderSpecificHandEvent event )
{
ItemStack stack = event.getItemStack();
if( stack.getItem() != ComputerCraft.Items.printout ) return;
event.setCanceled( true );
renderItemFirstPerson( event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack() );
INSTANCE.renderItemFirstPerson( event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack() );
}
@Override
@@ -51,7 +63,7 @@ public class ItemPrintoutRenderer extends ItemMapLikeRenderer
}
@SubscribeEvent
public void onRenderInFrame( RenderItemInFrameEvent event )
public static void onRenderInFrame( RenderItemInFrameEvent event )
{
ItemStack stack = event.getItem();
if( stack.getItem() != ComputerCraft.Items.printout ) return;
@@ -69,6 +81,7 @@ public class ItemPrintoutRenderer extends ItemMapLikeRenderer
drawPrintout( stack );
GlStateManager.enableLighting();
GlStateManager.disableBlend();
}
private static void drawPrintout( ItemStack stack )

View File

@@ -23,17 +23,24 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import org.lwjgl.opengl.GL11;
public class RenderOverlayCable
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
public final class RenderOverlayCable
{
private static final float EXPAND = 0.002f;
private static final double MIN = CableBounds.MIN - EXPAND;
private static final double MAX = CableBounds.MAX + EXPAND;
private RenderOverlayCable()
{
}
@SubscribeEvent
public void drawHighlight( DrawBlockHighlightEvent event )
public static void drawHighlight( DrawBlockHighlightEvent event )
{
if( event.getTarget().typeOfHit != RayTraceResult.Type.BLOCK ) return;

View File

@@ -49,7 +49,7 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
// Ensure each monitor terminal is rendered only once. We allow rendering a specific tile
// multiple times in a single frame to ensure compatibility with shaders which may run a
// pass multiple times.
long renderFrame = FrameInfo.instance().getRenderFrame();
long renderFrame = FrameInfo.getRenderFrame();
if( originTerminal.lastRenderFrame == renderFrame && !monitorPos.equals( originTerminal.lastRenderPos ) )
{
return;
@@ -230,7 +230,7 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
GlStateManager.glEndList();
}
}
if( FrameInfo.instance().getGlobalCursorBlink() )
if( FrameInfo.getGlobalCursorBlink() )
{
GlStateManager.callList( originTerminal.renderDisplayLists[2] );
GlStateManager.resetColor();

View File

@@ -16,6 +16,7 @@ public interface ILuaAPI extends dan200.computercraft.api.lua.ILuaAPI
{
void advance( double v );
@Override
default void update()
{
advance( 0.05 );

View File

@@ -26,12 +26,14 @@ public class ResourceQueue<T extends Resource<T>> extends ResourceGroup<T>
{
}
@Override
public synchronized void shutdown()
{
super.shutdown();
pending.clear();
}
@Override
public synchronized boolean queue( Supplier<T> resource )
{
if( !active ) return false;
@@ -40,6 +42,7 @@ public class ResourceQueue<T extends Resource<T>> extends ResourceGroup<T>
return true;
}
@Override
public synchronized void release( T resource )
{
super.release( resource );

View File

@@ -239,6 +239,7 @@ public class HttpRequest extends Resource<HttpRequest>
if( tryClose() ) environment.queueEvent( SUCCESS_EVENT, new Object[] { address, object } );
}
@Override
protected void dispose()
{
super.dispose();

View File

@@ -1,144 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.core.filesystem;
import dan200.computercraft.api.filesystem.IMount;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.FileSystem;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.stream.Stream;
public class FileSystemMount implements IMount
{
private final Entry rootEntry;
public FileSystemMount( FileSystem fileSystem, String root ) throws IOException
{
Path rootPath = fileSystem.getPath( root );
rootEntry = new Entry( "", rootPath );
populate( rootEntry );
}
private void populate( Entry root ) throws IOException
{
if( !root.directory ) return;
Queue<Entry> entries = new ArrayDeque<>();
entries.add( root );
while( !entries.isEmpty() )
{
Entry entry = entries.remove();
try( Stream<Path> childStream = Files.list( entry.path ) )
{
Iterator<Path> children = childStream.iterator();
while( children.hasNext() )
{
Path childPath = children.next();
Entry child = new Entry( childPath.getFileName().toString(), childPath );
entry.children.put( child.name, child );
if( child.directory ) entries.add( child );
}
}
}
}
@Override
public boolean exists( @Nonnull String path )
{
return getFile( path ) != null;
}
@Override
public boolean isDirectory( @Nonnull String path )
{
Entry entry = getFile( path );
return entry != null && entry.directory;
}
@Override
public void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException
{
Entry entry = getFile( path );
if( entry == null || !entry.directory ) throw new IOException( "/" + path + ": Not a directory" );
contents.addAll( entry.children.keySet() );
}
@Override
public long getSize( @Nonnull String path ) throws IOException
{
Entry file = getFile( path );
if( file == null ) throw new IOException( "/" + path + ": No such file" );
return file.size;
}
@Nonnull
@Override
@Deprecated
public InputStream openForRead( @Nonnull String path ) throws IOException
{
Entry file = getFile( path );
if( file == null || file.directory ) throw new IOException( "/" + path + ": No such file" );
return Files.newInputStream( file.path, StandardOpenOption.READ );
}
@Nonnull
@Override
public ReadableByteChannel openChannelForRead( @Nonnull String path ) throws IOException
{
Entry file = getFile( path );
if( file == null || file.directory ) throw new IOException( "/" + path + ": No such file" );
return Files.newByteChannel( file.path, StandardOpenOption.READ );
}
private Entry getFile( String path )
{
if( path.equals( "" ) ) return rootEntry;
if( !path.contains( "/" ) ) return rootEntry.children.get( path );
String[] components = path.split( "/" );
Entry entry = rootEntry;
for( String component : components )
{
if( entry == null || entry.children == null ) return null;
entry = entry.children.get( component );
}
return entry;
}
private static class Entry
{
final String name;
final Path path;
final boolean directory;
final long size;
final Map<String, Entry> children;
private Entry( String name, Path path ) throws IOException
{
if( name.endsWith( "/" ) || name.endsWith( "\\" ) ) name = name.substring( 0, name.length() - 1 );
this.name = name;
this.path = path;
BasicFileAttributes attributes = Files.readAttributes( path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS );
this.directory = attributes.isDirectory();
this.size = directory ? 0 : attributes.size();
this.children = directory ? new HashMap<>() : null;
}
}
}

View File

@@ -6,242 +6,266 @@
package dan200.computercraft.core.filesystem;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.io.ByteStreams;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.core.apis.handles.ArrayByteChannel;
import dan200.computercraft.shared.util.IoUtil;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@Deprecated
public class JarMount implements IMount
{
private static class FileInZip
{
private String m_path;
private boolean m_directory;
private long m_size;
private Map<String, FileInZip> m_children;
/**
* Only cache files smaller than 1MiB.
*/
private static final int MAX_CACHED_SIZE = 1 << 20;
public FileInZip( String path, boolean directory, long size )
{
m_path = path;
m_directory = directory;
m_size = m_directory ? 0 : size;
m_children = new LinkedHashMap<>();
}
/**
* Limit the entire cache to 64MiB.
*/
private static final int MAX_CACHE_SIZE = 64 << 20;
public String getPath()
{
return m_path;
}
/**
* We maintain a cache of the contents of all files in the mount. This allows us to allow
* seeking within ROM files, and reduces the amount we need to access disk for computer startup.
*/
private static final Cache<FileEntry, byte[]> CONTENTS_CACHE = CacheBuilder.newBuilder()
.concurrencyLevel( 4 )
.expireAfterAccess( 60, TimeUnit.SECONDS )
.maximumWeight( MAX_CACHE_SIZE )
.weakKeys()
.<FileEntry, byte[]>weigher( ( k, v ) -> v.length )
.build();
public boolean isDirectory()
{
return m_directory;
}
/**
* We have a {@link ReferenceQueue} of all mounts, a long with their corresponding {@link ZipFile}. If
* the mount has been destroyed, we clean up after it.
*/
private static final ReferenceQueue<JarMount> MOUNT_QUEUE = new ReferenceQueue<>();
public long getSize()
{
return m_size;
}
private final ZipFile zip;
private final FileEntry root;
public void list( List<String> contents )
{
contents.addAll( m_children.keySet() );
}
public void insertChild( FileInZip child )
{
String localPath = FileSystem.toLocal( child.getPath(), m_path );
m_children.put( localPath, child );
}
public FileInZip getFile( String path )
{
// If we've reached the target, return this
if( path.equals( m_path ) )
{
return this;
}
// Otherwise, get the next component of the path
String localPath = FileSystem.toLocal( path, m_path );
int slash = localPath.indexOf( "/" );
if( slash >= 0 )
{
localPath = localPath.substring( 0, slash );
}
// And recurse down using it
FileInZip subFile = m_children.get( localPath );
if( subFile != null )
{
return subFile.getFile( path );
}
return null;
}
public FileInZip getParent( String path )
{
if( path.length() == 0 )
{
return null;
}
FileInZip file = getFile( FileSystem.getDirectory( path ) );
if( file.isDirectory() )
{
return file;
}
return null;
}
}
private ZipFile m_zipFile;
private FileInZip m_root;
private String m_rootPath;
@Deprecated
public JarMount( File jarFile, String subPath ) throws IOException
{
if( !jarFile.exists() || jarFile.isDirectory() )
{
throw new FileNotFoundException();
}
// Cleanup any old mounts. It's unlikely that there will be any, but it's best to be safe.
cleanup();
if( !jarFile.exists() || jarFile.isDirectory() ) throw new FileNotFoundException();
// Open the zip file
try
{
m_zipFile = new ZipFile( jarFile );
zip = new ZipFile( jarFile );
}
catch( Exception e )
{
throw new IOException( "Error loading zip file" );
}
if( m_zipFile.getEntry( subPath ) == null )
// Ensure the root entry exists.
if( zip.getEntry( subPath ) == null )
{
m_zipFile.close();
zip.close();
throw new IOException( "Zip does not contain path" );
}
// We now create a weak reference to this mount. This is automatically added to the appropriate queue.
new MountReference( this );
// Read in all the entries
Enumeration<? extends ZipEntry> zipEntries = m_zipFile.entries();
root = new FileEntry( "" );
Enumeration<? extends ZipEntry> zipEntries = zip.entries();
while( zipEntries.hasMoreElements() )
{
ZipEntry entry = zipEntries.nextElement();
String entryName = entry.getName();
if( entryName.startsWith( subPath ) )
{
entryName = FileSystem.toLocal( entryName, subPath );
if( m_root == null )
{
if( entryName.equals( "" ) )
{
m_root = new FileInZip( entryName, entry.isDirectory(), entry.getSize() );
m_rootPath = subPath;
if( !m_root.isDirectory() ) break;
}
else
{
// TODO: handle this case. The code currently assumes we find the root before anything else
}
}
else
{
FileInZip parent = m_root.getParent( entryName );
if( parent != null )
{
parent.insertChild( new FileInZip( entryName, entry.isDirectory(), entry.getSize() ) );
}
else
{
// TODO: handle this case. The code currently assumes we find folders before their contents
}
}
}
String entryPath = entry.getName();
if( !entryPath.startsWith( subPath ) ) continue;
String localPath = FileSystem.toLocal( entryPath, subPath );
create( entry, localPath );
}
}
// IMount implementation
private FileEntry get( String path )
{
FileEntry lastEntry = root;
int lastIndex = 0;
while( lastEntry != null && lastIndex < path.length() )
{
int nextIndex = path.indexOf( '/', lastIndex );
if( nextIndex < 0 ) nextIndex = path.length();
lastEntry = lastEntry.children == null ? null : lastEntry.children.get( path.substring( lastIndex, nextIndex ) );
lastIndex = nextIndex + 1;
}
return lastEntry;
}
private void create( ZipEntry entry, String localPath )
{
FileEntry lastEntry = root;
int lastIndex = 0;
while( lastIndex < localPath.length() )
{
int nextIndex = localPath.indexOf( '/', lastIndex );
if( nextIndex < 0 ) nextIndex = localPath.length();
String part = localPath.substring( lastIndex, nextIndex );
if( lastEntry.children == null ) lastEntry.children = new HashMap<>( 0 );
FileEntry nextEntry = lastEntry.children.get( part );
if( nextEntry == null || !nextEntry.isDirectory() )
{
lastEntry.children.put( part, nextEntry = new FileEntry( part ) );
}
lastEntry = nextEntry;
lastIndex = nextIndex + 1;
}
lastEntry.setup( entry );
}
@Override
public boolean exists( @Nonnull String path )
{
FileInZip file = m_root.getFile( path );
return file != null;
return get( path ) != null;
}
@Override
public boolean isDirectory( @Nonnull String path )
{
FileInZip file = m_root.getFile( path );
if( file != null )
{
return file.isDirectory();
}
return false;
FileEntry file = get( path );
return file != null && file.isDirectory();
}
@Override
public void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException
{
FileInZip file = m_root.getFile( path );
if( file != null && file.isDirectory() )
{
file.list( contents );
}
else
{
throw new IOException( "/" + path + ": Not a directory" );
}
FileEntry file = get( path );
if( file == null || !file.isDirectory() ) throw new IOException( "/" + path + ": Not a directory" );
file.list( contents );
}
@Override
public long getSize( @Nonnull String path ) throws IOException
{
FileInZip file = m_root.getFile( path );
if( file != null )
{
return file.getSize();
}
FileEntry file = get( path );
if( file != null ) return file.size;
throw new IOException( "/" + path + ": No such file" );
}
@Nonnull
@Override
@Deprecated
public InputStream openForRead( @Nonnull String path ) throws IOException
{
FileInZip file = m_root.getFile( path );
return Channels.newInputStream( openChannelForRead( path ) );
}
@Nonnull
@Override
public ReadableByteChannel openChannelForRead( @Nonnull String path ) throws IOException
{
FileEntry file = get( path );
if( file != null && !file.isDirectory() )
{
byte[] contents = CONTENTS_CACHE.getIfPresent( file );
if( contents != null ) return new ArrayByteChannel( contents );
try
{
String fullPath = m_rootPath;
if( path.length() > 0 )
{
fullPath = fullPath + "/" + path;
}
ZipEntry entry = m_zipFile.getEntry( fullPath );
ZipEntry entry = zip.getEntry( file.path );
if( entry != null )
{
return m_zipFile.getInputStream( entry );
try( InputStream stream = zip.getInputStream( entry ) )
{
if( stream.available() > MAX_CACHED_SIZE ) return Channels.newChannel( stream );
contents = ByteStreams.toByteArray( stream );
CONTENTS_CACHE.put( file, contents );
return new ArrayByteChannel( contents );
}
}
}
catch( Exception e )
{
// treat errors as non-existance of file
// Treat errors as non-existence of file
}
}
throw new IOException( "/" + path + ": No such file" );
}
private static class FileEntry
{
final String name;
String path;
long size;
Map<String, FileEntry> children;
FileEntry( String name )
{
this.name = name;
}
void setup( ZipEntry entry )
{
path = entry.getName();
size = entry.getSize();
if( children == null && entry.isDirectory() ) children = new HashMap<>( 0 );
}
boolean isDirectory()
{
return children != null;
}
void list( List<String> contents )
{
if( children != null ) contents.addAll( children.keySet() );
}
}
private static class MountReference extends WeakReference<JarMount>
{
final ZipFile file;
MountReference( JarMount file )
{
super( file, MOUNT_QUEUE );
this.file = file.zip;
}
}
private static void cleanup()
{
Reference<? extends JarMount> next;
while( (next = MOUNT_QUEUE.poll()) != null ) IoUtil.closeQuietly( ((MountReference) next).file );
}
}

View File

@@ -29,11 +29,18 @@ public class Terminal
private final Palette m_palette;
private boolean m_changed;
private final Runnable onChanged;
public Terminal( int width, int height )
{
this( width, height, null );
}
public Terminal( int width, int height, Runnable changedCallback )
{
m_width = width;
m_height = height;
this.onChanged = changedCallback;
m_cursorColour = 0;
m_cursorBackgroundColour = 15;
@@ -65,7 +72,7 @@ public class Terminal
m_cursorY = 0;
m_cursorBlink = false;
clear();
m_changed = true;
setChanged();
m_palette.resetColours();
}
@@ -122,7 +129,7 @@ public class Terminal
m_backgroundColour[i].write( oldBackgroundColour[i] );
}
}
m_changed = true;
setChanged();
}
public void setCursorPos( int x, int y )
@@ -131,7 +138,7 @@ public class Terminal
{
m_cursorX = x;
m_cursorY = y;
m_changed = true;
setChanged();
}
}
@@ -140,7 +147,7 @@ public class Terminal
if( m_cursorBlink != blink )
{
m_cursorBlink = blink;
m_changed = true;
setChanged();
}
}
@@ -149,7 +156,7 @@ public class Terminal
if( m_cursorColour != colour )
{
m_cursorColour = colour;
m_changed = true;
setChanged();
}
}
@@ -158,7 +165,7 @@ public class Terminal
if( m_cursorBackgroundColour != colour )
{
m_cursorBackgroundColour = colour;
m_changed = true;
setChanged();
}
}
@@ -201,7 +208,7 @@ public class Terminal
m_text[y].write( text, x );
m_textColour[y].write( textColour, x );
m_backgroundColour[y].write( backgroundColour, x );
m_changed = true;
setChanged();
}
}
@@ -214,7 +221,7 @@ public class Terminal
m_text[y].write( text, x );
m_textColour[y].fill( base16.charAt( m_cursorColour ), x, x + text.length() );
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ), x, x + text.length() );
m_changed = true;
setChanged();
}
}
@@ -244,7 +251,7 @@ public class Terminal
m_text = newText;
m_textColour = newTextColour;
m_backgroundColour = newBackgroundColour;
m_changed = true;
setChanged();
}
}
@@ -256,7 +263,7 @@ public class Terminal
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
}
m_changed = true;
setChanged();
}
public synchronized void clearLine()
@@ -267,7 +274,7 @@ public class Terminal
m_text[y].fill( ' ' );
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
m_changed = true;
setChanged();
}
}
@@ -285,7 +292,7 @@ public class Terminal
m_text[y].write( text );
m_textColour[y].write( textColour );
m_backgroundColour[y].write( backgroundColour );
m_changed = true;
setChanged();
}
public synchronized TextBuffer getTextColourLine( int y )
@@ -306,17 +313,23 @@ public class Terminal
return null;
}
public boolean getChanged()
/**
* @deprecated All {@code *Changed()} methods are deprecated: one should pass in a callback
* instead.
*/
@Deprecated
public final boolean getChanged()
{
return m_changed;
}
public void setChanged()
public final void setChanged()
{
m_changed = true;
if( onChanged != null ) onChanged.run();
}
public void clearChanged()
public final void clearChanged()
{
m_changed = false;
}
@@ -371,6 +384,6 @@ public class Terminal
{
m_palette.readFromNBT( nbt );
}
m_changed = true;
setChanged();
}
}

View File

@@ -1,13 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.server.proxy;
import dan200.computercraft.shared.proxy.CCTurtleProxyCommon;
public class CCTurtleProxyServer extends CCTurtleProxyCommon
{
}

View File

@@ -1,22 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.server.proxy;
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import java.io.File;
public class ComputerCraftProxyServer extends ComputerCraftProxyCommon
{
@Override
public File getWorldDir( World world )
{
return DimensionManager.getWorld( 0 ).getSaveHandler().getWorldDirectory();
}
}

View File

@@ -49,7 +49,7 @@ public final class PocketUpgrades
for( IPocketUpgrade upgrade : upgrades.values() )
{
ItemStack craftingStack = upgrade.getCraftingItem();
if( !craftingStack.isEmpty() && InventoryUtil.areItemsStackable( stack, craftingStack ) )
if( !craftingStack.isEmpty() && InventoryUtil.areItemsSimilar( stack, craftingStack ) )
{
return upgrade;
}
@@ -63,7 +63,7 @@ public final class PocketUpgrades
List<IPocketUpgrade> vanilla = new ArrayList<>();
vanilla.add( ComputerCraft.PocketUpgrades.wirelessModem );
vanilla.add( ComputerCraft.PocketUpgrades.advancedModem );
vanilla.add( ComputerCraft.PocketUpgrades.pocketSpeaker );
vanilla.add( ComputerCraft.PocketUpgrades.speaker );
return vanilla;
}
}

View File

@@ -0,0 +1,432 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.shared.computer.blocks.BlockCommandComputer;
import dan200.computercraft.shared.computer.blocks.BlockComputer;
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.items.ItemCommandComputer;
import dan200.computercraft.shared.computer.items.ItemComputer;
import dan200.computercraft.shared.media.items.ItemDiskExpanded;
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
import dan200.computercraft.shared.media.items.ItemPrintout;
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.common.ItemPeripheral;
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
import dan200.computercraft.shared.peripheral.modem.wired.*;
import dan200.computercraft.shared.peripheral.modem.wireless.BlockAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.ItemAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.TileAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.TileWirelessModem;
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
import dan200.computercraft.shared.peripheral.speaker.TileSpeaker;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory;
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.blocks.TileTurtleAdvanced;
import dan200.computercraft.shared.turtle.blocks.TileTurtleExpanded;
import dan200.computercraft.shared.turtle.items.ItemTurtleAdvanced;
import dan200.computercraft.shared.turtle.items.ItemTurtleLegacy;
import dan200.computercraft.shared.turtle.items.ItemTurtleNormal;
import dan200.computercraft.shared.turtle.items.TurtleItemFactory;
import dan200.computercraft.shared.turtle.upgrades.*;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.ImpostorRecipe;
import dan200.computercraft.shared.util.ImpostorShapelessRecipe;
import net.minecraft.block.Block;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.registries.IForgeRegistry;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID )
public final class Registry
{
private Registry()
{
}
@SubscribeEvent
public static void registerBlocks( RegistryEvent.Register<Block> event )
{
IForgeRegistry<Block> registry = event.getRegistry();
// Computers
ComputerCraft.Blocks.computer = new BlockComputer();
ComputerCraft.Blocks.commandComputer = new BlockCommandComputer();
registry.registerAll(
ComputerCraft.Blocks.computer.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "computer" ) ),
ComputerCraft.Blocks.commandComputer.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "command_computer" ) )
);
// Turtle
ComputerCraft.Blocks.turtle = new BlockTurtle();
ComputerCraft.Blocks.turtleExpanded = new BlockTurtle();
ComputerCraft.Blocks.turtleAdvanced = new BlockTurtle();
registry.registerAll(
ComputerCraft.Blocks.turtle.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) ),
ComputerCraft.Blocks.turtleExpanded.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_expanded" ) ),
ComputerCraft.Blocks.turtleAdvanced.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_advanced" ) )
);
// Peripheral
ComputerCraft.Blocks.peripheral = new BlockPeripheral();
registry.register( ComputerCraft.Blocks.peripheral.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "peripheral" ) ) );
// Cable
ComputerCraft.Blocks.cable = new BlockCable();
registry.register( ComputerCraft.Blocks.cable.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "cable" ) ) );
// Advanced modem
ComputerCraft.Blocks.advancedModem = new BlockAdvancedModem();
registry.register( ComputerCraft.Blocks.advancedModem.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "advanced_modem" ) ) );
// Full block modem
ComputerCraft.Blocks.wiredModemFull = new BlockWiredModemFull();
registry.register( ComputerCraft.Blocks.wiredModemFull.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full" ) ) );
registerTileEntities();
}
private static void registerTileEntities()
{
GameRegistry.registerTileEntity( TileComputer.class, new ResourceLocation( ComputerCraft.MOD_ID, "computer" ) );
GameRegistry.registerTileEntity( TileCommandComputer.class, new ResourceLocation( ComputerCraft.MOD_ID, "command_computer" ) );
GameRegistry.registerTileEntity( TileTurtle.class, new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) );
GameRegistry.registerTileEntity( TileTurtleExpanded.class, new ResourceLocation( ComputerCraft.MOD_ID, "turtleex" ) );
GameRegistry.registerTileEntity( TileTurtleAdvanced.class, new ResourceLocation( ComputerCraft.MOD_ID, "turtleadv" ) );
GameRegistry.registerTileEntity( TileDiskDrive.class, new ResourceLocation( ComputerCraft.MOD_ID, "diskdrive" ) );
GameRegistry.registerTileEntity( TileWirelessModem.class, new ResourceLocation( ComputerCraft.MOD_ID, "wirelessmodem" ) );
GameRegistry.registerTileEntity( TileMonitor.class, new ResourceLocation( ComputerCraft.MOD_ID, "monitor" ) );
GameRegistry.registerTileEntity( TilePrinter.class, new ResourceLocation( ComputerCraft.MOD_ID, "ccprinter" ) );
GameRegistry.registerTileEntity( TileCable.class, new ResourceLocation( ComputerCraft.MOD_ID, "wiredmodem" ) );
GameRegistry.registerTileEntity( TileAdvancedModem.class, new ResourceLocation( ComputerCraft.MOD_ID, "advanced_modem" ) );
GameRegistry.registerTileEntity( TileSpeaker.class, new ResourceLocation( ComputerCraft.MOD_ID, "speaker" ) );
GameRegistry.registerTileEntity( TileWiredModemFull.class, new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full" ) );
}
private static <T extends ItemBlock> T setupItemBlock( T item )
{
item.setRegistryName( item.getBlock().getRegistryName() );
return item;
}
@SubscribeEvent
public static void registerItems( RegistryEvent.Register<Item> event )
{
IForgeRegistry<Item> registry = event.getRegistry();
// Computers
ComputerCraft.Items.computer = new ItemComputer( ComputerCraft.Blocks.computer );
ComputerCraft.Items.commandComputer = new ItemCommandComputer( ComputerCraft.Blocks.commandComputer );
registry.registerAll(
setupItemBlock( ComputerCraft.Items.computer ),
setupItemBlock( ComputerCraft.Items.commandComputer )
);
// Pocket computer
ComputerCraft.Items.pocketComputer = new ItemPocketComputer();
registry.register(
ComputerCraft.Items.pocketComputer.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "pocket_computer" ) )
);
// Turtle
ComputerCraft.Items.turtle = new ItemTurtleLegacy( ComputerCraft.Blocks.turtle );
ComputerCraft.Items.turtleExpanded = new ItemTurtleNormal( ComputerCraft.Blocks.turtleExpanded );
ComputerCraft.Items.turtleAdvanced = new ItemTurtleAdvanced( ComputerCraft.Blocks.turtleAdvanced );
registry.registerAll(
setupItemBlock( ComputerCraft.Items.turtle ),
setupItemBlock( ComputerCraft.Items.turtleExpanded ),
setupItemBlock( ComputerCraft.Items.turtleAdvanced )
);
// Printouts
ComputerCraft.Items.printout = new ItemPrintout();
registry.register( ComputerCraft.Items.printout.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "printout" ) ) );
// Disks
ComputerCraft.Items.disk = new ItemDiskLegacy();
ComputerCraft.Items.diskExpanded = new ItemDiskExpanded();
ComputerCraft.Items.treasureDisk = new ItemTreasureDisk();
registry.registerAll(
ComputerCraft.Items.disk.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "disk" ) ),
ComputerCraft.Items.diskExpanded.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "disk_expanded" ) ),
ComputerCraft.Items.treasureDisk.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "treasure_disk" ) )
);
// Peripherals
ComputerCraft.Items.peripheral = new ItemPeripheral( ComputerCraft.Blocks.peripheral );
ComputerCraft.Items.advancedModem = new ItemAdvancedModem( ComputerCraft.Blocks.advancedModem );
ComputerCraft.Items.cable = new ItemCable( ComputerCraft.Blocks.cable );
ComputerCraft.Items.wiredModemFull = new ItemWiredModemFull( ComputerCraft.Blocks.wiredModemFull );
registry.registerAll(
setupItemBlock( ComputerCraft.Items.peripheral ),
setupItemBlock( ComputerCraft.Items.advancedModem ),
setupItemBlock( ComputerCraft.Items.cable ),
setupItemBlock( ComputerCraft.Items.wiredModemFull )
);
registerTurtleUpgrades();
registerPocketUpgrades();
registerLegacyUpgrades();
}
@SubscribeEvent
public static void registerRecipes( RegistryEvent.Register<IRecipe> event )
{
IForgeRegistry<IRecipe> registry = event.getRegistry();
// Register fake recipes for the recipe book and JEI. We have several dynamic recipes,
// and we'd like people to be able to see them.
// Turtle upgrades
// TODO: Figure out a way to do this in a "nice" way.
for( ITurtleUpgrade upgrade : TurtleUpgrades.getVanillaUpgrades() )
{
ItemStack craftingItem = upgrade.getCraftingItem();
// A turtle just containing this upgrade
for( ComputerFamily family : ComputerFamily.values() )
{
if( !TurtleUpgrades.suitableForFamily( family, upgrade ) ) continue;
ItemStack baseTurtle = TurtleItemFactory.create( -1, null, -1, family, null, null, 0, null );
if( !baseTurtle.isEmpty() )
{
ItemStack craftedTurtle = TurtleItemFactory.create( -1, null, -1, family, upgrade, null, 0, null );
ItemStack craftedTurtleFlipped = TurtleItemFactory.create( -1, null, -1, family, null, upgrade, 0, null );
registry.register(
new ImpostorRecipe( "computercraft:" + family.toString() + "_turtle_upgrade", 2, 1, new ItemStack[] { baseTurtle, craftingItem }, craftedTurtle )
.setRegistryName( new ResourceLocation( "computercraft:" + family + "_turtle_upgrade_" + upgrade.getUpgradeID().toString().replace( ':', '_' ) + "_1" ) )
);
registry.register(
new ImpostorRecipe( "computercraft:" + family.toString() + "_turtle_upgrade", 2, 1, new ItemStack[] { craftingItem, baseTurtle }, craftedTurtleFlipped )
.setRegistryName( new ResourceLocation( "computercraft:" + family + "_turtle_upgrade_" + upgrade.getUpgradeID().toString().replace( ':', '_' ) + "_2" ) )
);
}
}
}
// Coloured disks
ItemStack paper = new ItemStack( Items.PAPER, 1 );
ItemStack redstone = new ItemStack( Items.REDSTONE, 1 );
for( int colour = 0; colour < 16; colour++ )
{
ItemStack disk = ItemDiskLegacy.createFromIDAndColour( -1, null, Colour.values()[colour].getHex() );
ItemStack dye = new ItemStack( Items.DYE, 1, colour );
int diskIdx = 0;
ItemStack[] disks = new ItemStack[15];
for( int otherColour = 0; otherColour < 16; otherColour++ )
{
if( colour != otherColour )
{
disks[diskIdx++] = ItemDiskLegacy.createFromIDAndColour( -1, null, Colour.values()[otherColour].getHex() );
}
}
// Normal recipe
registry.register(
new ImpostorShapelessRecipe( "computercraft:disk", disk, new ItemStack[] { redstone, paper, dye } )
.setRegistryName( new ResourceLocation( "computercraft:disk_imposter_" + colour ) )
);
// Conversion recipe
registry.register(
new ImpostorShapelessRecipe( "computercraft:disk", disk, NonNullList.from( Ingredient.EMPTY, Ingredient.fromStacks( disks ), Ingredient.fromStacks( dye ) ) )
.setRegistryName( new ResourceLocation( "computercraft:disk_imposter_convert_" + colour ) )
);
}
// Pocket computer upgrades
ItemStack pocketComputer = PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.Normal, null );
ItemStack advancedPocketComputer = PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.Advanced, null );
for( IPocketUpgrade upgrade : PocketUpgrades.getVanillaUpgrades() )
{
registry.register( new ImpostorRecipe(
"computercraft:normal_pocket_upgrade",
1, 2,
new ItemStack[] { upgrade.getCraftingItem(), pocketComputer },
PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.Normal, upgrade )
).setRegistryName( new ResourceLocation( "computercraft:normal_pocket_upgrade_" + upgrade.getUpgradeID().toString().replace( ':', '_' ) ) )
);
registry.register(
new ImpostorRecipe( "computercraft:advanced_pocket_upgrade",
1, 2,
new ItemStack[] { upgrade.getCraftingItem(), advancedPocketComputer },
PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.Advanced, upgrade )
).setRegistryName( new ResourceLocation( "computercraft:advanced_pocket_upgrade_" + upgrade.getUpgradeID().toString().replace( ':', '_' ) ) )
);
}
}
public static void registerTurtleUpgrades()
{
// Upgrades
ComputerCraft.TurtleUpgrades.wirelessModem = new TurtleModem( false, new ResourceLocation( "computercraft", "wireless_modem" ), 1 );
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.wirelessModem );
ComputerCraft.TurtleUpgrades.advancedModem = new TurtleModem( true, new ResourceLocation( "computercraft", "advanced_modem" ), -1 );
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.advancedModem );
ComputerCraft.TurtleUpgrades.speaker = new TurtleSpeaker( new ResourceLocation( "computercraft", "speaker" ), 8 );
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.speaker );
ComputerCraft.TurtleUpgrades.craftingTable = new TurtleCraftingTable( new ResourceLocation( "minecraft", "crafting_table" ), 2 );
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.craftingTable );
ComputerCraft.TurtleUpgrades.diamondSword = new TurtleSword( new ResourceLocation( "minecraft", "diamond_sword" ), 3, Items.DIAMOND_SWORD );
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.diamondSword );
ComputerCraft.TurtleUpgrades.diamondShovel = new TurtleShovel( new ResourceLocation( "minecraft", "diamond_shovel" ), 4, Items.DIAMOND_SHOVEL );
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.diamondShovel );
ComputerCraft.TurtleUpgrades.diamondPickaxe = new TurtleTool( new ResourceLocation( "minecraft", "diamond_pickaxe" ), 5, Items.DIAMOND_PICKAXE );
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.diamondPickaxe );
ComputerCraft.TurtleUpgrades.diamondAxe = new TurtleAxe( new ResourceLocation( "minecraft", "diamond_axe" ), 6, Items.DIAMOND_AXE );
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.diamondAxe );
ComputerCraft.TurtleUpgrades.diamondHoe = new TurtleHoe( new ResourceLocation( "minecraft", "diamond_hoe" ), 7, Items.DIAMOND_HOE );
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.diamondHoe );
}
public static void registerPocketUpgrades()
{
// Register pocket upgrades
ComputerCraft.PocketUpgrades.wirelessModem = new PocketModem( false );
ComputerCraftAPI.registerPocketUpgrade( ComputerCraft.PocketUpgrades.wirelessModem );
ComputerCraft.PocketUpgrades.advancedModem = new PocketModem( true );
ComputerCraftAPI.registerPocketUpgrade( ComputerCraft.PocketUpgrades.advancedModem );
ComputerCraft.PocketUpgrades.speaker = new PocketSpeaker();
ComputerCraftAPI.registerPocketUpgrade( ComputerCraft.PocketUpgrades.speaker );
}
@SuppressWarnings( "deprecation" )
private static void registerLegacyUpgrades()
{
ComputerCraft.PocketUpgrades.pocketSpeaker = ComputerCraft.PocketUpgrades.speaker;
ComputerCraft.Upgrades.advancedModem = ComputerCraft.TurtleUpgrades.advancedModem;
}
@SubscribeEvent
public static void remapItems( RegistryEvent.MissingMappings<Item> mappings )
{
// We have to use mappings.getAllMappings() as the mod ID is upper case but the domain lower.
for( RegistryEvent.MissingMappings.Mapping<Item> mapping : mappings.getAllMappings() )
{
String domain = mapping.key.getNamespace();
if( !domain.equalsIgnoreCase( ComputerCraft.MOD_ID ) ) continue;
String key = mapping.key.getPath();
if( key.equalsIgnoreCase( "CC-Computer" ) )
{
mapping.remap( ComputerCraft.Items.computer );
}
else if( key.equalsIgnoreCase( "CC-Peripheral" ) )
{
mapping.remap( ComputerCraft.Items.peripheral );
}
else if( key.equalsIgnoreCase( "CC-Cable" ) )
{
mapping.remap( ComputerCraft.Items.cable );
}
else if( key.equalsIgnoreCase( "diskExpanded" ) )
{
mapping.remap( ComputerCraft.Items.diskExpanded );
}
else if( key.equalsIgnoreCase( "treasureDisk" ) )
{
mapping.remap( ComputerCraft.Items.treasureDisk );
}
else if( key.equalsIgnoreCase( "pocketComputer" ) )
{
mapping.remap( ComputerCraft.Items.pocketComputer );
}
else if( key.equalsIgnoreCase( "CC-Turtle" ) )
{
mapping.remap( ComputerCraft.Items.turtle );
}
else if( key.equalsIgnoreCase( "CC-TurtleExpanded" ) )
{
mapping.remap( ComputerCraft.Items.turtleExpanded );
}
else if( key.equalsIgnoreCase( "CC-TurtleAdvanced" ) )
{
mapping.remap( ComputerCraft.Items.turtleAdvanced );
}
}
}
@SubscribeEvent
public static void remapBlocks( RegistryEvent.MissingMappings<Block> mappings )
{
// We have to use mappings.getAllMappings() as the mod ID is upper case but the domain lower.
for( RegistryEvent.MissingMappings.Mapping<Block> mapping : mappings.getAllMappings() )
{
String domain = mapping.key.getNamespace();
if( !domain.equalsIgnoreCase( ComputerCraft.MOD_ID ) ) continue;
String key = mapping.key.getPath();
if( key.equalsIgnoreCase( "CC-Computer" ) )
{
mapping.remap( ComputerCraft.Blocks.computer );
}
else if( key.equalsIgnoreCase( "CC-Peripheral" ) )
{
mapping.remap( ComputerCraft.Blocks.peripheral );
}
else if( key.equalsIgnoreCase( "CC-Cable" ) )
{
mapping.remap( ComputerCraft.Blocks.cable );
}
else if( key.equalsIgnoreCase( "CC-Turtle" ) )
{
mapping.remap( ComputerCraft.Blocks.turtle );
}
else if( key.equalsIgnoreCase( "CC-TurtleExpanded" ) )
{
mapping.remap( ComputerCraft.Blocks.turtleExpanded );
}
else if( key.equalsIgnoreCase( "CC-TurtleAdvanced" ) )
{
mapping.remap( ComputerCraft.Blocks.turtleAdvanced );
}
}
}
}

View File

@@ -7,20 +7,29 @@
package dan200.computercraft.shared;
import com.google.common.base.Preconditions;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.permissions.ITurtlePermissionProvider;
import dan200.computercraft.api.turtle.event.TurtleActionEvent;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.LinkedHashSet;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID )
public final class TurtlePermissions
{
private static final Collection<ITurtlePermissionProvider> providers = new LinkedHashSet<>();
private TurtlePermissions()
{
}
public static void register( @Nonnull ITurtlePermissionProvider upgrade )
{
Preconditions.checkNotNull( upgrade, "upgrade cannot be null" );
@@ -57,4 +66,13 @@ public final class TurtlePermissions
}
return true;
}
@SubscribeEvent
public static void onTurtleAction( TurtleActionEvent event )
{
if( ComputerCraft.turtleDisabledActions.contains( event.getAction() ) )
{
event.setCanceled( true, "Action has been disabled" );
}
}
}

View File

@@ -101,7 +101,7 @@ public final class TurtleUpgrades
for( ITurtleUpgrade upgrade : upgrades.values() )
{
ItemStack craftingStack = upgrade.getCraftingItem();
if( !craftingStack.isEmpty() && InventoryUtil.areItemsStackable( stack, craftingStack ) )
if( !craftingStack.isEmpty() && InventoryUtil.areItemsSimilar( stack, craftingStack ) )
{
return upgrade;
}
@@ -113,15 +113,15 @@ public final class TurtleUpgrades
public static Iterable<ITurtleUpgrade> getVanillaUpgrades()
{
List<ITurtleUpgrade> vanilla = new ArrayList<>();
vanilla.add( ComputerCraft.Upgrades.diamondPickaxe );
vanilla.add( ComputerCraft.Upgrades.diamondAxe );
vanilla.add( ComputerCraft.Upgrades.diamondSword );
vanilla.add( ComputerCraft.Upgrades.diamondShovel );
vanilla.add( ComputerCraft.Upgrades.diamondHoe );
vanilla.add( ComputerCraft.Upgrades.craftingTable );
vanilla.add( ComputerCraft.Upgrades.wirelessModem );
vanilla.add( ComputerCraft.Upgrades.advancedModem );
vanilla.add( ComputerCraft.Upgrades.turtleSpeaker );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondPickaxe );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondAxe );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondSword );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondShovel );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondHoe );
vanilla.add( ComputerCraft.TurtleUpgrades.craftingTable );
vanilla.add( ComputerCraft.TurtleUpgrades.wirelessModem );
vanilla.add( ComputerCraft.TurtleUpgrades.advancedModem );
vanilla.add( ComputerCraft.TurtleUpgrades.speaker );
return vanilla;
}

View File

@@ -24,7 +24,11 @@ import javax.annotation.Nonnull;
public class CommandCopy extends CommandBase implements IClientCommand
{
public static final CommandCopy INSTANCE = new CommandCopy();
private static final String NAME = "computercraft_copy";
/**
* We start with a "~" so we're less likely to show up on completions.
*/
private static final String NAME = "~computercraft_copy";
private CommandCopy()
{
@@ -47,7 +51,7 @@ public class CommandCopy extends CommandBase implements IClientCommand
@Override
public String getUsage( @Nonnull ICommandSender sender )
{
return "computercraft_copy <text>";
return "/" + NAME + " <text>";
}
@Override

View File

@@ -6,8 +6,8 @@
package dan200.computercraft.shared.command.text;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.command.CommandUtils;
import dan200.computercraft.shared.network.NetworkHandler;
import dan200.computercraft.shared.network.client.ChatTableClientMessage;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayerMP;
@@ -120,7 +120,7 @@ public class TableBuilder
if( CommandUtils.isPlayer( source ) )
{
trim( 18 );
ComputerCraft.sendToPlayer( (EntityPlayerMP) source, new ChatTableClientMessage( this ) );
NetworkHandler.sendToPlayer( (EntityPlayerMP) source, new ChatTableClientMessage( this ) );
}
else
{

View File

@@ -10,7 +10,6 @@ import net.minecraft.block.Block;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@@ -22,6 +21,7 @@ import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.util.Random;
public abstract class BlockGeneric extends Block implements ITileEntityProvider
{
@@ -31,8 +31,6 @@ public abstract class BlockGeneric extends Block implements ITileEntityProvider
this.hasTileEntity = true;
}
protected abstract IBlockState getDefaultBlockState( int damage, EnumFacing placedSide );
protected abstract TileGeneric createTile( IBlockState state );
protected abstract TileGeneric createTile( int damage );
@@ -53,14 +51,6 @@ public abstract class BlockGeneric extends Block implements ITileEntityProvider
}
}
@Nonnull
@Override
@Deprecated
public final IBlockState getStateForPlacement( World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, int damage, EntityLivingBase placer )
{
return getDefaultBlockState( damage, side );
}
@Override
public boolean removedByPlayer( @Nonnull IBlockState state, World world, @Nonnull BlockPos pos, @Nonnull EntityPlayer player, boolean willHarvest )
{
@@ -149,6 +139,13 @@ public abstract class BlockGeneric extends Block implements ITileEntityProvider
}
}
@Override
public void updateTick( World world, BlockPos pos, IBlockState state, Random rand )
{
TileEntity te = world.getTileEntity( pos );
if( te instanceof TileGeneric ) ((TileGeneric) te).updateTick();
}
@Override
@Deprecated
public final boolean canProvidePower( IBlockState state )

View File

@@ -22,19 +22,14 @@ public class ClientTerminal implements ITerminal
m_terminalChanged = false;
}
public void update()
{
if( m_terminal != null )
{
m_terminalChanged |= m_terminal.getChanged();
m_terminal.clearChanged();
}
}
public boolean pollTerminalChanged()
{
boolean changed = m_terminalChanged;
m_terminalChanged = false;
Terminal terminal = m_terminal;
if( terminal != null ) terminal.clearChanged();
return changed;
}
@@ -71,7 +66,7 @@ public class ClientTerminal implements ITerminal
{
if( m_terminal == null )
{
m_terminal = new Terminal( width, height );
m_terminal = new Terminal( width, height, () -> m_terminalChanged = true );
m_terminalChanged = true;
}
else

View File

@@ -9,35 +9,33 @@ package dan200.computercraft.shared.common;
import dan200.computercraft.core.terminal.Terminal;
import net.minecraft.nbt.NBTTagCompound;
import java.util.concurrent.atomic.AtomicBoolean;
public class ServerTerminal implements ITerminal
{
private final boolean m_colour;
private Terminal m_terminal;
private boolean m_terminalChanged;
private boolean m_terminalChangedLastFrame;
private final AtomicBoolean m_terminalChanged = new AtomicBoolean( false );
private boolean m_terminalChangedLastFrame = false;
public ServerTerminal( boolean colour )
{
m_colour = colour;
m_terminal = null;
m_terminalChanged = false;
m_terminalChangedLastFrame = false;
}
public ServerTerminal( boolean colour, int terminalWidth, int terminalHeight )
{
m_colour = colour;
m_terminal = new Terminal( terminalWidth, terminalHeight );
m_terminalChanged = false;
m_terminalChangedLastFrame = false;
m_terminal = new Terminal( terminalWidth, terminalHeight, this::markTerminalChanged );
}
public void resize( int width, int height )
protected void resize( int width, int height )
{
if( m_terminal == null )
{
m_terminal = new Terminal( width, height );
m_terminalChanged = true;
m_terminal = new Terminal( width, height, this::markTerminalChanged );
markTerminalChanged();
}
else
{
@@ -50,23 +48,21 @@ public class ServerTerminal implements ITerminal
if( m_terminal != null )
{
m_terminal = null;
m_terminalChanged = true;
markTerminalChanged();
}
}
protected void markTerminalChanged()
{
m_terminalChanged = true;
m_terminalChanged.set( true );
}
public void update()
{
m_terminalChangedLastFrame = m_terminalChanged || (m_terminal != null && m_terminal.getChanged());
if( m_terminal != null )
{
m_terminal.clearChanged();
}
m_terminalChanged = false;
Terminal terminal = m_terminal;
if( terminal != null ) terminal.clearChanged();
m_terminalChangedLastFrame = m_terminalChanged.getAndSet( false );
}
public boolean hasTerminalChanged()

View File

@@ -72,6 +72,10 @@ public abstract class TileGeneric extends TileEntity
{
}
protected void updateTick()
{
}
public boolean getRedstoneConnectivity( EnumFacing side )
{
return false;

View File

@@ -8,19 +8,15 @@ package dan200.computercraft.shared.computer.blocks;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.util.DirectionUtil;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
@@ -87,14 +83,7 @@ public class BlockCommandComputer extends BlockComputerBase
@Override
protected IBlockState getDefaultBlockState( ComputerFamily family, EnumFacing placedSide )
{
if( placedSide.getAxis() != EnumFacing.Axis.Y )
{
return getDefaultState().withProperty( Properties.FACING, placedSide );
}
else
{
return getDefaultState();
}
return getDefaultState().withProperty( Properties.FACING, placedSide );
}
@Override
@@ -114,20 +103,4 @@ public class BlockCommandComputer extends BlockComputerBase
{
return new TileCommandComputer();
}
@Override
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase player, @Nonnull ItemStack itemstack )
{
// Not sure why this is necessary
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TileCommandComputer )
{
tile.setWorld( world ); // Not sure why this is necessary
tile.setPos( pos ); // Not sure why this is necessary
}
// Set direction
EnumFacing dir = DirectionUtil.fromEntityRot( player );
setDirection( world, pos, dir );
}
}

View File

@@ -9,17 +9,13 @@ package dan200.computercraft.shared.computer.blocks;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.items.ComputerItemFactory;
import dan200.computercraft.shared.computer.items.ItemComputer;
import dan200.computercraft.shared.util.DirectionUtil;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
@@ -99,24 +95,9 @@ public class BlockComputer extends BlockComputerBase
@Override
protected IBlockState getDefaultBlockState( ComputerFamily family, EnumFacing placedSide )
{
IBlockState state = getDefaultState();
if( placedSide.getAxis() != EnumFacing.Axis.Y )
{
state = state.withProperty( Properties.FACING, placedSide );
}
switch( family )
{
case Normal:
default:
{
return state.withProperty( Properties.ADVANCED, false );
}
case Advanced:
{
return state.withProperty( Properties.ADVANCED, true );
}
}
return getDefaultState()
.withProperty( Properties.FACING, placedSide )
.withProperty( Properties.ADVANCED, family == ComputerFamily.Advanced );
}
@Nonnull
@@ -131,7 +112,7 @@ public class BlockComputer extends BlockComputerBase
@Override
public ComputerFamily getFamily( int damage )
{
return ((ItemComputer) Item.getItemFromBlock( this )).getFamily( damage );
return ComputerCraft.Items.computer.getFamily( damage );
}
@Override
@@ -153,22 +134,6 @@ public class BlockComputer extends BlockComputerBase
return new TileComputer();
}
@Override
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase player, @Nonnull ItemStack stack )
{
// Not sure why this is necessary
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TileComputer )
{
tile.setWorld( world ); // Not sure why this is necessary
tile.setPos( pos ); // Not sure why this is necessary
}
// Set direction
EnumFacing dir = DirectionUtil.fromEntityRot( player );
setDirection( world, pos, dir );
}
@Nonnull
@Override
public ItemStack getPickBlock( @Nonnull IBlockState state, RayTraceResult target, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player )

View File

@@ -8,16 +8,18 @@ package dan200.computercraft.shared.computer.blocks;
import dan200.computercraft.shared.common.BlockDirectional;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.items.ItemComputerBase;
import dan200.computercraft.shared.util.DirectionUtil;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.Item;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
public abstract class BlockComputerBase extends BlockDirectional
{
public BlockComputerBase( Material material )
@@ -47,11 +49,12 @@ public abstract class BlockComputerBase extends BlockDirectional
protected abstract TileComputerBase createTile( ComputerFamily family );
@Nonnull
@Override
protected final IBlockState getDefaultBlockState( int damage, EnumFacing placedSide )
@Deprecated
public final IBlockState getStateForPlacement( World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, int damage, EntityLivingBase placer )
{
ItemComputerBase item = (ItemComputerBase) Item.getItemFromBlock( this );
return getDefaultBlockState( item.getFamily( damage ), placedSide );
return getDefaultBlockState( getFamily( damage ), DirectionUtil.fromEntityRot( placer ) );
}
@Override

View File

@@ -7,9 +7,9 @@
package dan200.computercraft.shared.computer.core;
import com.google.common.base.Objects;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.common.ClientTerminal;
import dan200.computercraft.shared.computer.blocks.ComputerState;
import dan200.computercraft.shared.network.NetworkHandler;
import dan200.computercraft.shared.network.server.ComputerActionServerMessage;
import dan200.computercraft.shared.network.server.QueueEventServerMessage;
import dan200.computercraft.shared.network.server.RequestComputerMessage;
@@ -32,10 +32,8 @@ public class ClientComputer extends ClientTerminal implements IComputer
m_instanceID = instanceID;
}
@Override
public void update()
{
super.update();
m_changedLastFrame = m_changed;
m_changed = false;
}
@@ -53,7 +51,7 @@ public class ClientComputer extends ClientTerminal implements IComputer
public void requestState()
{
// Request state from server
ComputerCraft.sendToServer( new RequestComputerMessage( getInstanceID() ) );
NetworkHandler.sendToServer( new RequestComputerMessage( getInstanceID() ) );
}
// IComputer
@@ -94,28 +92,28 @@ public class ClientComputer extends ClientTerminal implements IComputer
public void turnOn()
{
// Send turnOn to server
ComputerCraft.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.TURN_ON ) );
NetworkHandler.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.TURN_ON ) );
}
@Override
public void shutdown()
{
// Send shutdown to server
ComputerCraft.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.SHUTDOWN ) );
NetworkHandler.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.SHUTDOWN ) );
}
@Override
public void reboot()
{
// Send reboot to server
ComputerCraft.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.REBOOT ) );
NetworkHandler.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.REBOOT ) );
}
@Override
public void queueEvent( String event, Object[] arguments )
{
// Send event to server
ComputerCraft.sendToServer( new QueueEventServerMessage( m_instanceID, event, arguments ) );
NetworkHandler.sendToServer( new QueueEventServerMessage( m_instanceID, event, arguments ) );
}
public void setState( ComputerState state, NBTTagCompound userData )

View File

@@ -16,6 +16,7 @@ import dan200.computercraft.core.apis.IAPIEnvironment;
import dan200.computercraft.core.computer.Computer;
import dan200.computercraft.core.computer.IComputerEnvironment;
import dan200.computercraft.shared.common.ServerTerminal;
import dan200.computercraft.shared.network.NetworkHandler;
import dan200.computercraft.shared.network.client.ComputerDataClientMessage;
import dan200.computercraft.shared.network.client.ComputerDeletedClientMessage;
import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage;
@@ -163,7 +164,7 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
if( hasOutputChanged() || force )
{
// Send computer state to all clients
ComputerCraft.sendToAllPlayers( createComputerPacket() );
NetworkHandler.sendToAllPlayers( createComputerPacket() );
}
if( hasTerminalChanged() || force )
@@ -178,7 +179,7 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
{
if( isInteracting( player ) )
{
ComputerCraft.sendToPlayer( player, packet );
NetworkHandler.sendToPlayer( player, packet );
}
}
}
@@ -188,19 +189,19 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
public void sendComputerState( EntityPlayer player )
{
// Send state to client
ComputerCraft.sendToPlayer( player, createComputerPacket() );
NetworkHandler.sendToPlayer( player, createComputerPacket() );
}
public void sendTerminalState( EntityPlayer player )
{
// Send terminal state to client
ComputerCraft.sendToPlayer( player, createTerminalPacket() );
NetworkHandler.sendToPlayer( player, createTerminalPacket() );
}
public void broadcastDelete()
{
// Send deletion to client
ComputerCraft.sendToAllPlayers( new ComputerDeletedClientMessage( getInstanceID() ) );
NetworkHandler.sendToAllPlayers( new ComputerDeletedClientMessage( getInstanceID() ) );
}
public IWritableMount getRootMount()

View File

@@ -9,7 +9,6 @@ package dan200.computercraft.shared.computer.items;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
@@ -31,15 +30,9 @@ public class ComputerItemFactory
{
case Normal:
case Advanced:
{
ItemComputer computer = ((ItemComputer) Item.getItemFromBlock( ComputerCraft.Blocks.computer ));
return computer.create( id, label, family );
}
return ComputerCraft.Items.computer.create( id, label, family );
case Command:
{
ItemCommandComputer commandComputer = ((ItemCommandComputer) Item.getItemFromBlock( ComputerCraft.Blocks.commandComputer ));
return commandComputer.create( id, label, family );
}
return ComputerCraft.Items.commandComputer.create( id, label, family );
default:
return ItemStack.EMPTY;
}

View File

@@ -22,9 +22,9 @@ public class JEIComputerCraft implements IModPlugin
@Override
public void registerItemSubtypes( ISubtypeRegistry subtypeRegistry )
{
subtypeRegistry.registerSubtypeInterpreter( Item.getItemFromBlock( ComputerCraft.Blocks.turtle ), turtleSubtype );
subtypeRegistry.registerSubtypeInterpreter( Item.getItemFromBlock( ComputerCraft.Blocks.turtleExpanded ), turtleSubtype );
subtypeRegistry.registerSubtypeInterpreter( Item.getItemFromBlock( ComputerCraft.Blocks.turtleAdvanced ), turtleSubtype );
subtypeRegistry.registerSubtypeInterpreter( ComputerCraft.Items.turtle, turtleSubtype );
subtypeRegistry.registerSubtypeInterpreter( ComputerCraft.Items.turtleExpanded, turtleSubtype );
subtypeRegistry.registerSubtypeInterpreter( ComputerCraft.Items.turtleAdvanced, turtleSubtype );
subtypeRegistry.registerSubtypeInterpreter( ComputerCraft.Items.pocketComputer, pocketSubtype );

View File

@@ -0,0 +1,106 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.network;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.network.client.*;
import dan200.computercraft.shared.network.server.ComputerActionServerMessage;
import dan200.computercraft.shared.network.server.QueueEventServerMessage;
import dan200.computercraft.shared.network.server.RequestComputerMessage;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.IThreadListener;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.relauncher.Side;
import java.util.function.Supplier;
public final class NetworkHandler
{
public static SimpleNetworkWrapper network;
private NetworkHandler()
{
}
private static final int COMPUTER_ACTION_SERVER_MESSAGE = 0;
private static final int QUEUE_EVENT_SERVER_MESSAGE = 1;
private static final int REQUEST_COMPUTER_SERVER_MESSAGE = 2;
private static final int CHAT_TABLE_CLIENT_MESSAGE = 10;
private static final int COMPUTER_DATA_CLIENT_MESSAGE = 11;
private static final int COMPUTER_DELETED_CLIENT_MESSAGE = 12;
private static final int COMPUTER_TERMINAL_CLIENT_MESSAGE = 13;
private static final int PLAY_RECORD_CLIENT_MESSAGE = 14;
public static void setup()
{
network = NetworkRegistry.INSTANCE.newSimpleChannel( ComputerCraft.MOD_ID );
// Server messages
registerMainThread( NetworkHandler.COMPUTER_ACTION_SERVER_MESSAGE, Side.SERVER, ComputerActionServerMessage::new );
registerMainThread( NetworkHandler.QUEUE_EVENT_SERVER_MESSAGE, Side.SERVER, QueueEventServerMessage::new );
registerMainThread( NetworkHandler.REQUEST_COMPUTER_SERVER_MESSAGE, Side.SERVER, RequestComputerMessage::new );
// Client messages
registerMainThread( NetworkHandler.PLAY_RECORD_CLIENT_MESSAGE, Side.CLIENT, PlayRecordClientMessage::new );
registerMainThread( NetworkHandler.COMPUTER_DATA_CLIENT_MESSAGE, Side.CLIENT, ComputerDataClientMessage::new );
registerMainThread( NetworkHandler.COMPUTER_TERMINAL_CLIENT_MESSAGE, Side.CLIENT, ComputerTerminalClientMessage::new );
registerMainThread( NetworkHandler.COMPUTER_DELETED_CLIENT_MESSAGE, Side.CLIENT, ComputerDeletedClientMessage::new );
registerMainThread( NetworkHandler.CHAT_TABLE_CLIENT_MESSAGE, Side.CLIENT, ChatTableClientMessage::new );
}
public static void sendToPlayer( EntityPlayer player, IMessage packet )
{
network.sendTo( packet, (EntityPlayerMP) player );
}
public static void sendToAllPlayers( IMessage packet )
{
network.sendToAll( packet );
}
public static void sendToServer( IMessage packet )
{
network.sendToServer( packet );
}
public static void sendToAllAround( IMessage packet, NetworkRegistry.TargetPoint point )
{
network.sendToAllAround( packet, point );
}
/**
* /**
* Register packet, and a thread-unsafe handler for it.
*
* @param id The identifier for this packet type
* @param side The side to register this packet handler under
* @param factory The factory for this type of packet.
*/
private static <T extends NetworkMessage> void registerMainThread( int id, Side side, Supplier<T> factory )
{
network.registerMessage( MAIN_THREAD_HANDLER, factory.get().getClass(), id, side );
}
private static final IMessageHandler<NetworkMessage, IMessage> MAIN_THREAD_HANDLER = ( packet, context ) -> {
IThreadListener listener = context.side == Side.CLIENT ? Minecraft.getMinecraft() : context.getServerHandler().player.server;
if( listener.isCallingFromMinecraftThread() )
{
packet.handle( context );
}
else
{
listener.addScheduledTask( () -> packet.handle( context ) );
}
return null;
};
}

View File

@@ -6,18 +6,12 @@
package dan200.computercraft.shared.network;
import dan200.computercraft.ComputerCraft;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.IThreadListener;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import javax.annotation.Nonnull;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
/**
* The base interface for any message which will be sent to the client or server.
@@ -27,13 +21,6 @@ import java.util.function.Supplier;
*/
public interface NetworkMessage extends IMessage
{
/**
* The unique identifier for this packet type
*
* @return This packet type's identifier
*/
int getId();
/**
* Write this packet to a buffer.
*
@@ -52,6 +39,13 @@ public interface NetworkMessage extends IMessage
*/
void fromBytes( @Nonnull PacketBuffer buf );
/**
* Handle this {@link NetworkMessage}.
*
* @param context The context with which to handle this message
*/
void handle( MessageContext context );
@Override
default void fromBytes( ByteBuf buf )
{
@@ -63,56 +57,4 @@ public interface NetworkMessage extends IMessage
{
toBytes( new PacketBuffer( buf ) );
}
/**
* Register a packet, and a thread-safe handler for it.
*
* @param side The side to register this packet handler under
* @param factory The factory for this type of packet.
* @param handler The handler for this type of packet. Note, this may be called on any thread,
* and so should be thread-safe.
*/
@SuppressWarnings( "unchecked" )
static <T extends NetworkMessage> void register(
Side side,
Supplier<T> factory,
BiConsumer<MessageContext, T> handler
)
{
T instance = factory.get();
ComputerCraft.networkWrapper.registerMessage( ( packet, ctx ) -> {
handler.accept( ctx, (T) packet );
return null;
}, instance.getClass(), instance.getId(), side );
}
/**
* Register packet, and a thread-unsafe handler for it.
*
* @param side The side to register this packet handler under
* @param factory The factory for this type of packet.
* @param handler The handler for this type of packet. This will be called on the "main"
* thread (either client or server).
*/
@SuppressWarnings( "unchecked" )
static <T extends NetworkMessage> void registerMainThread(
Side side,
Supplier<T> factory,
BiConsumer<MessageContext, T> handler
)
{
T instance = factory.get();
ComputerCraft.networkWrapper.registerMessage( ( packet, ctx ) -> {
IThreadListener listener = side == Side.CLIENT ? Minecraft.getMinecraft() : ctx.getServerHandler().player.server;
if( listener.isCallingFromMinecraftThread() )
{
handler.accept( ctx, (T) packet );
}
else
{
listener.addScheduledTask( () -> handler.accept( ctx, (T) packet ) );
}
return null;
}, instance.getClass(), instance.getId(), side );
}
}

View File

@@ -1,24 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.network;
public final class NetworkMessages
{
private NetworkMessages()
{
}
public static final int COMPUTER_ACTION_SERVER_MESSAGE = 0;
public static final int QUEUE_EVENT_SERVER_MESSAGE = 1;
public static final int REQUEST_COMPUTER_SERVER_MESSAGE = 2;
public static final int CHAT_TABLE_CLIENT_MESSAGE = 10;
public static final int COMPUTER_DATA_CLIENT_MESSAGE = 11;
public static final int COMPUTER_DELETED_CLIENT_MESSAGE = 12;
public static final int COMPUTER_TERMINAL_CLIENT_MESSAGE = 13;
public static final int PLAY_RECORD_CLIENT_MESSAGE = 14;
}

View File

@@ -6,12 +6,15 @@
package dan200.computercraft.shared.network.client;
import dan200.computercraft.client.ClientTableFormatter;
import dan200.computercraft.shared.command.text.TableBuilder;
import dan200.computercraft.shared.network.NetworkMessage;
import dan200.computercraft.shared.network.NetworkMessages;
import dan200.computercraft.shared.util.NBTUtil;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
@@ -29,17 +32,6 @@ public class ChatTableClientMessage implements NetworkMessage
{
}
@Override
public int getId()
{
return NetworkMessages.CHAT_TABLE_CLIENT_MESSAGE;
}
public TableBuilder getTable()
{
return table;
}
@Override
public void toBytes( @Nonnull PacketBuffer buf )
{
@@ -84,4 +76,11 @@ public class ChatTableClientMessage implements NetworkMessage
}
this.table = table;
}
@Override
@SideOnly( Side.CLIENT )
public void handle( MessageContext context )
{
ClientTableFormatter.INSTANCE.display( table );
}
}

View File

@@ -10,11 +10,8 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.network.NetworkMessage;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.relauncher.Side;
import javax.annotation.Nonnull;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
/**
* A packet, which performs an action on a {@link ClientComputer}.
@@ -58,12 +55,4 @@ public abstract class ComputerClientMessage implements NetworkMessage
}
return computer;
}
public static <T extends ComputerClientMessage> void register( Supplier<T> factory, BiConsumer<ClientComputer, T> handler )
{
NetworkMessage.registerMainThread( Side.CLIENT, factory, ( context, packet ) -> {
ClientComputer computer = packet.getComputer();
if( computer != null ) handler.accept( computer, packet );
} );
}
}

View File

@@ -8,10 +8,10 @@ package dan200.computercraft.shared.network.client;
import dan200.computercraft.shared.computer.blocks.ComputerState;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.network.NetworkMessages;
import dan200.computercraft.shared.util.NBTUtil;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import javax.annotation.Nonnull;
@@ -34,22 +34,6 @@ public class ComputerDataClientMessage extends ComputerClientMessage
{
}
@Override
public int getId()
{
return NetworkMessages.COMPUTER_DATA_CLIENT_MESSAGE;
}
public ComputerState getState()
{
return state;
}
public NBTTagCompound getUserData()
{
return userData;
}
@Override
public void toBytes( @Nonnull PacketBuffer buf )
{
@@ -65,4 +49,10 @@ public class ComputerDataClientMessage extends ComputerClientMessage
state = buf.readEnumValue( ComputerState.class );
userData = NBTUtil.readCompoundTag( buf );
}
@Override
public void handle( MessageContext context )
{
getComputer().setState( state, userData );
}
}

View File

@@ -6,7 +6,8 @@
package dan200.computercraft.shared.network.client;
import dan200.computercraft.shared.network.NetworkMessages;
import dan200.computercraft.ComputerCraft;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
public class ComputerDeletedClientMessage extends ComputerClientMessage
{
@@ -20,8 +21,8 @@ public class ComputerDeletedClientMessage extends ComputerClientMessage
}
@Override
public int getId()
public void handle( MessageContext context )
{
return NetworkMessages.COMPUTER_DELETED_CLIENT_MESSAGE;
ComputerCraft.clientComputerRegistry.remove( getInstanceId() );
}
}

View File

@@ -6,10 +6,10 @@
package dan200.computercraft.shared.network.client;
import dan200.computercraft.shared.network.NetworkMessages;
import dan200.computercraft.shared.util.NBTUtil;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import javax.annotation.Nonnull;
@@ -27,17 +27,6 @@ public class ComputerTerminalClientMessage extends ComputerClientMessage
{
}
@Override
public int getId()
{
return NetworkMessages.COMPUTER_TERMINAL_CLIENT_MESSAGE;
}
public NBTTagCompound getTag()
{
return tag;
}
@Override
public void toBytes( @Nonnull PacketBuffer buf )
{
@@ -51,4 +40,10 @@ public class ComputerTerminalClientMessage extends ComputerClientMessage
super.fromBytes( buf );
tag = NBTUtil.readCompoundTag( buf );
}
@Override
public void handle( MessageContext context )
{
getComputer().readDescription( tag );
}
}

View File

@@ -7,10 +7,13 @@
package dan200.computercraft.shared.network.client;
import dan200.computercraft.shared.network.NetworkMessage;
import dan200.computercraft.shared.network.NetworkMessages;
import net.minecraft.client.Minecraft;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
@@ -43,27 +46,6 @@ public class PlayRecordClientMessage implements NetworkMessage
{
}
@Override
public int getId()
{
return NetworkMessages.PLAY_RECORD_CLIENT_MESSAGE;
}
public BlockPos getPos()
{
return pos;
}
public String getName()
{
return name;
}
public SoundEvent getSoundEvent()
{
return soundEvent;
}
@Override
public void toBytes( @Nonnull PacketBuffer buf )
{
@@ -90,4 +72,13 @@ public class PlayRecordClientMessage implements NetworkMessage
soundEvent = SoundEvent.REGISTRY.getObjectById( buf.readInt() );
}
}
@Override
@SideOnly( Side.CLIENT )
public void handle( MessageContext context )
{
Minecraft mc = Minecraft.getMinecraft();
mc.world.playRecord( pos, soundEvent );
if( name != null ) mc.ingameGUI.setRecordPlayingMessage( name );
}
}

View File

@@ -6,7 +6,7 @@
package dan200.computercraft.shared.network.server;
import dan200.computercraft.shared.network.NetworkMessages;
import dan200.computercraft.shared.computer.core.ServerComputer;
import net.minecraft.network.PacketBuffer;
import javax.annotation.Nonnull;
@@ -25,12 +25,6 @@ public class ComputerActionServerMessage extends ComputerServerMessage
{
}
@Override
public int getId()
{
return NetworkMessages.COMPUTER_ACTION_SERVER_MESSAGE;
}
@Override
public void toBytes( @Nonnull PacketBuffer buf )
{
@@ -45,9 +39,21 @@ public class ComputerActionServerMessage extends ComputerServerMessage
action = buf.readEnumValue( Action.class );
}
public Action getAction()
@Override
protected void handle( ServerComputer computer )
{
return action;
switch( action )
{
case TURN_ON:
computer.turnOn();
break;
case REBOOT:
computer.reboot();
break;
case SHUTDOWN:
computer.shutdown();
break;
}
}
public enum Action

View File

@@ -12,11 +12,8 @@ import dan200.computercraft.shared.network.NetworkMessage;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import javax.annotation.Nonnull;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
/**
* A packet, which performs an action on a {@link ServerComputer}.
@@ -61,11 +58,12 @@ public abstract class ComputerServerMessage implements NetworkMessage
return computer;
}
public static <T extends ComputerServerMessage> void register( Supplier<T> factory, BiConsumer<ServerComputer, T> handler )
@Override
public void handle( MessageContext context )
{
NetworkMessage.registerMainThread( Side.SERVER, factory, ( context, packet ) -> {
ServerComputer computer = packet.getComputer( context );
if( computer != null ) handler.accept( computer, packet );
} );
ServerComputer computer = getComputer( context );
if( computer != null ) handle( computer );
}
protected abstract void handle( ServerComputer computer );
}

View File

@@ -6,7 +6,7 @@
package dan200.computercraft.shared.network.server;
import dan200.computercraft.shared.network.NetworkMessages;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.util.NBTUtil;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
@@ -36,24 +36,6 @@ public class QueueEventServerMessage extends ComputerServerMessage
{
}
@Override
public int getId()
{
return NetworkMessages.QUEUE_EVENT_SERVER_MESSAGE;
}
@Nonnull
public String getEvent()
{
return event;
}
@Nullable
public Object[] getArgs()
{
return args;
}
@Override
public void toBytes( @Nonnull PacketBuffer buf )
{
@@ -71,4 +53,10 @@ public class QueueEventServerMessage extends ComputerServerMessage
NBTTagCompound args = NBTUtil.readCompoundTag( buf );
this.args = args == null ? null : NBTUtil.decodeObjects( args );
}
@Override
protected void handle( ServerComputer computer )
{
computer.queueEvent( event, args );
}
}

View File

@@ -6,9 +6,11 @@
package dan200.computercraft.shared.network.server;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.network.NetworkMessage;
import dan200.computercraft.shared.network.NetworkMessages;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import javax.annotation.Nonnull;
@@ -25,17 +27,6 @@ public class RequestComputerMessage implements NetworkMessage
{
}
@Override
public int getId()
{
return NetworkMessages.REQUEST_COMPUTER_SERVER_MESSAGE;
}
public int getInstance()
{
return instance;
}
@Override
public void toBytes( @Nonnull PacketBuffer buf )
{
@@ -47,4 +38,11 @@ public class RequestComputerMessage implements NetworkMessage
{
instance = buf.readVarInt();
}
@Override
public void handle( MessageContext context )
{
ServerComputer computer = ComputerCraft.serverComputerRegistry.get( instance );
if( computer != null ) computer.sendComputerState( context.getServerHandler().player );
}
}

View File

@@ -7,6 +7,8 @@
package dan200.computercraft.shared.peripheral.common;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
import dan200.computercraft.shared.peripheral.modem.ModemBounds;
@@ -15,19 +17,21 @@ import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
import dan200.computercraft.shared.peripheral.speaker.TileSpeaker;
import dan200.computercraft.shared.util.DirectionUtil;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.Item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
@@ -35,7 +39,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
public class BlockPeripheral extends BlockPeripheralBase
public class BlockPeripheral extends BlockGeneric
{
public static class Properties
{
@@ -45,6 +49,7 @@ public class BlockPeripheral extends BlockPeripheralBase
public BlockPeripheral()
{
super( Material.ROCK );
setHardness( 2.0f );
setTranslationKey( "computercraft:peripheral" );
setCreativeTab( ComputerCraft.mainCreativeTab );
@@ -188,202 +193,107 @@ public class BlockPeripheral extends BlockPeripheralBase
@Deprecated
public IBlockState getActualState( @Nonnull IBlockState state, IBlockAccess world, BlockPos pos )
{
int anim;
EnumFacing dir;
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TilePeripheralBase )
{
TilePeripheralBase peripheral = (TilePeripheralBase) tile;
anim = peripheral.getAnim();
dir = peripheral.getDirection();
}
else
{
anim = 0;
dir = state.getValue( Properties.FACING );
switch( state.getValue( Properties.VARIANT ) )
{
case WirelessModemDownOff:
case WirelessModemDownOn:
{
dir = EnumFacing.DOWN;
break;
}
case WirelessModemUpOff:
case WirelessModemUpOn:
{
dir = EnumFacing.UP;
break;
}
}
}
PeripheralType type = getPeripheralType( state );
switch( type )
{
case DiskDrive:
{
state = state.withProperty( Properties.FACING, dir );
switch( anim )
if( !(tile instanceof TileDiskDrive) ) return state;
TileDiskDrive drive = (TileDiskDrive) tile;
state = state.withProperty( Properties.FACING, drive.getDirection() );
switch( drive.getAnim() )
{
case 0:
default:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveEmpty );
break;
}
case 0:
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveEmpty );
case 1:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveInvalid );
break;
}
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveInvalid );
case 2:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveFull );
break;
}
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveFull );
}
break;
}
case Printer:
{
state = state.withProperty( Properties.FACING, dir );
switch( anim )
if( !(tile instanceof TilePrinter) ) return state;
TilePrinter printer = (TilePrinter) tile;
state = state.withProperty( Properties.FACING, printer.getDirection() );
switch( printer.getAnim() )
{
case 0:
default:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterEmpty );
break;
}
case 0:
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterEmpty );
case 1:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterTopFull );
break;
}
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterTopFull );
case 2:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBottomFull );
break;
}
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBottomFull );
case 3:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBothFull );
break;
}
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBothFull );
}
break;
}
case WirelessModem:
{
switch( dir )
if( !(tile instanceof TileWirelessModem) ) return state;
TileWirelessModem modem = (TileWirelessModem) tile;
EnumFacing direction = modem.getDirection();
switch( direction )
{
case UP:
{
state = state.withProperty( Properties.FACING, EnumFacing.NORTH );
switch( anim )
{
case 0:
default:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemUpOff );
break;
}
case 1:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemUpOn );
break;
}
}
break;
}
return state
.withProperty( Properties.FACING, EnumFacing.NORTH )
.withProperty( Properties.VARIANT,
modem.isOn() ? BlockPeripheralVariant.WirelessModemUpOn : BlockPeripheralVariant.WirelessModemUpOff );
case DOWN:
{
state = state.withProperty( Properties.FACING, EnumFacing.NORTH );
switch( anim )
{
case 0:
default:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemDownOff );
break;
}
case 1:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemDownOn );
break;
}
}
break;
}
return state
.withProperty( Properties.FACING, EnumFacing.NORTH )
.withProperty( Properties.VARIANT,
modem.isOn() ? BlockPeripheralVariant.WirelessModemDownOn : BlockPeripheralVariant.WirelessModemDownOff );
default:
{
state = state.withProperty( Properties.FACING, dir );
switch( anim )
{
case 0:
default:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemOff );
break;
}
case 1:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemOn );
break;
}
}
break;
return state
.withProperty( Properties.FACING, direction )
.withProperty( Properties.VARIANT,
modem.isOn() ? BlockPeripheralVariant.WirelessModemOn : BlockPeripheralVariant.WirelessModemOff );
}
}
break;
}
case Speaker:
{
state = state.withProperty( Properties.FACING, dir );
break;
if( !(tile instanceof TileSpeaker) ) return state;
return state.withProperty( Properties.FACING, ((TileSpeaker) tile).getDirection() );
}
case Monitor:
case AdvancedMonitor:
{
EnumFacing front;
int xIndex, yIndex, width, height;
if( tile instanceof TileMonitor )
{
TileMonitor monitor = (TileMonitor) tile;
dir = monitor.getDirection();
front = monitor.getFront();
xIndex = monitor.getXIndex();
yIndex = monitor.getYIndex();
width = monitor.getWidth();
height = monitor.getHeight();
}
else
{
dir = EnumFacing.NORTH;
front = EnumFacing.NORTH;
xIndex = 0;
yIndex = 0;
width = 1;
height = 1;
}
if( !(tile instanceof TileMonitor) ) return state;
TileMonitor monitor = (TileMonitor) tile;
EnumFacing dir = monitor.getDirection();
EnumFacing front = monitor.getFront();
int xIndex = monitor.getXIndex();
int yIndex = monitor.getYIndex();
int width = monitor.getWidth();
int height = monitor.getHeight();
BlockPeripheralVariant baseVariant;
if( front == EnumFacing.UP )
{
baseVariant = (type == PeripheralType.AdvancedMonitor) ?
baseVariant = type == PeripheralType.AdvancedMonitor ?
BlockPeripheralVariant.AdvancedMonitorUp :
BlockPeripheralVariant.MonitorUp;
}
else if( front == EnumFacing.DOWN )
{
baseVariant = (type == PeripheralType.AdvancedMonitor) ?
baseVariant = type == PeripheralType.AdvancedMonitor ?
BlockPeripheralVariant.AdvancedMonitorDown :
BlockPeripheralVariant.MonitorDown;
}
else
{
baseVariant = (type == PeripheralType.AdvancedMonitor) ?
baseVariant = type == PeripheralType.AdvancedMonitor ?
BlockPeripheralVariant.AdvancedMonitor :
BlockPeripheralVariant.Monitor;
}
@@ -447,20 +357,21 @@ public class BlockPeripheral extends BlockPeripheralBase
}
}
state = state.withProperty( Properties.FACING, dir );
state = state.withProperty( Properties.VARIANT,
BlockPeripheralVariant.values()[baseVariant.ordinal() + subType]
);
break;
return state
.withProperty( Properties.FACING, dir )
.withProperty( Properties.VARIANT, BlockPeripheralVariant.values()[baseVariant.ordinal() + subType] );
}
default:
return state;
}
return state;
}
@Nonnull
@Override
public IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
@Deprecated
public final IBlockState getStateForPlacement( World world, BlockPos pos, EnumFacing placedSide, float hitX, float hitY, float hitZ, int damage, EntityLivingBase placer )
{
switch( type )
switch( getPeripheralType( damage ) )
{
case DiskDrive:
default:
@@ -516,59 +427,39 @@ public class BlockPeripheral extends BlockPeripheralBase
}
}
@Override
public PeripheralType getPeripheralType( int damage )
{
return ((ItemPeripheral) Item.getItemFromBlock( this )).getPeripheralType( damage );
return ComputerCraft.Items.peripheral.getPeripheralType( damage );
}
@Override
public PeripheralType getPeripheralType( IBlockState state )
{
return state.getValue( Properties.VARIANT ).getPeripheralType();
}
@Override
public TilePeripheralBase createTile( PeripheralType type )
private TileGeneric createTile( PeripheralType type )
{
switch( type )
{
case DiskDrive:
default:
{
return new TileDiskDrive();
}
case WirelessModem:
{
return new TileWirelessModem();
}
case Monitor:
case AdvancedMonitor:
{
return new TileMonitor();
}
case Printer:
{
return new TilePrinter();
}
case Speaker:
{
return new TileSpeaker();
}
}
}
@Override
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase player, @Nonnull ItemStack stack )
{
// Not sure why this is necessary
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TilePeripheralBase )
{
tile.setWorld( world ); // Not sure why this is necessary
tile.setPos( pos ); // Not sure why this is necessary
}
switch( getPeripheralType( state ) )
{
case Speaker:
@@ -576,11 +467,11 @@ public class BlockPeripheral extends BlockPeripheralBase
case Printer:
{
EnumFacing dir = DirectionUtil.fromEntityRot( player );
setDirection( world, pos, dir );
if( stack.hasDisplayName() && tile instanceof TilePeripheralBase )
{
TilePeripheralBase peripheral = (TilePeripheralBase) tile;
peripheral.setLabel( stack.getDisplayName() );
peripheral.setDirection( dir );
}
break;
}
@@ -667,13 +558,46 @@ public class BlockPeripheral extends BlockPeripheralBase
@Override
@Deprecated
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess source, BlockPos pos )
@Nonnull
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess world, BlockPos pos )
{
if( getPeripheralType( state ) == PeripheralType.WirelessModem )
{
return ModemBounds.getBounds( getDirection( source, pos ) );
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TileWirelessModem )
{
return ModemBounds.getBounds( ((TileWirelessModem) tile).getDirection() );
}
}
return super.getBoundingBox( state, source, pos );
return super.getBoundingBox( state, world, pos );
}
@Override
public final boolean canPlaceBlockOnSide( @Nonnull World world, @Nonnull BlockPos pos, EnumFacing side )
{
return true; // ItemPeripheralBase handles this
}
@Override
public final TileGeneric createTile( IBlockState state )
{
return createTile( getPeripheralType( state ) );
}
@Override
public final TileGeneric createTile( int damage )
{
return createTile( getPeripheralType( damage ) );
}
@Nonnull
@Override
public ItemStack getPickBlock( @Nonnull IBlockState state, RayTraceResult target, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player )
{
TileEntity tile = world.getTileEntity( pos );
return tile instanceof ITilePeripheral
? PeripheralItemFactory.create( (ITilePeripheral) tile )
: super.getPickBlock( state, target, world, pos, player );
}
}

View File

@@ -1,78 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.peripheral.common;
import dan200.computercraft.shared.common.BlockDirectional;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.PeripheralType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
public abstract class BlockPeripheralBase extends BlockDirectional
{
public BlockPeripheralBase()
{
super( Material.ROCK );
}
protected abstract IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide );
protected abstract PeripheralType getPeripheralType( int damage );
protected abstract PeripheralType getPeripheralType( IBlockState state );
protected abstract TilePeripheralBase createTile( PeripheralType type );
@Override
public final boolean canPlaceBlockOnSide( @Nonnull World world, @Nonnull BlockPos pos, EnumFacing side )
{
return true; // ItemPeripheralBase handles this
}
@Override
protected final IBlockState getDefaultBlockState( int damage, EnumFacing placedSide )
{
ItemPeripheralBase item = (ItemPeripheralBase) Item.getItemFromBlock( this );
return getDefaultBlockState( item.getPeripheralType( damage ), placedSide );
}
@Override
public final TileGeneric createTile( IBlockState state )
{
return createTile( getPeripheralType( state ) );
}
@Override
public final TileGeneric createTile( int damage )
{
return createTile( getPeripheralType( damage ) );
}
public final PeripheralType getPeripheralType( IBlockAccess world, BlockPos pos )
{
return getPeripheralType( world.getBlockState( pos ) );
}
@Nonnull
@Override
public ItemStack getPickBlock( @Nonnull IBlockState state, RayTraceResult target, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player )
{
TileEntity tile = world.getTileEntity( pos );
return tile instanceof IPeripheralTile ? PeripheralItemFactory.create( (IPeripheralTile) tile ) : super.getPickBlock( state, target, world, pos, player );
}
}

View File

@@ -7,15 +7,9 @@
package dan200.computercraft.shared.peripheral.common;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.common.IDirectionalTile;
import dan200.computercraft.shared.peripheral.PeripheralType;
import net.minecraft.util.EnumFacing;
public interface IPeripheralTile extends IDirectionalTile
public interface IPeripheralTile
{
PeripheralType getPeripheralType();
IPeripheral getPeripheral( EnumFacing side );
String getLabel();
}

View File

@@ -0,0 +1,26 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.peripheral.common;
import dan200.computercraft.shared.peripheral.PeripheralType;
/**
* The tile for {@link BlockPeripheral}.
*/
public interface ITilePeripheral
{
PeripheralType getPeripheralType();
default String getLabel()
{
return null;
}
default void setLabel( String label )
{
}
}

View File

@@ -8,9 +8,6 @@ package dan200.computercraft.shared.peripheral.common;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.modem.wired.ItemCable;
import dan200.computercraft.shared.peripheral.modem.wireless.ItemAdvancedModem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
@@ -18,7 +15,7 @@ import javax.annotation.Nonnull;
public class PeripheralItemFactory
{
@Nonnull
public static ItemStack create( IPeripheralTile tile )
public static ItemStack create( ITilePeripheral tile )
{
return create( tile.getPeripheralType(), tile.getLabel(), 1 );
}
@@ -26,9 +23,6 @@ public class PeripheralItemFactory
@Nonnull
public static ItemStack create( PeripheralType type, String label, int quantity )
{
ItemPeripheral peripheral = ((ItemPeripheral) Item.getItemFromBlock( ComputerCraft.Blocks.peripheral ));
ItemCable cable = ((ItemCable) Item.getItemFromBlock( ComputerCraft.Blocks.cable ));
ItemAdvancedModem advancedModem = ((ItemAdvancedModem) Item.getItemFromBlock( ComputerCraft.Blocks.advancedModem ));
switch( type )
{
case Speaker:
@@ -37,18 +31,12 @@ public class PeripheralItemFactory
case Monitor:
case AdvancedMonitor:
case WirelessModem:
{
return peripheral.create( type, label, quantity );
}
return ComputerCraft.Items.peripheral.create( type, label, quantity );
case WiredModem:
case Cable:
{
return cable.create( type, label, quantity );
}
return ComputerCraft.Items.cable.create( type, quantity );
case AdvancedModem:
{
return advancedModem.create( type, label, quantity );
}
return new ItemStack( ComputerCraft.Blocks.advancedModem, quantity );
case WiredModemFull:
return new ItemStack( ComputerCraft.Blocks.wiredModemFull, quantity );
}

View File

@@ -7,6 +7,7 @@
package dan200.computercraft.shared.peripheral.common;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.common.IDirectionalTile;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.PeripheralType;
import net.minecraft.item.ItemStack;
@@ -17,12 +18,9 @@ import net.minecraft.util.NonNullList;
import javax.annotation.Nonnull;
public abstract class TilePeripheralBase extends TileGeneric
implements IPeripheralTile, ITickable
public abstract class TilePeripheralBase extends TileGeneric implements IPeripheralTile, ITickable, IDirectionalTile, ITilePeripheral
{
// Statics
protected EnumFacing m_dir;
private EnumFacing m_dir;
private int m_anim;
private boolean m_changed;
@@ -39,9 +37,9 @@ public abstract class TilePeripheralBase extends TileGeneric
@Override
public BlockPeripheralBase getBlock()
public BlockPeripheral getBlock()
{
return (BlockPeripheralBase) super.getBlock();
return (BlockPeripheral) super.getBlock();
}
@Override
@@ -53,8 +51,6 @@ public abstract class TilePeripheralBase extends TileGeneric
}
}
// IPeripheralTile implementation
@Override
public final PeripheralType getPeripheralType()
{
@@ -77,6 +73,7 @@ public abstract class TilePeripheralBase extends TileGeneric
return null;
}
@Override
public void setLabel( String label )
{
m_label = label;
@@ -90,11 +87,6 @@ public abstract class TilePeripheralBase extends TileGeneric
return m_dir;
}
public EnumFacing getCachedDirection()
{
return m_dir;
}
@Override
public void setDirection( EnumFacing dir )
{
@@ -110,7 +102,7 @@ public abstract class TilePeripheralBase extends TileGeneric
return m_anim;
}
public void setAnim( int anim )
protected void setAnim( int anim )
{
if( anim != m_anim )
{

View File

@@ -181,21 +181,19 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
int channel = parseChannel( arguments, 0 );
int replyChannel = parseChannel( arguments, 1 );
Object payload = arguments.length > 2 ? arguments[2] : null;
synchronized( this )
World world = getWorld();
Vec3d position = getPosition();
IPacketNetwork network = m_network;
if( world != null && position != null && network != null )
{
World world = getWorld();
Vec3d position = getPosition();
if( world != null && position != null && m_network != null )
Packet packet = new Packet( channel, replyChannel, payload, this );
if( isInterdimensional() )
{
Packet packet = new Packet( channel, replyChannel, payload, this );
if( isInterdimensional() )
{
m_network.transmitInterdimensional( packet );
}
else
{
m_network.transmitSameDimension( packet, getRange() );
}
network.transmitInterdimensional( packet );
}
else
{
network.transmitSameDimension( packet, getRange() );
}
}
return null;

View File

@@ -14,16 +14,27 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class ModemState
{
private boolean open = false;
private AtomicBoolean changed = new AtomicBoolean( true );
private final Runnable onChanged;
private final AtomicBoolean changed = new AtomicBoolean( true );
private boolean open = false;
private final IntSet channels = new IntOpenHashSet();
public ModemState()
{
this.onChanged = null;
}
public ModemState( Runnable onChanged )
{
this.onChanged = onChanged;
}
private void setOpen( boolean open )
{
if( this.open == open ) return;
this.open = open;
this.changed.set( true );
if( !changed.getAndSet( true ) && onChanged != null ) onChanged.run();
}
public boolean pollChanged()

View File

@@ -1,80 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.peripheral.modem;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import javax.annotation.Nonnull;
public abstract class TileModemBase extends TilePeripheralBase
{
protected ModemPeripheral m_modem;
protected TileModemBase()
{
m_modem = createPeripheral();
}
protected abstract ModemPeripheral createPeripheral();
@Override
public void destroy()
{
if( m_modem != null )
{
m_modem.destroy();
m_modem = null;
}
}
@Override
public void onNeighbourChange()
{
EnumFacing dir = getDirection();
if( !getWorld().isSideSolid( getPos().offset( dir ), dir.getOpposite() ) )
{
// Drop everything and remove block
((BlockGeneric) getBlockType()).dropAllItems( getWorld(), getPos(), false );
getWorld().setBlockToAir( getPos() );
}
}
@Override
public void update()
{
super.update();
if( !getWorld().isRemote && m_modem.getModemState().pollChanged() )
{
updateAnim();
}
}
protected void updateAnim()
{
setAnim( m_modem.getModemState().isOpen() ? 1 : 0 );
}
@Override
public final void readDescription( @Nonnull NBTTagCompound nbt )
{
super.readDescription( nbt );
updateBlock();
}
// IPeripheralTile implementation
@Override
public IPeripheral getPeripheral( EnumFacing side )
{
return side == getDirection() ? m_modem : null;
}
}

View File

@@ -9,11 +9,12 @@ package dan200.computercraft.shared.peripheral.modem.wired;
import com.google.common.collect.ImmutableMap;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.BlockPeripheralBase;
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockFaceShape;
@@ -22,7 +23,6 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
@@ -39,7 +39,7 @@ import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
public class BlockCable extends BlockPeripheralBase
public class BlockCable extends BlockGeneric
{
// Statics
@@ -66,6 +66,7 @@ public class BlockCable extends BlockPeripheralBase
public BlockCable()
{
super( Material.ROCK );
setHardness( 1.5f );
setTranslationKey( "computercraft:cable" );
setCreativeTab( ComputerCraft.mainCreativeTab );
@@ -142,10 +143,12 @@ public class BlockCable extends BlockPeripheralBase
return meta;
}
@Override
public IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
@Deprecated
public final IBlockState getStateForPlacement( World world, BlockPos pos, EnumFacing placedSide, float hitX, float hitY, float hitZ, int damage, EntityLivingBase placer )
{
switch( type )
switch( ComputerCraft.Items.cable.getPeripheralType( damage ) )
{
case Cable:
return getDefaultState()
@@ -190,7 +193,7 @@ public class BlockCable extends BlockPeripheralBase
.withProperty( Properties.DOWN, doesConnectVisually( state, world, pos, EnumFacing.DOWN ) );
TileEntity tile = world.getTileEntity( pos );
int anim = tile instanceof TilePeripheralBase ? ((TilePeripheralBase) tile).getAnim() : 0;
int anim = tile instanceof TileCable ? ((TileCable) tile).getState() : 0;
BlockCableModemVariant modem = state.getValue( Properties.MODEM );
if( modem != BlockCableModemVariant.None )
@@ -209,13 +212,6 @@ public class BlockCable extends BlockPeripheralBase
return true;
}
@Override
public PeripheralType getPeripheralType( int damage )
{
return ((ItemCable) Item.getItemFromBlock( this )).getPeripheralType( damage );
}
@Override
public PeripheralType getPeripheralType( IBlockState state )
{
boolean cable = state.getValue( Properties.CABLE );
@@ -235,7 +231,13 @@ public class BlockCable extends BlockPeripheralBase
}
@Override
public TilePeripheralBase createTile( PeripheralType type )
protected TileGeneric createTile( IBlockState state )
{
return new TileCable();
}
@Override
protected TileGeneric createTile( int damage )
{
return new TileCable();
}
@@ -381,4 +383,11 @@ public class BlockCable extends BlockPeripheralBase
{
return BlockFaceShape.UNDEFINED;
}
@Override
@Deprecated
public boolean hasCustomBreakingProgress( IBlockState state )
{
return true;
}
}

View File

@@ -7,20 +7,19 @@
package dan200.computercraft.shared.peripheral.modem.wired;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.BlockPeripheralBase;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.common.TileGeneric;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import javax.annotation.Nonnull;
public class BlockWiredModemFull extends BlockPeripheralBase
public class BlockWiredModemFull extends BlockGeneric
{
// Statics
@@ -34,6 +33,7 @@ public class BlockWiredModemFull extends BlockPeripheralBase
public BlockWiredModemFull()
{
super( Material.ROCK );
setHardness( 1.5f );
setTranslationKey( "computercraft:wired_modem_full" );
setCreativeTab( ComputerCraft.mainCreativeTab );
@@ -43,12 +43,6 @@ public class BlockWiredModemFull extends BlockPeripheralBase
);
}
@Override
protected IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
{
return getDefaultState();
}
@Nonnull
@Override
protected BlockStateContainer createBlockState()
@@ -74,7 +68,7 @@ public class BlockWiredModemFull extends BlockPeripheralBase
if( te instanceof TileWiredModemFull )
{
TileWiredModemFull modem = (TileWiredModemFull) te;
int anim = modem.getAnim();
int anim = modem.getState();
state = state
.withProperty( Properties.MODEM_ON, (anim & 1) != 0 )
.withProperty( Properties.PERIPHERAL_ON, (anim & 2) != 0 );
@@ -84,19 +78,13 @@ public class BlockWiredModemFull extends BlockPeripheralBase
}
@Override
public PeripheralType getPeripheralType( int damage )
protected TileGeneric createTile( IBlockState state )
{
return PeripheralType.WiredModemFull;
return new TileWiredModemFull();
}
@Override
public PeripheralType getPeripheralType( IBlockState state )
{
return PeripheralType.WiredModemFull;
}
@Override
public TilePeripheralBase createTile( PeripheralType type )
protected TileGeneric createTile( int damage )
{
return new TileWiredModemFull();
}

View File

@@ -34,7 +34,7 @@ public class ItemCable extends ItemPeripheralBase
}
@Nonnull
public ItemStack create( PeripheralType type, String label, int quantity )
public ItemStack create( PeripheralType type, int quantity )
{
ItemStack stack;
switch( type )
@@ -54,10 +54,7 @@ public class ItemCable extends ItemPeripheralBase
return ItemStack.EMPTY;
}
}
if( label != null )
{
stack.setStackDisplayName( label );
}
return stack;
}
@@ -81,11 +78,11 @@ public class ItemCable extends ItemPeripheralBase
// Try to add a cable to a modem
PeripheralType type = getPeripheralType( stack );
Block existing = world.getBlockState( pos ).getBlock();
IBlockState existingState = world.getBlockState( pos );
Block existing = existingState.getBlock();
if( existing == ComputerCraft.Blocks.cable )
{
PeripheralType existingType = ComputerCraft.Blocks.cable.getPeripheralType( world, pos );
PeripheralType existingType = ComputerCraft.Blocks.cable.getPeripheralType( existingState );
if( existingType == PeripheralType.WiredModem && type == PeripheralType.Cable )
{
if( !stack.isEmpty() )
@@ -112,12 +109,12 @@ public class ItemCable extends ItemPeripheralBase
if( !existing.isAir( existingState, world, pos ) && (type == PeripheralType.Cable || existingState.isSideSolid( world, pos, side )) )
{
BlockPos offset = pos.offset( side );
Block offsetExisting = world.getBlockState( offset ).getBlock();
IBlockState offsetExistingState = world.getBlockState( offset );
Block offsetExisting = offsetExistingState.getBlock();
if( offsetExisting == ComputerCraft.Blocks.cable )
{
// Try to add a modem to a cable
PeripheralType offsetExistingType = ComputerCraft.Blocks.cable.getPeripheralType( world, offset );
PeripheralType offsetExistingType = ComputerCraft.Blocks.cable.getPeripheralType( offsetExistingState );
if( offsetExistingType == PeripheralType.Cable && type == PeripheralType.WiredModem )
{
if( !stack.isEmpty() )

View File

@@ -7,17 +7,18 @@
package dan200.computercraft.shared.peripheral.modem.wired;
import com.google.common.base.Objects;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.command.CommandCopy;
import dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
import dan200.computercraft.shared.peripheral.modem.ModemState;
import dan200.computercraft.shared.peripheral.modem.TileModemBase;
import dan200.computercraft.shared.util.TickScheduler;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
@@ -37,42 +38,35 @@ import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Map;
public class TileCable extends TileModemBase
public class TileCable extends TileGeneric implements IPeripheralTile
{
private static class CableElement extends WiredModemElement
private class CableElement extends WiredModemElement
{
private final TileCable m_entity;
private CableElement( TileCable m_entity )
{
this.m_entity = m_entity;
}
@Nonnull
@Override
public World getWorld()
{
return m_entity.getWorld();
return TileCable.this.getWorld();
}
@Nonnull
@Override
public Vec3d getPosition()
{
BlockPos pos = m_entity.getPos();
BlockPos pos = TileCable.this.getPos();
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
}
@Override
protected void attachPeripheral( String name, IPeripheral peripheral )
{
((WiredModemPeripheral) m_entity.m_modem).attachPeripheral( name, peripheral );
m_modem.attachPeripheral( name, peripheral );
}
@Override
protected void detachPeripheral( String name )
{
((WiredModemPeripheral) m_entity.m_modem).detachPeripheral( name );
m_modem.detachPeripheral( name );
}
}
@@ -83,35 +77,35 @@ public class TileCable extends TileModemBase
private boolean m_destroyed = false;
private boolean m_hasDirection = false;
private EnumFacing modemDirection;
private boolean hasModemDirection = false;
private boolean m_connectionsFormed = false;
private WiredModemElement m_cable;
private IWiredNode m_node;
@Override
protected ModemPeripheral createPeripheral()
private final WiredModemElement m_cable = new CableElement();
private final IWiredNode m_node = m_cable.getNode();
private final WiredModemPeripheral m_modem = new WiredModemPeripheral(
new ModemState( () -> TickScheduler.schedule( this ) ),
m_cable
)
{
m_cable = new CableElement( this );
m_node = m_cable.getNode();
return new WiredModemPeripheral( new ModemState(), m_cable )
@Nonnull
@Override
protected WiredModemLocalPeripheral getLocalPeripheral()
{
@Nonnull
@Override
protected WiredModemLocalPeripheral getLocalPeripheral()
{
return m_peripheral;
}
return m_peripheral;
}
@Nonnull
@Override
public Vec3d getPosition()
{
BlockPos pos = getPos().offset( getCachedDirection() );
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
}
};
}
@Nonnull
@Override
public Vec3d getPosition()
{
BlockPos pos = getPos().offset( modemDirection );
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
}
};
private int m_state = 0;
private void remove()
{
@@ -128,9 +122,9 @@ public class TileCable extends TileModemBase
if( !m_destroyed )
{
m_destroyed = true;
m_modem.destroy();
remove();
}
super.destroy();
}
@Override
@@ -151,43 +145,37 @@ public class TileCable extends TileModemBase
public void onLoad()
{
super.onLoad();
updateDirection();
if( !world.isRemote )
{
updateDirection();
world.scheduleUpdate( pos, getBlockType(), 0 );
}
}
@Override
public void updateContainingBlockInfo()
{
m_hasDirection = false;
super.updateContainingBlockInfo();
hasModemDirection = false;
if( !world.isRemote ) world.scheduleUpdate( pos, getBlockType(), 0 );
}
private void updateDirection()
{
if( !m_hasDirection )
if( !hasModemDirection )
{
m_hasDirection = true;
m_dir = getDirection();
hasModemDirection = true;
modemDirection = getDirection();
}
}
@Override
public EnumFacing getDirection()
private EnumFacing getDirection()
{
IBlockState state = getBlockState();
EnumFacing facing = state.getValue( BlockCable.Properties.MODEM ).getFacing();
return facing != null ? facing : EnumFacing.NORTH;
}
@Override
public void setDirection( EnumFacing dir )
{
IBlockState state = getBlockState();
BlockCableModemVariant modem = state.getValue( BlockCable.Properties.MODEM );
if( modem != BlockCableModemVariant.None )
{
setBlockState( state.withProperty( BlockCable.Properties.MODEM, BlockCableModemVariant.fromFacing( dir ) ) );
}
}
@Override
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
{
@@ -199,12 +187,12 @@ public class TileCable extends TileModemBase
case Cable:
case WiredModem:
{
drops.add( PeripheralItemFactory.create( type, getLabel(), 1 ) );
drops.add( PeripheralItemFactory.create( type, null, 1 ) );
break;
}
case WiredModemWithCable:
{
drops.add( PeripheralItemFactory.create( PeripheralType.WiredModem, getLabel(), 1 ) );
drops.add( PeripheralItemFactory.create( PeripheralType.WiredModem, null, 1 ) );
drops.add( PeripheralItemFactory.create( PeripheralType.Cable, null, 1 ) );
break;
}
@@ -226,7 +214,7 @@ public class TileCable extends TileModemBase
case WiredModem:
{
// Drop everything and remove block
((BlockGeneric) getBlockType()).dropAllItems( getWorld(), getPos(), false );
getBlock().dropAllItems( getWorld(), getPos(), false );
getWorld().setBlockToAir( getPos() );
// This'll call #destroy(), so we don't need to reset the network here.
@@ -235,8 +223,7 @@ public class TileCable extends TileModemBase
case WiredModemWithCable:
{
// Drop the modem and convert to cable
((BlockGeneric) getBlockType()).dropItem( getWorld(), getPos(), PeripheralItemFactory.create( PeripheralType.WiredModem, getLabel(), 1 ) );
setLabel( null );
getBlock().dropItem( getWorld(), getPos(), PeripheralItemFactory.create( PeripheralType.WiredModem, null, 1 ) );
setBlockState( getBlockState().withProperty( BlockCable.Properties.MODEM, BlockCableModemVariant.None ) );
modemChanged();
connectionsChanged();
@@ -328,21 +315,46 @@ public class TileCable extends TileModemBase
}
@Override
protected void updateAnim()
protected void writeDescription( @Nonnull NBTTagCompound nbt )
{
int anim = 0;
if( m_modem.getModemState().isOpen() ) anim |= 1;
if( m_peripheralAccessAllowed ) anim |= 2;
setAnim( anim );
super.writeDescription( nbt );
nbt.setInteger( "state", m_state );
}
@Override
public void update()
public final void readDescription( @Nonnull NBTTagCompound nbt )
{
super.readDescription( nbt );
m_state = nbt.getInteger( "state" );
updateBlock();
}
public int getState()
{
return m_state;
}
private void updateState()
{
int state = 0;
if( m_modem.getModemState().isOpen() ) state |= 1;
if( m_peripheralAccessAllowed ) state |= 2;
if( state != m_state )
{
m_state = state;
updateBlock();
}
}
@Override
protected void updateTick()
{
super.update();
updateDirection();
if( !getWorld().isRemote )
{
updateDirection();
if( m_modem.getModemState().pollChanged() ) updateState();
if( !m_connectionsFormed )
{
m_connectionsFormed = true;
@@ -350,7 +362,7 @@ public class TileCable extends TileModemBase
connectionsChanged();
if( m_peripheralAccessAllowed )
{
m_peripheral.attach( world, pos, m_dir );
m_peripheral.attach( world, pos, modemDirection );
updateConnectedPeripherals();
}
}
@@ -396,7 +408,7 @@ public class TileCable extends TileModemBase
m_peripheral.detach();
m_node.updatePeripherals( Collections.emptyMap() );
markDirty();
updateAnim();
updateState();
}
}
@@ -419,7 +431,7 @@ public class TileCable extends TileModemBase
m_node.updatePeripherals( Collections.emptyMap() );
}
updateAnim();
updateState();
}
private void updateConnectedPeripherals()
@@ -429,7 +441,7 @@ public class TileCable extends TileModemBase
{
// If there are no peripherals then disable access and update the display state.
m_peripheralAccessAllowed = false;
updateAnim();
updateState();
}
m_node.updatePeripherals( peripherals );
@@ -441,12 +453,14 @@ public class TileCable extends TileModemBase
return true;
}
// IWiredElement capability
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
{
if( capability == CapabilityWiredElement.CAPABILITY ) return BlockCable.canConnectIn( getBlockState(), facing );
if( capability == CapabilityWiredElement.CAPABILITY )
{
return !m_destroyed && BlockCable.canConnectIn( getBlockState(), facing );
}
return super.hasCapability( capability, facing );
}
@@ -456,21 +470,23 @@ public class TileCable extends TileModemBase
{
if( capability == CapabilityWiredElement.CAPABILITY )
{
return BlockCable.canConnectIn( getBlockState(), facing ) ? CapabilityWiredElement.CAPABILITY.cast( m_cable ) : null;
return !m_destroyed && BlockCable.canConnectIn( getBlockState(), facing )
? CapabilityWiredElement.CAPABILITY.cast( m_cable )
: null;
}
return super.getCapability( capability, facing );
}
// IPeripheralTile
@Override
public IPeripheral getPeripheral( EnumFacing side )
{
if( getPeripheralType() != PeripheralType.Cable )
{
return super.getPeripheral( side );
}
return null;
return !m_destroyed && getPeripheralType() != PeripheralType.Cable && side == getDirection() ? m_modem : null;
}
public PeripheralType getPeripheralType()
{
IBlockState state = getBlockState();
return ComputerCraft.Blocks.cable.getPeripheralType( state );
}
}

View File

@@ -7,18 +7,23 @@
package dan200.computercraft.shared.peripheral.modem.wired;
import com.google.common.base.Objects;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.command.CommandCopy;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
import dan200.computercraft.shared.peripheral.modem.ModemState;
import dan200.computercraft.shared.util.TickScheduler;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextComponentString;
@@ -30,7 +35,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
public class TileWiredModemFull extends TilePeripheralBase
public class TileWiredModemFull extends TileGeneric implements IPeripheralTile
{
private static class FullElement extends WiredModemElement
{
@@ -85,10 +90,12 @@ public class TileWiredModemFull extends TilePeripheralBase
private boolean m_destroyed = false;
private boolean m_connectionsFormed = false;
private final ModemState m_modemState = new ModemState();
private final ModemState m_modemState = new ModemState( () -> TickScheduler.schedule( this ) );
private final WiredModemElement m_element = new FullElement( this );
private final IWiredNode m_node = m_element.getNode();
private int m_state = 0;
public TileWiredModemFull()
{
for( int i = 0; i < m_peripherals.length; i++ ) m_peripherals[i] = new WiredModemLocalPeripheral();
@@ -129,14 +136,9 @@ public class TileWiredModemFull extends TilePeripheralBase
}
@Override
public EnumFacing getDirection()
{
return EnumFacing.NORTH;
}
@Override
public void setDirection( EnumFacing dir )
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
{
drops.add( new ItemStack( ComputerCraft.Items.wiredModemFull ) );
}
@Override
@@ -231,27 +233,51 @@ public class TileWiredModemFull extends TilePeripheralBase
return nbt;
}
protected void updateAnim()
public int getState()
{
int anim = 0;
if( m_modemState.isOpen() ) anim |= 1;
if( m_peripheralAccessAllowed ) anim |= 2;
setAnim( anim );
return m_state;
}
private void updateState()
{
int state = 0;
if( m_modemState.isOpen() ) state |= 1;
if( m_peripheralAccessAllowed ) state |= 2;
if( state != m_state )
{
m_state = state;
updateBlock();
}
}
@Override
protected void writeDescription( @Nonnull NBTTagCompound nbt )
{
super.writeDescription( nbt );
nbt.setInteger( "state", m_state );
}
@Override
public final void readDescription( @Nonnull NBTTagCompound nbt )
{
super.readDescription( nbt );
m_state = nbt.getInteger( "state" );
updateBlock();
}
@Override
public void update()
public void onLoad()
{
super.onLoad();
if( !world.isRemote ) world.scheduleUpdate( pos, getBlockType(), 0 );
}
@Override
protected void updateTick()
{
if( !getWorld().isRemote )
{
if( m_modemState.pollChanged() ) updateAnim();
if( m_modemState.pollChanged() ) updateState();
if( !m_connectionsFormed )
{
@@ -268,8 +294,6 @@ public class TileWiredModemFull extends TilePeripheralBase
}
}
}
super.update();
}
private void connectionsChanged()
@@ -291,7 +315,6 @@ public class TileWiredModemFull extends TilePeripheralBase
}
}
// private stuff
private void togglePeripheralAccess()
{
if( !m_peripheralAccessAllowed )
@@ -317,7 +340,7 @@ public class TileWiredModemFull extends TilePeripheralBase
m_node.updatePeripherals( Collections.emptyMap() );
}
updateAnim();
updateState();
}
private Set<String> getConnectedPeripheralNames()
@@ -349,7 +372,7 @@ public class TileWiredModemFull extends TilePeripheralBase
{
// If there are no peripherals then disable access and update the display state.
m_peripheralAccessAllowed = false;
updateAnim();
updateState();
}
m_node.updatePeripherals( peripherals );
@@ -360,7 +383,8 @@ public class TileWiredModemFull extends TilePeripheralBase
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
{
return capability == CapabilityWiredElement.CAPABILITY || super.hasCapability( capability, facing );
if( capability == CapabilityWiredElement.CAPABILITY ) return !m_destroyed;
return super.hasCapability( capability, facing );
}
@Nullable
@@ -369,17 +393,18 @@ public class TileWiredModemFull extends TilePeripheralBase
{
if( capability == CapabilityWiredElement.CAPABILITY )
{
if( m_destroyed ) return null;
return CapabilityWiredElement.CAPABILITY.cast( m_element );
}
return super.getCapability( capability, facing );
}
// IPeripheralTile
@Override
public IPeripheral getPeripheral( EnumFacing side )
{
if( m_destroyed ) return null;
WiredModemPeripheral peripheral = m_modems[side.ordinal()];
if( peripheral == null )
{

View File

@@ -19,7 +19,6 @@ import net.minecraftforge.common.util.Constants;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File;
import java.util.Collections;
import java.util.Map;
@@ -66,10 +65,7 @@ public final class WiredModemLocalPeripheral
else if( id < 0 || !type.equals( this.type ) )
{
this.type = type;
this.id = IDAssigner.getNextIDFromFile( new File(
ComputerCraft.getWorldDir( world ),
"computer/lastid_" + type + ".txt"
) );
this.id = IDAssigner.getNextIDFromFile( "computer/lastid_" + type + ".txt" );
}
return oldPeripheral == null || !oldPeripheral.equals( peripheral );

View File

@@ -7,33 +7,37 @@
package dan200.computercraft.shared.peripheral.modem.wireless;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.BlockPeripheralBase;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.modem.ModemBounds;
import net.minecraft.block.BlockDirectional;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
public class BlockAdvancedModem extends BlockPeripheralBase
public class BlockAdvancedModem extends BlockGeneric
{
public static class Properties
{
public static final PropertyDirection FACING = PropertyDirection.create( "facing" );
public static final PropertyDirection FACING = BlockDirectional.FACING;
public static final PropertyBool ON = PropertyBool.create( "on" );
}
public BlockAdvancedModem()
{
super( Material.ROCK );
setHardness( 2.0f );
setTranslationKey( "computercraft:advanced_modem" );
setCreativeTab( ComputerCraft.mainCreativeTab );
@@ -55,17 +59,13 @@ public class BlockAdvancedModem extends BlockPeripheralBase
@Deprecated
public IBlockState getStateFromMeta( int meta )
{
IBlockState state = getDefaultState();
state = state.withProperty( Properties.FACING, EnumFacing.byIndex( meta ) );
state = state.withProperty( Properties.ON, false );
return state;
return getDefaultState().withProperty( Properties.FACING, EnumFacing.byIndex( meta ) );
}
@Override
public int getMetaFromState( IBlockState state )
{
EnumFacing dir = state.getValue( Properties.FACING );
return dir.getIndex();
return state.getValue( Properties.FACING ).getIndex();
}
@Nonnull
@@ -73,47 +73,26 @@ public class BlockAdvancedModem extends BlockPeripheralBase
@Deprecated
public IBlockState getActualState( @Nonnull IBlockState state, IBlockAccess world, BlockPos pos )
{
int anim;
EnumFacing dir;
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TilePeripheralBase )
{
TilePeripheralBase peripheral = (TilePeripheralBase) tile;
anim = peripheral.getAnim();
dir = peripheral.getDirection();
}
else
{
anim = 0;
dir = state.getValue( Properties.FACING );
}
state = state.withProperty( Properties.FACING, dir );
state = state.withProperty( Properties.ON, anim > 0 );
return state;
return state.withProperty( Properties.ON, tile instanceof TileAdvancedModem && ((TileAdvancedModem) tile).isOn() );
}
@Nonnull
@Override
public IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
@Deprecated
public IBlockState getStateForPlacement( World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer )
{
EnumFacing dir = placedSide.getOpposite();
return getDefaultState().withProperty( Properties.FACING, dir );
return getDefaultState().withProperty( Properties.FACING, facing.getOpposite() );
}
@Override
public PeripheralType getPeripheralType( int damage )
protected TileGeneric createTile( IBlockState state )
{
return PeripheralType.AdvancedModem;
return new TileAdvancedModem();
}
@Override
public PeripheralType getPeripheralType( IBlockState state )
{
return PeripheralType.AdvancedModem;
}
@Override
public TilePeripheralBase createTile( PeripheralType type )
protected TileGeneric createTile( int damage )
{
return new TileAdvancedModem();
}
@@ -140,6 +119,7 @@ public class BlockAdvancedModem extends BlockPeripheralBase
return BlockFaceShape.UNDEFINED;
}
@Nonnull
@Override
@Deprecated
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess source, BlockPos pos )

View File

@@ -27,30 +27,6 @@ public class ItemAdvancedModem extends ItemPeripheralBase
setCreativeTab( ComputerCraft.mainCreativeTab );
}
@Nonnull
public ItemStack create( PeripheralType type, String label, int quantity )
{
ItemStack stack;
switch( type )
{
case AdvancedModem:
{
stack = new ItemStack( this, quantity, 0 );
break;
}
default:
{
// Ignore types we can't handle
return ItemStack.EMPTY;
}
}
if( label != null )
{
stack.setStackDisplayName( label );
}
return stack;
}
@Override
public void getSubItems( @Nullable CreativeTabs tabs, @Nonnull NonNullList<ItemStack> list )
{

View File

@@ -6,116 +6,24 @@
package dan200.computercraft.shared.peripheral.modem.wireless;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
import dan200.computercraft.shared.peripheral.modem.ModemState;
import dan200.computercraft.shared.peripheral.modem.TileModemBase;
import net.minecraft.block.state.IBlockState;
import dan200.computercraft.ComputerCraft;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.util.NonNullList;
import javax.annotation.Nonnull;
public class TileAdvancedModem extends TileModemBase
public class TileAdvancedModem extends TileWirelessModemBase
{
// Statics
private static class Peripheral extends WirelessModemPeripheral
@Override
protected EnumFacing getDirection()
{
private TileModemBase m_entity;
public Peripheral( TileModemBase entity )
{
super( new ModemState(), true );
m_entity = entity;
}
@Nonnull
@Override
public World getWorld()
{
return m_entity.getWorld();
}
@Nonnull
@Override
public Vec3d getPosition()
{
BlockPos pos = m_entity.getPos().offset( m_entity.getCachedDirection() );
return new Vec3d( pos.getX(), pos.getY(), pos.getZ() );
}
@Override
public boolean equals( IPeripheral other )
{
if( other instanceof Peripheral )
{
Peripheral otherModem = (Peripheral) other;
return otherModem.m_entity == m_entity;
}
return false;
}
}
// Members
private boolean m_hasDirection = false;
public TileAdvancedModem()
{
m_dir = EnumFacing.DOWN;
return getBlockState().getValue( BlockAdvancedModem.Properties.FACING );
}
@Override
public void onLoad()
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
{
super.onLoad();
updateDirection();
}
@Override
public void updateContainingBlockInfo()
{
m_hasDirection = false;
}
@Override
public void update()
{
super.update();
updateDirection();
}
private void updateDirection()
{
if( !m_hasDirection )
{
m_hasDirection = true;
m_dir = getDirection();
}
}
@Override
public EnumFacing getDirection()
{
// Wireless Modem
IBlockState state = getBlockState();
return state.getValue( BlockAdvancedModem.Properties.FACING );
}
@Override
public void setDirection( EnumFacing dir )
{
// Wireless Modem
setBlockState( getBlockState()
.withProperty( BlockAdvancedModem.Properties.FACING, dir )
);
}
@Override
protected ModemPeripheral createPeripheral()
{
return new Peripheral( this );
if( !creative ) drops.add( new ItemStack( ComputerCraft.Items.advancedModem ) );
}
}

View File

@@ -7,100 +7,23 @@
package dan200.computercraft.shared.peripheral.modem.wireless;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.common.IDirectionalTile;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.common.BlockPeripheralVariant;
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
import dan200.computercraft.shared.peripheral.modem.ModemState;
import dan200.computercraft.shared.peripheral.modem.TileModemBase;
import dan200.computercraft.shared.peripheral.common.ITilePeripheral;
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
public class TileWirelessModem extends TileModemBase
public class TileWirelessModem extends TileWirelessModemBase implements IDirectionalTile, ITilePeripheral
{
// Statics
private static class Peripheral extends WirelessModemPeripheral
{
private TileModemBase m_entity;
public Peripheral( TileModemBase entity )
{
super( new ModemState(), false );
m_entity = entity;
}
@Nonnull
@Override
public World getWorld()
{
return m_entity.getWorld();
}
@Nonnull
@Override
public Vec3d getPosition()
{
BlockPos pos = m_entity.getPos().offset( m_entity.getCachedDirection() );
return new Vec3d( pos.getX(), pos.getY(), pos.getZ() );
}
@Override
public boolean equals( IPeripheral other )
{
if( other instanceof Peripheral )
{
Peripheral otherModem = (Peripheral) other;
return otherModem.m_entity == m_entity;
}
return false;
}
}
// Members
private boolean m_hasDirection = false;
public TileWirelessModem()
{
m_dir = EnumFacing.DOWN;
}
@Override
public void onLoad()
{
super.onLoad();
updateDirection();
}
@Override
public void updateContainingBlockInfo()
{
m_hasDirection = false;
}
@Override
public void update()
{
super.update();
updateDirection();
}
private void updateDirection()
{
if( !m_hasDirection )
{
m_hasDirection = true;
m_dir = getDirection();
}
}
@Override
public EnumFacing getDirection()
{
@@ -110,18 +33,12 @@ public class TileWirelessModem extends TileModemBase
{
case WirelessModemDownOff:
case WirelessModemDownOn:
{
return EnumFacing.DOWN;
}
case WirelessModemUpOff:
case WirelessModemUpOn:
{
return EnumFacing.UP;
}
default:
{
return state.getValue( BlockPeripheral.Properties.FACING );
}
}
}
@@ -152,15 +69,21 @@ public class TileWirelessModem extends TileModemBase
}
}
@Override
protected ModemPeripheral createPeripheral()
{
return new Peripheral( this );
}
@Override
public boolean shouldRefresh( World world, BlockPos pos, @Nonnull IBlockState oldState, @Nonnull IBlockState newState )
{
return super.shouldRefresh( world, pos, oldState, newState ) || ComputerCraft.Blocks.peripheral.getPeripheralType( newState ) != PeripheralType.WirelessModem;
}
@Override
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
{
if( !creative ) drops.add( PeripheralItemFactory.create( PeripheralType.WirelessModem, null, 1 ) );
}
@Override
public PeripheralType getPeripheralType()
{
return PeripheralType.WirelessModem;
}
}

View File

@@ -0,0 +1,154 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.peripheral.modem.wireless;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
import dan200.computercraft.shared.peripheral.modem.ModemState;
import dan200.computercraft.shared.util.TickScheduler;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
public abstract class TileWirelessModemBase extends TileGeneric implements IPeripheralTile
{
private static class Peripheral extends WirelessModemPeripheral
{
private final TileWirelessModemBase entity;
Peripheral( TileWirelessModemBase entity )
{
super( new ModemState( () -> TickScheduler.schedule( entity ) ), true );
this.entity = entity;
}
@Nonnull
@Override
public World getWorld()
{
return entity.getWorld();
}
@Nonnull
@Override
public Vec3d getPosition()
{
BlockPos pos = entity.getPos().offset( entity.modemDirection );
return new Vec3d( pos.getX(), pos.getY(), pos.getZ() );
}
@Override
public boolean equals( IPeripheral other )
{
return this == other;
}
}
private boolean hasModemDirection = false;
private EnumFacing modemDirection = EnumFacing.DOWN;
private final ModemPeripheral modem = new Peripheral( this );
private boolean destroyed = false;
private boolean on = false;
@Override
public void onLoad()
{
super.onLoad();
updateDirection();
world.scheduleUpdate( getPos(), getBlockType(), 0 );
}
@Override
public void destroy()
{
if( !destroyed )
{
modem.destroy();
destroyed = true;
}
}
@Override
public void updateContainingBlockInfo()
{
hasModemDirection = false;
super.updateContainingBlockInfo();
world.scheduleUpdate( getPos(), getBlockType(), 0 );
}
@Override
public void updateTick()
{
updateDirection();
if( modem.getModemState().pollChanged() )
{
boolean newOn = modem.getModemState().isOpen();
if( newOn != on )
{
on = newOn;
updateBlock();
}
}
}
private void updateDirection()
{
if( !hasModemDirection )
{
hasModemDirection = true;
modemDirection = getDirection();
}
}
protected abstract EnumFacing getDirection();
@Override
public void onNeighbourChange()
{
EnumFacing dir = getDirection();
if( !getWorld().isSideSolid( getPos().offset( dir ), dir.getOpposite() ) )
{
// Drop everything and remove block
getBlock().dropAllItems( getWorld(), getPos(), false );
getWorld().setBlockToAir( getPos() );
}
}
@Override
protected void writeDescription( @Nonnull NBTTagCompound nbt )
{
super.writeDescription( nbt );
nbt.setBoolean( "on", on );
}
@Override
public final void readDescription( @Nonnull NBTTagCompound nbt )
{
super.readDescription( nbt );
on = nbt.getBoolean( "on" );
updateBlock();
}
public boolean isOn()
{
return on;
}
@Override
public IPeripheral getPeripheral( EnumFacing side )
{
return !destroyed && side == getDirection() ? modem : null;
}
}

View File

@@ -8,12 +8,16 @@ package dan200.computercraft.shared.peripheral.monitor;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.common.ServerTerminal;
import dan200.computercraft.shared.util.TickScheduler;
import java.util.concurrent.atomic.AtomicBoolean;
public class ServerMonitor extends ServerTerminal
{
private final TileMonitor origin;
private int textScale = 2;
private boolean resized;
private final AtomicBoolean resized = new AtomicBoolean( false );
private final AtomicBoolean changed = new AtomicBoolean( false );
public ServerMonitor( boolean colour, TileMonitor origin )
{
@@ -41,10 +45,28 @@ public class ServerMonitor extends ServerTerminal
if( oldWidth != termWidth || oldHeight != termHeight )
{
getTerminal().clear();
resized = true;
resized.set( true );
markChanged();
}
}
@Override
protected void markTerminalChanged()
{
super.markTerminalChanged();
markChanged();
}
private void markChanged()
{
if( !changed.getAndSet( true ) ) TickScheduler.schedule( origin );
}
protected void clearChanged()
{
changed.set( false );
}
public int getTextScale()
{
return textScale;
@@ -57,14 +79,14 @@ public class ServerMonitor extends ServerTerminal
rebuild();
}
public synchronized boolean pollResized()
public boolean pollResized()
{
if( resized )
{
resized = false;
return true;
}
return resized.getAndSet( false );
}
return false;
public boolean pollTerminalChanged()
{
update();
return hasTerminalChanged();
}
}

View File

@@ -11,15 +11,20 @@ import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.common.ServerTerminal;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
import dan200.computercraft.shared.peripheral.common.ITilePeripheral;
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -28,7 +33,7 @@ import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Set;
public class TileMonitor extends TilePeripheralBase
public class TileMonitor extends TileGeneric implements ITilePeripheral, IPeripheralTile
{
// Statics
@@ -78,6 +83,7 @@ public class TileMonitor extends TilePeripheralBase
super.onLoad();
m_advanced = getBlockState().getValue( BlockPeripheral.Properties.VARIANT )
.getPeripheralType() == PeripheralType.AdvancedMonitor;
world.scheduleUpdate( getPos(), getBlockType(), 0 );
}
@Override
@@ -146,44 +152,32 @@ public class TileMonitor extends TilePeripheralBase
}
@Override
public void update()
public void updateTick()
{
super.update();
if( m_xIndex != 0 || m_yIndex != 0 || m_serverMonitor == null ) return;
if( !getWorld().isRemote )
m_serverMonitor.clearChanged();
if( m_serverMonitor.pollResized() )
{
if( m_xIndex == 0 && m_yIndex == 0 && m_serverMonitor != null )
for( int x = 0; x < m_width; x++ )
{
if( m_serverMonitor.pollResized() )
for( int y = 0; y < m_height; y++ )
{
for( int x = 0; x < m_width; x++ )
{
for( int y = 0; y < m_height; y++ )
{
TileMonitor monitor = getNeighbour( x, y );
if( monitor == null ) continue;
TileMonitor monitor = getNeighbour( x, y );
if( monitor == null ) continue;
for( IComputerAccess computer : monitor.m_computers )
{
computer.queueEvent( "monitor_resize", new Object[] {
computer.getAttachmentName()
} );
}
}
for( IComputerAccess computer : monitor.m_computers )
{
computer.queueEvent( "monitor_resize", new Object[] {
computer.getAttachmentName()
} );
}
}
}
}
m_serverMonitor.update();
if( m_serverMonitor.hasTerminalChanged() ) updateBlock();
}
}
else
{
if( m_xIndex == 0 && m_yIndex == 0 && m_clientMonitor != null )
{
m_clientMonitor.update();
}
}
if( m_serverMonitor.pollTerminalChanged() ) updateBlock();
}
// IPeripheralTile implementation
@@ -197,6 +191,12 @@ public class TileMonitor extends TilePeripheralBase
return m_peripheral;
}
@Override
public PeripheralType getPeripheralType()
{
return m_advanced ? PeripheralType.AdvancedMonitor : PeripheralType.Monitor;
}
public ServerMonitor getCachedServerMonitor()
{
return m_serverMonitor;
@@ -319,7 +319,6 @@ public class TileMonitor extends TilePeripheralBase
}
// Sizing and placement stuff
@Override
public EnumFacing getDirection()
{
int dir = getDir() % 6;
@@ -444,7 +443,7 @@ public class TileMonitor extends TilePeripheralBase
return getSimilarMonitorAt( pos.offset( right, xOffset ).offset( down, yOffset ) );
}
public TileMonitor getOrigin()
private TileMonitor getOrigin()
{
return getNeighbour( 0, 0 );
}
@@ -752,15 +751,16 @@ public class TileMonitor extends TilePeripheralBase
{
case Monitor:
case AdvancedMonitor:
{
return false;
}
default:
{
return true;
}
}
}
}
@Override
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
{
if( !creative ) drops.add( PeripheralItemFactory.create( this ) );
}
}

View File

@@ -14,8 +14,8 @@ import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.util.DefaultSidedInventory;
import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
@@ -521,11 +521,7 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
double x = pos.getX() + 0.5;
double y = pos.getY() + 0.75;
double z = pos.getZ() + 0.5;
EntityItem entityitem = new EntityItem( getWorld(), x, y, z, stack );
entityitem.motionX = getWorld().rand.nextFloat() * 0.2 - 0.1;
entityitem.motionY = getWorld().rand.nextFloat() * 0.2 - 0.1;
entityitem.motionZ = getWorld().rand.nextFloat() * 0.2 - 0.1;
getWorld().spawnEntity( entityitem );
WorldUtil.dropItemStack( stack, getWorld(), x, y, z );
}
}
}

View File

@@ -17,6 +17,7 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
@@ -25,25 +26,11 @@ import java.util.concurrent.atomic.AtomicInteger;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.core.apis.ArgumentHelper.optReal;
public class SpeakerPeripheral implements IPeripheral
public abstract class SpeakerPeripheral implements IPeripheral
{
private final TileSpeaker m_speaker;
private long m_clock;
private long m_lastPlayTime;
private final AtomicInteger m_notesThisTick;
public SpeakerPeripheral()
{
this( null );
}
SpeakerPeripheral( TileSpeaker speaker )
{
m_clock = 0;
m_lastPlayTime = 0;
m_notesThisTick = new AtomicInteger();
m_speaker = speaker;
}
private long m_clock = 0;
private long m_lastPlayTime = 0;
private final AtomicInteger m_notesThisTick = new AtomicInteger();
public void update()
{
@@ -51,14 +38,20 @@ public class SpeakerPeripheral implements IPeripheral
m_notesThisTick.set( 0 );
}
public World getWorld()
public abstract World getWorld();
public Vec3d getPosition()
{
return m_speaker.getWorld();
// FIXME: Should be abstract, but we need this for Plethora compat. We'll
// be able to change this in a few versions as we implement both there.
@SuppressWarnings( "deprecation" ) BlockPos pos = getPos();
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
}
@Deprecated
public BlockPos getPos()
{
return m_speaker.getPos();
return new BlockPos( getPosition() );
}
public boolean madeSound( long ticks )
@@ -66,16 +59,6 @@ public class SpeakerPeripheral implements IPeripheral
return m_clock - m_lastPlayTime <= ticks;
}
/* IPeripheral implementation */
@Override
public boolean equals( IPeripheral other )
{
if( other == this ) return true;
if( !(other instanceof SpeakerPeripheral) ) return false;
return m_speaker == ((SpeakerPeripheral) other).m_speaker;
}
@Nonnull
@Override
public String getType()
@@ -155,17 +138,16 @@ public class SpeakerPeripheral implements IPeripheral
}
World world = getWorld();
BlockPos pos = getPos();
Vec3d pos = getPosition();
context.issueMainThreadTask( () -> {
MinecraftServer server = world.getMinecraftServer();
if( server == null ) return null;
double x = pos.getX() + 0.5, y = pos.getY() + 0.5, z = pos.getZ() + 0.5;
float adjVolume = Math.min( volume, 3.0f );
server.getPlayerList().sendToAllNearExcept(
null, x, y, z, adjVolume > 1.0f ? 16 * adjVolume : 16.0, world.provider.getDimension(),
new SPacketCustomSound( name, SoundCategory.RECORDS, x, y, z, adjVolume, pitch )
null, pos.x, pos.y, pos.z, adjVolume > 1.0f ? 16 * adjVolume : 16.0, world.provider.getDimension(),
new SPacketCustomSound( name, SoundCategory.RECORDS, pos.x, pos.y, pos.z, adjVolume, pitch )
);
return null;
} );

View File

@@ -9,6 +9,11 @@ package dan200.computercraft.shared.peripheral.speaker;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import javax.annotation.Nullable;
public class TileSpeaker extends TilePeripheralBase
{
@@ -21,7 +26,7 @@ public class TileSpeaker extends TilePeripheralBase
public TileSpeaker()
{
super();
m_peripheral = new SpeakerPeripheral( this );
m_peripheral = new Peripheral( this );
}
@Override
@@ -37,4 +42,33 @@ public class TileSpeaker extends TilePeripheralBase
{
return m_peripheral;
}
private static class Peripheral extends SpeakerPeripheral
{
private final TileSpeaker speaker;
private Peripheral( TileSpeaker speaker )
{
this.speaker = speaker;
}
@Override
public World getWorld()
{
return speaker.getWorld();
}
@Override
public Vec3d getPosition()
{
BlockPos pos = speaker.getPos();
return new Vec3d( pos.getX(), pos.getY(), pos.getZ() );
}
@Override
public boolean equals( @Nullable IPeripheral other )
{
return this == other || (other instanceof Peripheral && speaker == ((Peripheral) other).speaker);
}
}
}

View File

@@ -12,6 +12,7 @@ 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 dan200.computercraft.shared.network.NetworkHandler;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
@@ -176,6 +177,7 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
}
}
@Override
public void broadcastState( boolean force )
{
super.broadcastState( force );
@@ -186,7 +188,7 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
EntityPlayerMP player = (EntityPlayerMP) m_entity;
if( player.connection != null && !isInteracting( player ) )
{
ComputerCraft.sendToPlayer( player, createTerminalPacket() );
NetworkHandler.sendToPlayer( player, createTerminalPacket() );
}
}
}

View File

@@ -49,7 +49,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
setTranslationKey( "computercraft:pocket_computer" );
setCreativeTab( ComputerCraft.mainCreativeTab );
addPropertyOverride( new ResourceLocation( ComputerCraft.MOD_ID, "state" ), COMPUTER_STATE );
addPropertyOverride( new ResourceLocation( ComputerCraft.MOD_ID, "type" ), COMPUTER_TYPE );
addPropertyOverride( new ResourceLocation( ComputerCraft.MOD_ID, "coloured" ), COMPUTER_COLOURED );
}
public ItemStack create( int id, String label, int colour, ComputerFamily family, IPocketUpgrade upgrade )
@@ -565,9 +565,8 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
return state.ordinal();
};
private static final IItemPropertyGetter COMPUTER_TYPE = ( stack, world, player ) -> {
private static final IItemPropertyGetter COMPUTER_COLOURED = ( stack, world, player ) -> {
ItemPocketComputer item = (ItemPocketComputer) stack.getItem();
if( item.getColour( stack ) != -1 ) return 2;
return item.getFamily( stack ) == ComputerFamily.Advanced ? 1 : 0;
return item.getColour( stack ) != -1 ? 1 : 0;
};
}

View File

@@ -25,6 +25,11 @@ public abstract class AbstractPocketUpgrade implements IPocketUpgrade
this.stack = stack;
}
protected AbstractPocketUpgrade( ResourceLocation id, ItemStack stack )
{
this( id, "upgrade." + id + ".adjective", stack );
}
@Nonnull
@Override
public final ResourceLocation getUpgradeID()

View File

@@ -12,7 +12,6 @@ import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
import dan200.computercraft.shared.peripheral.modem.ModemState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.ResourceLocation;
import javax.annotation.Nonnull;
@@ -54,15 +53,8 @@ public class PocketModem extends AbstractPocketUpgrade
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 );
}
if( entity != null ) modem.setLocation( entity.getEntityWorld(), entity.getPositionEyes( 1 ) );
ModemState state = modem.getModemState();
if( state.pollChanged() ) access.setLight( state.isOpen() ? 0xBA0000 : -1 );

View File

@@ -15,24 +15,18 @@ import javax.annotation.Nonnull;
public class PocketModemPeripheral extends WirelessModemPeripheral
{
private World world;
private Vec3d position;
private World world = null;
private Vec3d position = Vec3d.ZERO;
public PocketModemPeripheral( boolean advanced )
{
super( new ModemState(), advanced );
world = null;
position = new Vec3d( 0.0, 0.0, 0.0 );
}
public void setLocation( World world, double x, double y, double z )
void setLocation( World world, Vec3d position )
{
position = new Vec3d( x, y, z );
if( this.world != world )
{
this.world = world;
switchNetwork();
}
this.position = position;
this.world = world;
}
@Nonnull
@@ -46,7 +40,7 @@ public class PocketModemPeripheral extends WirelessModemPeripheral
@Override
public Vec3d getPosition()
{
return world != null ? position : null;
return position;
}
@Override

View File

@@ -23,7 +23,6 @@ public class PocketSpeaker extends AbstractPocketUpgrade
{
super(
new ResourceLocation( "computercraft", "speaker" ),
"upgrade.computercraft:speaker.adjective",
PeripheralItemFactory.create( PeripheralType.Speaker, null, 1 )
);
}

View File

@@ -8,24 +8,17 @@ package dan200.computercraft.shared.pocket.peripherals;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.peripheral.speaker.SpeakerPeripheral;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class PocketSpeakerPeripheral extends SpeakerPeripheral
{
private World world;
private BlockPos position;
PocketSpeakerPeripheral()
{
super();
world = null;
position = BlockPos.ORIGIN;
}
private World world = null;
private Vec3d position = Vec3d.ZERO;
void setLocation( World world, double x, double y, double z )
{
position = new BlockPos( x, y, z );
position = new Vec3d( x, y, z );
this.world = world;
}
@@ -36,7 +29,7 @@ public class PocketSpeakerPeripheral extends SpeakerPeripheral
}
@Override
public BlockPos getPos()
public Vec3d getPosition()
{
return world != null ? position : null;
}

View File

@@ -7,57 +7,15 @@
package dan200.computercraft.shared.proxy;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.event.TurtleActionEvent;
import dan200.computercraft.shared.TurtleUpgrades;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.blocks.TileTurtleAdvanced;
import dan200.computercraft.shared.turtle.blocks.TileTurtleExpanded;
import dan200.computercraft.shared.turtle.core.TurtlePlayer;
import dan200.computercraft.shared.turtle.items.ItemTurtleAdvanced;
import dan200.computercraft.shared.turtle.items.ItemTurtleLegacy;
import dan200.computercraft.shared.turtle.items.ItemTurtleNormal;
import dan200.computercraft.shared.turtle.items.TurtleItemFactory;
import dan200.computercraft.shared.turtle.upgrades.*;
import dan200.computercraft.shared.util.DropConsumer;
import dan200.computercraft.shared.util.ImpostorRecipe;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.registry.EntityRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.registries.IForgeRegistry;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.function.Function;
public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
public class CCTurtleProxyCommon implements ICCTurtleProxy
{
private Function<ItemStack, ItemStack> dropConsumer;
private List<ItemStack> remainingDrops;
private WeakReference<World> dropWorld;
private BlockPos dropPos;
private AxisAlignedBB dropBounds;
private WeakReference<Entity> dropEntity;
@Override
public void preInit()
{
MinecraftForge.EVENT_BUS.register( this );
EntityRegistry.registerModEntity(
new ResourceLocation( ComputerCraft.MOD_ID, "turtle_player" ), TurtlePlayer.class, "turtle_player",
0, ComputerCraft.instance, Integer.MAX_VALUE, Integer.MAX_VALUE, false
@@ -67,203 +25,5 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
@Override
public void init()
{
registerForgeHandlers();
registerTileEntities();
}
@SubscribeEvent
public void registerBlocks( RegistryEvent.Register<Block> event )
{
IForgeRegistry<Block> registry = event.getRegistry();
// Turtle
ComputerCraft.Blocks.turtle = BlockTurtle.createTurtleBlock();
registry.register( ComputerCraft.Blocks.turtle.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) ) );
ComputerCraft.Blocks.turtleExpanded = BlockTurtle.createTurtleBlock();
registry.register( ComputerCraft.Blocks.turtleExpanded.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_expanded" ) ) );
// Advanced Turtle
ComputerCraft.Blocks.turtleAdvanced = BlockTurtle.createTurtleBlock();
registry.register( ComputerCraft.Blocks.turtleAdvanced.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_advanced" ) ) );
}
@SubscribeEvent
public void registerItems( RegistryEvent.Register<Item> event )
{
IForgeRegistry<Item> registry = event.getRegistry();
registry.register( new ItemTurtleLegacy( ComputerCraft.Blocks.turtle ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) ) );
registry.register( new ItemTurtleNormal( ComputerCraft.Blocks.turtleExpanded ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_expanded" ) ) );
registry.register( new ItemTurtleAdvanced( ComputerCraft.Blocks.turtleAdvanced ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_advanced" ) ) );
registerUpgrades();
}
@SubscribeEvent
public void registerRecipes( RegistryEvent.Register<IRecipe> event )
{
IForgeRegistry<IRecipe> registry = event.getRegistry();
// Add a bunch of impostor recipes
// TODO: Figure out a way to do this in a "nice" way.
for( ITurtleUpgrade upgrade : TurtleUpgrades.getVanillaUpgrades() )
{
// Add fake recipes to fool NEI
ItemStack craftingItem = upgrade.getCraftingItem();
// A turtle just containing this upgrade
for( ComputerFamily family : ComputerFamily.values() )
{
if( !TurtleUpgrades.suitableForFamily( family, upgrade ) ) continue;
ItemStack baseTurtle = TurtleItemFactory.create( -1, null, -1, family, null, null, 0, null );
if( !baseTurtle.isEmpty() )
{
ItemStack craftedTurtle = TurtleItemFactory.create( -1, null, -1, family, upgrade, null, 0, null );
ItemStack craftedTurtleFlipped = TurtleItemFactory.create( -1, null, -1, family, null, upgrade, 0, null );
registry.register(
new ImpostorRecipe( "computercraft:" + family.toString() + "_turtle_upgrade", 2, 1, new ItemStack[] { baseTurtle, craftingItem }, craftedTurtle )
.setRegistryName( new ResourceLocation( "computercraft:" + family + "_turtle_upgrade_" + upgrade.getUpgradeID().toString().replace( ':', '_' ) + "_1" ) )
);
registry.register(
new ImpostorRecipe( "computercraft:" + family.toString() + "_turtle_upgrade", 2, 1, new ItemStack[] { craftingItem, baseTurtle }, craftedTurtleFlipped )
.setRegistryName( new ResourceLocation( "computercraft:" + family + "_turtle_upgrade_" + upgrade.getUpgradeID().toString().replace( ':', '_' ) + "_2" ) )
);
/*
// A turtle containing this upgrade and another upgrade
for( ITurtleUpgrade otherUpgrade : m_turtleUpgrades.values() )
{
if( isUpgradeVanilla( otherUpgrade ) && isUpgradeSuitableForFamily( family, otherUpgrade ) )
{
ItemStack otherCraftingItem = otherUpgrade.getCraftingItem();
ItemStack otherCraftedTurtle = TurtleItemFactory.create( -1, null, -1, family, null, otherUpgrade, 0, null );
ItemStack comboCraftedTurtle = TurtleItemFactory.create( -1, null, -1, family, upgrade, otherUpgrade, 0, null );
ItemStack otherCraftedTurtleFlipped = TurtleItemFactory.create( -1, null, -1, family, otherUpgrade, null, 0, null );
ItemStack comboCraftedTurtleFlipped = TurtleItemFactory.create( -1, null, -1, family, otherUpgrade, upgrade, 0, null );
recipeList.add( new ImpostorRecipe( 2, 1, new ItemStack[] { otherCraftingItem, craftedTurtle }, comboCraftedTurtle ) );
recipeList.add( new ImpostorRecipe( 2, 1, new ItemStack[] { otherCraftedTurtle, craftingItem }, comboCraftedTurtle ) );
recipeList.add( new ImpostorRecipe( 2, 1, new ItemStack[] { craftedTurtleFlipped, otherCraftingItem }, comboCraftedTurtleFlipped ) );
recipeList.add( new ImpostorRecipe( 2, 1, new ItemStack[] { craftingItem, otherCraftedTurtleFlipped }, comboCraftedTurtleFlipped ) );
recipeList.add( new ImpostorRecipe( 3, 1, new ItemStack[] { otherCraftingItem, baseTurtle, craftingItem, }, comboCraftedTurtle ) );
recipeList.add( new ImpostorRecipe( 3, 1, new ItemStack[] { craftingItem, baseTurtle, otherCraftingItem }, comboCraftedTurtleFlipped ) );
}
}
*/
}
}
}
}
private void registerUpgrades()
{
// Upgrades
ComputerCraft.Upgrades.wirelessModem = new TurtleModem( false, new ResourceLocation( "computercraft", "wireless_modem" ), 1 );
TurtleUpgrades.registerInternal( ComputerCraft.Upgrades.wirelessModem );
ComputerCraft.Upgrades.craftingTable = new TurtleCraftingTable( 2 );
TurtleUpgrades.registerInternal( ComputerCraft.Upgrades.craftingTable );
ComputerCraft.Upgrades.diamondSword = new TurtleSword( new ResourceLocation( "minecraft", "diamond_sword" ), 3, "upgrade.minecraft:diamond_sword.adjective", Items.DIAMOND_SWORD );
TurtleUpgrades.registerInternal( ComputerCraft.Upgrades.diamondSword );
ComputerCraft.Upgrades.diamondShovel = new TurtleShovel( new ResourceLocation( "minecraft", "diamond_shovel" ), 4, "upgrade.minecraft:diamond_shovel.adjective", Items.DIAMOND_SHOVEL );
TurtleUpgrades.registerInternal( ComputerCraft.Upgrades.diamondShovel );
ComputerCraft.Upgrades.diamondPickaxe = new TurtleTool( new ResourceLocation( "minecraft", "diamond_pickaxe" ), 5, "upgrade.minecraft:diamond_pickaxe.adjective", Items.DIAMOND_PICKAXE );
TurtleUpgrades.registerInternal( ComputerCraft.Upgrades.diamondPickaxe );
ComputerCraft.Upgrades.diamondAxe = new TurtleAxe( new ResourceLocation( "minecraft", "diamond_axe" ), 6, "upgrade.minecraft:diamond_axe.adjective", Items.DIAMOND_AXE );
TurtleUpgrades.registerInternal( ComputerCraft.Upgrades.diamondAxe );
ComputerCraft.Upgrades.diamondHoe = new TurtleHoe( new ResourceLocation( "minecraft", "diamond_hoe" ), 7, "upgrade.minecraft:diamond_hoe.adjective", Items.DIAMOND_HOE );
TurtleUpgrades.registerInternal( ComputerCraft.Upgrades.diamondHoe );
ComputerCraft.Upgrades.advancedModem = new TurtleModem( true, new ResourceLocation( "computercraft", "advanced_modem" ), -1 );
TurtleUpgrades.registerInternal( ComputerCraft.Upgrades.advancedModem );
ComputerCraft.Upgrades.turtleSpeaker = new TurtleSpeaker( new ResourceLocation( "computercraft", "speaker" ), 8 );
TurtleUpgrades.registerInternal( ComputerCraft.Upgrades.turtleSpeaker );
}
@SubscribeEvent
public void remapItems( RegistryEvent.MissingMappings<Item> mappings )
{
// We have to use mappings.getAllMappings() as the mod ID is upper case but the domain lower.
for( RegistryEvent.MissingMappings.Mapping<Item> mapping : mappings.getAllMappings() )
{
String domain = mapping.key.getNamespace();
if( !domain.equalsIgnoreCase( ComputerCraft.MOD_ID ) ) continue;
String key = mapping.key.getPath();
if( key.equalsIgnoreCase( "CC-Turtle" ) )
{
mapping.remap( Item.getItemFromBlock( ComputerCraft.Blocks.turtle ) );
}
else if( key.equalsIgnoreCase( "CC-TurtleExpanded" ) )
{
mapping.remap( Item.getItemFromBlock( ComputerCraft.Blocks.turtleExpanded ) );
}
else if( key.equalsIgnoreCase( "CC-TurtleAdvanced" ) )
{
mapping.remap( Item.getItemFromBlock( ComputerCraft.Blocks.turtleAdvanced ) );
}
}
}
@SubscribeEvent
public void remapBlocks( RegistryEvent.MissingMappings<Block> mappings )
{
// We have to use mappings.getAllMappings() as the mod ID is upper case but the domain lower.
for( RegistryEvent.MissingMappings.Mapping<Block> mapping : mappings.getAllMappings() )
{
String domain = mapping.key.getNamespace();
if( !domain.equalsIgnoreCase( ComputerCraft.MOD_ID ) ) continue;
String key = mapping.key.getPath();
if( key.equalsIgnoreCase( "CC-Turtle" ) )
{
mapping.remap( ComputerCraft.Blocks.turtle );
}
else if( key.equalsIgnoreCase( "CC-TurtleExpanded" ) )
{
mapping.remap( ComputerCraft.Blocks.turtleExpanded );
}
else if( key.equalsIgnoreCase( "CC-TurtleAdvanced" ) )
{
mapping.remap( ComputerCraft.Blocks.turtleAdvanced );
}
}
}
private void registerTileEntities()
{
// TileEntities
GameRegistry.registerTileEntity( TileTurtle.class, new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) );
GameRegistry.registerTileEntity( TileTurtleExpanded.class, new ResourceLocation( ComputerCraft.MOD_ID, "turtleex" ) );
GameRegistry.registerTileEntity( TileTurtleAdvanced.class, new ResourceLocation( ComputerCraft.MOD_ID, "turtleadv" ) );
}
private void registerForgeHandlers()
{
MinecraftForge.EVENT_BUS.register( new ForgeHandlers() );
MinecraftForge.EVENT_BUS.register( DropConsumer.instance() );
}
private class ForgeHandlers
{
@SubscribeEvent
public void onTurtleAction( TurtleActionEvent event )
{
if( ComputerCraft.turtleDisabledActions.contains( event.getAction() ) )
{
event.setCanceled( true, "Action has been disabled" );
}
}
}
}

View File

@@ -8,105 +8,60 @@ package dan200.computercraft.shared.proxy;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.client.gui.*;
import dan200.computercraft.core.computer.MainThread;
import dan200.computercraft.shared.Config;
import dan200.computercraft.shared.PocketUpgrades;
import dan200.computercraft.shared.command.CommandComputerCraft;
import dan200.computercraft.shared.command.ContainerViewComputer;
import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider;
import dan200.computercraft.shared.computer.blocks.BlockCommandComputer;
import dan200.computercraft.shared.computer.blocks.BlockComputer;
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.*;
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
import dan200.computercraft.shared.computer.items.ItemCommandComputer;
import dan200.computercraft.shared.computer.items.ItemComputer;
import dan200.computercraft.shared.datafix.Fixes;
import dan200.computercraft.shared.integration.charset.IntegrationCharset;
import dan200.computercraft.shared.media.common.DefaultMediaProvider;
import dan200.computercraft.shared.media.inventory.ContainerHeldItem;
import dan200.computercraft.shared.media.items.ItemDiskExpanded;
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
import dan200.computercraft.shared.media.items.ItemPrintout;
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
import dan200.computercraft.shared.network.NetworkMessage;
import dan200.computercraft.shared.network.client.*;
import dan200.computercraft.shared.network.server.ComputerActionServerMessage;
import dan200.computercraft.shared.network.server.ComputerServerMessage;
import dan200.computercraft.shared.network.server.QueueEventServerMessage;
import dan200.computercraft.shared.network.server.RequestComputerMessage;
import dan200.computercraft.shared.peripheral.commandblock.CommandBlockPeripheralProvider;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.common.DefaultPeripheralProvider;
import dan200.computercraft.shared.peripheral.common.ItemPeripheral;
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
import dan200.computercraft.shared.peripheral.modem.wired.*;
import dan200.computercraft.shared.peripheral.modem.wireless.BlockAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.ItemAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.TileAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.TileWirelessModem;
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
import dan200.computercraft.shared.peripheral.speaker.TileSpeaker;
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory;
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.CreativeTabMain;
import dan200.computercraft.shared.util.ImpostorRecipe;
import dan200.computercraft.shared.util.ImpostorShapelessRecipe;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import net.minecraft.block.Block;
import net.minecraft.command.CommandHandler;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.inventory.Container;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.client.event.ConfigChangedEvent;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.common.network.FMLNetworkEvent;
import net.minecraftforge.fml.common.network.IGuiHandler;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.registries.IForgeRegistry;
import pl.asie.charset.ModCharset;
public abstract class ComputerCraftProxyCommon implements IComputerCraftProxy
public class ComputerCraftProxyCommon implements IComputerCraftProxy
{
@Override
public void preInit()
{
MinecraftForge.EVENT_BUS.register( this );
// Creative tab
ComputerCraft.mainCreativeTab = new CreativeTabMain( CreativeTabs.getNextID() );
}
@@ -114,9 +69,8 @@ public abstract class ComputerCraftProxyCommon implements IComputerCraftProxy
@Override
public void init()
{
registerTileEntities();
registerForgeHandlers();
registerNetwork();
registerProviders();
NetworkRegistry.INSTANCE.registerGuiHandler( ComputerCraft.instance, new GuiHandler() );
Fixes.register( FMLCommonHandler.instance().getDataFixer() );
if( Loader.isModLoaded( ModCharset.MODID ) ) IntegrationCharset.register();
@@ -129,229 +83,8 @@ public abstract class ComputerCraftProxyCommon implements IComputerCraftProxy
handler.registerCommand( new CommandComputerCraft() );
}
@SubscribeEvent
public void registerBlocks( RegistryEvent.Register<Block> event )
private void registerProviders()
{
IForgeRegistry<Block> registry = event.getRegistry();
// Computer
ComputerCraft.Blocks.computer = new BlockComputer();
registry.register( ComputerCraft.Blocks.computer.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "computer" ) ) );
// Peripheral
ComputerCraft.Blocks.peripheral = new BlockPeripheral();
registry.register( ComputerCraft.Blocks.peripheral.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "peripheral" ) ) );
// Cable
ComputerCraft.Blocks.cable = new BlockCable();
registry.register( ComputerCraft.Blocks.cable.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "cable" ) ) );
// Command Computer
ComputerCraft.Blocks.commandComputer = new BlockCommandComputer();
registry.register( ComputerCraft.Blocks.commandComputer.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "command_computer" ) ) );
// Command Computer
ComputerCraft.Blocks.advancedModem = new BlockAdvancedModem();
registry.register( ComputerCraft.Blocks.advancedModem.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "advanced_modem" ) ) );
// Full block modem
ComputerCraft.Blocks.wiredModemFull = new BlockWiredModemFull();
registry.register( ComputerCraft.Blocks.wiredModemFull.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full" ) ) );
}
@SubscribeEvent
public void registerItems( RegistryEvent.Register<Item> event )
{
IForgeRegistry<Item> registry = event.getRegistry();
// Computer
registry.register( new ItemComputer( ComputerCraft.Blocks.computer ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "computer" ) ) );
// Peripheral
registry.register( new ItemPeripheral( ComputerCraft.Blocks.peripheral ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "peripheral" ) ) );
// Cable
registry.register( new ItemCable( ComputerCraft.Blocks.cable ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "cable" ) ) );
// Command Computer
registry.register( new ItemCommandComputer( ComputerCraft.Blocks.commandComputer ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "command_computer" ) ) );
// Advanced modem
registry.register( new ItemAdvancedModem( ComputerCraft.Blocks.advancedModem ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "advanced_modem" ) ) );
// Full block modem
registry.register( new ItemWiredModemFull( ComputerCraft.Blocks.wiredModemFull ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full" ) ) );
// Items
// Floppy Disk
ComputerCraft.Items.disk = new ItemDiskLegacy();
registry.register( ComputerCraft.Items.disk.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "disk" ) ) );
ComputerCraft.Items.diskExpanded = new ItemDiskExpanded();
registry.register( ComputerCraft.Items.diskExpanded.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "disk_expanded" ) ) );
// Treasure Disk
ComputerCraft.Items.treasureDisk = new ItemTreasureDisk();
registry.register( ComputerCraft.Items.treasureDisk.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "treasure_disk" ) ) );
// Printout
ComputerCraft.Items.printout = new ItemPrintout();
registry.register( ComputerCraft.Items.printout.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "printout" ) ) );
// Pocket computer
ComputerCraft.Items.pocketComputer = new ItemPocketComputer();
registry.register( ComputerCraft.Items.pocketComputer.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "pocket_computer" ) ) );
registerUpgrades();
}
@SubscribeEvent
public void registerRecipes( RegistryEvent.Register<IRecipe> event )
{
IForgeRegistry<IRecipe> registry = event.getRegistry();
// Impostor Disk recipes (to fool NEI)
ItemStack paper = new ItemStack( Items.PAPER, 1 );
ItemStack redstone = new ItemStack( Items.REDSTONE, 1 );
for( int colour = 0; colour < 16; colour++ )
{
ItemStack disk = ItemDiskLegacy.createFromIDAndColour( -1, null, Colour.values()[colour].getHex() );
ItemStack dye = new ItemStack( Items.DYE, 1, colour );
int diskIdx = 0;
ItemStack[] disks = new ItemStack[15];
for( int otherColour = 0; otherColour < 16; otherColour++ )
{
if( colour != otherColour )
{
disks[diskIdx++] = ItemDiskLegacy.createFromIDAndColour( -1, null, Colour.values()[otherColour].getHex() );
}
}
// Normal recipe
registry.register(
new ImpostorShapelessRecipe( "computercraft:disk", disk, new ItemStack[] { redstone, paper, dye } )
.setRegistryName( new ResourceLocation( "computercraft:disk_imposter_" + colour ) )
);
// Conversion recipe
registry.register(
new ImpostorShapelessRecipe( "computercraft:disk", disk, NonNullList.from( Ingredient.EMPTY, Ingredient.fromStacks( disks ), Ingredient.fromStacks( dye ) ) )
.setRegistryName( new ResourceLocation( "computercraft:disk_imposter_convert_" + colour ) )
);
}
// Impostor Pocket Computer recipes (to fool NEI)
ItemStack pocketComputer = PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.Normal, null );
ItemStack advancedPocketComputer = PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.Advanced, null );
for( IPocketUpgrade upgrade : PocketUpgrades.getVanillaUpgrades() )
{
registry.register( new ImpostorRecipe(
"computercraft:normal_pocket_upgrade",
1, 2,
new ItemStack[] { upgrade.getCraftingItem(), pocketComputer },
PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.Normal, upgrade )
).setRegistryName( new ResourceLocation( "computercraft:normal_pocket_upgrade_" + upgrade.getUpgradeID().toString().replace( ':', '_' ) ) )
);
registry.register(
new ImpostorRecipe( "computercraft:advanced_pocket_upgrade",
1, 2,
new ItemStack[] { upgrade.getCraftingItem(), advancedPocketComputer },
PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.Advanced, upgrade )
).setRegistryName( new ResourceLocation( "computercraft:advanced_pocket_upgrade_" + upgrade.getUpgradeID().toString().replace( ':', '_' ) ) )
);
}
}
private void registerUpgrades()
{
// Register pocket upgrades
ComputerCraft.PocketUpgrades.wirelessModem = new PocketModem( false );
ComputerCraftAPI.registerPocketUpgrade( ComputerCraft.PocketUpgrades.wirelessModem );
ComputerCraft.PocketUpgrades.advancedModem = new PocketModem( true );
ComputerCraftAPI.registerPocketUpgrade( ComputerCraft.PocketUpgrades.advancedModem );
ComputerCraft.PocketUpgrades.pocketSpeaker = new PocketSpeaker();
ComputerCraftAPI.registerPocketUpgrade( ComputerCraft.PocketUpgrades.pocketSpeaker );
}
@SubscribeEvent
public void remapItems( RegistryEvent.MissingMappings<Item> mappings )
{
// We have to use mappings.getAllMappings() as the mod ID is upper case but the domain lower.
for( RegistryEvent.MissingMappings.Mapping<Item> mapping : mappings.getAllMappings() )
{
String domain = mapping.key.getNamespace();
if( !domain.equalsIgnoreCase( ComputerCraft.MOD_ID ) ) continue;
String key = mapping.key.getPath();
if( key.equalsIgnoreCase( "CC-Computer" ) )
{
mapping.remap( Item.getItemFromBlock( ComputerCraft.Blocks.computer ) );
}
else if( key.equalsIgnoreCase( "CC-Peripheral" ) )
{
mapping.remap( Item.getItemFromBlock( ComputerCraft.Blocks.peripheral ) );
}
else if( key.equalsIgnoreCase( "CC-Cable" ) )
{
mapping.remap( Item.getItemFromBlock( ComputerCraft.Blocks.cable ) );
}
else if( key.equalsIgnoreCase( "diskExpanded" ) )
{
mapping.remap( ComputerCraft.Items.diskExpanded );
}
else if( key.equalsIgnoreCase( "treasureDisk" ) )
{
mapping.remap( ComputerCraft.Items.treasureDisk );
}
else if( key.equalsIgnoreCase( "pocketComputer" ) )
{
mapping.remap( ComputerCraft.Items.pocketComputer );
}
}
}
@SubscribeEvent
public void remapBlocks( RegistryEvent.MissingMappings<Block> mappings )
{
// We have to use mappings.getAllMappings() as the mod ID is upper case but the domain lower.
for( RegistryEvent.MissingMappings.Mapping<Block> mapping : mappings.getAllMappings() )
{
String domain = mapping.key.getNamespace();
if( !domain.equalsIgnoreCase( ComputerCraft.MOD_ID ) ) continue;
String key = mapping.key.getPath();
if( key.equalsIgnoreCase( "CC-Computer" ) )
{
mapping.remap( ComputerCraft.Blocks.computer );
}
else if( key.equalsIgnoreCase( "CC-Peripheral" ) )
{
mapping.remap( ComputerCraft.Blocks.peripheral );
}
else if( key.equalsIgnoreCase( "CC-Cable" ) )
{
mapping.remap( ComputerCraft.Blocks.cable );
}
}
}
private void registerTileEntities()
{
// Tile Entities
GameRegistry.registerTileEntity( TileComputer.class, new ResourceLocation( ComputerCraft.MOD_ID, "computer" ) );
GameRegistry.registerTileEntity( TileDiskDrive.class, new ResourceLocation( ComputerCraft.MOD_ID, "diskdrive" ) );
GameRegistry.registerTileEntity( TileWirelessModem.class, new ResourceLocation( ComputerCraft.MOD_ID, "wirelessmodem" ) );
GameRegistry.registerTileEntity( TileMonitor.class, new ResourceLocation( ComputerCraft.MOD_ID, "monitor" ) );
GameRegistry.registerTileEntity( TilePrinter.class, new ResourceLocation( ComputerCraft.MOD_ID, "ccprinter" ) );
GameRegistry.registerTileEntity( TileCable.class, new ResourceLocation( ComputerCraft.MOD_ID, "wiredmodem" ) );
GameRegistry.registerTileEntity( TileCommandComputer.class, new ResourceLocation( ComputerCraft.MOD_ID, "command_computer" ) );
GameRegistry.registerTileEntity( TileAdvancedModem.class, new ResourceLocation( ComputerCraft.MOD_ID, "advanced_modem" ) );
GameRegistry.registerTileEntity( TileSpeaker.class, new ResourceLocation( ComputerCraft.MOD_ID, "speaker" ) );
GameRegistry.registerTileEntity( TileWiredModemFull.class, new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full" ) );
// Register peripheral providers
ComputerCraftAPI.registerPeripheralProvider( new DefaultPeripheralProvider() );
if( ComputerCraft.enableCommandBlock )
@@ -369,66 +102,12 @@ public abstract class ComputerCraftProxyCommon implements IComputerCraftProxy
CapabilityWiredElement.register();
}
private void registerForgeHandlers()
public class GuiHandler implements IGuiHandler
{
ForgeHandlers handlers = new ForgeHandlers();
MinecraftForge.EVENT_BUS.register( handlers );
NetworkRegistry.INSTANCE.registerGuiHandler( ComputerCraft.instance, handlers );
}
private void registerNetwork()
{
// Server messages
ComputerServerMessage.register( ComputerActionServerMessage::new, ( computer, packet ) -> {
switch( packet.getAction() )
{
case TURN_ON:
computer.turnOn();
break;
case REBOOT:
computer.reboot();
break;
case SHUTDOWN:
computer.shutdown();
break;
}
} );
ComputerServerMessage.register( QueueEventServerMessage::new, ( computer, packet ) ->
computer.queueEvent( packet.getEvent(), packet.getArgs() ) );
NetworkMessage.registerMainThread( Side.SERVER, RequestComputerMessage::new, ( context, packet ) -> {
ServerComputer computer = ComputerCraft.serverComputerRegistry.get( packet.getInstance() );
if( computer != null ) computer.sendComputerState( context.getServerHandler().player );
} );
// Client messages
NetworkMessage.registerMainThread( Side.CLIENT, PlayRecordClientMessage::new, ( computer, packet ) ->
playRecordClient( packet.getPos(), packet.getSoundEvent(), packet.getName() ) );
ComputerClientMessage.register( ComputerDataClientMessage::new, ( computer, packet ) ->
computer.setState( packet.getState(), packet.getUserData() ) );
ComputerClientMessage.register( ComputerTerminalClientMessage::new, ( computer, packet ) ->
computer.readDescription( packet.getTag() ) );
NetworkMessage.registerMainThread( Side.CLIENT, ComputerDeletedClientMessage::new, ( context, packet ) ->
ComputerCraft.clientComputerRegistry.remove( packet.getInstanceId() ) );
NetworkMessage.registerMainThread( Side.CLIENT, ChatTableClientMessage::new, ( context, packet ) ->
showTableClient( packet.getTable() ) );
}
public class ForgeHandlers implements IGuiHandler
{
private ForgeHandlers()
private GuiHandler()
{
}
// IGuiHandler implementation
@Override
public Object getServerGuiElement( int id, EntityPlayer player, World world, int x, int y, int z )
{
@@ -561,23 +240,29 @@ public abstract class ComputerCraftProxyCommon implements IComputerCraftProxy
return null;
}
}
}
// Event handlers
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID )
public final static class ForgeHandlers
{
private ForgeHandlers()
{
}
@SubscribeEvent
public void onConnectionOpened( FMLNetworkEvent.ClientConnectedToServerEvent event )
public static void onConnectionOpened( FMLNetworkEvent.ClientConnectedToServerEvent event )
{
ComputerCraft.clientComputerRegistry.reset();
}
@SubscribeEvent
public void onConnectionClosed( FMLNetworkEvent.ClientDisconnectionFromServerEvent event )
public static void onConnectionClosed( FMLNetworkEvent.ClientDisconnectionFromServerEvent event )
{
ComputerCraft.clientComputerRegistry.reset();
}
@SubscribeEvent
public void onClientTick( TickEvent.ClientTickEvent event )
public static void onClientTick( TickEvent.ClientTickEvent event )
{
if( event.phase == TickEvent.Phase.START )
{
@@ -586,7 +271,7 @@ public abstract class ComputerCraftProxyCommon implements IComputerCraftProxy
}
@SubscribeEvent
public void onServerTick( TickEvent.ServerTickEvent event )
public static void onServerTick( TickEvent.ServerTickEvent event )
{
if( event.phase == TickEvent.Phase.START )
{
@@ -596,23 +281,13 @@ public abstract class ComputerCraftProxyCommon implements IComputerCraftProxy
}
@SubscribeEvent
public void onWorldLoad( WorldEvent.Load event )
{
}
@SubscribeEvent
public void onWorldUnload( WorldEvent.Unload event )
{
}
@SubscribeEvent
public void onConfigChanged( ConfigChangedEvent.OnConfigChangedEvent event )
public static void onConfigChanged( ConfigChangedEvent.OnConfigChangedEvent event )
{
if( event.getModID().equals( ComputerCraft.MOD_ID ) ) Config.sync();
}
@SubscribeEvent
public void onContainerOpen( PlayerContainerEvent.Open event )
public static void onContainerOpen( PlayerContainerEvent.Open event )
{
// If we're opening a computer container then broadcast the terminal state
Container container = event.getContainer();

View File

@@ -6,13 +6,7 @@
package dan200.computercraft.shared.proxy;
import dan200.computercraft.shared.command.text.TableBuilder;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.io.File;
public interface IComputerCraftProxy
{
@@ -21,14 +15,4 @@ public interface IComputerCraftProxy
void init();
void initServer( MinecraftServer server );
File getWorldDir( World world );
default void playRecordClient( BlockPos pos, SoundEvent record, String info )
{
}
default void showTableClient( TableBuilder table )
{
}
}

View File

@@ -43,11 +43,6 @@ public class BlockTurtle extends BlockComputerBase
public static final PropertyDirection FACING = PropertyDirection.create( "facing", EnumFacing.Plane.HORIZONTAL );
}
public static BlockTurtle createTurtleBlock()
{
return new BlockTurtle();
}
// Members
public BlockTurtle()
@@ -182,16 +177,10 @@ public class BlockTurtle extends BlockComputerBase
@Override
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase player, @Nonnull ItemStack itemstack )
{
// Not sure why this is necessary
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TileTurtle )
if( tile instanceof TileTurtle && player instanceof EntityPlayer )
{
tile.setWorld( world ); // Not sure why this is necessary
tile.setPos( pos ); // Not sure why this is necessary
if( player instanceof EntityPlayer )
{
((TileTurtle) tile).setOwningPlayer( ((EntityPlayer) player).getGameProfile() );
}
((TileTurtle) tile).setOwningPlayer( ((EntityPlayer) player).getGameProfile() );
}
// Set direction

View File

@@ -13,7 +13,6 @@ import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.turtle.*;
import dan200.computercraft.shared.TurtleUpgrades;
import dan200.computercraft.shared.computer.blocks.ComputerProxy;
import dan200.computercraft.shared.computer.blocks.TileComputerBase;
import dan200.computercraft.shared.computer.core.ComputerFamily;
@@ -185,11 +184,11 @@ public class TurtleBrain implements ITurtleAccess
int subType = nbt.getInteger( "subType" );
if( (subType & 0x1) > 0 )
{
leftUpgrade = ComputerCraft.Upgrades.diamondPickaxe;
leftUpgrade = ComputerCraft.TurtleUpgrades.diamondPickaxe;
}
if( (subType & 0x2) > 0 )
{
rightUpgrade = ComputerCraft.Upgrades.wirelessModem;
rightUpgrade = ComputerCraft.TurtleUpgrades.wirelessModem;
}
}
else
@@ -199,22 +198,22 @@ public class TurtleBrain implements ITurtleAccess
{
if( nbt.getTagId( "leftUpgrade" ) == Constants.NBT.TAG_STRING )
{
leftUpgrade = TurtleUpgrades.get( nbt.getString( "leftUpgrade" ) );
leftUpgrade = dan200.computercraft.shared.TurtleUpgrades.get( nbt.getString( "leftUpgrade" ) );
}
else
{
leftUpgrade = TurtleUpgrades.get( nbt.getShort( "leftUpgrade" ) );
leftUpgrade = dan200.computercraft.shared.TurtleUpgrades.get( nbt.getShort( "leftUpgrade" ) );
}
}
if( nbt.hasKey( "rightUpgrade" ) )
{
if( nbt.getTagId( "rightUpgrade" ) == Constants.NBT.TAG_STRING )
{
rightUpgrade = TurtleUpgrades.get( nbt.getString( "rightUpgrade" ) );
rightUpgrade = dan200.computercraft.shared.TurtleUpgrades.get( nbt.getString( "rightUpgrade" ) );
}
else
{
rightUpgrade = TurtleUpgrades.get( nbt.getShort( "rightUpgrade" ) );
rightUpgrade = dan200.computercraft.shared.TurtleUpgrades.get( nbt.getShort( "rightUpgrade" ) );
}
}
}
@@ -346,7 +345,7 @@ public class TurtleBrain implements ITurtleAccess
// Upgrades
if( nbt.hasKey( "leftUpgrade" ) )
{
setUpgrade( TurtleSide.Left, TurtleUpgrades.get( nbt.getString( "leftUpgrade" ) ) );
setUpgrade( TurtleSide.Left, dan200.computercraft.shared.TurtleUpgrades.get( nbt.getString( "leftUpgrade" ) ) );
}
else
{
@@ -354,7 +353,7 @@ public class TurtleBrain implements ITurtleAccess
}
if( nbt.hasKey( "rightUpgrade" ) )
{
setUpgrade( TurtleSide.Right, TurtleUpgrades.get( nbt.getString( "rightUpgrade" ) ) );
setUpgrade( TurtleSide.Right, dan200.computercraft.shared.TurtleUpgrades.get( nbt.getString( "rightUpgrade" ) ) );
}
else
{

View File

@@ -226,7 +226,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
// Start claiming entity drops
Entity hitEntity = hit.getKey();
Vec3d hitPos = hit.getValue();
DropConsumer.instance().set(
DropConsumer.set(
hitEntity,
drop -> InventoryUtil.storeItems( drop, turtle.getItemHandler(), turtle.getSelectedSlot() )
);
@@ -266,7 +266,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
}
// Stop claiming drops
List<ItemStack> remainingDrops = DropConsumer.instance().clear();
List<ItemStack> remainingDrops = DropConsumer.clear();
for( ItemStack remaining : remainingDrops )
{
WorldUtil.dropItemStack( remaining, world, position, turtle.getDirection().getOpposite() );

View File

@@ -54,6 +54,10 @@ public abstract class ItemTurtleBase extends ItemComputerBase implements ITurtle
if( !isInCreativeTab( tabs ) ) return;
ComputerFamily family = getFamily();
ItemStack normalStack = TurtleItemFactory.create( -1, null, -1, family, null, null, 0, null );
if( !normalStack.isEmpty() && normalStack.getItem() == this ) list.add( normalStack );
for( ITurtleUpgrade upgrade : TurtleUpgrades.getVanillaUpgrades() )
{
if( !TurtleUpgrades.suitableForFamily( family, upgrade ) ) continue;

View File

@@ -31,8 +31,8 @@ public class ItemTurtleLegacy extends ItemTurtleBase
public ItemStack create( int id, String label, int colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, int fuelLevel, ResourceLocation overlay )
{
// Legacy turtles only support pickaxes and modems
if( (leftUpgrade != null && leftUpgrade != ComputerCraft.Upgrades.diamondPickaxe) ||
(rightUpgrade != null && rightUpgrade != ComputerCraft.Upgrades.wirelessModem) ||
if( (leftUpgrade != null && leftUpgrade != ComputerCraft.TurtleUpgrades.diamondPickaxe) ||
(rightUpgrade != null && rightUpgrade != ComputerCraft.TurtleUpgrades.wirelessModem) ||
(colour != -1) || (overlay != null) )
{
return null;
@@ -114,7 +114,7 @@ public class ItemTurtleLegacy extends ItemTurtleBase
{
if( (damage & 0x1) > 0 )
{
return ComputerCraft.Upgrades.diamondPickaxe;
return ComputerCraft.TurtleUpgrades.diamondPickaxe;
}
break;
}
@@ -122,7 +122,7 @@ public class ItemTurtleLegacy extends ItemTurtleBase
{
if( (damage & 0x2) > 0 )
{
return ComputerCraft.Upgrades.wirelessModem;
return ComputerCraft.TurtleUpgrades.wirelessModem;
}
break;
}

View File

@@ -11,7 +11,6 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.turtle.blocks.ITurtleTile;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
@@ -43,14 +42,14 @@ public class TurtleItemFactory
{
case Normal:
{
ItemTurtleBase legacy = ((ItemTurtleBase) Item.getItemFromBlock( ComputerCraft.Blocks.turtle ));
ItemTurtleBase normal = ((ItemTurtleBase) Item.getItemFromBlock( ComputerCraft.Blocks.turtleExpanded ));
ItemTurtleBase legacy = ComputerCraft.Items.turtle;
ItemTurtleBase normal = ComputerCraft.Items.turtleExpanded;
ItemStack legacyStack = legacy.create( id, label, colour, leftUpgrade, rightUpgrade, fuelLevel, overlay );
return (legacyStack != null) ? legacyStack : normal.create( id, label, colour, leftUpgrade, rightUpgrade, fuelLevel, overlay );
return legacyStack != null ? legacyStack : normal.create( id, label, colour, leftUpgrade, rightUpgrade, fuelLevel, overlay );
}
case Advanced:
{
ItemTurtleBase advanced = ((ItemTurtleBase) Item.getItemFromBlock( ComputerCraft.Blocks.turtleAdvanced ));
ItemTurtleBase advanced = ComputerCraft.Items.turtleAdvanced;
return advanced.create( id, label, colour, leftUpgrade, rightUpgrade, fuelLevel, overlay );
}
default:

View File

@@ -42,6 +42,21 @@ public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade
this( id, legacyId, type, adjective, new ItemStack( block ) );
}
public AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, ItemStack stack )
{
this( id, legacyId, type, "upgrade." + id + ".adjective", stack );
}
public AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, Item item )
{
this( id, legacyId, type, new ItemStack( item ) );
}
public AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, Block block )
{
this( id, legacyId, type, new ItemStack( block ) );
}
@Nonnull
@Override
public final ResourceLocation getUpgradeID()

View File

@@ -16,6 +16,11 @@ public class TurtleAxe extends TurtleTool
super( id, legacyId, adjective, item );
}
public TurtleAxe( ResourceLocation id, int legacyId, Item item )
{
super( id, legacyId, item );
}
@Override
protected float getDamageMultiplier()
{

View File

@@ -31,12 +31,9 @@ public class TurtleCraftingTable extends AbstractTurtleUpgrade
@SideOnly( Side.CLIENT )
private ModelResourceLocation m_rightModel;
public TurtleCraftingTable( int legacyId )
public TurtleCraftingTable( ResourceLocation id, int legacyId )
{
super(
new ResourceLocation( "minecraft", "crafting_table" ), legacyId, TurtleUpgradeType.Peripheral,
"upgrade.minecraft:crafting_table.adjective", Blocks.CRAFTING_TABLE
);
super( id, legacyId, TurtleUpgradeType.Peripheral, Blocks.CRAFTING_TABLE );
}
@Override

View File

@@ -30,6 +30,11 @@ public class TurtleHoe extends TurtleTool
super( id, legacyId, adjective, item );
}
public TurtleHoe( ResourceLocation id, int legacyId, Item item )
{
super( id, legacyId, item );
}
@Override
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
{

View File

@@ -85,9 +85,7 @@ public class TurtleModem extends AbstractTurtleUpgrade
{
super(
id, legacyId, TurtleUpgradeType.Peripheral,
advanced ? "upgrade.computercraft:advanced_modem.adjective" : "upgrade.computercraft:wireless_modem.adjective",
advanced ? PeripheralItemFactory.create( PeripheralType.AdvancedModem, null, 1 ) : PeripheralItemFactory.create( PeripheralType.WirelessModem, null, 1 )
);
this.advanced = advanced;
}

View File

@@ -30,6 +30,11 @@ public class TurtleShovel extends TurtleTool
super( id, legacyId, adjective, item );
}
public TurtleShovel( ResourceLocation id, int legacyId, Item item )
{
super( id, legacyId, item );
}
@Override
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
{

View File

@@ -20,6 +20,7 @@ import net.minecraft.client.renderer.block.model.ModelManager;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -47,21 +48,16 @@ public class TurtleSpeaker extends AbstractTurtleUpgrade
}
@Override
public BlockPos getPos()
public Vec3d getPosition()
{
return turtle.getPosition();
BlockPos pos = turtle.getPosition();
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
}
@Override
public boolean equals( IPeripheral other )
{
if( other instanceof Peripheral )
{
Peripheral otherPeripheral = (Peripheral) other;
return otherPeripheral.turtle == turtle;
}
return false;
return this == other || (other instanceof Peripheral && turtle == ((Peripheral) other).turtle);
}
}
@@ -73,8 +69,8 @@ public class TurtleSpeaker extends AbstractTurtleUpgrade
public TurtleSpeaker( ResourceLocation id, int legacyId )
{
super( id, legacyId, TurtleUpgradeType.Peripheral,
"upgrade.computercraft:speaker.adjective",
super(
id, legacyId, TurtleUpgradeType.Peripheral,
PeripheralItemFactory.create( PeripheralType.Speaker, null, 1 )
);
}

View File

@@ -21,6 +21,11 @@ public class TurtleSword extends TurtleTool
super( id, legacyId, adjective, item );
}
public TurtleSword( ResourceLocation id, int legacyId, Item item )
{
super( id, legacyId, item );
}
@Override
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
{

View File

@@ -55,6 +55,12 @@ public class TurtleTool extends AbstractTurtleUpgrade
m_item = new ItemStack( item, 1, 0 );
}
public TurtleTool( ResourceLocation id, int legacyID, Item item )
{
super( id, legacyID, TurtleUpgradeType.Tool, item );
m_item = new ItemStack( item, 1, 0 );
}
@Nonnull
@Override
@SideOnly( Side.CLIENT )
@@ -135,7 +141,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
}
// Start claiming entity drops
DropConsumer.instance().set( hitEntity, turtleDropConsumer( turtle ) );
DropConsumer.set( hitEntity, turtleDropConsumer( turtle ) );
// Attack the entity
boolean attacked = false;
@@ -225,7 +231,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
}
// Consume the items the block drops
DropConsumer.instance().set( world, blockPosition, turtleDropConsumer( turtle ) );
DropConsumer.set( world, blockPosition, turtleDropConsumer( turtle ) );
TileEntity tile = world.getTileEntity( blockPosition );
@@ -257,7 +263,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
private void stopConsuming( ITurtleAccess turtle )
{
List<ItemStack> extra = DropConsumer.instance().clear();
List<ItemStack> extra = DropConsumer.clear();
for( ItemStack remainder : extra )
{
WorldUtil.dropItemStack( remainder, turtle.getWorld(), turtle.getPosition(), turtle.getDirection().getOpposite() );

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.shared.util;
import dan200.computercraft.ComputerCraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
@@ -15,6 +16,7 @@ import net.minecraft.world.World;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.living.LivingDropsEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -23,23 +25,21 @@ import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class DropConsumer
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID )
public final class DropConsumer
{
private static final DropConsumer instance = new DropConsumer();
public static DropConsumer instance()
private DropConsumer()
{
return instance;
}
private Function<ItemStack, ItemStack> dropConsumer;
private List<ItemStack> remainingDrops;
private WeakReference<World> dropWorld;
private BlockPos dropPos;
private AxisAlignedBB dropBounds;
private WeakReference<Entity> dropEntity;
private static Function<ItemStack, ItemStack> dropConsumer;
private static List<ItemStack> remainingDrops;
private static WeakReference<World> dropWorld;
private static BlockPos dropPos;
private static AxisAlignedBB dropBounds;
private static WeakReference<Entity> dropEntity;
public void set( Entity entity, Function<ItemStack, ItemStack> consumer )
public static void set( Entity entity, Function<ItemStack, ItemStack> consumer )
{
dropConsumer = consumer;
remainingDrops = new ArrayList<>();
@@ -51,7 +51,7 @@ public class DropConsumer
entity.captureDrops = true;
}
public void set( World world, BlockPos pos, Function<ItemStack, ItemStack> consumer )
public static void set( World world, BlockPos pos, Function<ItemStack, ItemStack> consumer )
{
dropConsumer = consumer;
remainingDrops = new ArrayList<>();
@@ -61,7 +61,7 @@ public class DropConsumer
dropBounds = new AxisAlignedBB( pos ).grow( 2, 2, 2 );
}
public List<ItemStack> clear()
public static List<ItemStack> clear()
{
if( dropEntity != null )
{
@@ -89,14 +89,14 @@ public class DropConsumer
return remainingStacks;
}
private void handleDrops( ItemStack stack )
private static void handleDrops( ItemStack stack )
{
ItemStack remaining = dropConsumer.apply( stack );
if( !remaining.isEmpty() ) remainingDrops.add( remaining );
}
@SubscribeEvent( priority = EventPriority.LOWEST )
public void onEntityLivingDrops( LivingDropsEvent event )
public static void onEntityLivingDrops( LivingDropsEvent event )
{
// Capture any mob drops for the current entity
if( dropEntity != null && event.getEntity() == dropEntity.get() )
@@ -108,7 +108,7 @@ public class DropConsumer
}
@SubscribeEvent( priority = EventPriority.LOWEST )
public void onHarvestDrops( BlockEvent.HarvestDropsEvent event )
public static void onHarvestDrops( BlockEvent.HarvestDropsEvent event )
{
// Capture block drops for the current entity
if( dropWorld != null && dropWorld.get() == event.getWorld()
@@ -123,7 +123,7 @@ public class DropConsumer
}
@SubscribeEvent( priority = EventPriority.LOWEST )
public void onEntitySpawn( EntityJoinWorldEvent event )
public static void onEntitySpawn( EntityJoinWorldEvent event )
{
// Capture any nearby item spawns
if( dropWorld != null && dropWorld.get() == event.getWorld() && event.getEntity() instanceof EntityItem

Some files were not shown because too many files have changed in this diff Show More