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

Compare commits

..

47 Commits

Author SHA1 Message Date
SquidDev
92567b4d7e Merge branch 'master' into mc-1.14.x 2019-11-29 20:23:56 +00:00
SquidDev
0ae70fed13 Correctly implement mouse movement within read
Note to self: if you're going to modify the rom, make sure you test on a
computer which doesn't overwrite the rom with something else.
2019-11-29 20:15:58 +00:00
SquidDev
3b7300543a Correctly invalidate the ROM mount cache
Before it would remain the same across world reloads, and thus would be
out-of-date after leaving the first world. This architecture technically
allows for running multiple servers at once, though that's not going to
matter that soon.
2019-11-26 18:16:49 +00:00
SquidDev
642351af1a Merge branch 'master' into mc-1.14.x 2019-11-25 09:15:20 +00:00
SquidDev
121802a683 Bump version 2019-11-25 08:58:36 +00:00
SquidDev
08cf55e55f Correct implementation of clamp
That's what I get for inlining definitions.
2019-11-23 14:36:43 +00:00
SquidDev
3c8c0d78ef Use correct render type for turtles
This fixes them not rendering particles when broken. Particle rendering
is a little janky right now, as it uses the whole texture - we should
probably split up the texture into smaller images. Fixes #315
2019-11-23 13:24:36 +00:00
SquidDev
c4d18aa9ca Allow navigating read's input using the mouse 2019-11-23 13:21:07 +00:00
SquidDev
2d4a87adc9 Fix the eye height for turtle fake players
This was causing the eye height of the turtle to be above it when
placing down, causing all sorts of funkiness. Fixes #297
2019-11-23 13:05:26 +00:00
SquidDev
bedac71e3d Add a fake network handler to the TurtleFakePlayer
This should fix several issues (see #304, etc...). I'll try to get round
to PRing this into Forge at some point, though on the other hand this is
/super/ ugly.
2019-11-23 12:12:02 +00:00
SquidDev
ee4e42e730 Dont' remove treasure disks from JEI
This shouldn't matter either way - we don't expose it in the creative
menu, and there's no recipes for it. This should shut up a log message
though. Fixes #305.
2019-11-23 11:23:25 +00:00
SquidDev
0de75f05dd Make parameter name a bit nicer
Woops
2019-11-23 11:17:03 +00:00
SquidDev
be6dd21e54 Make monitors "properly" solid blocks
This fixes monitor rendering underwater (closes #314). By default,
isSolid returns true if the render layer is SOLID. As we use CUTOUT due
to our funky TE rendering, we need to override this to return true
anyway.

This will cause some side effects, as monitors now blocking light
propagation, but I don't think that's the end of the world.
2019-11-23 10:31:55 +00:00
SquidDev
927ddb0bde Remove Charset and MCMP integration for now
It's not clear if either of these are coming back soon, and it should be
fairly simple to add them back when needed.
2019-11-23 10:14:32 +00:00
SquidDev
a8fadabaf1 Correct spelling in error message 2019-11-23 09:59:37 +00:00
SquidDev
44d0f78c1b Bump versions 2019-11-23 09:58:54 +00:00
SquidDev
38f9a015ca Wrap all remaining uses of Grgit
This allows you to build from a zip folder of CC:T. Fixes #307. Also fix
the build, woops.
2019-10-30 17:07:29 +00:00
SquidDev
c311cdc6f5 Make our Javadoc validation a little stricter
I'm not sure there's much utility in this, but still feels worth doing.
2019-10-27 15:16:47 +00:00
SquidDev
a93e0f3284 Expose ArgumentHelper in the public API
This is sufficiently useful a class, that it's worthwhile exposing it.
Hopefully we can slowly encourage other mods to migrate to it (well, at
least in 1.14), and so make error messages more consistent.

Also:
 - Add Javadoc for all public methods
 - Clarify the method names a little (getNumber -> getDouble,
   getReal -> getFiniteDouble).
 - Make the *Table methods return a Map<?,?> instead of
   Map<Object, Object>.
2019-10-27 14:29:07 +00:00
SquidDev
14b3065ba4 Check for trailing whitespace
I'd rather assumed one of the existing checkers did this already, but
apparently not.
2019-10-16 09:22:38 +01:00
SquidDev
3ea2d6a0a8 Merge branch 'master' into mc-1.14.x 2019-10-04 19:56:49 +01:00
SquidDev
c802290437 Bump version 2019-10-04 19:52:02 +01:00
SquidDev
f7781defe5 Merge branch 'master' into mc-1.14.x 2019-10-04 19:44:34 +01:00
SquidDev
418420523a Proxy the current turtle's inventory
Previously we were just returning the current tile. However, if someone
was holding a reference to this inventory (such as a GUI), then it'd be
outdated and invalid once the turtle had moved.

This caused a couple of issues:
 - turtle_inventory events would not be fired when moving items in the
   turtle GUI.
 - As of 75e2845c01, turtles would no
   longer share their inventory state after moving. Thus, removing items
   from a GUI using an invalid inventory would move them from an old
   tile, duplicating the items.

Fixes #298, fixes #300
2019-10-04 16:53:48 +01:00
SquidDev
d342a1f368 Prevent wired modems dropping on block change
Fixes #303
2019-10-01 20:06:38 +01:00
SquidDev
81f85361d5 Move Lua files to the correct location
I really need to fix this.
2019-10-01 19:43:03 +01:00
SquidDev
f1621b30ec Remove redundant imports 2019-10-01 19:15:13 +01:00
SquidDev
d4f6a594b6 Merge branch 'master' into mc-1.14.x 2019-10-01 18:58:40 +01:00
SquidDev
ff5ba5c131 Update GUI code to be compatible with 1.14.4
Not quite sure when this changed, but I'm fairly sure isMouseOver wasn't
a thing when I wrote this. Or I'm a plonker. Both are possible.

Also fixes mouse dragging not being handled in turtles.

Fixes #299
2019-10-01 18:53:46 +01:00
SquidDev
4243f30308 Bump Forge version 2019-10-01 18:53:38 +01:00
Jonathan Coates
813e91073d Merge pull request #302 from Wendelstein7/master
Fixed turtle property category
2019-09-30 15:59:55 +01:00
Jonathan Coates
7250f22ff6 Update CI to also run on PRs 2019-09-30 15:37:52 +01:00
Wendelstein7
db31a53bba Fixed turtle property category
Likely was a leftover from copy pasting and a tired programmer.
2019-09-30 15:15:22 +02:00
SquidDev
3023f235a4 Goodbye Travis, I'm with GH Actions now 2019-09-27 08:56:53 +01:00
SquidDev
79cd8b4da5 Also return the number of affected entities
Closes #293. Doesn't really solve anything there aside from exposing the
number, but sadly there's not really anything obvious I can do on my end
- the command API just doesn't expose anything else.
2019-09-15 18:48:51 +01:00
Jonathan Coates
8e4d311cd9 Refactor shell completion into a separate module (#281)
- Adds cc.completions module, with a couple of helper functions for
   working with the more general completion functionality (i.e. that
   provided by read).
 - Adds cc.shell.completions module, which provides shell-specific
   completion functions.
 - Add a "program completion builder", which allows you to write stuff
   like this:

       shell.setCompletionFunction( "rom/programs/redstone.lua", 
         completion.build(
           { completion.choice, { "probe", "set ", "pulse " } },
           completion.side) )

Closes #232
2019-09-15 18:48:40 +01:00
SquidDev
9bd8c86a94 Change event priority to HIGHEST
See the comments in a802f25dd6 -
effectively we want to make sure we arrive before any other thing which
may capture items (some magnet mods, etc...).
2019-09-15 16:42:21 +01:00
Jonathan Coates
cbc0c1d0b6 A little experiment with GitHub actions
Let's give this a go.
2019-09-14 09:16:13 +01:00
SquidDev
49c37857d4 Window.reposition now allow changing the redirect buffer
See #270
2019-09-13 20:55:20 +01:00
SquidDev
b1139a4bf6 Bump to Forge RB 2019-09-12 21:09:57 +01:00
Jonathan Coates
7e8559278e Merge pull request #291 from parly/patch-1.14.x-1
Fix os.time() and os.day() behavior on 1.14
2019-08-19 15:34:20 +01:00
parly
1e7f1c98fc Fix os.time() and os.day() behavior 2019-08-19 23:04:57 +09:00
SquidDev
a802f25dd6 Do not listen to block/entity drop events
It appears several mods inject their own drops on the LOWEST priority,
meaning that we capture the existing drops, and the other mod will clear
the (now empty) drop list and add its own, resulting in dupe bugs.

While I'd argue it's somewhat dubious doing this on the LOWEST priority,
it's not a battle I'm prepared to fight. For now, we just remove the
block/entity drop handlers, and handle all drop logic when entities are
spawned.

Fixes #288
2019-08-19 10:33:53 +01:00
SquidDev
f1d6d21d6d Add back texture registration hook
I totally forgot to do this when Forge re-added this functionality.

Fixes #285
2019-08-18 16:12:16 +01:00
Jonathan Coates
a80302c513 Merge pull request #287 from Lignum/patch-1
The pettiest of spelling fixes
2019-08-15 06:59:59 +01:00
Lignum
1c46949da7 Available 2019-08-15 07:37:02 +02:00
SquidDev
46d78af068 Fix changelog being out-of-sync 2019-08-04 11:05:44 +01:00
122 changed files with 1787 additions and 1147 deletions

18
.github/workflows/main-ci.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
name: Build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Gradle
run: ./gradlew build --no-daemon

View File

@@ -1,14 +0,0 @@
language: java
script: ./gradlew build --no-daemon
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/s
jdk:
- openjdk8

View File

@@ -1,5 +1,5 @@
# ![CC: Tweaked](logo.png)
[![Current build status](https://travis-ci.org/SquidDev-CC/CC-Tweaked.svg?branch=master)](https://travis-ci.org/SquidDev-CC/CC-Tweaked "Current build status") [![Download CC: Tweaked on CurseForge](http://cf.way2muchnoise.eu/title/cc-tweaked.svg)](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
[![Current build status](https://github.com/SquidDev-CC/CC-Tweaked/workflows/Build/badge.svg)](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [![Download CC: Tweaked on CurseForge](http://cf.way2muchnoise.eu/title/cc-tweaked.svg)](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
turtles and more to Minecraft.

View File

@@ -9,7 +9,7 @@ buildscript {
}
dependencies {
classpath 'com.google.code.gson:gson:2.8.1'
classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.134'
classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.154'
classpath 'net.sf.proguard:proguard-gradle:6.1.0beta2'
classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
}
@@ -90,15 +90,15 @@ configurations {
}
dependencies {
checkstyle "com.puppycrawl.tools:checkstyle:8.21"
checkstyle "com.puppycrawl.tools:checkstyle:8.25"
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
compileOnly fg.deobf("mezz.jei:jei-1.14.3:6.0.0.7:api")
compileOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.25:api")
// deobfProvided "pl.asie:Charset-Lib:0.5.4.6"
// deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
runtimeOnly fg.deobf("mezz.jei:jei-1.14.3:6.0.0.7")
runtimeOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.25")
shade 'org.squiddev:Cobalt:0.5.0-SNAPSHOT'
@@ -108,15 +108,6 @@ dependencies {
deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
}
sourceSets {
main {
java {
exclude 'dan200/computercraft/shared/integration/mcmp'
exclude 'dan200/computercraft/shared/integration/charset'
}
}
}
// Compile tasks
javadoc {
@@ -374,6 +365,7 @@ task checkRelease {
if (!ok) throw new IllegalStateException("Could not check release")
}
}
check.dependsOn checkRelease
curseforge {
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
@@ -445,7 +437,9 @@ githubRelease {
token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
owner 'SquidDev-CC'
repo 'CC-Tweaked'
targetCommitish { Grgit.open(dir: '.').branch.current().name }
try {
targetCommitish = Grgit.open(dir: '.').branch.current().name
} catch(Exception ignored) { }
tagName "v${mc_version}-${mod_version}"
releaseName "[${mc_version}] ${mod_version}"

View File

@@ -14,9 +14,7 @@
<!-- Annotations -->
<module name="AnnotationLocation" />
<module name="AnnotationUseStyle" />
<module name="MissingDeprecated">
<property name="skipNoJavadoc" value="true" />
</module>
<module name="MissingDeprecated" />
<module name="MissingOverride" />
<!-- Blocks -->
@@ -57,6 +55,9 @@
<module name="SimplifyBooleanReturn" />
<module name="StringLiteralEquality" />
<module name="UnnecessaryParentheses" />
<module name="UnnecessarySemicolonAfterTypeMemberDeclaration" />
<module name="UnnecessarySemicolonInTryWithResources" />
<module name="UnnecessarySemicolonInEnumeration" />
<!-- Imports -->
<module name="CustomImportOrder" />
@@ -65,10 +66,16 @@
<module name="UnusedImports" />
<!-- Javadoc -->
<!-- TODO: Missing* checks for the dan200.computercraft.api package? -->
<module name="AtclauseOrder" />
<!-- TODO: Cleanup our documentation before enabling JavadocMethod, JavadocStyle, JavadocType and SummaryJavadoc. -->
<module name="InvalidJavadocPosition" />
<module name="JavadocBlockTagLocation" />
<module name="JavadocMethod"/>
<module name="JavadocType"/>
<module name="JavadocStyle" />
<module name="NonEmptyAtclauseDescription" />
<module name="SingleLineJavadoc" />
<module name="SummaryJavadocCheck"/>
<!-- Misc -->
<module name="ArrayTypeStyle" />
@@ -155,5 +162,8 @@
<module name="FileTabCharacter" />
<module name="NewlineAtEndOfFile" />
<module name="RegexpSingleline">
<property name="format" value="\s+$"/>
<property name="message" value="Trailing whitespace"/>
</module>
</module>

View File

@@ -6,4 +6,7 @@
<!-- All the config options and method fields. -->
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraft.java" />
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraftAPI.java" />
<!-- Do not check for missing package Javadoc. -->
<suppress checks="JavadocStyle" files=".*[\\/]package-info.java" />
</suppressions>

View File

@@ -1,7 +1,7 @@
# Mod properties
mod_version=1.84.1
mod_version=1.85.2
# Minecraft properties
# Minecraft properties (update mods.toml when changing)
mc_version=1.14.4
forge_version=28.0.45
mappings_version=20190806-1.14.3
forge_version=28.1.71
mappings_version=20191123-1.14.3

View File

@@ -6,11 +6,9 @@
package dan200.computercraft;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.core.apis.AddressPredicate;
import dan200.computercraft.core.apis.http.websocket.Websocket;
import dan200.computercraft.core.filesystem.ResourceMount;
import dan200.computercraft.shared.Config;
import dan200.computercraft.shared.computer.blocks.BlockComputer;
import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
@@ -194,13 +192,6 @@ public final class ComputerCraft
return "${version}";
}
static IMount createResourceMount( String domain, String subPath )
{
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
ResourceMount mount = new ResourceMount( domain, subPath, manager );
return mount.exists( "" ) ? mount : null;
}
public static InputStream getResourceFile( String domain, String subPath )
{
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();

View File

@@ -6,6 +6,7 @@
package dan200.computercraft;
import com.google.common.collect.MapMaker;
import dan200.computercraft.api.ComputerCraftAPI.IComputerCraftAPI;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount;
@@ -20,20 +21,26 @@ import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.core.apis.ApiFactories;
import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.core.filesystem.ResourceMount;
import dan200.computercraft.shared.*;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import dan200.computercraft.shared.wired.WiredNode;
import net.minecraft.resources.IReloadableResourceManager;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import javax.annotation.Nonnull;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.Map;
public final class ComputerCraftAPIImpl implements IComputerCraftAPI
{
@@ -43,6 +50,9 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
{
}
private WeakReference<IReloadableResourceManager> currentResources;
private final Map<ResourceLocation, ResourceMount> mountCache = new MapMaker().weakValues().concurrencyLevel( 1 ).makeMap();
@Nonnull
@Override
public String getInstalledVersion()
@@ -72,7 +82,9 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
@Override
public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
{
return ComputerCraft.createResourceMount( domain, subPath );
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
ResourceMount mount = ResourceMount.get( domain, subPath, manager );
return mount.exists( "" ) ? mount : null;
}
@Override

View File

@@ -31,8 +31,9 @@ import javax.annotation.Nullable;
/**
* The static entry point to the ComputerCraft API.
* Members in this class must be called after mod_ComputerCraft has been initialised,
* but may be called before it is fully loaded.
*
* Members in this class must be called after mod_ComputerCraft has been initialised, but may be called before it is
* fully loaded.
*/
public final class ComputerCraftAPI
{
@@ -189,7 +190,7 @@ public final class ComputerCraftAPI
}
/**
* Registers a media provider to provide {@link IMedia} implementations for Items
* Registers a media provider to provide {@link IMedia} implementations for Items.
*
* @param provider The media provider to register.
* @see IMediaProvider
@@ -220,7 +221,7 @@ public final class ComputerCraftAPI
}
/**
* Construct a new wired node for a given wired element
* Construct a new wired node for a given wired element.
*
* @param element The element to construct it for
* @return The element's node
@@ -233,7 +234,7 @@ public final class ComputerCraftAPI
}
/**
* Get the wired network element for a block in world
* Get the wired network element for a block in world.
*
* @param world The world the block exists in
* @param pos The position the block exists in

View File

@@ -19,7 +19,7 @@ import java.util.List;
/**
* Represents a read only part of a virtual filesystem that can be mounted onto a computer using
* {@link IComputerAccess#mount(String, IMount)}
* {@link IComputerAccess#mount(String, IMount)}.
*
* Ready made implementations of this interface can be created using
* {@link ComputerCraftAPI#createSaveDirMount(World, String, long)} or
@@ -60,7 +60,7 @@ public interface IMount
void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException;
/**
* Returns the size of a file with a given path, in bytes
* Returns the size of a file with a given path, in bytes.
*
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
* @return The size of the file, in bytes.

View File

@@ -0,0 +1,335 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
/**
* Provides methods for extracting values and validating Lua arguments, such as those provided to
* {@link ILuaObject#callMethod(ILuaContext, int, Object[])} or
* {@link IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])}.
*
* This provides two sets of functions: the {@code get*} methods, which require an argument to be valid, and
* {@code opt*}, which accept a default value and return that if the argument was not present or was {@code null}.
* If the argument is of the wrong type, a suitable error message will be thrown, with a similar format to Lua's own
* error messages.
*
* <h2>Example usage:</h2>
* <pre>
* {@code
* int slot = getInt( args, 0 );
* int amount = optInt( args, 1, 64 );
* }
* </pre>
*/
public final class ArgumentHelper
{
private ArgumentHelper()
{
}
/**
* Get a string representation of the given value's type.
*
* @param value The value whose type we are trying to compute.
* @return A string representation of the given value's type, in a similar format to that provided by Lua's
* {@code type} function.
*/
@Nonnull
public static String getType( @Nullable Object value )
{
if( value == null ) return "nil";
if( value instanceof String ) return "string";
if( value instanceof Boolean ) return "boolean";
if( value instanceof Number ) return "number";
if( value instanceof Map ) return "table";
return "userdata";
}
/**
* Construct a "bad argument" exception, from an expected type and the actual value provided.
*
* @param index The argument number, starting from 0.
* @param expected The expected type for this argument.
* @param actual The actual value provided for this argument.
* @return The constructed exception, which should be thrown immediately.
*/
@Nonnull
public static LuaException badArgumentOf( int index, @Nonnull String expected, @Nullable Object actual )
{
return badArgument( index, expected, getType( actual ) );
}
/**
* Construct a "bad argument" exception, from an expected and actual type.
*
* @param index The argument number, starting from 0.
* @param expected The expected type for this argument.
* @param actual The provided type for this argument.
* @return The constructed exception, which should be thrown immediately.
*/
@Nonnull
public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual )
{
return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" );
}
/**
* Get an argument as a double.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a number.
* @see #getFiniteDouble(Object[], int) if you require this to be finite (i.e. not infinite or NaN).
*/
public static double getDouble( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "nil" );
Object value = args[index];
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return ((Number) value).doubleValue();
}
/**
* Get an argument as an integer.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not an integer.
*/
public static int getInt( @Nonnull Object[] args, int index ) throws LuaException
{
return (int) getLong( args, index );
}
/**
* Get an argument as a long.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a long.
*/
public static long getLong( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "nil" );
Object value = args[index];
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return checkFinite( index, (Number) value ).longValue();
}
/**
* Get an argument as a finite number (not infinite or NaN).
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not finite.
*/
public static double getFiniteDouble( @Nonnull Object[] args, int index ) throws LuaException
{
return checkFinite( index, getDouble( args, index ) );
}
/**
* Get an argument as a boolean.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a boolean.
*/
public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "boolean", "nil" );
Object value = args[index];
if( !(value instanceof Boolean) ) throw badArgumentOf( index, "boolean", value );
return (Boolean) value;
}
/**
* Get an argument as a string.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a string.
*/
@Nonnull
public static String getString( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "string", "nil" );
Object value = args[index];
if( !(value instanceof String) ) throw badArgumentOf( index, "string", value );
return (String) value;
}
/**
* Get an argument as a table.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a table.
*/
@Nonnull
public static Map<?, ?> getTable( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "table", "nil" );
Object value = args[index];
if( !(value instanceof Map) ) throw badArgumentOf( index, "table", value );
return (Map<?, ?>) value;
}
/**
* Get an argument as a double.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number.
*/
public static double optDouble( @Nonnull Object[] args, int index, double def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return ((Number) value).doubleValue();
}
/**
* Get an argument as an int.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number.
*/
public static int optInt( @Nonnull Object[] args, int index, int def ) throws LuaException
{
return (int) optLong( args, index, def );
}
/**
* Get an argument as a long.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number.
*/
public static long optLong( @Nonnull Object[] args, int index, long def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return checkFinite( index, (Number) value ).longValue();
}
/**
* Get an argument as a finite number (not infinite or NaN).
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not finite.
*/
public static double optFiniteDouble( @Nonnull Object[] args, int index, double def ) throws LuaException
{
return checkFinite( index, optDouble( args, index, def ) );
}
/**
* Get an argument as a boolean.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a boolean.
*/
public static boolean optBoolean( @Nonnull Object[] args, int index, boolean def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Boolean) ) throw badArgumentOf( index, "boolean", value );
return (Boolean) value;
}
/**
* Get an argument as a string.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a string.
*/
public static String optString( @Nonnull Object[] args, int index, String def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof String) ) throw badArgumentOf( index, "string", value );
return (String) value;
}
/**
* Get an argument as a table.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a table.
*/
public static Map<?, ?> optTable( @Nonnull Object[] args, int index, Map<Object, Object> def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Map) ) throw badArgumentOf( index, "table", value );
return (Map<?, ?>) value;
}
private static Number checkFinite( int index, Number value ) throws LuaException
{
checkFinite( index, value.doubleValue() );
return value;
}
private static double checkFinite( int index, double value ) throws LuaException
{
if( !Double.isFinite( value ) ) throw badArgument( index, "number", getNumericType( value ) );
return value;
}
/**
* Returns a more detailed representation of this number's type. If this is finite, it will just return "number",
* otherwise it returns whether it is infinite or NaN.
*
* @param value The value to extract the type for.
* @return This value's numeric type.
*/
@Nonnull
public static String getNumericType( double value )
{
if( Double.isNaN( value ) ) return "nan";
if( value == Double.POSITIVE_INFINITY ) return "inf";
if( value == Double.NEGATIVE_INFINITY ) return "-inf";
return "number";
}
}

View File

@@ -26,7 +26,7 @@ public interface IComputerSystem extends IComputerAccess
IFileSystem getFileSystem();
/**
* Get the label for this computer
* Get the label for this computer.
*
* @return This computer's label, or {@code null} if it is not set.
*/

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.api.peripheral;
import dan200.computercraft.api.lua.ArgumentHelper;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
@@ -58,9 +59,11 @@ public interface IPeripheral
* Lua values of type "table" will be represented by Object type Map.<br>
* Lua values of any other type will be represented by a null object.<br>
* This array will be empty if no arguments are passed.
*
* It is recommended you use {@link ArgumentHelper} in order to validate and process arguments.
* @return An array of objects, representing values you wish to return to the lua program. Integers, Doubles, Floats,
* Strings, Booleans, Maps and ILuaObject and null be converted to their corresponding lua type. All other types
* will be converted to nil.
* Strings, Booleans, Maps, ILuaObject and null be converted to their corresponding lua type. All other types will
* be converted to nil.
*
* You may return null to indicate no values should be returned.
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the
@@ -70,6 +73,7 @@ public interface IPeripheral
* InterruptedException will be thrown. This exception must not be caught or
* intercepted, or the computer will leak memory and end up in a broken state.
* @see #getMethodNames
* @see ArgumentHelper
*/
@Nullable
Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException;

View File

@@ -16,7 +16,7 @@ import javax.annotation.Nullable;
import java.util.Map;
/**
* Wrapper class for pocket computers
* Wrapper class for pocket computers.
*/
public interface IPocketAccess
{

View File

@@ -12,12 +12,12 @@ package dan200.computercraft.api.turtle;
public enum TurtleSide
{
/**
* The turtle's left side (where the pickaxe usually is on a Wireless Mining Turtle)
* The turtle's left side (where the pickaxe usually is on a Wireless Mining Turtle).
*/
Left,
/**
* The turtle's right side (where the modem usually is on a Wireless Mining Turtle)
* The turtle's right side (where the modem usually is on a Wireless Mining Turtle).
*/
Right,
}

View File

@@ -18,12 +18,12 @@ import net.minecraft.util.Direction;
public enum TurtleVerb
{
/**
* The turtle called {@code turtle.dig()}, {@code turtle.digUp()} or {@code turtle.digDown()}
* The turtle called {@code turtle.dig()}, {@code turtle.digUp()} or {@code turtle.digDown()}.
*/
Dig,
/**
* The turtle called {@code turtle.attack()}, {@code turtle.attackUp()} or {@code turtle.attackDown()}
* The turtle called {@code turtle.attack()}, {@code turtle.attackUp()} or {@code turtle.attackDown()}.
*/
Attack,
}

View File

@@ -71,7 +71,7 @@ public enum TurtleAction
EQUIP,
/**
* Inspect a block in world
* Inspect a block in world.
*
* @see TurtleBlockEvent.Inspect
*/

View File

@@ -112,7 +112,7 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
}
/**
* Get the upgrade doing the digging
* Get the upgrade doing the digging.
*
* @return The upgrade doing the digging.
*/

View File

@@ -31,7 +31,7 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent
}
/**
* Get the inventory being interacted with
* Get the inventory being interacted with.
*
* @return The inventory being interacted with, {@code null} if the item will be dropped to/sucked from the world.
*/

View File

@@ -12,6 +12,7 @@ import dan200.computercraft.shared.common.IColouredItem;
import dan200.computercraft.shared.media.items.ItemDisk;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.util.Colour;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.IUnbakedModel;
import net.minecraft.client.renderer.model.ModelResourceLocation;
@@ -58,8 +59,8 @@ public final class ClientRegistry
};
private static final String[] EXTRA_TEXTURES = new String[] {
// TODO: Gather these automatically from the model. I'm unable to get this working with Forge's current
// model loading code.
// TODO: Gather these automatically from the model. Sadly the model loader isn't available
// when stitching textures.
"block/turtle_colour",
"block/turtle_elf_overlay",
"block/turtle_crafty_face",
@@ -77,13 +78,12 @@ public final class ClientRegistry
@SubscribeEvent
public static void onTextureStitchEvent( TextureStitchEvent.Pre event )
{
/*
IResourceManager manager = Minecraft.getInstance().getResourceManager();
if( event.getMap() != Minecraft.getInstance().getTextureMap() ) return;
for( String extra : EXTRA_TEXTURES )
{
// TODO: event.getMap().registerSprite( manager, new ResourceLocation( ComputerCraft.MOD_ID, extra ) );
event.addSprite( new ResourceLocation( ComputerCraft.MOD_ID, extra ) );
}
*/
}
@SubscribeEvent

View File

@@ -176,11 +176,4 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|| super.mouseDragged( x, y, button, deltaX, deltaY );
}
@Override
public boolean mouseReleased( double x, double y, int button )
{
return (getFocused() != null && getFocused().mouseReleased( x, y, button ))
|| super.mouseReleased( x, y, button );
}
}

View File

@@ -129,4 +129,11 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY );
}
@Override
public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
{
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|| super.mouseDragged( x, y, button, deltaX, deltaY );
}
}

View File

@@ -241,11 +241,12 @@ public class WidgetTerminal implements IGuiEventListener
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
computer.mouseDrag( button + 1, charX + 1, charY + 1 );
lastMouseX = charX;
lastMouseY = charY;
lastMouseButton = button;
if( button == lastMouseButton && (charX != lastMouseX || charY != lastMouseY) )
{
computer.mouseDrag( button + 1, charX + 1, charY + 1 );
lastMouseX = charX;
lastMouseY = charY;
}
}
return false;
@@ -427,4 +428,10 @@ public class WidgetTerminal implements IGuiEventListener
ClientComputer computer = this.computer.get();
if( computer != null ) computer.queueEvent( event, args );
}
@Override
public boolean isMouseOver( double x, double y )
{
return true;
}
}

View File

@@ -95,4 +95,11 @@ public class WidgetWrapper implements IGuiEventListener
{
return height;
}
@Override
public boolean isMouseOver( double x, double y )
{
double dx = x - this.x, dy = y - this.y;
return dx >= 0 && dx < width && dy >= 0 && dy < height;
}
}

View File

@@ -18,7 +18,7 @@ import net.minecraft.util.math.MathHelper;
public abstract class ItemMapLikeRenderer
{
/**
* The main rendering method for the item
* The main rendering method for the item.
*
* @param stack The stack to render
* @see FirstPersonRenderer#renderMapFirstPerson(ItemStack)
@@ -87,7 +87,7 @@ public abstract class ItemMapLikeRenderer
}
/**
* Render an item in the middle of the screen
* Render an item in the middle of the screen.
*
* @param pitch The pitch of the player
* @param equipProgress The equip progress of this item

View File

@@ -32,7 +32,7 @@ import static dan200.computercraft.client.gui.FixedWidthFontRenderer.*;
import static dan200.computercraft.client.gui.GuiComputer.*;
/**
* Emulates map rendering for pocket computers
* Emulates map rendering for pocket computers.
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class ItemPocketRenderer extends ItemMapLikeRenderer

View File

@@ -23,7 +23,7 @@ import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAG
import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH;
/**
* Emulates map and item-frame rendering for printouts
* Emulates map and item-frame rendering for printouts.
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class ItemPrintoutRenderer extends ItemMapLikeRenderer

View File

@@ -28,32 +28,32 @@ public final class PrintoutRenderer
private static final double BG_SIZE = 256.0;
/**
* Width of a page
* Width of a page.
*/
public static final int X_SIZE = 172;
/**
* Height of a page
* Height of a page.
*/
public static final int Y_SIZE = 209;
/**
* Padding between the left and right of a page and the text
* Padding between the left and right of a page and the text.
*/
public static final int X_TEXT_MARGIN = 13;
/**
* Padding between the top and bottom of a page and the text
* Padding between the top and bottom of a page and the text.
*/
public static final int Y_TEXT_MARGIN = 11;
/**
* Width of the extra page texture
* Width of the extra page texture.
*/
private static final int X_FOLD_SIZE = 12;
/**
* Size of the leather cover
* Size of the leather cover.
*/
public static final int COVER_SIZE = 12;

View File

@@ -105,6 +105,8 @@ public class TileEntityCableRenderer extends TileEntityRenderer<TileCable>
}
/**
* Set up the state for rendering block-breaking progress.
*
* @see WorldRenderer#preRenderDamagedBlocks()
*/
private void preRenderDamagedBlocks()
@@ -123,6 +125,8 @@ public class TileEntityCableRenderer extends TileEntityRenderer<TileCable>
}
/**
* Tear down the state for rendering block-breaking progress.
*
* @see WorldRenderer#postRenderDamagedBlocks()
*/
private void postRenderDamagedBlocks()

View File

@@ -160,7 +160,7 @@ public class AddressPredicate
}
/**
* Determine whether the given address matches a series of patterns
* Determine whether the given address matches a series of patterns.
*
* @param address The address to check.
* @return Whether it matches any of these patterns.

View File

@@ -13,256 +13,106 @@ import javax.annotation.Nullable;
import java.util.Map;
/**
* Various helpers for arguments
* A stub for any mods which depended on this version of the argument helper.
*
* @deprecated Use {@link dan200.computercraft.api.lua.ArgumentHelper}.
*/
@Deprecated
public final class ArgumentHelper
{
private ArgumentHelper()
{
throw new IllegalStateException( "Cannot instantiate singleton " + getClass().getName() );
}
@Nonnull
public static String getType( @Nullable Object type )
{
if( type == null ) return "nil";
if( type instanceof String ) return "string";
if( type instanceof Boolean ) return "boolean";
if( type instanceof Number ) return "number";
if( type instanceof Map ) return "table";
Class<?> klass = type.getClass();
if( klass.isArray() )
{
StringBuilder name = new StringBuilder();
while( klass.isArray() )
{
name.append( "[]" );
klass = klass.getComponentType();
}
name.insert( 0, klass.getName() );
return name.toString();
}
else
{
return klass.getName();
}
return dan200.computercraft.api.lua.ArgumentHelper.getType( type );
}
@Nonnull
public static LuaException badArgument( int index, @Nonnull String expected, @Nullable Object actual )
{
return badArgument( index, expected, getType( actual ) );
return dan200.computercraft.api.lua.ArgumentHelper.badArgumentOf( index, expected, actual );
}
@Nonnull
public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual )
{
return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" );
return dan200.computercraft.api.lua.ArgumentHelper.badArgument( index, expected, actual );
}
public static double getNumber( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "nil" );
Object value = args[index];
if( value instanceof Number )
{
return ((Number) value).doubleValue();
}
else
{
throw badArgument( index, "number", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.getDouble( args, index );
}
public static int getInt( @Nonnull Object[] args, int index ) throws LuaException
{
return (int) getLong( args, index );
return dan200.computercraft.api.lua.ArgumentHelper.getInt( args, index );
}
public static long getLong( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "nil" );
Object value = args[index];
if( value instanceof Number )
{
return checkReal( index, (Number) value ).longValue();
}
else
{
throw badArgument( index, "number", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.getLong( args, index );
}
public static double getReal( @Nonnull Object[] args, int index ) throws LuaException
{
return checkReal( index, getNumber( args, index ) );
return dan200.computercraft.api.lua.ArgumentHelper.getFiniteDouble( args, index );
}
public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "boolean", "nil" );
Object value = args[index];
if( value instanceof Boolean )
{
return (Boolean) value;
}
else
{
throw badArgument( index, "boolean", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.getBoolean( args, index );
}
@Nonnull
public static String getString( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "string", "nil" );
Object value = args[index];
if( value instanceof String )
{
return (String) value;
}
else
{
throw badArgument( index, "string", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.getString( args, index );
}
@SuppressWarnings( "unchecked" )
@Nonnull
@SuppressWarnings( "unchecked" )
public static Map<Object, Object> getTable( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "table", "nil" );
Object value = args[index];
if( value instanceof Map )
{
return (Map<Object, Object>) value;
}
else
{
throw badArgument( index, "table", value );
}
return (Map<Object, Object>) dan200.computercraft.api.lua.ArgumentHelper.getTable( args, index );
}
public static double optNumber( @Nonnull Object[] args, int index, double def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null )
{
return def;
}
else if( value instanceof Number )
{
return ((Number) value).doubleValue();
}
else
{
throw badArgument( index, "number", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.optDouble( args, index, def );
}
public static int optInt( @Nonnull Object[] args, int index, int def ) throws LuaException
{
return (int) optLong( args, index, def );
return dan200.computercraft.api.lua.ArgumentHelper.optInt( args, index, def );
}
public static long optLong( @Nonnull Object[] args, int index, long def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null )
{
return def;
}
else if( value instanceof Number )
{
return checkReal( index, (Number) value ).longValue();
}
else
{
throw badArgument( index, "number", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.optLong( args, index, def );
}
public static double optReal( @Nonnull Object[] args, int index, double def ) throws LuaException
{
return checkReal( index, optNumber( args, index, def ) );
return dan200.computercraft.api.lua.ArgumentHelper.optFiniteDouble( args, index, def );
}
public static boolean optBoolean( @Nonnull Object[] args, int index, boolean def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null )
{
return def;
}
else if( value instanceof Boolean )
{
return (Boolean) value;
}
else
{
throw badArgument( index, "boolean", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.optBoolean( args, index, def );
}
public static String optString( @Nonnull Object[] args, int index, String def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null )
{
return def;
}
else if( value instanceof String )
{
return (String) value;
}
else
{
throw badArgument( index, "string", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.optString( args, index, def );
}
@SuppressWarnings( "unchecked" )
public static Map<Object, Object> optTable( @Nonnull Object[] args, int index, Map<Object, Object> def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null )
{
return def;
}
else if( value instanceof Map )
{
return (Map<Object, Object>) value;
}
else
{
throw badArgument( index, "table", value );
}
}
private static Number checkReal( int index, Number value ) throws LuaException
{
checkReal( index, value.doubleValue() );
return value;
}
private static double checkReal( int index, double value ) throws LuaException
{
if( Double.isNaN( value ) )
{
throw badArgument( index, "number", "nan" );
}
else if( value == Double.POSITIVE_INFINITY )
{
throw badArgument( index, "number", "inf" );
}
else if( value == Double.NEGATIVE_INFINITY )
{
throw badArgument( index, "number", "-inf" );
}
else
{
return value;
}
return (Map<Object, Object>) dan200.computercraft.api.lua.ArgumentHelper.optTable( args, index, def );
}
}

View File

@@ -27,7 +27,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public class FSAPI implements ILuaAPI
{

View File

@@ -23,7 +23,7 @@ import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
import static dan200.computercraft.core.apis.TableHelper.*;
public class HTTPAPI implements ILuaAPI
@@ -89,7 +89,7 @@ public class HTTPAPI implements ILuaAPI
case 0: // request
{
String address, postString, requestMethod;
Map<Object, Object> headerTable;
Map<?, ?> headerTable;
boolean binary, redirect;
if( args.length >= 1 && args[0] instanceof Map )
@@ -172,7 +172,7 @@ public class HTTPAPI implements ILuaAPI
case 2: // websocket
{
String address = getString( args, 0 );
Map<Object, Object> headerTbl = optTable( args, 1, Collections.emptyMap() );
Map<?, ?> headerTbl = optTable( args, 1, Collections.emptyMap() );
if( !ComputerCraft.http_websocket_enable )
{

View File

@@ -19,7 +19,7 @@ import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatterBuilder;
import java.util.*;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class OSAPI implements ILuaAPI
{
@@ -229,7 +229,7 @@ public class OSAPI implements ILuaAPI
case 1:
{
// startTimer
double timer = getReal( args, 0 );
double timer = getFiniteDouble( args, 0 );
synchronized( m_timers )
{
m_timers.put( m_nextTimerToken, new Timer( (int) Math.round( timer / 0.05 ) ) );
@@ -239,7 +239,7 @@ public class OSAPI implements ILuaAPI
case 2:
{
// setAlarm
double time = getReal( args, 0 );
double time = getFiniteDouble( args, 0 );
if( time < 0.0 || time >= 24.0 )
{
throw new LuaException( "Number out of range" );

View File

@@ -22,7 +22,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChangeListener
{

View File

@@ -15,7 +15,7 @@ import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class RedstoneAPI implements ILuaAPI
{

View File

@@ -6,14 +6,17 @@
package dan200.computercraft.core.apis;
import dan200.computercraft.api.lua.ArgumentHelper;
import dan200.computercraft.api.lua.LuaException;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
import static dan200.computercraft.api.lua.ArgumentHelper.getNumericType;
/**
* Various helpers for tables
* Various helpers for tables.
*/
public final class TableHelper
{
@@ -200,21 +203,7 @@ public final class TableHelper
private static double checkReal( @Nonnull String key, double value ) throws LuaException
{
if( Double.isNaN( value ) )
{
throw badKey( key, "number", "nan" );
}
else if( value == Double.POSITIVE_INFINITY )
{
throw badKey( key, "number", "inf" );
}
else if( value == Double.NEGATIVE_INFINITY )
{
throw badKey( key, "number", "-inf" );
}
else
{
return value;
}
if( !Double.isFinite( value ) ) throw badKey( key, "number", getNumericType( value ) );
return value;
}
}

View File

@@ -17,7 +17,7 @@ import org.apache.commons.lang3.ArrayUtils;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class TermAPI implements ILuaAPI
{
@@ -242,9 +242,9 @@ public class TermAPI implements ILuaAPI
}
else
{
double r = getReal( args, 1 );
double g = getReal( args, 2 );
double b = getReal( args, 3 );
double r = getFiniteDouble( args, 1 );
double g = getFiniteDouble( args, 2 );
double b = getFiniteDouble( args, 3 );
setColour( m_terminal, colour, r, g, b );
}
return null;

View File

@@ -21,8 +21,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
import static dan200.computercraft.core.apis.ArgumentHelper.optBoolean;
import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
import static dan200.computercraft.api.lua.ArgumentHelper.optBoolean;
public class BinaryReadableHandle extends HandleGeneric
{

View File

@@ -7,9 +7,9 @@
package dan200.computercraft.core.apis.handles;
import com.google.common.collect.ObjectArrays;
import dan200.computercraft.api.lua.ArgumentHelper;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.core.apis.ArgumentHelper;
import dan200.computercraft.shared.util.StringUtil;
import javax.annotation.Nonnull;
@@ -73,7 +73,7 @@ public class BinaryWritableHandle extends HandleGeneric
}
else
{
throw ArgumentHelper.badArgument( 0, "string or number", args.length > 0 ? args[0] : null );
throw ArgumentHelper.badArgumentOf( 0, "string or number", args.length > 0 ? args[0] : null );
}
return null;
}

View File

@@ -20,8 +20,8 @@ import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import static dan200.computercraft.core.apis.ArgumentHelper.optBoolean;
import static dan200.computercraft.core.apis.ArgumentHelper.optInt;
import static dan200.computercraft.api.lua.ArgumentHelper.optBoolean;
import static dan200.computercraft.api.lua.ArgumentHelper.optInt;
public class EncodedReadableHandle extends HandleGeneric
{

View File

@@ -16,8 +16,8 @@ import java.io.IOException;
import java.nio.channels.Channel;
import java.nio.channels.SeekableByteChannel;
import static dan200.computercraft.core.apis.ArgumentHelper.optLong;
import static dan200.computercraft.core.apis.ArgumentHelper.optString;
import static dan200.computercraft.api.lua.ArgumentHelper.optLong;
import static dan200.computercraft.api.lua.ArgumentHelper.optString;
public abstract class HandleGeneric implements ILuaObject
{
@@ -47,7 +47,7 @@ public abstract class HandleGeneric implements ILuaObject
}
/**
* Shared implementation for various file handle types
* Shared implementation for various file handle types.
*
* @param channel The channel to seek in
* @param args The Lua arguments to process, like Lua's {@code file:seek}.

View File

@@ -99,7 +99,7 @@ public final class NetworkUtils
}
/**
* Checks a host is allowed
* Checks a host is allowed.
*
* @param host The domain to check against
* @throws HTTPRequestException If the host is not permitted.

View File

@@ -20,6 +20,8 @@ import java.util.function.Consumer;
/**
* A holder for one or more resources, with a lifetime.
*
* @param <T> The type of this resource. Should be the class extending from {@link Resource}.
*/
public abstract class Resource<T extends Resource<T>> implements Closeable
{
@@ -42,8 +44,9 @@ public abstract class Resource<T extends Resource<T>> implements Closeable
}
/**
* Checks if this has been cancelled. If so, it'll clean up any
* existing resources and cancel any pending futures.
* Checks if this has been cancelled. If so, it'll clean up any existing resources and cancel any pending futures.
*
* @return Whether this resource has been closed.
*/
public final boolean checkClosed()
{
@@ -80,6 +83,7 @@ public abstract class Resource<T extends Resource<T>> implements Closeable
/**
* Create a {@link WeakReference} which will close {@code this} when collected.
*
* @param <R> The object we are wrapping in a reference.
* @param object The object to reference to
* @return The weak reference.
*/

View File

@@ -14,6 +14,8 @@ import java.util.function.Supplier;
/**
* A collection of {@link Resource}s, with an upper bound on capacity.
*
* @param <T> The type of the resource this group manages.
*/
public class ResourceGroup<T extends Resource<T>>
{

View File

@@ -12,6 +12,8 @@ import java.util.function.Supplier;
/**
* A {@link ResourceGroup} which will queue items when the group at capacity.
*
* @param <T> The type of the resource this queue manages.
*/
public class ResourceQueue<T extends Resource<T>> extends ResourceGroup<T>
{

View File

@@ -40,7 +40,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Represents one or more
* Represents an in-progress HTTP request.
*/
public class HttpRequest extends Resource<HttpRequest>
{

View File

@@ -226,7 +226,11 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<HttpOb
}
/**
* Determine the redirect from this response
* Determine the redirect from this response.
*
* @param status The status of the HTTP response.
* @param headers The headers of the HTTP response.
* @return The URI to redirect to, or {@code null} if no redirect should occur.
*/
private URI getRedirect( HttpResponseStatus status, HttpHeaders headers )
{

View File

@@ -23,7 +23,7 @@ import javax.annotation.Nullable;
import java.io.Closeable;
import java.util.Arrays;
import static dan200.computercraft.core.apis.ArgumentHelper.optBoolean;
import static dan200.computercraft.api.lua.ArgumentHelper.optBoolean;
import static dan200.computercraft.core.apis.http.websocket.Websocket.CLOSE_EVENT;
import static dan200.computercraft.core.apis.http.websocket.Websocket.MESSAGE_EVENT;

View File

@@ -56,9 +56,6 @@ final class ComputerExecutor
{
private static final int QUEUE_LIMIT = 256;
private static IMount romMount;
private static final Object romMountLock = new Object();
private final Computer computer;
private final List<ILuaAPI> apis = new ArrayList<>();
final TimeoutState timeout = new TimeoutState();
@@ -268,7 +265,7 @@ final class ComputerExecutor
}
/**
* Queue an event if the computer is on
* Queue an event if the computer is on.
*
* @param event The event's name
* @param args The event's arguments
@@ -329,16 +326,10 @@ final class ComputerExecutor
private IMount getRomMount()
{
if( romMount != null ) return romMount;
synchronized( romMountLock )
{
if( romMount != null ) return romMount;
return romMount = computer.getComputerEnvironment().createResourceMount( "computercraft", "lua/rom" );
}
return computer.getComputerEnvironment().createResourceMount( "computercraft", "lua/rom" );
}
IWritableMount getRootMount()
private IWritableMount getRootMount()
{
if( rootMount == null )
{

View File

@@ -50,7 +50,7 @@ import static dan200.computercraft.core.computer.TimeoutState.TIMEOUT;
public final class ComputerThread
{
/**
* How often the computer thread monitor should run, in milliseconds
* How often the computer thread monitor should run, in milliseconds.
*
* @see Monitor
*/
@@ -83,7 +83,7 @@ public final class ComputerThread
private static final Object threadLock = new Object();
/**
* Whether the computer thread system is currently running
* Whether the computer thread system is currently running.
*/
private static volatile boolean running = false;
@@ -105,7 +105,7 @@ public final class ComputerThread
private static final Condition hasWork = computerLock.newCondition();
/**
* Active queues to execute
* Active queues to execute.
*/
private static final TreeSet<ComputerExecutor> computerQueue = new TreeSet<>( ( a, b ) -> {
if( a == b ) return 0; // Should never happen, but let's be consistent here
@@ -126,7 +126,7 @@ public final class ComputerThread
private ComputerThread() {}
/**
* Start the computer thread
* Start the computer thread.
*/
static void start()
{
@@ -194,7 +194,7 @@ public final class ComputerThread
}
/**
* Mark a computer as having work, enqueuing it on the thread
* Mark a computer as having work, enqueuing it on the thread.
*
* You must be holding {@link ComputerExecutor}'s {@code queueLock} when calling this method - it should only
* be called from {@code enqueue}.
@@ -244,6 +244,8 @@ public final class ComputerThread
* {@link #minimumVirtualRuntime} based on the current tasks.
*
* This is called before queueing tasks, to ensure that {@link #minimumVirtualRuntime} is up-to-date.
*
* @param current The machine which we updating runtimes from.
*/
private static void updateRuntimes( @Nullable ComputerExecutor current )
{
@@ -321,7 +323,7 @@ public final class ComputerThread
}
/**
* The scaled period for a single task
* The scaled period for a single task.
*
* @return The scaled period for the task
* @see #DEFAULT_LATENCY
@@ -336,7 +338,7 @@ public final class ComputerThread
}
/**
* Determine if the thread has computers queued up
* Determine if the thread has computers queued up.
*
* @return If we have work queued up.
*/

View File

@@ -36,12 +36,12 @@ import java.util.concurrent.TimeUnit;
public final class TimeoutState
{
/**
* The total time a task is allowed to run before aborting in nanoseconds
* The total time a task is allowed to run before aborting in nanoseconds.
*/
static final long TIMEOUT = TimeUnit.MILLISECONDS.toNanos( 7000 );
/**
* The time the task is allowed to run after each abort in nanoseconds
* The time the task is allowed to run after each abort in nanoseconds.
*/
static final long ABORT_TIMEOUT = TimeUnit.MILLISECONDS.toNanos( 1500 );
@@ -111,6 +111,8 @@ public final class TimeoutState
/**
* If the machine should be passively aborted.
*
* @return {@code true} if we should throw a timeout error.
*/
public boolean isSoftAborted()
{
@@ -118,7 +120,9 @@ public final class TimeoutState
}
/**
* If the machine should be forcibly aborted.
* Determine if the machine should be forcibly aborted.
*
* @return {@code true} if the machine should be forcibly shut down.
*/
public boolean isHardAborted()
{
@@ -146,7 +150,7 @@ public final class TimeoutState
}
/**
* Pauses the cumulative time, to be resumed by {@link #startTimer()}
* Pauses the cumulative time, to be resumed by {@link #startTimer()}.
*
* @see #nanoCumulative()
*/

View File

@@ -8,13 +8,16 @@ package dan200.computercraft.core.filesystem;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.MapMaker;
import com.google.common.io.ByteStreams;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.core.apis.handles.ArrayByteChannel;
import net.minecraft.resources.IReloadableResourceManager;
import net.minecraft.resources.IResource;
import net.minecraft.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.ResourceLocationException;
import net.minecraftforge.resource.IResourceType;
import net.minecraftforge.resource.ISelectiveResourceReloadListener;
@@ -29,7 +32,7 @@ import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
public class ResourceMount implements IMount
public final class ResourceMount implements IMount
{
/**
* Only cache files smaller than 1MiB.
@@ -55,6 +58,13 @@ public class ResourceMount implements IMount
.<FileEntry, byte[]>weigher( ( k, v ) -> v.length )
.build();
private static final MapMaker CACHE_TEMPLATE = new MapMaker().weakValues().concurrencyLevel( 1 );
/**
* Maintain a cache of currently loaded resource mounts. This cache is invalidated when currentManager changes.
*/
private static final Map<IReloadableResourceManager, Map<ResourceLocation, ResourceMount>> MOUNT_CACHE = new WeakHashMap<>( 2 );
private final String namespace;
private final String subPath;
private final IReloadableResourceManager manager;
@@ -62,7 +72,26 @@ public class ResourceMount implements IMount
@Nullable
private FileEntry root;
public ResourceMount( String namespace, String subPath, IReloadableResourceManager manager )
public static ResourceMount get( String namespace, String subPath, IReloadableResourceManager manager )
{
Map<ResourceLocation, ResourceMount> cache;
synchronized( MOUNT_CACHE )
{
cache = MOUNT_CACHE.get( manager );
if( cache == null ) MOUNT_CACHE.put( manager, cache = CACHE_TEMPLATE.makeMap() );
}
ResourceLocation path = new ResourceLocation( namespace, subPath );
synchronized( cache )
{
ResourceMount mount = cache.get( path );
if( mount == null ) cache.put( path, mount = new ResourceMount( namespace, subPath, manager ) );
return mount;
}
}
private ResourceMount( String namespace, String subPath, IReloadableResourceManager manager )
{
this.namespace = namespace;
this.subPath = subPath;
@@ -119,7 +148,17 @@ public class ResourceMount implements IMount
FileEntry nextEntry = lastEntry.children.get( part );
if( nextEntry == null )
{
lastEntry.children.put( part, nextEntry = new FileEntry( new ResourceLocation( namespace, subPath + "/" + path ) ) );
ResourceLocation childPath;
try
{
childPath = new ResourceLocation( namespace, subPath + "/" + path );
}
catch( ResourceLocationException e )
{
ComputerCraft.log.warn( "Cannot create resource location for {} ({})", part, e.getMessage() );
return;
}
lastEntry.children.put( part, nextEntry = new FileEntry( childPath ) );
}
lastEntry = nextEntry;

View File

@@ -38,7 +38,7 @@ public final class MachineResult
public static final MachineResult TIMEOUT = new MachineResult( true, false, TimeoutState.ABORT_MESSAGE );
/**
* An error with no user-friendly error message
* An error with no user-friendly error message.
*/
public static final MachineResult GENERIC_ERROR = new MachineResult( true, false, null );

View File

@@ -314,6 +314,9 @@ public class Terminal
}
/**
* Determine whether this terminal has changed.
*
* @return If this terminal is dirty.
* @deprecated All {@code *Changed()} methods are deprecated: one should pass in a callback
* instead.
*/

View File

@@ -11,7 +11,10 @@ import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
/**
* A {@link Command} which accepts an argument
* A {@link Command} which accepts an argument.
*
* @param <S> The command source we consume.
* @param <T> The argument given to this command when executed.
*/
@FunctionalInterface
public interface ArgCommand<S, T>

View File

@@ -25,8 +25,10 @@ import static dan200.computercraft.shared.command.Exceptions.ARGUMENT_EXPECTED;
import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.literal;
/**
* An alternative way of building command nodes, so one does not have to nest
* An alternative way of building command nodes, so one does not have to nest.
* {@link ArgumentBuilder#then(CommandNode)}s.
*
* @param <S> The command source we consume.
*/
public class CommandBuilder<S> implements CommandNodeBuilder<S, Command<S>>
{

View File

@@ -10,6 +10,9 @@ import com.mojang.brigadier.tree.CommandNode;
/**
* A builder which generates a {@link CommandNode} from the provided action.
*
* @param <S> The command source we consume.
* @param <T> The type of action to execute when this command is run.
*/
@FunctionalInterface
public interface CommandNodeBuilder<S, T>

View File

@@ -12,7 +12,7 @@ import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.util.text.event.HoverEvent;
/**
* Various helpers for building chat messages
* Various helpers for building chat messages.
*/
public final class ChatHelpers
{

View File

@@ -107,7 +107,7 @@ public class TableBuilder
}
/**
* Trim this table to a given height
* Trim this table to a given height.
*
* @param height The desired height.
*/

View File

@@ -22,7 +22,7 @@ public interface TableFormatter
ITextComponent HEADER = coloured( "=", TextFormatting.GRAY );
/**
* Get additional padding for the component
* Get additional padding for the component.
*
* @param component The component to pad
* @param width The desired width for the component
@@ -32,7 +32,7 @@ public interface TableFormatter
ITextComponent getPadding( ITextComponent component, int width );
/**
* Get the minimum padding between each column
* Get the minimum padding between each column.
*
* @return The minimum padding.
*/

View File

@@ -8,7 +8,6 @@ package dan200.computercraft.shared.common;
import dan200.computercraft.shared.network.container.ContainerData;
import dan200.computercraft.shared.network.container.HeldItemContainerData;
import dan200.computercraft.shared.util.InventoryUtil;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
@@ -33,7 +32,7 @@ public class ContainerHeldItem extends Container
super( type, id );
this.hand = hand;
stack = InventoryUtil.copyItem( player.getHeldItem( hand ) );
stack = player.getHeldItem( hand ).copy();
}
private static ContainerHeldItem createPrintout( int id, PlayerInventory inventory, HeldItemContainerData data )

View File

@@ -32,8 +32,8 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public class CommandAPI implements ILuaAPI
{
@@ -85,7 +85,7 @@ public class CommandAPI implements ILuaAPI
{
receiver.clearOutput();
int result = commandManager.handleCommand( m_computer.getSource(), command );
return new Object[] { result > 0, receiver.copyOutput() };
return new Object[] { result > 0, receiver.copyOutput(), result };
}
catch( Throwable t )
{
@@ -194,7 +194,7 @@ public class CommandAPI implements ILuaAPI
);
if( !World.isValid( min ) || !World.isValid( max ) )
{
throw new LuaException( "Co-ordinates out or range" );
throw new LuaException( "Co-ordinates out of range" );
}
if( (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1) * (max.getZ() - min.getZ() + 1) > 4096 )
{
@@ -233,7 +233,7 @@ public class CommandAPI implements ILuaAPI
}
else
{
throw new LuaException( "co-ordinates out or range" );
throw new LuaException( "Co-ordinates out of range" );
}
} );
}

View File

@@ -230,7 +230,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
}
/**
* Gets the redstone input for an adjacent block
* Gets the redstone input for an adjacent block.
*
* @param world The world we exist in
* @param pos The position of the neighbour

View File

@@ -7,7 +7,7 @@
package dan200.computercraft.shared.computer.core;
/**
* Receives some input and forwards it to a computer
* Receives some input and forwards it to a computer.
*
* @see InputState
* @see IComputer

View File

@@ -311,13 +311,13 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
@Override
public double getTimeOfDay()
{
return (m_world.getGameTime() + 6000) % 24000 / 1000.0;
return (m_world.getDayTime() + 6000) % 24000 / 1000.0;
}
@Override
public int getDay()
{
return (int) ((m_world.getGameTime() + 6000) / 24000) + 1;
return (int) ((m_world.getDayTime() + 6000) / 24000) + 1;
}
@Override

View File

@@ -1,89 +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.integration.charset;
import dan200.computercraft.shared.common.TileGeneric;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import pl.asie.charset.api.wires.IBundledEmitter;
import pl.asie.charset.api.wires.IBundledReceiver;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static dan200.computercraft.shared.integration.charset.IntegrationCharset.CAPABILITY_EMITTER;
import static dan200.computercraft.shared.integration.charset.IntegrationCharset.CAPABILITY_RECEIVER;
final class BundledCapabilityProvider implements ICapabilityProvider
{
private final TileGeneric tile;
private IBundledReceiver receiver;
private IBundledEmitter[] emitters;
BundledCapabilityProvider( TileGeneric tile )
{
this.tile = tile;
}
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable Direction side )
{
return capability == CAPABILITY_EMITTER || capability == CAPABILITY_RECEIVER;
}
@Nullable
@Override
public <T> T getCapability( @Nonnull Capability<T> capability, @Nullable Direction side )
{
if( capability == CAPABILITY_RECEIVER )
{
IBundledReceiver receiver = this.receiver;
if( receiver == null )
{
receiver = this.receiver = () -> tile.onNeighbourChange( tile.getPos().offset( side ) );
}
return CAPABILITY_RECEIVER.cast( receiver );
}
else if( capability == CAPABILITY_EMITTER )
{
IBundledEmitter[] emitters = this.emitters;
if( emitters == null ) emitters = this.emitters = new IBundledEmitter[7];
int index = side == null ? 6 : side.getIndex();
IBundledEmitter emitter = emitters[index];
if( emitter == null )
{
if( side == null )
{
emitter = emitters[index] = () -> {
int flags = 0;
for( Direction facing : Direction.VALUES ) flags |= tile.getBundledRedstoneOutput( facing );
return toBytes( flags );
};
}
else
{
emitter = emitters[index] = () -> toBytes( tile.getBundledRedstoneOutput( side ) );
}
}
return CAPABILITY_EMITTER.cast( emitter );
}
else
{
return null;
}
}
private static byte[] toBytes( int flag )
{
byte[] channels = new byte[16];
for( int i = 0; i < 16; i++ ) channels[i] = (flag & (1 << i)) == 0 ? (byte) 0 : 15;
return channels;
}
}

View File

@@ -1,33 +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.integration.charset;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import static dan200.computercraft.shared.integration.charset.IntegrationCharset.CAPABILITY_EMITTER;
public class BundledRedstoneProvider implements IBundledRedstoneProvider
{
@Override
public int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
TileEntity tile = world.getTileEntity( pos );
if( tile == null || !tile.hasCapability( CAPABILITY_EMITTER, side ) ) return -1;
byte[] signal = tile.getCapability( CAPABILITY_EMITTER, side ).getBundledSignal();
if( signal == null ) return -1;
int flag = 0;
for( int i = 0; i < signal.length; i++ ) flag |= signal[i] > 0 ? 1 << i : 0;
return flag;
}
}

View File

@@ -1,52 +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.integration.charset;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.shared.common.TileGeneric;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import pl.asie.charset.api.wires.IBundledEmitter;
import pl.asie.charset.api.wires.IBundledReceiver;
public final class IntegrationCharset
{
private static final ResourceLocation CAPABILITY_KEY = new ResourceLocation( ComputerCraft.MOD_ID, "charset" );
@CapabilityInject( IBundledEmitter.class )
static Capability<IBundledEmitter> CAPABILITY_EMITTER = null;
@CapabilityInject( IBundledReceiver.class )
static Capability<IBundledReceiver> CAPABILITY_RECEIVER = null;
private IntegrationCharset()
{
}
public static void register()
{
if( CAPABILITY_EMITTER == null || CAPABILITY_RECEIVER == null ) return;
MinecraftForge.EVENT_BUS.register( IntegrationCharset.class );
ComputerCraftAPI.registerBundledRedstoneProvider( new BundledRedstoneProvider() );
}
@SubscribeEvent
public static void attachGenericCapabilities( AttachCapabilitiesEvent<TileEntity> event )
{
TileEntity tile = event.getObject();
if( tile instanceof TileGeneric )
{
event.addCapability( CAPABILITY_KEY, new BundledCapabilityProvider( (TileGeneric) tile ) );
}
}
}

View File

@@ -35,7 +35,6 @@ import net.minecraft.util.ResourceLocation;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static dan200.computercraft.shared.integration.jei.RecipeResolver.MAIN_FAMILIES;
@@ -92,10 +91,6 @@ public class JEIComputerCraft implements IModPlugin
runtime.getIngredientManager().addIngredientsAtRuntime( VanillaTypes.ITEM, upgradeItems );
// Hide treasure disks
runtime.getIngredientManager().removeIngredientsAtRuntime( VanillaTypes.ITEM,
Collections.singletonList( new ItemStack( ComputerCraft.Items.treasureDisk ) ) );
// Hide all upgrade recipes
IRecipeCategory<?> category = (IRecipeCategory<?>) registry.getRecipeCategory( VanillaRecipeCategoryUid.CRAFTING );
if( category != null )
@@ -114,7 +109,7 @@ public class JEIComputerCraft implements IModPlugin
}
/**
* Distinguishes turtles by upgrades and family
* Distinguishes turtles by upgrades and family.
*/
private static final ISubtypeInterpreter turtleSubtype = stack -> {
Item item = stack.getItem();
@@ -134,7 +129,7 @@ public class JEIComputerCraft implements IModPlugin
};
/**
* Distinguishes pocket computers by upgrade and family
* Distinguishes pocket computers by upgrade and family.
*/
private static final ISubtypeInterpreter pocketSubtype = stack -> {
Item item = stack.getItem();
@@ -150,7 +145,7 @@ public class JEIComputerCraft implements IModPlugin
};
/**
* Distinguishes disks by colour
* Distinguishes disks by colour.
*/
private static final ISubtypeInterpreter diskSubtype = stack -> {
Item item = stack.getItem();

View File

@@ -1,49 +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.integration.mcmp;
import mcmultipart.MCMultiPart;
import mcmultipart.api.item.ItemBlockMultipart;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Loader;
import javax.annotation.Nonnull;
public final class MCMPHooks
{
private MCMPHooks()
{
}
public static ActionResultType onItemUse( BlockItem itemBlock, PlayerEntity player, World world, @Nonnull BlockPos pos, @Nonnull Hand hand, @Nonnull Direction facing, float hitX, float hitY, float hitZ )
{
if( !Loader.isModLoaded( MCMultiPart.MODID ) ) return ActionResultType.PASS;
return ItemBlockMultipart.place(
player, world, pos, hand, facing, hitX, hitY, hitZ, itemBlock,
itemBlock.getBlock()::getStateForPlacement,
MCMPIntegration.multipartMap.get( itemBlock.getBlock() ),
(
ItemStack stack, PlayerEntity thisPlayer, World thisWorld, BlockPos thisPos, Direction thisFacing,
float thisX, float thisY, float thisZ, BlockState thisState
) ->
thisPlayer.canPlayerEdit( thisPos, thisFacing, stack ) &&
thisWorld.getBlockState( thisPos ).getBlock().isReplaceable( thisWorld, thisPos ) &&
itemBlock.getBlock().canPlaceBlockAt( thisWorld, thisPos ) &&
itemBlock.getBlock().canPlaceBlockOnSide( thisWorld, thisPos, thisFacing ) &&
itemBlock.placeBlockAt( stack, thisPlayer, thisWorld, thisPos, thisFacing, thisX, thisY, thisZ, thisState ),
ItemBlockMultipart::placePartAt
);
}
}

View File

@@ -1,127 +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.integration.mcmp;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralTile;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.peripheral.modem.wireless.TileAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.TileWirelessModem;
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import mcmultipart.api.addon.IMCMPAddon;
import mcmultipart.api.addon.MCMPAddon;
import mcmultipart.api.container.IMultipartContainer;
import mcmultipart.api.multipart.IMultipart;
import mcmultipart.api.multipart.IMultipartRegistry;
import mcmultipart.api.multipart.IMultipartTile;
import mcmultipart.api.ref.MCMPCapabilities;
import mcmultipart.api.slot.EnumFaceSlot;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
@MCMPAddon
public class MCMPIntegration implements IMCMPAddon
{
private static final ResourceLocation CAPABILITY_KEY = new ResourceLocation( ComputerCraft.MOD_ID, "mcmultipart" );
static final Map<Block, IMultipart> multipartMap = new HashMap<>();
private static void register( IMultipartRegistry registry, Block block, IMultipart multipart )
{
registry.registerPartWrapper( block, multipart );
multipartMap.put( block, multipart );
}
@Override
public void registerParts( IMultipartRegistry registry )
{
// Setup all parts
register( registry, ComputerCraft.Blocks.peripheral, new PartPeripheral() );
register( registry, ComputerCraft.Blocks.advancedModem, new PartAdvancedModem() );
// Subscribe to capability events
MinecraftForge.EVENT_BUS.register( MCMPIntegration.class );
// Register a peripheral provider
ComputerCraftAPI.registerPeripheralProvider( ( world, pos, side ) ->
{
TileEntity tile = world.getTileEntity( pos );
if( tile == null || !tile.hasCapability( MCMPCapabilities.MULTIPART_CONTAINER, null ) ) return null;
IMultipartContainer container = tile.getCapability( MCMPCapabilities.MULTIPART_CONTAINER, null );
if( container == null ) return null;
IMultipartTile multipart = container.getPartTile( EnumFaceSlot.fromFace( side ) ).orElse( null );
if( multipart == null ) return null;
if( multipart instanceof IPeripheral ) return (IPeripheral) multipart;
if( multipart instanceof IPeripheralTile ) return ((IPeripheralTile) multipart).getPeripheral( side );
TileEntity underlying = multipart.getTileEntity();
if( underlying instanceof IPeripheral ) return (IPeripheral) underlying;
if( underlying instanceof IPeripheralTile ) return ((IPeripheralTile) underlying).getPeripheral( side );
return null;
} );
}
@SubscribeEvent
public static void attach( AttachCapabilitiesEvent<TileEntity> event )
{
TileEntity tile = event.getObject();
if( tile instanceof TileAdvancedModem || tile instanceof TileWirelessModem
|| tile instanceof TilePeripheralBase || tile instanceof TileMonitor )
{
// We need to attach to modems (obviously), but also any other tile created by BlockPeripheral. Otherwise
// IMultipart.convertToMultipartTile will error.
event.addCapability( CAPABILITY_KEY, new BasicMultipart( tile ) );
}
}
private static final class BasicMultipart implements ICapabilityProvider
{
private final TileEntity tile;
private IMultipartTile wrapped;
private BasicMultipart( TileEntity tile )
{
this.tile = tile;
}
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable Direction facing )
{
return capability == MCMPCapabilities.MULTIPART_TILE;
}
@Nullable
@Override
public <T> T getCapability( @Nonnull Capability<T> capability, @Nullable Direction facing )
{
if( capability == MCMPCapabilities.MULTIPART_TILE )
{
IMultipartTile wrapped = this.wrapped;
if( wrapped == null ) wrapped = this.wrapped = IMultipartTile.wrap( tile );
return MCMPCapabilities.MULTIPART_TILE.cast( wrapped );
}
return null;
}
}
}

View File

@@ -1,41 +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.integration.mcmp;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.modem.wireless.BlockAdvancedModem;
import mcmultipart.api.multipart.IMultipart;
import mcmultipart.api.slot.EnumFaceSlot;
import mcmultipart.api.slot.IPartSlot;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class PartAdvancedModem implements IMultipart
{
@Override
public IPartSlot getSlotForPlacement( World world, BlockPos pos, BlockState state, Direction facing, float hitX, float hitY, float hitZ, LivingEntity placer )
{
return EnumFaceSlot.fromFace( state.getValue( BlockAdvancedModem.FACING ) );
}
@Override
public IPartSlot getSlotFromWorld( IBlockAccess world, BlockPos pos, BlockState state )
{
return EnumFaceSlot.fromFace( state.getValue( BlockAdvancedModem.FACING ) );
}
@Override
public Block getBlock()
{
return ComputerCraft.Blocks.advancedModem;
}
}

View File

@@ -1,67 +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.integration.mcmp;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.common.BlockPeripheralVariant;
import mcmultipart.api.multipart.IMultipart;
import mcmultipart.api.slot.EnumCenterSlot;
import mcmultipart.api.slot.EnumFaceSlot;
import mcmultipart.api.slot.IPartSlot;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
public class PartPeripheral implements IMultipart
{
@Override
public IPartSlot getSlotForPlacement( World world, BlockPos pos, BlockState state, Direction facing, float hitX, float hitY, float hitZ, LivingEntity placer )
{
return getSlot( state );
}
@Override
public IPartSlot getSlotFromWorld( IBlockAccess world, BlockPos pos, BlockState state )
{
return getSlot( state );
}
@Nonnull
private static IPartSlot getSlot( BlockState state )
{
BlockPeripheralVariant type = state.getValue( BlockPeripheral.VARIANT );
if( type == BlockPeripheralVariant.WirelessModemUpOn || type == BlockPeripheralVariant.WirelessModemUpOff )
{
return EnumFaceSlot.UP;
}
else if( type == BlockPeripheralVariant.WirelessModemDownOn || type == BlockPeripheralVariant.WirelessModemDownOff )
{
return EnumFaceSlot.DOWN;
}
else if( type == BlockPeripheralVariant.WirelessModemOff || type == BlockPeripheralVariant.WirelessModemOn )
{
return EnumFaceSlot.fromFace( state.getValue( BlockPeripheral.FACING ) );
}
else
{
return EnumCenterSlot.CENTER;
}
}
@Override
public Block getBlock()
{
return ComputerCraft.Blocks.peripheral;
}
}

View File

@@ -20,7 +20,7 @@ import net.minecraftforge.fml.common.ObfuscationReflectionHelper.UnableToFindFie
import javax.annotation.Nonnull;
/**
* An implementation of IMedia for ItemRecord's
* An implementation of IMedia for ItemRecords.
*/
public final class RecordMedia implements IMedia
{

View File

@@ -90,6 +90,7 @@ public final class NetworkHandler
* /**
* Register packet, and a thread-unsafe handler for it.
*
* @param <T> The type of the packet to send.
* @param id The identifier for this packet type
* @param factory The factory for this type of packet.
*/
@@ -106,6 +107,8 @@ public final class NetworkHandler
* /**
* Register packet, and a thread-unsafe handler for it.
*
* @param <T> The type of the packet to send.
* @param type The class of the type of packet to send.
* @param id The identifier for this packet type
* @param decoder The factory for this type of packet.
*/

View File

@@ -13,7 +13,7 @@ import net.minecraft.util.Hand;
import javax.annotation.Nonnull;
/**
* Opens a printout GUI based on the currently held item
* Opens a printout GUI based on the currently held item.
*
* @see ContainerHeldItem
* @see dan200.computercraft.shared.media.items.ItemPrintout

View File

@@ -14,7 +14,7 @@ import net.minecraft.tileentity.CommandBlockTileEntity;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public class CommandBlockPeripheral implements IPeripheral
{

View File

@@ -18,7 +18,7 @@ import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.optString;
import static dan200.computercraft.api.lua.ArgumentHelper.optString;
class DiskDrivePeripheral implements IPeripheral
{

View File

@@ -21,7 +21,7 @@ import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Set;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPacketReceiver
{

View File

@@ -210,7 +210,7 @@ public class BlockCable extends BlockGeneric implements IWaterLoggable
BlockPos offsetPos = pos.offset( facing );
BlockState offsetState = world.getBlockState( offsetPos );
return Block.hasSolidSide( offsetState, world, offsetPos, facing.getOpposite() );
return hasSolidSide( offsetState, world, offsetPos, facing.getOpposite() );
}
@Nullable

View File

@@ -201,8 +201,7 @@ public class TileCable extends TileGeneric implements IPeripheralTile
public void onNeighbourChange( @Nonnull BlockPos neighbour )
{
Direction dir = getDirection();
if( neighbour.equals( getPos().offset( dir ) ) && hasModem()
&& getBlockState().isValidPosition( world, pos ) )
if( neighbour.equals( getPos().offset( dir ) ) && hasModem() && !getBlockState().isValidPosition( getWorld(), getPos() ) )
{
if( hasCable() )
{

View File

@@ -23,7 +23,7 @@ import java.util.Collections;
import java.util.Map;
/**
* Represents a local peripheral exposed on the wired network
* Represents a local peripheral exposed on the wired network.
*
* This is responsible for getting the peripheral in world, tracking id and type and determining whether
* it has changed.
@@ -39,7 +39,7 @@ public final class WiredModemLocalPeripheral
private IPeripheral peripheral;
/**
* Attach a new peripheral from the world
* Attach a new peripheral from the world.
*
* @param world The world to search in
* @param origin The position to search from
@@ -76,7 +76,7 @@ public final class WiredModemLocalPeripheral
}
/**
* Detach the current peripheral
* Detach the current peripheral.
*
* @return Whether the peripheral changed
*/

View File

@@ -28,7 +28,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public abstract class WiredModemPeripheral extends ModemPeripheral implements IWiredSender
{

View File

@@ -49,9 +49,18 @@ public class BlockMonitor extends BlockGeneric
@Override
public BlockRenderLayer getRenderLayer()
{
// We use the CUTOUT layer, as otherwise monitor rendering will cause flickering.
return BlockRenderLayer.CUTOUT;
}
@Override
@Deprecated
public boolean isSolid( BlockState state )
{
// We override isSolid, as our overriding of getRenderLayer means that it would otherwise return false.
return true;
}
@Override
protected void fillStateContainer( StateContainer.Builder<Block, BlockState> builder )
{

View File

@@ -17,7 +17,7 @@ import org.apache.commons.lang3.ArrayUtils;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class MonitorPeripheral implements IPeripheral
{
@@ -123,7 +123,7 @@ public class MonitorPeripheral implements IPeripheral
case 8:
{
// setTextScale
int scale = (int) (getReal( args, 0 ) * 2.0);
int scale = (int) (getFiniteDouble( args, 0 ) * 2.0);
if( scale < 1 || scale > 10 )
{
throw new LuaException( "Expected number in range 0.5-5" );
@@ -184,9 +184,9 @@ public class MonitorPeripheral implements IPeripheral
}
else
{
double r = getReal( args, 1 );
double g = getReal( args, 2 );
double b = getReal( args, 3 );
double r = getFiniteDouble( args, 1 );
double g = getFiniteDouble( args, 2 );
double b = getFiniteDouble( args, 3 );
TermAPI.setColour( terminal, colour, r, g, b );
}
return null;

View File

@@ -15,8 +15,8 @@ import dan200.computercraft.shared.util.StringUtil;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
import static dan200.computercraft.core.apis.ArgumentHelper.optString;
import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
import static dan200.computercraft.api.lua.ArgumentHelper.optString;
public class PrinterPeripheral implements IPeripheral
{

View File

@@ -23,8 +23,8 @@ import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.util.concurrent.atomic.AtomicInteger;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.core.apis.ArgumentHelper.optReal;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
import static dan200.computercraft.api.lua.ArgumentHelper.optFiniteDouble;
public abstract class SpeakerPeripheral implements IPeripheral
{
@@ -72,8 +72,8 @@ public abstract class SpeakerPeripheral implements IPeripheral
case 0: // playSound
{
String name = getString( args, 0 );
float volume = (float) optReal( args, 1, 1.0 );
float pitch = (float) optReal( args, 2, 1.0 );
float volume = (float) optFiniteDouble( args, 1, 1.0 );
float pitch = (float) optFiniteDouble( args, 2, 1.0 );
ResourceLocation identifier;
try
@@ -100,8 +100,8 @@ public abstract class SpeakerPeripheral implements IPeripheral
private synchronized Object[] playNote( Object[] arguments, ILuaContext context ) throws LuaException
{
String name = getString( arguments, 0 );
float volume = (float) optReal( arguments, 1, 1.0 );
float pitch = (float) optReal( arguments, 2, 1.0 );
float volume = (float) optFiniteDouble( arguments, 1, 1.0 );
float pitch = (float) optFiniteDouble( arguments, 2, 1.0 );
NoteBlockInstrument instrument = null;
for( NoteBlockInstrument testInstrument : NoteBlockInstrument.values() )

View File

@@ -67,8 +67,6 @@ public final class ComputerCraftProxyCommon
PlayerCreativeLootCondition.class,
PlayerCreativeLootCondition.INSTANCE
) );
// if( Loader.isModLoaded( ModCharset.MODID ) ) IntegrationCharset.register();
}
private static void registerProviders()

View File

@@ -12,8 +12,7 @@ import dan200.computercraft.api.turtle.event.TurtleRefuelEvent;
import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.FurnaceTileEntity;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@@ -52,15 +51,9 @@ public final class FurnaceRefuelHandler implements TurtleRefuelEvent.Handler
return fuelToGive;
}
private static int getFuelPerItem( @Nonnull ItemStack stack )
{
int basicBurnTime = stack.getBurnTime();
int burnTime = ForgeEventFactory.getItemBurnTime(
stack,
basicBurnTime == -1 ? FurnaceTileEntity.getBurnTimes().getOrDefault( stack.getItem(), 0 ) : basicBurnTime
);
return (burnTime * 5) / 100;
return (ForgeHooks.getBurnTime( stack ) * 5) / 100;
}
@SubscribeEvent

View File

@@ -28,7 +28,7 @@ import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class TurtleAPI implements ILuaAPI
{

View File

@@ -73,7 +73,7 @@ public class BlockTurtle extends BlockComputerBase<TileTurtle> implements IWater
@Deprecated
public BlockRenderType getRenderType( BlockState state )
{
return BlockRenderType.INVISIBLE;
return BlockRenderType.ENTITYBLOCK_ANIMATED;
}
@Nonnull

View File

@@ -237,7 +237,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
m_inventoryChanged = false;
for( int n = 0; n < getSizeInventory(); n++ )
{
m_previousInventory.set( n, InventoryUtil.copyItem( getStackInSlot( n ) ) );
m_previousInventory.set( n, getStackInSlot( n ).copy() );
}
}
}
@@ -286,7 +286,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
if( slot < getSizeInventory() )
{
m_inventory.set( slot, ItemStack.read( tag ) );
m_previousInventory.set( slot, InventoryUtil.copyItem( m_inventory.get( slot ) ) );
m_previousInventory.set( slot, m_inventory.get( slot ).copy() );
}
}

View File

@@ -23,6 +23,7 @@ import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.Holiday;
import dan200.computercraft.shared.util.HolidayUtil;
import dan200.computercraft.shared.util.InventoryDelegate;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
@@ -43,6 +44,7 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.InvWrapper;
import javax.annotation.Nonnull;
import java.util.*;
@@ -68,6 +70,9 @@ public class TurtleBrain implements ITurtleAccess
private ComputerProxy m_proxy;
private GameProfile m_owningPlayer;
private final IInventory m_inventory = (InventoryDelegate) () -> m_owner;
private final IItemHandlerModifiable m_inventoryWrapper = new InvWrapper( m_inventory );
private Queue<TurtleCommandQueueEntry> m_commandQueue = new ArrayDeque<>();
private int m_commandsIssued = 0;
@@ -150,7 +155,7 @@ public class TurtleBrain implements ITurtleAccess
}
/**
* Read common data for saving and client synchronisation
* Read common data for saving and client synchronisation.
*
* @param nbt The tag to read from
*/
@@ -439,14 +444,14 @@ public class TurtleBrain implements ITurtleAccess
@Override
public IInventory getInventory()
{
return m_owner;
return m_inventory;
}
@Nonnull
@Override
public IItemHandlerModifiable getItemHandler()
{
return m_owner.getItemHandler();
return m_inventoryWrapper;
}
@Override

View File

@@ -9,12 +9,18 @@ package dan200.computercraft.shared.turtle.core;
import com.mojang.authlib.GameProfile;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.shared.util.FakeNetHandler;
import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.entity.EntityClassification;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.*;
import net.minecraft.entity.passive.horse.AbstractHorseEntity;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.EffectInstance;
import net.minecraft.tileentity.SignTileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.server.ServerWorld;
@@ -22,6 +28,7 @@ import net.minecraftforge.common.util.FakePlayer;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.OptionalInt;
import java.util.UUID;
public final class TurtlePlayer extends FakePlayer
@@ -40,6 +47,7 @@ public final class TurtlePlayer extends FakePlayer
private TurtlePlayer( ITurtleAccess turtle )
{
super( (ServerWorld) turtle.getWorld(), getProfile( turtle.getOwningPlayer() ) );
this.connection = new FakeNetHandler( this );
setState( turtle );
}
@@ -50,6 +58,13 @@ public final class TurtlePlayer extends FakePlayer
private void setState( ITurtleAccess turtle )
{
if( openContainer != null )
{
ComputerCraft.log.warn( "Turtle has open container ({})", openContainer );
openContainer.onContainerClosed( this );
openContainer = null;
}
BlockPos position = turtle.getPosition();
posX = position.getX() + 0.5;
posY = position.getY() + 0.5;
@@ -126,6 +141,86 @@ public final class TurtlePlayer extends FakePlayer
return new Vec3d( posX, posY, posZ );
}
// TODO: Work out what needs stubbing again.
// Or just replace the network.
@Override
public float getEyeHeight( @Nonnull Pose pose )
{
return 0;
}
@Override
public float getStandingEyeHeight( Pose pose, EntitySize size )
{
return 0;
}
//region Code which depends on the connection
@Nonnull
@Override
public OptionalInt openContainer( @Nullable INamedContainerProvider prover )
{
return OptionalInt.empty();
}
@Override
public void sendEnterCombat()
{
}
@Override
public void sendEndCombat()
{
}
@Override
public boolean startRiding( @Nonnull Entity entityIn, boolean force )
{
return false;
}
@Override
public void stopRiding()
{
}
@Override
public void openSignEditor( SignTileEntity signTile )
{
}
@Override
public void openHorseInventory( AbstractHorseEntity horse, IInventory inventory )
{
}
@Override
public void openBook( ItemStack stack, @Nonnull Hand hand )
{
}
@Override
public void closeScreen()
{
}
@Override
public void updateHeldItem()
{
}
@Override
protected void onNewPotionEffect( EffectInstance id )
{
}
@Override
protected void onChangedPotionEffect( EffectInstance id, boolean apply )
{
}
@Override
protected void onFinishedPotionEffect( EffectInstance effect )
{
}
//endregion
}

View File

@@ -15,7 +15,7 @@ import dan200.computercraft.shared.turtle.core.TurtleCraftCommand;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.optInt;
import static dan200.computercraft.api.lua.ArgumentHelper.optInt;
public class CraftingTablePeripheral implements IPeripheral
{

View File

@@ -14,8 +14,6 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
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.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@@ -36,7 +34,6 @@ public final class DropConsumer
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;
@@ -46,7 +43,6 @@ public final class DropConsumer
remainingDrops = new ArrayList<>();
dropEntity = new WeakReference<>( entity );
dropWorld = new WeakReference<>( entity.world );
dropPos = null;
dropBounds = new AxisAlignedBB( entity.getPosition() ).grow( 2, 2, 2 );
entity.captureDrops( new ArrayList<>() );
@@ -55,10 +51,9 @@ public final class DropConsumer
public static void set( World world, BlockPos pos, Function<ItemStack, ItemStack> consumer )
{
dropConsumer = consumer;
remainingDrops = new ArrayList<>();
remainingDrops = new ArrayList<>( 2 );
dropEntity = null;
dropWorld = new WeakReference<>( world );
dropPos = pos;
dropBounds = new AxisAlignedBB( pos ).grow( 2, 2, 2 );
}
@@ -83,7 +78,6 @@ public final class DropConsumer
remainingDrops = null;
dropEntity = null;
dropWorld = null;
dropPos = null;
dropBounds = null;
return remainingStacks;
@@ -95,34 +89,7 @@ public final class DropConsumer
if( !remaining.isEmpty() ) remainingDrops.add( remaining );
}
@SubscribeEvent( priority = EventPriority.LOWEST )
public static void onEntityLivingDrops( LivingDropsEvent event )
{
// Capture any mob drops for the current entity
if( dropEntity != null && event.getEntity() == dropEntity.get() )
{
Collection<ItemEntity> drops = event.getDrops();
for( ItemEntity entityItem : drops ) handleDrops( entityItem.getItem() );
drops.clear();
}
}
@SubscribeEvent( priority = EventPriority.LOWEST )
public static void onHarvestDrops( BlockEvent.HarvestDropsEvent event )
{
// Capture block drops for the current entity
if( dropWorld != null && dropWorld.get() == event.getWorld()
&& dropPos != null && dropPos.equals( event.getPos() ) )
{
for( ItemStack item : event.getDrops() )
{
if( event.getWorld().getRandom().nextFloat() < event.getDropChance() ) handleDrops( item );
}
event.getDrops().clear();
}
}
@SubscribeEvent( priority = EventPriority.LOWEST )
@SubscribeEvent( priority = EventPriority.HIGHEST )
public static void onEntitySpawn( EntityJoinWorldEvent event )
{
// Capture any nearby item spawns

View File

@@ -0,0 +1,360 @@
/*
* 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.util;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import net.minecraft.network.*;
import net.minecraft.network.play.ServerPlayNetHandler;
import net.minecraft.network.play.client.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.common.util.FakePlayer;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.crypto.SecretKey;
public class FakeNetHandler extends ServerPlayNetHandler
{
public FakeNetHandler( @Nonnull FakePlayer player )
{
super( player.getServerWorld().getServer(), new FakeNetworkManager(), player );
}
@Override
public void tick()
{
}
@Override
public void disconnect( @Nonnull ITextComponent reason )
{
}
@Override
public void onDisconnect( ITextComponent reason )
{
}
@Override
public void sendPacket( @Nonnull IPacket<?> packet )
{
}
@Override
public void sendPacket( @Nonnull IPacket<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> whenSent )
{
}
@Override
public void processInput( CInputPacket packet )
{
}
@Override
public void processVehicleMove( CMoveVehiclePacket packet )
{
}
@Override
public void processConfirmTeleport( CConfirmTeleportPacket packet )
{
}
@Override
public void handleRecipeBookUpdate( CRecipeInfoPacket packet )
{
}
@Override
public void handleSeenAdvancements( CSeenAdvancementsPacket packet )
{
}
@Override
public void processTabComplete( CTabCompletePacket packet )
{
}
@Override
public void processUpdateCommandBlock( @Nonnull CUpdateCommandBlockPacket packet )
{
}
@Override
public void processUpdateCommandMinecart( @Nonnull CUpdateMinecartCommandBlockPacket packet )
{
}
@Override
public void processPickItem( CPickItemPacket packet )
{
}
@Override
public void processRenameItem( @Nonnull CRenameItemPacket packet )
{
}
@Override
public void processUpdateBeacon( @Nonnull CUpdateBeaconPacket packet )
{
}
@Override
public void processUpdateStructureBlock( @Nonnull CUpdateStructureBlockPacket packet )
{
}
@Override
public void func_217262_a( @Nonnull CUpdateJigsawBlockPacket packet )
{
}
@Override
public void processSelectTrade( CSelectTradePacket packet )
{
}
@Override
public void processEditBook( CEditBookPacket packet )
{
}
@Override
public void processNBTQueryEntity( @Nonnull CQueryEntityNBTPacket packet )
{
}
@Override
public void processNBTQueryBlockEntity( @Nonnull CQueryTileEntityNBTPacket packet )
{
}
@Override
public void processPlayer( CPlayerPacket packet )
{
}
@Override
public void processPlayerDigging( CPlayerDiggingPacket packet )
{
}
@Override
public void processTryUseItemOnBlock( CPlayerTryUseItemOnBlockPacket packet )
{
}
@Override
public void processTryUseItem( CPlayerTryUseItemPacket packet )
{
}
@Override
public void handleSpectate( @Nonnull CSpectatePacket packet )
{
}
@Override
public void handleResourcePackStatus( CResourcePackStatusPacket packet )
{
}
@Override
public void processSteerBoat( @Nonnull CSteerBoatPacket packet )
{
}
@Override
public void processHeldItemChange( CHeldItemChangePacket packet )
{
}
@Override
public void processChatMessage( @Nonnull CChatMessagePacket packet )
{
}
@Override
public void handleAnimation( CAnimateHandPacket packet )
{
}
@Override
public void processEntityAction( CEntityActionPacket packet )
{
}
@Override
public void processUseEntity( CUseEntityPacket packet )
{
}
@Override
public void processClientStatus( CClientStatusPacket packet )
{
}
@Override
public void processCloseWindow( @Nonnull CCloseWindowPacket packet )
{
}
@Override
public void processClickWindow( CClickWindowPacket packet )
{
}
@Override
public void processPlaceRecipe( @Nonnull CPlaceRecipePacket packet )
{
}
@Override
public void processEnchantItem( CEnchantItemPacket packet )
{
}
@Override
public void processCreativeInventoryAction( @Nonnull CCreativeInventoryActionPacket packet )
{
}
@Override
public void processConfirmTransaction( CConfirmTransactionPacket packet )
{
}
@Override
public void processUpdateSign( CUpdateSignPacket packet )
{
}
@Override
public void processKeepAlive( @Nonnull CKeepAlivePacket packet )
{
}
@Override
public void processPlayerAbilities( CPlayerAbilitiesPacket packet )
{
}
@Override
public void processClientSettings( @Nonnull CClientSettingsPacket packet )
{
}
@Override
public void processCustomPayload( CCustomPayloadPacket packet )
{
}
@Override
public void func_217263_a( @Nonnull CSetDifficultyPacket packet )
{
}
@Override
public void func_217261_a( @Nonnull CLockDifficultyPacket packet )
{
}
private static class FakeNetworkManager extends NetworkManager
{
private INetHandler handler;
private ITextComponent closeReason;
FakeNetworkManager()
{
super( PacketDirection.CLIENTBOUND );
}
@Override
public void channelActive( ChannelHandlerContext context )
{
}
@Override
public void setConnectionState( @Nonnull ProtocolType state )
{
}
@Override
public void channelInactive( ChannelHandlerContext context )
{
}
@Override
public void exceptionCaught( ChannelHandlerContext context, @Nonnull Throwable err )
{
}
@Override
protected void channelRead0( ChannelHandlerContext context, @Nonnull IPacket<?> packet )
{
}
@Override
public void setNetHandler( INetHandler handler )
{
this.handler = handler;
}
@Override
public void sendPacket( @Nonnull IPacket<?> packet )
{
}
@Override
public void sendPacket( @Nonnull IPacket<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> whenSent )
{
}
@Override
public void tick()
{
}
@Override
public void closeChannel( @Nonnull ITextComponent message )
{
this.closeReason = message;
}
@Override
public void enableEncryption( SecretKey key )
{
}
@Nonnull
@Override
public INetHandler getNetHandler()
{
return handler;
}
@Nullable
@Override
public ITextComponent getExitMessage()
{
return closeReason;
}
@Override
public void disableAutoRead()
{
}
@Override
public void setCompressionThreshold( int threshold )
{
}
}
}

View File

@@ -0,0 +1,120 @@
/*
* 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.util;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import java.util.Set;
/**
* Provides a delegate over inventories.
*
* This may be used both on {@link net.minecraft.tileentity.TileEntity}s to redirect the inventory to another tile,
* and by other interfaces to have inventories which change their backing store.
*/
@FunctionalInterface
public interface InventoryDelegate extends IInventory
{
IInventory getInventory();
@Override
default int getSizeInventory()
{
return getInventory().getSizeInventory();
}
@Override
default boolean isEmpty()
{
return getInventory().isEmpty();
}
@Nonnull
@Override
default ItemStack getStackInSlot( int slot )
{
return getInventory().getStackInSlot( slot );
}
@Nonnull
@Override
default ItemStack decrStackSize( int slot, int count )
{
return getInventory().decrStackSize( slot, count );
}
@Nonnull
@Override
default ItemStack removeStackFromSlot( int slot )
{
return getInventory().removeStackFromSlot( slot );
}
@Override
default void setInventorySlotContents( int slot, ItemStack stack )
{
getInventory().setInventorySlotContents( slot, stack );
}
@Override
default int getInventoryStackLimit()
{
return getInventory().getInventoryStackLimit();
}
@Override
default void markDirty()
{
getInventory().markDirty();
}
@Override
default boolean isUsableByPlayer( @Nonnull PlayerEntity player )
{
return getInventory().isUsableByPlayer( player );
}
@Override
default void openInventory( @Nonnull PlayerEntity player )
{
getInventory().openInventory( player );
}
@Override
default void closeInventory( @Nonnull PlayerEntity player )
{
getInventory().closeInventory( player );
}
@Override
default boolean isItemValidForSlot( int slot, @Nonnull ItemStack stack )
{
return getInventory().isItemValidForSlot( slot, stack );
}
@Override
default void clear()
{
getInventory().clear();
}
@Override
default int count( @Nonnull Item stack )
{
return getInventory().count( stack );
}
@Override
default boolean hasAny( @Nonnull Set<Item> set )
{
return getInventory().hasAny( set );
}
}

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