1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-19 07:57:38 +00:00

Compare commits

...

22 Commits

Author SHA1 Message Date
SquidDev
45e84e1ede Merge branch 'mc-1.13.x' into mc-1.14-fabric 2019-06-02 18:41:53 +01:00
SquidDev
725dfa764f Add highlight rendering for monitors and cables 2019-06-02 18:24:08 +01:00
SquidDev
c221502ec9 Correctly offset touch position on a monitor
Fixes #223
2019-06-02 18:06:24 +01:00
SquidDev
234f18c228 Merge branch 'mc-1.13.x' into mc-1.14-fabric 2019-06-02 17:54:00 +01:00
SquidDev
006ad109cb Update to 1.14.2
Ughr, mapping changes. Though this time they weren't too bad I guess.
2019-06-02 17:42:07 +01:00
SquidDev
0db080154c Fix incorrect inventory check
Closes #209
2019-05-26 16:29:28 +01:00
SquidDev
200311033f Small bodgey patch to fix NPEs when turtles place tiles 2019-05-14 17:17:34 +01:00
SquidDev
3192dc81ac Bump to 1.14.1 2019-05-14 16:35:40 +01:00
SquidDev
b11d4bb209 Bump to 1.14.1pr1
Which means bumping mappings version. Oh boy, this was not a bundle of
laughs...
2019-05-07 20:40:55 +01:00
SquidDev
2a716244e9 Don't use the TileTurtle as our property source
We probably need to do this for some other inventories too - to
investigate.

Fixes #198
2019-05-06 22:59:44 +01:00
SquidDev
19b7ed538a Hopefuly stub out all the network methods
Fixes #197
2019-05-06 22:46:44 +01:00
SquidDev
b0d9dc0b88 Merge branch 'mc-1.13.x' into mc-1.14-fabric 2019-05-06 21:53:59 +01:00
SquidDev
e6094a59fa Get us booting on a dedicated server
It doesn't appear that blocks are syncing, so we'll need to look into
that. Hopefully fixes #193
2019-04-29 08:04:24 +01:00
SquidDev
e8d7e6a562 Fix a whole bunch of bugs 2019-04-25 11:31:40 +01:00
SquidDev
536c2d9b2d Merge branch 'mc-1.13.x' into mc-1.14-fabric 2019-04-25 08:39:32 +01:00
SquidDev
f15a278f3b Bump versions 2019-04-24 11:54:03 +01:00
SquidDev
26b73c2ff3 Merge branch 'mc-1.13.x' into mc-1.14-fabric 2019-04-24 10:53:28 +01:00
SquidDev
c1e08fc3c7 Fix computer block drops not being handles
This is still not 100% perfect - we don't drop them when in creative.
However, it's a notable improvement on what it was.

Closes #174
2019-04-12 19:54:08 +01:00
SquidDev
b9ec6f236d Update to 1.14pr2 2019-04-12 19:49:39 +01:00
SquidDev
b1fff97bff Bump to 1.14pr1 2019-04-11 09:40:32 +01:00
SquidDev
c81bc70475 Merge branch 'mc-1.13.x' into mc-1.14-fabric 2019-04-11 08:57:04 +01:00
SquidDev
55a7ee4acf Initial update to Fabric 2019-04-03 23:27:10 +01:00
305 changed files with 5552 additions and 5838 deletions

View File

@@ -1,26 +1,17 @@
buildscript { buildscript {
repositories {
jcenter()
mavenCentral()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
}
dependencies { dependencies {
classpath 'com.google.code.gson:gson:2.8.1' classpath 'com.google.code.gson:gson:2.8.1'
classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.117'
classpath 'net.sf.proguard:proguard-gradle:6.1.0beta2' classpath 'net.sf.proguard:proguard-gradle:6.1.0beta2'
classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0' classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
} }
} }
plugins { plugins {
id 'fabric-loom' version '0.2.3-SNAPSHOT'
id 'com.matthewprenger.cursegradle' version '1.2.0' id 'com.matthewprenger.cursegradle' version '1.2.0'
id "com.github.breadmoirai.github-release" version "2.2.4" id "com.github.breadmoirai.github-release" version "2.2.4"
} }
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.ajoberstar.grgit' apply plugin: 'org.ajoberstar.grgit'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
apply plugin: 'maven' apply plugin: 'maven'
@@ -31,38 +22,10 @@ group = "org.squiddev"
archivesBaseName = "cc-tweaked-${mc_version}" archivesBaseName = "cc-tweaked-${mc_version}"
minecraft { minecraft {
runs {
client {
workingDirectory project.file('run')
property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
mods {
computercraft {
source sourceSets.main
}
}
}
server {
workingDirectory project.file('run')
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
property 'forge.logging.console.level', 'debug'
mods {
computercraft {
source sourceSets.main
}
}
}
}
mappings channel: 'snapshot', version: "${mappings_version}".toString()
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
} }
repositories { repositories {
mavenCentral()
maven { maven {
name "JEI" name "JEI"
url "http://dvs1.progwml6.com/files/maven" url "http://dvs1.progwml6.com/files/maven"
@@ -88,15 +51,15 @@ configurations {
} }
dependencies { dependencies {
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}" minecraft "com.mojang:minecraft:${mc_version}"
mappings "net.fabricmc:yarn:${mc_version}+build.${mappings_version}"
modCompile "net.fabricmc:fabric-loader:0.4.8+build.153"
modCompile "net.fabricmc.fabric-api:fabric-api:0.3.0+build.175"
compileOnly fg.deobf("mezz.jei:jei-1.13.2:5.0.0.20:api") implementation 'com.google.code.findbugs:jsr305:3.0.2'
// deobfProvided "pl.asie:Charset-Lib:0.5.4.6"
// deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
runtimeOnly fg.deobf("mezz.jei:jei-1.13.2:5.0.0.20")
shade 'org.squiddev:Cobalt:0.5.0-SNAPSHOT' shade 'org.squiddev:Cobalt:0.5.0-SNAPSHOT'
shade 'javax.vecmath:vecmath:1.5.2'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.1.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.1.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.1.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.1.0'
@@ -107,8 +70,7 @@ dependencies {
sourceSets { sourceSets {
main { main {
java { java {
exclude 'dan200/computercraft/shared/integration/mcmp' exclude 'dan200/computercraft/shared/integration'
exclude 'dan200/computercraft/shared/integration/charset'
} }
} }
} }
@@ -150,8 +112,11 @@ task proguard(type: ProGuardTask, dependsOn: jar) {
description "Removes unused shadowed classes from the jar" description "Removes unused shadowed classes from the jar"
group "compact" group "compact"
afterEvaluate {
// Fabric changes the jar's classifier so we to do this after evaluating!
injars jar.archivePath injars jar.archivePath
outjars "${jar.archivePath.absolutePath.replace(".jar", "")}-min.jar" outjars "${jar.archivePath.absolutePath.replace(".jar", "")}-min.jar"
}
// Add the main runtime jar and all non-shadowed dependencies // Add the main runtime jar and all non-shadowed dependencies
libraryjars "${System.getProperty('java.home')}/lib/rt.jar" libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
@@ -175,7 +140,7 @@ task proguard(type: ProGuardTask, dependsOn: jar) {
// LWJGL and Apache bundle Java 9 versions, which is great, but rather breaks Proguard // LWJGL and Apache bundle Java 9 versions, which is great, but rather breaks Proguard
dontwarn 'module-info' dontwarn 'module-info'
dontwarn 'org.apache.**,org.lwjgl.**' dontwarn 'org.apache.**,org.lwjgl.**,javax.crypto.SecretKey'
} }
task proguardMove(dependsOn: proguard) { task proguardMove(dependsOn: proguard) {
@@ -191,7 +156,7 @@ task proguardMove(dependsOn: proguard) {
} }
} }
remapJar.dependsOn proguardMove
processResources { processResources {
inputs.property "version", mod_version inputs.property "version", mod_version
@@ -213,7 +178,7 @@ processResources {
inputs.property "commithash", hash inputs.property "commithash", hash
from(sourceSets.main.resources.srcDirs) { from(sourceSets.main.resources.srcDirs) {
include 'META-INF/mods.toml' include 'fabric.mod.json'
include 'data/computercraft/lua/rom/help/credits.txt' include 'data/computercraft/lua/rom/help/credits.txt'
expand 'version': mod_version, expand 'version': mod_version,
@@ -222,12 +187,12 @@ processResources {
} }
from(sourceSets.main.resources.srcDirs) { from(sourceSets.main.resources.srcDirs) {
exclude 'META-INF/mods.toml' exclude 'fabric.mod.json'
exclude 'data/computercraft/lua/rom/help/credits.txt' exclude 'data/computercraft/lua/rom/help/credits.txt'
} }
} }
task compressJson(dependsOn: jar) { task compressJson(dependsOn: remapJar) {
group "compact" group "compact"
description "Minifies all JSON files, stripping whitespace" description "Minifies all JSON files, stripping whitespace"
@@ -313,12 +278,22 @@ curseforge {
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : '' apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
project { project {
id = '282001' id = '282001'
releaseType = 'release' addGameVersion '1.14.2'
releaseType = 'beta'
changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})." changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
relations { relations {
incompatible "computercraft" incompatible "computercraft"
requiredDependency "fabric"
} }
afterEvaluate {
mainArtifact(remapJar.output)
uploadTask.dependsOn(remapJar)
}
}
options {
forgeGradleIntegration = false
} }
} }
@@ -395,7 +370,7 @@ githubRelease {
def uploadTasks = ["uploadArchives", "curseforge", "githubRelease"] def uploadTasks = ["uploadArchives", "curseforge", "githubRelease"]
uploadTasks.forEach { tasks.getByName(it).dependsOn checkRelease } uploadTasks.forEach { tasks.getByName(it).dependsOn checkRelease }
task uploadAll(dependsOn: uploadTasks) { task uploadAll(dependsOn: [remapJar] + uploadTasks) {
group "upload" group "upload"
description "Uploads to all repositories (Maven, Curse, GitHub release)" description "Uploads to all repositories (Maven, Curse, GitHub release)"
} }
@@ -408,8 +383,6 @@ test {
} }
gradle.projectsEvaluated { gradle.projectsEvaluated {
reobfJar.dependsOn proguardMove
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint" << "-Xlint:-processing" // Causes Forge build to fail << "-Werror" options.compilerArgs << "-Xlint" << "-Xlint:-processing" // Causes Forge build to fail << "-Werror"
} }

View File

@@ -2,6 +2,5 @@
mod_version=1.83.1 mod_version=1.83.1
# Minecraft properties # Minecraft properties
mc_version=1.13.2 mc_version=1.14.2
forge_version=25.0.219 mappings_version=2
mappings_version=20190530-1.13.2

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -1 +1,12 @@
rootProject.name = "cc-tweaked-${mc_version}" pluginManagement {
repositories {
jcenter()
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
gradlePluginPortal()
}
}
rootProject.name = "cc-tweaked-${mc_version}-fabric"

View File

@@ -8,10 +8,10 @@ package dan200.computercraft;
import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.turtle.event.TurtleAction; import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.client.proxy.ComputerCraftProxyClient;
import dan200.computercraft.core.apis.AddressPredicate; import dan200.computercraft.core.apis.AddressPredicate;
import dan200.computercraft.core.apis.http.websocket.Websocket; import dan200.computercraft.core.apis.http.websocket.Websocket;
import dan200.computercraft.core.filesystem.ResourceMount; import dan200.computercraft.core.filesystem.ResourceMount;
import dan200.computercraft.shared.Config;
import dan200.computercraft.shared.computer.blocks.BlockComputer; import dan200.computercraft.shared.computer.blocks.BlockComputer;
import dan200.computercraft.shared.computer.core.ClientComputerRegistry; import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
import dan200.computercraft.shared.computer.core.ServerComputerRegistry; import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
@@ -30,13 +30,15 @@ import dan200.computercraft.shared.peripheral.speaker.BlockSpeaker;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.pocket.peripherals.PocketModem; import dan200.computercraft.shared.pocket.peripherals.PocketModem;
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker; import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
import dan200.computercraft.shared.turtle.blocks.BlockTurtle; import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
import dan200.computercraft.shared.turtle.items.ItemTurtle; import dan200.computercraft.shared.turtle.items.ItemTurtle;
import dan200.computercraft.shared.turtle.upgrades.*; import dan200.computercraft.shared.turtle.upgrades.*;
import net.minecraft.resources.IReloadableResourceManager; import net.fabricmc.api.EnvType;
import net.minecraft.util.ResourceLocation; import net.fabricmc.api.ModInitializer;
import net.minecraftforge.fml.common.Mod; import net.fabricmc.loader.api.FabricLoader;
import net.minecraftforge.fml.server.ServerLifecycleHooks; import net.minecraft.resource.ReloadableResourceManager;
import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@@ -45,8 +47,7 @@ import java.io.InputStream;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Mod( ComputerCraft.MOD_ID ) public final class ComputerCraft implements ModInitializer
public final class ComputerCraft
{ {
public static final String MOD_ID = "computercraft"; public static final String MOD_ID = "computercraft";
@@ -184,9 +185,22 @@ public final class ComputerCraft
// Logging // Logging
public static final Logger log = LogManager.getLogger( MOD_ID ); public static final Logger log = LogManager.getLogger( MOD_ID );
// Implementation
public static ComputerCraft instance;
public ComputerCraft() public ComputerCraft()
{ {
Config.load(); instance = this;
}
@Override
public void onInitialize()
{
ComputerCraftProxyCommon.setup();
if( FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT )
{
ComputerCraftProxyClient.setup();
}
} }
public static String getVersion() public static String getVersion()
@@ -196,17 +210,17 @@ public final class ComputerCraft
static IMount createResourceMount( String domain, String subPath ) static IMount createResourceMount( String domain, String subPath )
{ {
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager(); ReloadableResourceManager manager = ComputerCraftProxyCommon.getServer().getDataManager();
ResourceMount mount = new ResourceMount( domain, subPath, manager ); ResourceMount mount = new ResourceMount( domain, subPath, manager );
return mount.exists( "" ) ? mount : null; return mount.exists( "" ) ? mount : null;
} }
public static InputStream getResourceFile( String domain, String subPath ) public static InputStream getResourceFile( String domain, String subPath )
{ {
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager(); ReloadableResourceManager manager = ComputerCraftProxyCommon.getServer().getDataManager();
try try
{ {
return manager.getResource( new ResourceLocation( domain, subPath ) ).getInputStream(); return manager.getResource( new Identifier( domain, subPath ) ).getInputStream();
} }
catch( IOException ignored ) catch( IOException ignored )
{ {

View File

@@ -21,18 +21,19 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.core.apis.ApiFactories; import dan200.computercraft.core.apis.ApiFactories;
import dan200.computercraft.core.filesystem.FileMount; import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.shared.*; import dan200.computercraft.shared.*;
import dan200.computercraft.shared.peripheral.modem.wired.TileCable;
import dan200.computercraft.shared.peripheral.modem.wired.TileWiredModemFull;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork; import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.util.IDAssigner; import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import dan200.computercraft.shared.wired.WiredNode; import dan200.computercraft.shared.wired.WiredNode;
import net.minecraft.tileentity.TileEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File; import java.io.File;
public final class ComputerCraftAPIImpl implements IComputerCraftAPI public final class ComputerCraftAPIImpl implements IComputerCraftAPI
@@ -53,7 +54,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
@Override @Override
public int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath ) public int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath )
{ {
return IDAssigner.getNextId( parentSubPath ); return IDAssigner.getNextId( world, parentSubPath );
} }
@Override @Override
@@ -61,7 +62,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
{ {
try try
{ {
return new FileMount( new File( IDAssigner.getDir(), subPath ), capacity ); return new FileMount( new File( IDAssigner.getDir( world ), subPath ), capacity );
} }
catch( Exception e ) catch( Exception e )
{ {
@@ -94,7 +95,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
} }
@Override @Override
public int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side ) public int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
{ {
return BundledRedstone.getDefaultOutput( world, pos, side ); return BundledRedstone.getDefaultOutput( world, pos, side );
} }
@@ -131,11 +132,19 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
return new WiredNode( element ); return new WiredNode( element );
} }
@Nonnull @Nullable
@Override @Override
public LazyOptional<IWiredElement> getWiredElementAt( @Nonnull IBlockReader world, @Nonnull BlockPos pos, @Nonnull EnumFacing side ) public IWiredElement getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side )
{ {
TileEntity tile = world.getTileEntity( pos ); BlockEntity tile = world.getBlockEntity( pos );
return tile == null ? LazyOptional.empty() : tile.getCapability( CapabilityWiredElement.CAPABILITY, side ); if( tile instanceof TileCable )
{
return ((TileCable) tile).getElement( side );
}
else if( tile instanceof TileWiredModemFull )
{
return ((TileWiredModemFull) tile).getElement();
}
return null;
} }
} }

View File

@@ -8,10 +8,10 @@ package dan200.computercraft.api;
import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleUpgradeType; import dan200.computercraft.api.turtle.TurtleUpgradeType;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.IItemProvider; import net.minecraft.util.Identifier;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.SystemUtil;
import net.minecraft.util.Util;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -22,12 +22,12 @@ import javax.annotation.Nonnull;
*/ */
public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade
{ {
private final ResourceLocation id; private final Identifier id;
private final TurtleUpgradeType type; private final TurtleUpgradeType type;
private final String adjective; private final String adjective;
private final ItemStack stack; private final ItemStack stack;
protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, String adjective, ItemStack stack ) protected AbstractTurtleUpgrade( Identifier id, TurtleUpgradeType type, String adjective, ItemStack stack )
{ {
this.id = id; this.id = id;
this.type = type; this.type = type;
@@ -35,24 +35,24 @@ public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade
this.stack = stack; this.stack = stack;
} }
protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, String adjective, IItemProvider item ) protected AbstractTurtleUpgrade( Identifier id, TurtleUpgradeType type, String adjective, ItemConvertible item )
{ {
this( id, type, adjective, new ItemStack( item ) ); this( id, type, adjective, new ItemStack( item ) );
} }
protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, ItemStack stack ) protected AbstractTurtleUpgrade( Identifier id, TurtleUpgradeType type, ItemStack stack )
{ {
this( id, type, Util.makeTranslationKey( "upgrade", id ) + ".adjective", stack ); this( id, type, SystemUtil.createTranslationKey( "upgrade", id ) + ".adjective", stack );
} }
protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, IItemProvider item ) protected AbstractTurtleUpgrade( Identifier id, TurtleUpgradeType type, ItemConvertible item )
{ {
this( id, type, new ItemStack( item ) ); this( id, type, new ItemStack( item ) );
} }
@Nonnull @Nonnull
@Override @Override
public final ResourceLocation getUpgradeID() public final Identifier getUpgradeID()
{ {
return id; return id;
} }

View File

@@ -20,11 +20,10 @@ import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider; import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.ITurtleUpgrade;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -183,7 +182,7 @@ public final class ComputerCraftAPI
* If there is no block capable of emitting bundled redstone at the location, -1 will be returned. * If there is no block capable of emitting bundled redstone at the location, -1 will be returned.
* @see IBundledRedstoneProvider * @see IBundledRedstoneProvider
*/ */
public static int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side ) public static int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
{ {
return getInstance().getBundledRedstoneOutput( world, pos, side ); return getInstance().getBundledRedstoneOutput( world, pos, side );
} }
@@ -241,8 +240,8 @@ public final class ComputerCraftAPI
* @return The element's node * @return The element's node
* @see IWiredElement#getNode() * @see IWiredElement#getNode()
*/ */
@Nonnull @Nullable
public static LazyOptional<IWiredElement> getWiredElementAt( @Nonnull IBlockReader world, @Nonnull BlockPos pos, @Nonnull EnumFacing side ) public static IWiredElement getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side )
{ {
return getInstance().getWiredElementAt( world, pos, side ); return getInstance().getWiredElementAt( world, pos, side );
} }
@@ -284,7 +283,7 @@ public final class ComputerCraftAPI
void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider ); void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider );
int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side ); int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side );
void registerMediaProvider( @Nonnull IMediaProvider provider ); void registerMediaProvider( @Nonnull IMediaProvider provider );
@@ -298,7 +297,7 @@ public final class ComputerCraftAPI
@Nonnull @Nonnull
IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element ); IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element );
@Nonnull @Nullable
LazyOptional<IWiredElement> getWiredElementAt( @Nonnull IBlockReader world, @Nonnull BlockPos pos, @Nonnull EnumFacing side ); IWiredElement getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side );
} }
} }

View File

@@ -9,7 +9,7 @@ package dan200.computercraft.api.media;
import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IMount;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;

View File

@@ -6,9 +6,9 @@
package dan200.computercraft.api.peripheral; package dan200.computercraft.api.peripheral;
import net.minecraft.tileentity.TileEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -17,7 +17,8 @@ import javax.annotation.Nullable;
/** /**
* This interface is used to create peripheral implementations for blocks. * This interface is used to create peripheral implementations for blocks.
* *
* If you have a {@link TileEntity} which acts as a peripheral, you may alternatively implement {@link IPeripheralTile}. * If you have a {@link BlockEntity} which acts as a peripheral, you may alternatively implement
* {@link IPeripheralTile}.
* *
* @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider) * @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider)
*/ */
@@ -34,5 +35,5 @@ public interface IPeripheralProvider
* @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider) * @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider)
*/ */
@Nullable @Nullable
IPeripheral getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side ); IPeripheral getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side );
} }

View File

@@ -5,15 +5,15 @@
*/ */
package dan200.computercraft.api.peripheral; package dan200.computercraft.api.peripheral;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/** /**
* A {@link net.minecraft.tileentity.TileEntity} which may act as a peripheral. * A {@link net.minecraft.block.entity.BlockEntity} which may act as a peripheral.
* *
* If you need more complex capabilities (such as handling TEs not belonging to your mod), you should use * If you need more complex capabilities (such as handling TEs not belonging to your mod), you should use
* {@link IPeripheralProvider}. * {@link IPeripheralProvider}.
@@ -25,8 +25,8 @@ public interface IPeripheralTile
* *
* @param side The side to get the peripheral from. * @param side The side to get the peripheral from.
* @return A peripheral, or {@code null} if there is not a peripheral here. * @return A peripheral, or {@code null} if there is not a peripheral here.
* @see IPeripheralProvider#getPeripheral(World, BlockPos, EnumFacing) * @see IPeripheralProvider#getPeripheral(World, BlockPos, Direction)
*/ */
@Nullable @Nullable
IPeripheral getPeripheral( @Nonnull EnumFacing side ); IPeripheral getPeripheral( @Nonnull Direction side );
} }

View File

@@ -6,10 +6,10 @@
package dan200.computercraft.api.pocket; package dan200.computercraft.api.pocket;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.IItemProvider; import net.minecraft.util.Identifier;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.SystemUtil;
import net.minecraft.util.Util;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -20,30 +20,30 @@ import javax.annotation.Nonnull;
*/ */
public abstract class AbstractPocketUpgrade implements IPocketUpgrade public abstract class AbstractPocketUpgrade implements IPocketUpgrade
{ {
private final ResourceLocation id; private final Identifier id;
private final String adjective; private final String adjective;
private final ItemStack stack; private final ItemStack stack;
protected AbstractPocketUpgrade( ResourceLocation id, String adjective, ItemStack stack ) protected AbstractPocketUpgrade( Identifier id, String adjective, ItemStack stack )
{ {
this.id = id; this.id = id;
this.adjective = adjective; this.adjective = adjective;
this.stack = stack; this.stack = stack;
} }
protected AbstractPocketUpgrade( ResourceLocation id, String adjective, IItemProvider item ) protected AbstractPocketUpgrade( Identifier identifier, String adjective, ItemConvertible item )
{ {
this( id, adjective, new ItemStack( item ) ); this( identifier, adjective, new ItemStack( item ) );
} }
protected AbstractPocketUpgrade( ResourceLocation id, IItemProvider item ) protected AbstractPocketUpgrade( Identifier id, ItemConvertible item )
{ {
this( id, Util.makeTranslationKey( "upgrade", id ) + ".adjective", new ItemStack( item ) ); this( id, SystemUtil.createTranslationKey( "upgrade", id ) + ".adjective", new ItemStack( item ) );
} }
@Nonnull @Nonnull
@Override @Override
public final ResourceLocation getUpgradeID() public final Identifier getUpgradeID()
{ {
return id; return id;
} }

View File

@@ -8,8 +8,8 @@ package dan200.computercraft.api.pocket;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.Identifier;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -75,7 +75,7 @@ public interface IPocketAccess
* @see #updateUpgradeNBTData() * @see #updateUpgradeNBTData()
*/ */
@Nonnull @Nonnull
NBTTagCompound getUpgradeNBTData(); CompoundTag getUpgradeNBTData();
/** /**
* Mark the upgrade-specific NBT as dirty. * Mark the upgrade-specific NBT as dirty.
@@ -95,5 +95,5 @@ public interface IPocketAccess
* @return A collection of all upgrade names. * @return A collection of all upgrade names.
*/ */
@Nonnull @Nonnull
Map<ResourceLocation, IPeripheral> getUpgrades(); Map<Identifier, IPeripheral> getUpgrades();
} }

View File

@@ -10,7 +10,7 @@ import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.ITurtleUpgrade;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.Identifier;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -36,7 +36,7 @@ public interface IPocketUpgrade
* @see ComputerCraftAPI#registerPocketUpgrade(IPocketUpgrade) * @see ComputerCraftAPI#registerPocketUpgrade(IPocketUpgrade)
*/ */
@Nonnull @Nonnull
ResourceLocation getUpgradeID(); Identifier getUpgradeID();
/** /**
* Return an unlocalised string to describe the type of pocket computer this upgrade provides. * Return an unlocalised string to describe the type of pocket computer this upgrade provides.

View File

@@ -6,8 +6,8 @@
package dan200.computercraft.api.redstone; package dan200.computercraft.api.redstone;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -30,5 +30,5 @@ public interface IBundledRedstoneProvider
* handle this block. * handle this block.
* @see dan200.computercraft.api.ComputerCraftAPI#registerBundledRedstoneProvider(IBundledRedstoneProvider) * @see dan200.computercraft.api.ComputerCraftAPI#registerBundledRedstoneProvider(IBundledRedstoneProvider)
*/ */
int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side ); int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side );
} }

View File

@@ -10,13 +10,12 @@ import com.mojang.authlib.GameProfile;
import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Inventory;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandlerModifiable;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -83,10 +82,10 @@ public interface ITurtleAccess
* Returns the world direction the turtle is currently facing. * Returns the world direction the turtle is currently facing.
* *
* @return The world direction the turtle is currently facing. * @return The world direction the turtle is currently facing.
* @see #setDirection(EnumFacing) * @see #setDirection(Direction)
*/ */
@Nonnull @Nonnull
EnumFacing getDirection(); Direction getDirection();
/** /**
* Set the direction the turtle is facing. Note that this will not play a rotation animation, you will also need to * Set the direction the turtle is facing. Note that this will not play a rotation animation, you will also need to
@@ -95,7 +94,7 @@ public interface ITurtleAccess
* @param dir The new direction to set. This should be on either the x or z axis (so north, south, east or west). * @param dir The new direction to set. This should be on either the x or z axis (so north, south, east or west).
* @see #getDirection() * @see #getDirection()
*/ */
void setDirection( @Nonnull EnumFacing dir ); void setDirection( @Nonnull Direction dir );
/** /**
* Get the currently selected slot in the turtle's inventory. * Get the currently selected slot in the turtle's inventory.
@@ -147,21 +146,9 @@ public interface ITurtleAccess
* Get the inventory of this turtle * Get the inventory of this turtle
* *
* @return This turtle's inventory * @return This turtle's inventory
* @see #getItemHandler()
*/ */
@Nonnull @Nonnull
IInventory getInventory(); Inventory getInventory();
/**
* Get the inventory of this turtle as an {@link IItemHandlerModifiable}.
*
* @return This turtle's inventory
* @see #getInventory()
* @see IItemHandlerModifiable
* @see net.minecraftforge.items.CapabilityItemHandler#ITEM_HANDLER_CAPABILITY
*/
@Nonnull
IItemHandlerModifiable getItemHandler();
/** /**
* Determine whether this turtle will require fuel when performing actions. * Determine whether this turtle will require fuel when performing actions.
@@ -290,7 +277,7 @@ public interface ITurtleAccess
* @see #updateUpgradeNBTData(TurtleSide) * @see #updateUpgradeNBTData(TurtleSide)
*/ */
@Nonnull @Nonnull
NBTTagCompound getUpgradeNBTData( @Nullable TurtleSide side ); CompoundTag getUpgradeNBTData( @Nullable TurtleSide side );
/** /**
* Mark the upgrade-specific data as dirty on a specific side. This is required for the data to be synced to the * Mark the upgrade-specific data as dirty on a specific side. This is required for the data to be synced to the

View File

@@ -10,15 +10,13 @@ import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.turtle.event.TurtleAttackEvent; import dan200.computercraft.api.turtle.event.TurtleAttackEvent;
import dan200.computercraft.api.turtle.event.TurtleBlockEvent; import dan200.computercraft.api.turtle.event.TurtleBlockEvent;
import net.minecraft.client.renderer.model.IBakedModel; import net.fabricmc.api.EnvType;
import net.minecraft.client.renderer.model.ModelResourceLocation; import net.fabricmc.api.Environment;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing; import net.minecraft.util.Identifier;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Direction;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.event.entity.player.AttackEntityEvent;
import net.minecraftforge.event.world.BlockEvent;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -42,7 +40,7 @@ public interface ITurtleUpgrade
* @see ComputerCraftAPI#registerTurtleUpgrade(ITurtleUpgrade) * @see ComputerCraftAPI#registerTurtleUpgrade(ITurtleUpgrade)
*/ */
@Nonnull @Nonnull
ResourceLocation getUpgradeID(); Identifier getUpgradeID();
/** /**
* Return an unlocalised string to describe this type of turtle in turtle item names. * Return an unlocalised string to describe this type of turtle in turtle item names.
@@ -98,8 +96,8 @@ public interface ITurtleUpgrade
* Will only be called for Tool turtle. Called when turtle.dig() or turtle.attack() is called * Will only be called for Tool turtle. Called when turtle.dig() or turtle.attack() is called
* by the turtle, and the tool is required to do some work. * by the turtle, and the tool is required to do some work.
* *
* Conforming implementations should fire {@link BlockEvent.BreakEvent} and {@link TurtleBlockEvent.Dig}for digging, * Conforming implementations should fire {@code BlockEvent.BreakEvent} and {@link TurtleBlockEvent.Dig}for digging,
* {@link AttackEntityEvent} and {@link TurtleAttackEvent} for attacking. * {@code AttackEntityEvent} and {@link TurtleAttackEvent} for attacking.
* *
* @param turtle Access to the turtle that the tool resides on. * @param turtle Access to the turtle that the tool resides on.
* @param side Which side of the turtle (left or right) the tool resides on. * @param side Which side of the turtle (left or right) the tool resides on.
@@ -113,7 +111,7 @@ public interface ITurtleUpgrade
* to be called. * to be called.
*/ */
@Nonnull @Nonnull
default TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull EnumFacing direction ) default TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction direction )
{ {
return TurtleCommandResult.failure(); return TurtleCommandResult.failure();
} }
@@ -121,8 +119,8 @@ public interface ITurtleUpgrade
/** /**
* Called to obtain the model to be used when rendering a turtle peripheral. * Called to obtain the model to be used when rendering a turtle peripheral.
* *
* This can be obtained from {@link net.minecraft.client.renderer.ItemModelMesher#getItemModel(ItemStack)}, * This can be obtained from {@link net.minecraft.client.render.item.ItemModels#getModel(ItemStack)},
* {@link net.minecraft.client.renderer.model.ModelManager#getModel(ModelResourceLocation)} or any other * {@link net.minecraft.client.render.model.BakedModelManager#getModel(ModelIdentifier)} or any other
* source. * source.
* *
* @param turtle Access to the turtle that the upgrade resides on. This will be null when getting item models! * @param turtle Access to the turtle that the upgrade resides on. This will be null when getting item models!
@@ -131,8 +129,8 @@ public interface ITurtleUpgrade
* a transformation of {@code null} has the same effect as the identify matrix. * a transformation of {@code null} has the same effect as the identify matrix.
*/ */
@Nonnull @Nonnull
@OnlyIn( Dist.CLIENT ) @Environment( EnvType.CLIENT )
Pair<IBakedModel, Matrix4f> getModel( @Nullable ITurtleAccess turtle, @Nonnull TurtleSide side ); Pair<BakedModel, Matrix4f> getModel( @Nullable ITurtleAccess turtle, @Nonnull TurtleSide side );
/** /**
* Called once per tick for each turtle which has the upgrade equipped. * Called once per tick for each turtle which has the upgrade equipped.

View File

@@ -6,7 +6,7 @@
package dan200.computercraft.api.turtle; package dan200.computercraft.api.turtle;
import net.minecraft.util.EnumFacing; import net.minecraft.util.math.Direction;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -15,7 +15,7 @@ import javax.annotation.Nullable;
* Used to indicate the result of executing a turtle command. * Used to indicate the result of executing a turtle command.
* *
* @see ITurtleCommand#execute(ITurtleAccess) * @see ITurtleCommand#execute(ITurtleAccess)
* @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, EnumFacing) * @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction)
*/ */
public final class TurtleCommandResult public final class TurtleCommandResult
{ {

View File

@@ -6,14 +6,14 @@
package dan200.computercraft.api.turtle; package dan200.computercraft.api.turtle;
import net.minecraft.util.EnumFacing; import net.minecraft.util.math.Direction;
/** /**
* An enum representing the different actions that an {@link ITurtleUpgrade} of type Tool may be called on to perform by * An enum representing the different actions that an {@link ITurtleUpgrade} of type Tool may be called on to perform by
* a turtle. * a turtle.
* *
* @see ITurtleUpgrade#getType() * @see ITurtleUpgrade#getType()
* @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, EnumFacing) * @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction)
*/ */
public enum TurtleVerb public enum TurtleVerb
{ {

View File

@@ -0,0 +1,286 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.api.turtle.event;
import com.mojang.authlib.GameProfile;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import net.minecraft.block.entity.CommandBlockBlockEntity;
import net.minecraft.block.entity.SignBlockEntity;
import net.minecraft.command.arguments.EntityAnchorArgumentType;
import net.minecraft.container.Container;
import net.minecraft.container.NameableContainerProvider;
import net.minecraft.entity.Entity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.passive.HorseBaseEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.NetworkState;
import net.minecraft.network.Packet;
import net.minecraft.network.chat.ChatMessageType;
import net.minecraft.network.chat.Component;
import net.minecraft.recipe.Recipe;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.network.ServerPlayerInteractionManager;
import net.minecraft.server.network.packet.RequestCommandCompletionsC2SPacket;
import net.minecraft.server.network.packet.VehicleMoveC2SPacket;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent;
import net.minecraft.util.DefaultedList;
import net.minecraft.util.Hand;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.village.TraderOfferList;
import net.minecraft.world.GameMode;
import net.minecraft.world.dimension.DimensionType;
import javax.annotation.Nullable;
import javax.crypto.SecretKey;
import java.util.Collection;
import java.util.OptionalInt;
/**
* A wrapper for {@link ServerPlayerEntity} which denotes a "fake" player.
*
* Please note that this does not implement any of the traditional fake player behaviour. It simply exists to prevent
* me passing in normal players.
*/
public class FakePlayer extends ServerPlayerEntity
{
public FakePlayer( ServerWorld world, GameProfile gameProfile )
{
super( world.getServer(), world, gameProfile, new ServerPlayerInteractionManager( world ) );
networkHandler = new FakeNetHandler( this );
}
// region Direct networkHandler access
@Override
public void method_6000() { }
@Override
public void method_6044() { }
@Override
public void tick() { }
@Override
public void method_14226() { }
@Override
public void onDeath( DamageSource damage ) { }
@Nullable
@Override
public Entity changeDimension( DimensionType dimension )
{
return this;
}
@Override
public void wakeUp( boolean resetTimer, boolean notify, boolean setSpawn ) { }
@Override
public boolean startRiding( Entity entity, boolean flag )
{
return false;
}
@Override
public void stopRiding() { }
@Override
public void openEditSignScreen( SignBlockEntity tile ) { }
@Override
public OptionalInt openContainer( @Nullable NameableContainerProvider container )
{
return OptionalInt.empty();
}
@Override
public void sendTradeOffers( int id, TraderOfferList list, int level, int experience, boolean levelled ) { }
@Override
public void openHorseInventory( HorseBaseEntity horse, Inventory inventory ) { }
@Override
public void openEditBookScreen( ItemStack stack, Hand hand ) { }
@Override
public void openCommandBlockScreen( CommandBlockBlockEntity block ) { }
@Override
public void onContainerSlotUpdate( Container container, int slot, ItemStack stack ) { }
@Override
public void onContainerRegistered( Container container, DefaultedList<ItemStack> defaultedList ) { }
@Override
public void onContainerPropertyUpdate( Container container, int key, int value ) { }
@Override
public void closeContainer() { }
@Override
public void method_14241() { }
@Override
public void addChatMessage( Component textComponent, boolean status ) { }
@Override
protected void method_6040() { }
@Override
public void lookAt( EntityAnchorArgumentType.EntityAnchor anchor, Vec3d vec3d ) { }
@Override
public void method_14222( EntityAnchorArgumentType.EntityAnchor self, Entity entity, EntityAnchorArgumentType.EntityAnchor target ) { }
@Override
protected void method_6020( StatusEffectInstance statusEffectInstance ) { }
@Override
protected void method_6009( StatusEffectInstance statusEffectInstance, boolean particles ) { }
@Override
protected void method_6129( StatusEffectInstance statusEffectInstance ) { }
@Override
public void requestTeleport( double x, double y, double z ) { }
@Override
public void setGameMode( GameMode gameMode ) { }
@Override
public void sendChatMessage( Component textComponent, ChatMessageType chatMessageType ) { }
@Override
public String getServerBrand()
{
return "[Fake Player]";
}
@Override
public void method_14255( String url, String hash ) { }
@Override
public void onStoppedTracking( Entity entity ) { }
@Override
public void setCameraEntity( Entity entity ) { }
@Override
public void teleport( ServerWorld serverWorld, double x, double y, double z, float pitch, float yaw ) { }
@Override
public void sendInitialChunkPackets( ChunkPos chunkPos, Packet<?> packet, Packet<?> packet2 ) { }
@Override
public void sendUnloadChunkPacket( ChunkPos chunkPos ) { }
@Override
public void playSound( SoundEvent soundEvent, SoundCategory soundCategory, float volume, float pitch ) { }
// endregion
// Indirect
@Override
public int lockRecipes( Collection<Recipe<?>> recipes )
{
return 0;
}
@Override
public int unlockRecipes( Collection<Recipe<?>> recipes )
{
return 0;
}
//
private static class FakeNetHandler extends ServerPlayNetworkHandler
{
FakeNetHandler( ServerPlayerEntity player )
{
super( player.server, new FakeConnection(), player );
}
@Override
public void disconnect( Component message ) { }
@Override
public void onRequestCommandCompletions( RequestCommandCompletionsC2SPacket packet ) { }
@Override
public void sendPacket( Packet<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> listener ) { }
@Override
public void onVehicleMove( VehicleMoveC2SPacket move ) { }
}
private static class FakeConnection extends ClientConnection
{
FakeConnection()
{
super( NetworkSide.CLIENTBOUND );
}
@Override
public void channelActive( ChannelHandlerContext active )
{
}
@Override
public void setState( NetworkState state )
{
}
@Override
public void disconnect( Component message )
{
}
@Override
public void exceptionCaught( ChannelHandlerContext context, Throwable err )
{
}
@Override
protected void method_10770( ChannelHandlerContext context, Packet<?> packet )
{
}
@Override
public void tick()
{
}
@Override
public void setupEncryption( SecretKey key )
{
}
@Override
public void disableAutoRead()
{
}
@Override
public void setMinCompressedSize( int size )
{
}
@Override
public void send( Packet<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> listener )
{
}
}
}

View File

@@ -8,7 +8,6 @@ package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleCommandResult; import dan200.computercraft.api.turtle.TurtleCommandResult;
import net.minecraftforge.eventbus.api.Cancelable;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -17,11 +16,11 @@ import java.util.Objects;
/** /**
* An event fired when a turtle is performing a known action. * An event fired when a turtle is performing a known action.
*/ */
@Cancelable
public class TurtleActionEvent extends TurtleEvent public class TurtleActionEvent extends TurtleEvent
{ {
private final TurtleAction action; private final TurtleAction action;
private String failureMessage; private String failureMessage;
private boolean cancelled = false;
public TurtleActionEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action ) public TurtleActionEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action )
{ {
@@ -45,7 +44,6 @@ public class TurtleActionEvent extends TurtleEvent
* @see TurtleCommandResult#failure() * @see TurtleCommandResult#failure()
* @deprecated Use {@link #setCanceled(boolean, String)} instead. * @deprecated Use {@link #setCanceled(boolean, String)} instead.
*/ */
@Override
@Deprecated @Deprecated
public void setCanceled( boolean cancel ) public void setCanceled( boolean cancel )
{ {
@@ -63,7 +61,7 @@ public class TurtleActionEvent extends TurtleEvent
*/ */
public void setCanceled( boolean cancel, @Nullable String failureMessage ) public void setCanceled( boolean cancel, @Nullable String failureMessage )
{ {
super.setCanceled( cancel ); this.cancelled = true;
this.failureMessage = cancel ? failureMessage : null; this.failureMessage = cancel ? failureMessage : null;
} }
@@ -79,4 +77,15 @@ public class TurtleActionEvent extends TurtleEvent
{ {
return failureMessage; return failureMessage;
} }
/**
* Determine if this event is cancelled
*
* @return If this event is cancelled
* @see #setCanceled(boolean, String)
*/
public boolean isCancelled()
{
return cancelled;
}
} }

View File

@@ -11,9 +11,7 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.api.turtle.TurtleVerb; import dan200.computercraft.api.turtle.TurtleVerb;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.util.EnumFacing; import net.minecraft.util.math.Direction;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.event.entity.player.AttackEntityEvent;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Objects; import java.util.Objects;
@@ -21,10 +19,11 @@ import java.util.Objects;
/** /**
* Fired when a turtle attempts to attack an entity. * Fired when a turtle attempts to attack an entity.
* *
* This must be fired by {@link ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, EnumFacing)}, * This must be fired by {@link ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction)},
* as the base {@code turtle.attack()} command does not fire it. * as the base {@code turtle.attack()} command does not fire it.
* *
* Note that such commands should also fire {@link AttackEntityEvent}, so you do not need to listen to both. * Note that such commands should also fire {@link net.fabricmc.fabric.api.event.player.AttackEntityCallback}, so you do
* not need to listen to both.
* *
* @see TurtleAction#ATTACK * @see TurtleAction#ATTACK
*/ */

View File

@@ -12,13 +12,11 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.api.turtle.TurtleVerb; import dan200.computercraft.api.turtle.TurtleVerb;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.event.world.BlockEvent;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Map; import java.util.Map;
@@ -75,20 +73,21 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
/** /**
* Fired when a turtle attempts to dig a block. * Fired when a turtle attempts to dig a block.
* *
* This must be fired by {@link ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, EnumFacing)}, * This must be fired by {@link ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction)},
* as the base {@code turtle.dig()} command does not fire it. * as the base {@code turtle.dig()} command does not fire it.
* *
* Note that such commands should also fire {@link BlockEvent.BreakEvent}, so you do not need to listen to both. * Note that such commands should also fire {@link net.fabricmc.fabric.api.event.player.AttackBlockCallback}, so you
* do not need to listen to both.
* *
* @see TurtleAction#DIG * @see TurtleAction#DIG
*/ */
public static class Dig extends TurtleBlockEvent public static class Dig extends TurtleBlockEvent
{ {
private final IBlockState block; private final BlockState block;
private final ITurtleUpgrade upgrade; private final ITurtleUpgrade upgrade;
private final TurtleSide side; private final TurtleSide side;
public Dig( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull IBlockState block, @Nonnull ITurtleUpgrade upgrade, @Nonnull TurtleSide side ) public Dig( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState block, @Nonnull ITurtleUpgrade upgrade, @Nonnull TurtleSide side )
{ {
super( turtle, TurtleAction.DIG, player, world, pos ); super( turtle, TurtleAction.DIG, player, world, pos );
@@ -106,7 +105,7 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
* @return The block which is going to be broken. * @return The block which is going to be broken.
*/ */
@Nonnull @Nonnull
public IBlockState getBlock() public BlockState getBlock()
{ {
return block; return block;
} }
@@ -185,10 +184,10 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
*/ */
public static class Inspect extends TurtleBlockEvent public static class Inspect extends TurtleBlockEvent
{ {
private final IBlockState state; private final BlockState state;
private final Map<String, Object> data; private final Map<String, Object> data;
public Inspect( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull IBlockState state, @Nonnull Map<String, Object> data ) public Inspect( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nonnull Map<String, Object> data )
{ {
super( turtle, TurtleAction.INSPECT, player, world, pos ); super( turtle, TurtleAction.INSPECT, player, world, pos );
@@ -204,7 +203,7 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
* @return The inspected block state. * @return The inspected block state.
*/ */
@Nonnull @Nonnull
public IBlockState getState() public BlockState getState()
{ {
return state; return state;
} }

View File

@@ -6,8 +6,8 @@
package dan200.computercraft.api.turtle.event; package dan200.computercraft.api.turtle.event;
import com.google.common.eventbus.EventBus;
import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleAccess;
import net.minecraftforge.eventbus.api.Event;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Objects; import java.util.Objects;
@@ -20,8 +20,10 @@ import java.util.Objects;
* *
* @see TurtleActionEvent * @see TurtleActionEvent
*/ */
public abstract class TurtleEvent extends Event public abstract class TurtleEvent
{ {
public static final EventBus EVENT_BUS = new EventBus();
private final ITurtleAccess turtle; private final ITurtleAccess turtle;
protected TurtleEvent( @Nonnull ITurtleAccess turtle ) protected TurtleEvent( @Nonnull ITurtleAccess turtle )
@@ -40,4 +42,10 @@ public abstract class TurtleEvent extends Event
{ {
return turtle; return turtle;
} }
public static boolean post( TurtleActionEvent event )
{
EVENT_BUS.post( event );
return event.isCancelled();
}
} }

View File

@@ -7,11 +7,10 @@
package dan200.computercraft.api.turtle.event; package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleAccess;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -22,9 +21,9 @@ import java.util.Objects;
*/ */
public abstract class TurtleInventoryEvent extends TurtleBlockEvent public abstract class TurtleInventoryEvent extends TurtleBlockEvent
{ {
private final IItemHandler handler; private final Inventory handler;
protected TurtleInventoryEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable IItemHandler handler ) protected TurtleInventoryEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable Inventory handler )
{ {
super( turtle, action, player, world, pos ); super( turtle, action, player, world, pos );
this.handler = handler; this.handler = handler;
@@ -36,7 +35,7 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent
* @return The inventory being interacted with, {@code null} if the item will be dropped to/sucked from the world. * @return The inventory being interacted with, {@code null} if the item will be dropped to/sucked from the world.
*/ */
@Nullable @Nullable
public IItemHandler getItemHandler() public Inventory getItemHandler()
{ {
return handler; return handler;
} }
@@ -48,7 +47,7 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent
*/ */
public static class Suck extends TurtleInventoryEvent public static class Suck extends TurtleInventoryEvent
{ {
public Suck( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable IItemHandler handler ) public Suck( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable Inventory handler )
{ {
super( turtle, TurtleAction.SUCK, player, world, pos, handler ); super( turtle, TurtleAction.SUCK, player, world, pos, handler );
} }
@@ -63,7 +62,7 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent
{ {
private final ItemStack stack; private final ItemStack stack;
public Drop( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable IItemHandler handler, @Nonnull ItemStack stack ) public Drop( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable Inventory handler, @Nonnull ItemStack stack )
{ {
super( turtle, TurtleAction.DROP, player, world, pos, handler ); super( turtle, TurtleAction.DROP, player, world, pos, handler );

View File

@@ -7,7 +7,6 @@
package dan200.computercraft.api.turtle.event; package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleAccess;
import net.minecraftforge.common.util.FakePlayer;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Objects; import java.util.Objects;

View File

@@ -7,36 +7,28 @@
package dan200.computercraft.client; package dan200.computercraft.client;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.render.TurtleModelLoader;
import dan200.computercraft.shared.common.IColouredItem; import dan200.computercraft.shared.common.IColouredItem;
import dan200.computercraft.shared.media.items.ItemDisk; import dan200.computercraft.shared.media.items.ItemDisk;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.Colour;
import net.minecraft.client.Minecraft; import net.fabricmc.fabric.api.client.render.ColorProviderRegistry;
import net.minecraft.client.renderer.model.IBakedModel; import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback;
import net.minecraft.client.renderer.model.IUnbakedModel; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.renderer.model.ModelResourceLocation; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.renderer.model.ModelRotation; import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.render.model.ModelRotation;
import net.minecraft.resources.IResourceManager; import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.util.ResourceLocation; import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraftforge.api.distmarker.Dist; import net.minecraft.client.util.ModelIdentifier;
import net.minecraftforge.client.event.ColorHandlerEvent; import net.minecraft.resource.ResourceManager;
import net.minecraftforge.client.event.ModelBakeEvent; import net.minecraft.util.Identifier;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.function.Consumer;
/** /**
* Registers textures and models for items. * Registers textures and models for items.
*/ */
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class ClientRegistry public final class ClientRegistry
{ {
private static final String[] EXTRA_MODELS = new String[] { private static final String[] EXTRA_MODELS = new String[] {
@@ -70,69 +62,30 @@ public final class ClientRegistry
private ClientRegistry() {} private ClientRegistry() {}
@SubscribeEvent public static void onTextureStitchEvent( SpriteAtlasTexture atlasTexture, ClientSpriteRegistryCallback.Registry registry )
public static void registerModels( ModelRegistryEvent event )
{ {
ModelLoaderRegistry.registerLoader( TurtleModelLoader.INSTANCE );
}
@SubscribeEvent
public static void onTextureStitchEvent( TextureStitchEvent.Pre event )
{
IResourceManager manager = Minecraft.getInstance().getResourceManager();
for( String extra : EXTRA_TEXTURES ) for( String extra : EXTRA_TEXTURES )
{ {
event.getMap().registerSprite( manager, new ResourceLocation( ComputerCraft.MOD_ID, extra ) ); registry.register( new Identifier( ComputerCraft.MOD_ID, extra ) );
} }
} }
@SubscribeEvent public static void onModelBakeEvent( ResourceManager manager, Consumer<ModelIdentifier> out )
public static void onModelBakeEvent( ModelBakeEvent event )
{ {
// Load all extra models
ModelLoader loader = event.getModelLoader();
Map<ModelResourceLocation, IBakedModel> registry = event.getModelRegistry();
for( String model : EXTRA_MODELS ) for( String model : EXTRA_MODELS )
{ {
IBakedModel bakedModel = bake( loader, loader.getUnbakedModel( new ResourceLocation( ComputerCraft.MOD_ID, "item/" + model ) ) ); out.accept( new ModelIdentifier( new Identifier( ComputerCraft.MOD_ID, model ), "inventory" ) );
}
}
if( bakedModel != null ) public static void onItemColours()
{ {
registry.put( ColorProviderRegistry.ITEM.register(
new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, model ), "inventory" ),
bakedModel
);
}
}
// And load the custom turtle models in too.
registry.put(
new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_normal" ), "inventory" ),
bake( loader, TurtleModelLoader.INSTANCE.loadModel( new ResourceLocation( ComputerCraft.MOD_ID, "item/turtle_normal" ) ) )
);
registry.put(
new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_advanced" ), "inventory" ),
bake( loader, TurtleModelLoader.INSTANCE.loadModel( new ResourceLocation( ComputerCraft.MOD_ID, "item/turtle_advanced" ) ) )
);
}
@SubscribeEvent
public static void onItemColours( ColorHandlerEvent.Item event )
{
if( ComputerCraft.Items.disk == null || ComputerCraft.Blocks.turtleNormal == null )
{
ComputerCraft.log.warn( "Block/item registration has failed. Skipping registration of item colours." );
return;
}
event.getItemColors().register(
( stack, layer ) -> layer == 1 ? ((ItemDisk) stack.getItem()).getColour( stack ) : 0xFFFFFF, ( stack, layer ) -> layer == 1 ? ((ItemDisk) stack.getItem()).getColour( stack ) : 0xFFFFFF,
ComputerCraft.Items.disk ComputerCraft.Items.disk
); );
event.getItemColors().register( ( stack, layer ) -> { ColorProviderRegistry.ITEM.register( ( stack, layer ) -> {
switch( layer ) switch( layer )
{ {
case 0: case 0:
@@ -149,20 +102,16 @@ public final class ClientRegistry
}, ComputerCraft.Items.pocketComputerNormal, ComputerCraft.Items.pocketComputerAdvanced ); }, ComputerCraft.Items.pocketComputerNormal, ComputerCraft.Items.pocketComputerAdvanced );
// Setup turtle colours // Setup turtle colours
event.getItemColors().register( ColorProviderRegistry.ITEM.register(
( stack, tintIndex ) -> tintIndex == 0 ? ((IColouredItem) stack.getItem()).getColour( stack ) : 0xFFFFFF, ( stack, tintIndex ) -> tintIndex == 0 ? ((IColouredItem) stack.getItem()).getColour( stack ) : 0xFFFFFF,
ComputerCraft.Blocks.turtleNormal, ComputerCraft.Blocks.turtleAdvanced ComputerCraft.Blocks.turtleNormal, ComputerCraft.Blocks.turtleAdvanced
); );
} }
private static IBakedModel bake( ModelLoader loader, IUnbakedModel model ) private static BakedModel bake( ModelLoader loader, UnbakedModel model )
{ {
model.getTextures( loader::getUnbakedModel, new HashSet<>() ); model.getTextureDependencies( loader::getOrLoadModel, new HashSet<>() );
SpriteAtlasTexture sprite = MinecraftClient.getInstance().getSpriteAtlas();
return model.bake( return model.bake( loader, sprite::getSprite, ModelRotation.X0_Y0 );
loader::getUnbakedModel,
ModelLoader.defaultTextureGetter(),
ModelRotation.X0_Y0, false, DefaultVertexFormats.BLOCK
);
} }
} }

View File

@@ -10,13 +10,13 @@ import dan200.computercraft.shared.command.text.ChatHelpers;
import dan200.computercraft.shared.command.text.TableBuilder; import dan200.computercraft.shared.command.text.TableBuilder;
import dan200.computercraft.shared.command.text.TableFormatter; import dan200.computercraft.shared.command.text.TableFormatter;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import net.minecraft.client.Minecraft; import net.minecraft.ChatFormat;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.GuiNewChat; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.GuiUtilRenderComponents; import net.minecraft.client.gui.hud.ChatHud;
import net.minecraft.client.util.TextComponentUtil;
import net.minecraft.network.chat.Component;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -28,25 +28,25 @@ public class ClientTableFormatter implements TableFormatter
private static Int2IntOpenHashMap lastHeights = new Int2IntOpenHashMap(); private static Int2IntOpenHashMap lastHeights = new Int2IntOpenHashMap();
private static FontRenderer renderer() private static TextRenderer renderer()
{ {
return Minecraft.getInstance().fontRenderer; return MinecraftClient.getInstance().textRenderer;
} }
@Override @Override
@Nullable @Nullable
public ITextComponent getPadding( ITextComponent component, int width ) public Component getPadding( Component component, int width )
{ {
int extraWidth = width - getWidth( component ); int extraWidth = width - getWidth( component );
if( extraWidth <= 0 ) return null; if( extraWidth <= 0 ) return null;
FontRenderer renderer = renderer(); TextRenderer renderer = renderer();
float spaceWidth = renderer.getStringWidth( " " ); float spaceWidth = renderer.getCharWidth( ' ' );
int spaces = MathHelper.floor( extraWidth / spaceWidth ); int spaces = MathHelper.floor( extraWidth / spaceWidth );
int extra = extraWidth - (int) (spaces * spaceWidth); int extra = extraWidth - (int) (spaces * spaceWidth);
return ChatHelpers.coloured( StringUtils.repeat( ' ', spaces ) + StringUtils.repeat( (char) 712, extra ), TextFormatting.GRAY ); return ChatHelpers.coloured( StringUtils.repeat( ' ', spaces ) + StringUtils.repeat( (char) 712, extra ), ChatFormat.GRAY );
} }
@Override @Override
@@ -56,34 +56,34 @@ public class ClientTableFormatter implements TableFormatter
} }
@Override @Override
public int getWidth( ITextComponent component ) public int getWidth( Component component )
{ {
return renderer().getStringWidth( component.getFormattedText() ); return renderer().getStringWidth( component.getFormattedText() );
} }
@Override @Override
public void writeLine( int id, ITextComponent component ) public void writeLine( int id, Component component )
{ {
Minecraft mc = Minecraft.getInstance(); MinecraftClient mc = MinecraftClient.getInstance();
GuiNewChat chat = mc.ingameGUI.getChatGUI(); ChatHud chat = mc.inGameHud.getChatHud();
// Trim the text if it goes over the allowed length // Trim the text if it goes over the allowed length
int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getScale() ); int maxWidth = MathHelper.floor( chat.getWidth() / chat.getScale() );
List<ITextComponent> list = GuiUtilRenderComponents.splitText( component, maxWidth, mc.fontRenderer, false, false ); List<Component> list = TextComponentUtil.wrapLines( component, maxWidth, mc.textRenderer, false, false );
if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id ); if( !list.isEmpty() ) chat.addMessage( list.get( 0 ), id );
} }
@Override @Override
public int display( TableBuilder table ) public int display( TableBuilder table )
{ {
GuiNewChat chat = Minecraft.getInstance().ingameGUI.getChatGUI(); ChatHud chat = MinecraftClient.getInstance().inGameHud.getChatHud();
int lastHeight = lastHeights.get( table.getId() ); int lastHeight = lastHeights.get( table.getId() );
int height = TableFormatter.super.display( table ); int height = TableFormatter.super.display( table );
lastHeights.put( table.getId(), height ); lastHeights.put( table.getId(), height );
for( int i = height; i < lastHeight; i++ ) chat.deleteChatLine( i + table.getId() ); for( int i = height; i < lastHeight; i++ ) chat.removeMessage( i + table.getId() );
return height; return height;
} }
} }

View File

@@ -6,13 +6,6 @@
package dan200.computercraft.client; package dan200.computercraft.client;
import dan200.computercraft.ComputerCraft;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.gameevent.TickEvent;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class FrameInfo public final class FrameInfo
{ {
private static int tick; private static int tick;
@@ -32,15 +25,13 @@ public final class FrameInfo
return renderFrame; return renderFrame;
} }
@SubscribeEvent public static void onTick()
public static void onTick( TickEvent.ClientTickEvent event )
{ {
if( event.phase == TickEvent.Phase.START ) tick++; tick++;
} }
@SubscribeEvent public static void onRenderFrame()
public static void onRenderTick( TickEvent.RenderTickEvent event )
{ {
if( event.phase == TickEvent.Phase.START ) renderFrame++; renderFrame++;
} }
} }

View File

@@ -6,23 +6,23 @@
package dan200.computercraft.client.gui; package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.util.Palette; import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.Minecraft; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.render.Tessellator;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.texture.TextureManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.util.Identifier;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import java.util.Arrays; import java.util.Arrays;
public final class FixedWidthFontRenderer public final class FixedWidthFontRenderer
{ {
private static final ResourceLocation FONT = new ResourceLocation( "computercraft", "textures/gui/term_font.png" ); private static final Identifier FONT = new Identifier( "computercraft", "textures/gui/term_font.png" );
public static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/term_background.png" ); public static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/term_background.png" );
public static final int FONT_HEIGHT = 9; public static final int FONT_HEIGHT = 9;
public static final int FONT_WIDTH = 6; public static final int FONT_WIDTH = 6;
@@ -39,7 +39,7 @@ public final class FixedWidthFontRenderer
private FixedWidthFontRenderer() private FixedWidthFontRenderer()
{ {
m_textureManager = Minecraft.getInstance().getTextureManager(); m_textureManager = MinecraftClient.getInstance().getTextureManager();
} }
private static void greyscaleify( double[] rgb ) private static void greyscaleify( double[] rgb )
@@ -64,12 +64,12 @@ public final class FixedWidthFontRenderer
int xStart = 1 + column * (FONT_WIDTH + 2); int xStart = 1 + column * (FONT_WIDTH + 2);
int yStart = 1 + row * (FONT_HEIGHT + 2); int yStart = 1 + row * (FONT_HEIGHT + 2);
renderer.pos( x, y, 0.0 ).tex( xStart / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( x, y, 0.0 ).texture( xStart / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( xStart / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( x, y + FONT_HEIGHT, 0.0 ).texture( xStart / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( x + FONT_WIDTH, y, 0.0 ).tex( (xStart + FONT_WIDTH) / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( x + FONT_WIDTH, y, 0.0 ).texture( (xStart + FONT_WIDTH) / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( x + FONT_WIDTH, y, 0.0 ).tex( (xStart + FONT_WIDTH) / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( x + FONT_WIDTH, y, 0.0 ).texture( (xStart + FONT_WIDTH) / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( xStart / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( x, y + FONT_HEIGHT, 0.0 ).texture( xStart / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( x + FONT_WIDTH, y + FONT_HEIGHT, 0.0 ).tex( (xStart + FONT_WIDTH) / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( x + FONT_WIDTH, y + FONT_HEIGHT, 0.0 ).texture( (xStart + FONT_WIDTH) / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).next();
} }
private void drawQuad( BufferBuilder renderer, double x, double y, int color, double width, Palette p, boolean greyscale ) private void drawQuad( BufferBuilder renderer, double x, double y, int color, double width, Palette p, boolean greyscale )
@@ -83,12 +83,12 @@ public final class FixedWidthFontRenderer
float g = (float) colour[1]; float g = (float) colour[1];
float b = (float) colour[2]; float b = (float) colour[2];
renderer.pos( x, y, 0.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( x, y, 0.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( x, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( x + width, y, 0.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( x + width, y, 0.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( x + width, y, 0.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( x + width, y, 0.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( x, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( x + width, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( x + width, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).next();
} }
private boolean isGreyScale( int colour ) private boolean isGreyScale( int colour )
@@ -100,8 +100,8 @@ public final class FixedWidthFontRenderer
{ {
// Draw the quads // Draw the quads
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder renderer = tessellator.getBuffer(); BufferBuilder renderer = tessellator.getBufferBuilder();
renderer.begin( GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_COLOR ); renderer.begin( GL11.GL_TRIANGLES, VertexFormats.POSITION_COLOR );
if( leftMarginSize > 0.0 ) if( leftMarginSize > 0.0 )
{ {
int colour1 = "0123456789abcdef".indexOf( backgroundColour.charAt( 0 ) ); int colour1 = "0123456789abcdef".indexOf( backgroundColour.charAt( 0 ) );
@@ -129,17 +129,17 @@ public final class FixedWidthFontRenderer
} }
drawQuad( renderer, x + i * FONT_WIDTH, y, colour, FONT_WIDTH, p, greyScale ); drawQuad( renderer, x + i * FONT_WIDTH, y, colour, FONT_WIDTH, p, greyScale );
} }
GlStateManager.disableTexture2D(); GlStateManager.disableTexture();
tessellator.draw(); tessellator.draw();
GlStateManager.enableTexture2D(); GlStateManager.enableTexture();
} }
public void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale, Palette p ) public void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale, Palette p )
{ {
// Draw the quads // Draw the quads
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder renderer = tessellator.getBuffer(); BufferBuilder renderer = tessellator.getBufferBuilder();
renderer.begin( GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_TEX_COLOR ); renderer.begin( GL11.GL_TRIANGLES, VertexFormats.POSITION_UV_COLOR );
for( int i = 0; i < s.length(); i++ ) for( int i = 0; i < s.length(); i++ )
{ {
// Switch colour // Switch colour
@@ -195,6 +195,6 @@ public final class FixedWidthFontRenderer
public void bindFont() public void bindFont()
{ {
m_textureManager.bindTexture( FONT ); m_textureManager.bindTexture( FONT );
GlStateManager.texParameteri( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP ); GlStateManager.texParameter( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
} }
} }

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.client.gui; package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.gui.widgets.WidgetTerminal; import dan200.computercraft.client.gui.widgets.WidgetTerminal;
import dan200.computercraft.client.gui.widgets.WidgetWrapper; import dan200.computercraft.client.gui.widgets.WidgetWrapper;
@@ -13,17 +14,19 @@ import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.ClientComputer; import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.inventory.ContainerComputer; import dan200.computercraft.shared.computer.inventory.ContainerComputer;
import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.container.Container;
import net.minecraft.inventory.Container; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation; import net.minecraft.network.chat.TextComponent;
import net.minecraft.util.Identifier;
import org.lwjgl.glfw.GLFW;
public class GuiComputer extends GuiContainer public class GuiComputer<T extends Container> extends AbstractContainerScreen<T>
{ {
public static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners_normal.png" ); public static final Identifier BACKGROUND_NORMAL = new Identifier( ComputerCraft.MOD_ID, "textures/gui/corners_normal.png" );
public static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners_advanced.png" ); public static final Identifier BACKGROUND_ADVANCED = new Identifier( ComputerCraft.MOD_ID, "textures/gui/corners_advanced.png" );
public static final ResourceLocation BACKGROUND_COMMAND = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners_command.png" ); public static final Identifier BACKGROUND_COMMAND = new Identifier( ComputerCraft.MOD_ID, "textures/gui/corners_command.png" );
public static final ResourceLocation BACKGROUND_COLOUR = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners_colour.png" ); public static final Identifier BACKGROUND_COLOUR = new Identifier( ComputerCraft.MOD_ID, "textures/gui/corners_colour.png" );
private final ComputerFamily m_family; private final ComputerFamily m_family;
private final ClientComputer m_computer; private final ClientComputer m_computer;
@@ -33,9 +36,11 @@ public class GuiComputer extends GuiContainer
private WidgetTerminal terminal; private WidgetTerminal terminal;
private WidgetWrapper terminalWrapper; private WidgetWrapper terminalWrapper;
public GuiComputer( Container container, ComputerFamily family, ClientComputer computer, int termWidth, int termHeight )
public GuiComputer( T container, PlayerInventory player, ComputerFamily family, ClientComputer computer, int termWidth, int termHeight )
{ {
super( container ); super( container, player, new TextComponent( "" ) );
m_family = family; m_family = family;
m_computer = computer; m_computer = computer;
m_termWidth = termWidth; m_termWidth = termWidth;
@@ -43,10 +48,10 @@ public class GuiComputer extends GuiContainer
terminal = null; terminal = null;
} }
public GuiComputer( TileComputer computer ) public static GuiComputer<ContainerComputer> create( int id, TileComputer computer, PlayerInventory player )
{ {
this( return new GuiComputer<>(
new ContainerComputer( computer ), new ContainerComputer( id, computer ), player,
computer.getFamily(), computer.getFamily(),
computer.createClientComputer(), computer.createClientComputer(),
ComputerCraft.terminalWidth_computer, ComputerCraft.terminalWidth_computer,
@@ -55,32 +60,32 @@ public class GuiComputer extends GuiContainer
} }
@Override @Override
protected void initGui() protected void init()
{ {
mc.keyboardListener.enableRepeatEvents( true ); minecraft.keyboard.enableRepeatEvents( true );
int termPxWidth = m_termWidth * FixedWidthFontRenderer.FONT_WIDTH; int termPxWidth = m_termWidth * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = m_termHeight * FixedWidthFontRenderer.FONT_HEIGHT; int termPxHeight = m_termHeight * FixedWidthFontRenderer.FONT_HEIGHT;
xSize = termPxWidth + 4 + 24; containerWidth = termPxWidth + 4 + 24;
ySize = termPxHeight + 4 + 24; containerHeight = termPxHeight + 4 + 24;
super.initGui(); super.init();
terminal = new WidgetTerminal( mc, () -> m_computer, m_termWidth, m_termHeight, 2, 2, 2, 2 ); terminal = new WidgetTerminal( minecraft, () -> m_computer, m_termWidth, m_termHeight, 2, 2, 2, 2 );
terminalWrapper = new WidgetWrapper( terminal, 2 + 12 + guiLeft, 2 + 12 + guiTop, termPxWidth, termPxHeight ); terminalWrapper = new WidgetWrapper( terminal, 2 + 12 + left, 2 + 12 + top, termPxWidth, termPxHeight );
children.add( terminalWrapper ); children.add( terminalWrapper );
setFocused( terminalWrapper ); setFocused( terminalWrapper );
} }
@Override @Override
public void onGuiClosed() public void removed()
{ {
super.onGuiClosed(); super.removed();
children.remove( terminal ); children.remove( terminal );
terminal = null; terminal = null;
mc.keyboardListener.enableRepeatEvents( false ); minecraft.keyboard.enableRepeatEvents( false );
} }
@Override @Override
@@ -91,7 +96,7 @@ public class GuiComputer extends GuiContainer
} }
@Override @Override
public void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY ) public void drawBackground( float partialTicks, int mouseX, int mouseY )
{ {
// Work out where to draw // Work out where to draw
int startX = terminalWrapper.getX() - 2; int startX = terminalWrapper.getX() - 2;
@@ -108,39 +113,48 @@ public class GuiComputer extends GuiContainer
{ {
case Normal: case Normal:
default: default:
mc.getTextureManager().bindTexture( BACKGROUND_NORMAL ); minecraft.getTextureManager().bindTexture( BACKGROUND_NORMAL );
break; break;
case Advanced: case Advanced:
mc.getTextureManager().bindTexture( BACKGROUND_ADVANCED ); minecraft.getTextureManager().bindTexture( BACKGROUND_ADVANCED );
break; break;
case Command: case Command:
mc.getTextureManager().bindTexture( BACKGROUND_COMMAND ); minecraft.getTextureManager().bindTexture( BACKGROUND_COMMAND );
break; break;
} }
drawTexturedModalRect( startX - 12, startY - 12, 12, 28, 12, 12 ); blit( startX - 12, startY - 12, 12, 28, 12, 12 );
drawTexturedModalRect( startX - 12, endY, 12, 40, 12, 12 ); blit( startX - 12, endY, 12, 40, 12, 12 );
drawTexturedModalRect( endX, startY - 12, 24, 28, 12, 12 ); blit( endX, startY - 12, 24, 28, 12, 12 );
drawTexturedModalRect( endX, endY, 24, 40, 12, 12 ); blit( endX, endY, 24, 40, 12, 12 );
drawTexturedModalRect( startX, startY - 12, 0, 0, endX - startX, 12 ); blit( startX, startY - 12, 0, 0, endX - startX, 12 );
drawTexturedModalRect( startX, endY, 0, 12, endX - startX, 12 ); blit( startX, endY, 0, 12, endX - startX, 12 );
drawTexturedModalRect( startX - 12, startY, 0, 28, 12, endY - startY ); blit( startX - 12, startY, 0, 28, 12, endY - startY );
drawTexturedModalRect( endX, startY, 36, 28, 12, endY - startY ); blit( endX, startY, 36, 28, 12, endY - startY );
} }
@Override @Override
public void render( int mouseX, int mouseY, float partialTicks ) public void render( int mouseX, int mouseY, float partialTicks )
{ {
drawDefaultBackground(); renderBackground( 0 );
super.render( mouseX, mouseY, partialTicks ); super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY ); drawMouseoverTooltip( mouseX, mouseY );
}
@Override
public boolean keyPressed( int key, int scancode, int modifiers )
{
// When pressing tab, send it to the computer first
return (key == GLFW.GLFW_KEY_TAB && getFocused() == terminalWrapper && terminalWrapper.keyPressed( key, scancode, modifiers ))
|| super.keyPressed( key, scancode, modifiers );
} }
@Override @Override
public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY ) public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
{ {
// Make sure drag events are propagated to children
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY )) return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|| super.mouseDragged( x, y, button, deltaX, deltaY ); || super.mouseDragged( x, y, button, deltaX, deltaY );
} }
@@ -148,6 +162,7 @@ public class GuiComputer extends GuiContainer
@Override @Override
public boolean mouseReleased( double x, double y, int button ) public boolean mouseReleased( double x, double y, int button )
{ {
// Make sure release events are propagated to children
return (getFocused() != null && getFocused().mouseReleased( x, y, button )) return (getFocused() != null && getFocused().mouseReleased( x, y, button ))
|| super.mouseReleased( x, y, button ); || super.mouseReleased( x, y, button );
} }

View File

@@ -6,45 +6,44 @@
package dan200.computercraft.client.gui; package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive; import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.Identifier;
public class GuiDiskDrive extends GuiContainer public class GuiDiskDrive extends AbstractContainerScreen<ContainerDiskDrive>
{ {
private static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/disk_drive.png" ); private static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/disk_drive.png" );
private final ContainerDiskDrive m_container; public GuiDiskDrive( ContainerDiskDrive container, PlayerInventory inventory )
public GuiDiskDrive( ContainerDiskDrive container )
{ {
super( container ); super( container, inventory, ComputerCraft.Blocks.diskDrive.getTextComponent() );
m_container = container;
} }
@Override @Override
protected void drawGuiContainerForegroundLayer( int mouseX, int mouseY ) protected void drawForeground( int par1, int par2 )
{ {
String title = m_container.getDiskDrive().getDisplayName().getString(); String title = getTitle().getFormattedText();
fontRenderer.drawString( title, (xSize - fontRenderer.getStringWidth( title )) / 2.0f, 6, 0x404040 ); font.draw( title, (containerWidth - font.getStringWidth( title )) / 2.0f, 6, 0x404040 );
fontRenderer.drawString( I18n.format( "container.inventory" ), 8, ySize - 96 + 2, 0x404040 ); font.draw( I18n.translate( "container.inventory" ), 8, (containerHeight - 96) + 2, 0x404040 );
} }
@Override @Override
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY ) protected void drawBackground( float partialTicks, int mouseX, int mouseY )
{ {
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F ); GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
mc.getTextureManager().bindTexture( BACKGROUND ); minecraft.getTextureManager().bindTexture( BACKGROUND );
drawTexturedModalRect( guiLeft, guiTop, 0, 0, xSize, ySize ); blit( left, top, 0, 0, containerWidth, containerHeight );
} }
@Override @Override
public void render( int mouseX, int mouseY, float partialTicks ) public void render( int mouseX, int mouseY, float partialTicks )
{ {
drawDefaultBackground(); renderBackground();
super.render( mouseX, mouseY, partialTicks ); super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY ); drawMouseoverTooltip( mouseX, mouseY );
} }
} }

View File

@@ -10,15 +10,16 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer; import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
public class GuiPocketComputer extends GuiComputer public class GuiPocketComputer extends GuiComputer<ContainerPocketComputer>
{ {
public GuiPocketComputer( ContainerPocketComputer container ) public GuiPocketComputer( ContainerPocketComputer container, PlayerInventory player )
{ {
super( super(
container, container, player,
getFamily( container.getStack() ), getFamily( container.getStack() ),
ItemPocketComputer.createClientComputer( container.getStack() ), ItemPocketComputer.createClientComputer( container.getStack() ),
ComputerCraft.terminalWidth_pocketComputer, ComputerCraft.terminalWidth_pocketComputer,

View File

@@ -6,47 +6,46 @@
package dan200.computercraft.client.gui; package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter; import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.Identifier;
public class GuiPrinter extends GuiContainer public class GuiPrinter extends AbstractContainerScreen<ContainerPrinter>
{ {
private static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/printer.png" ); private static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/printer.png" );
private final ContainerPrinter container; public GuiPrinter( ContainerPrinter container, PlayerInventory player )
public GuiPrinter( ContainerPrinter container )
{ {
super( container ); super( container, player, ComputerCraft.Blocks.printer.getTextComponent() );
this.container = container;
} }
@Override @Override
protected void drawGuiContainerForegroundLayer( int mouseX, int mouseY ) protected void drawForeground( int mouseX, int mouseY )
{ {
String title = container.getPrinter().getDisplayName().getString(); String title = getTitle().getFormattedText();
fontRenderer.drawString( title, (xSize - fontRenderer.getStringWidth( title )) / 2.0f, 6, 0x404040 ); font.draw( title, (containerWidth - font.getStringWidth( title )) / 2.0f, 6, 0x404040 );
fontRenderer.drawString( I18n.format( "container.inventory" ), 8, ySize - 96 + 2, 0x404040 ); font.draw( I18n.translate( "container.inventory" ), 8, containerHeight - 96 + 2, 0x404040 );
} }
@Override @Override
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY ) protected void drawBackground( float f, int i, int j )
{ {
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F ); GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
mc.getTextureManager().bindTexture( BACKGROUND ); minecraft.getTextureManager().bindTexture( BACKGROUND );
drawTexturedModalRect( guiLeft, guiTop, 0, 0, xSize, ySize ); blit( left, top, 0, 0, containerWidth, containerHeight );
if( container.isPrinting() ) drawTexturedModalRect( guiLeft + 34, guiTop + 21, 176, 0, 25, 45 ); if( container.isPrinting() ) blit( left + 34, top + 21, 176, 0, 25, 45 );
} }
@Override @Override
public void render( int mouseX, int mouseY, float partialTicks ) public void render( int mouseX, int mouseY, float partialTicks )
{ {
drawDefaultBackground(); renderBackground();
super.render( mouseX, mouseY, partialTicks ); super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY ); drawMouseoverTooltip( mouseX, mouseY );
} }
} }

View File

@@ -6,16 +6,17 @@
package dan200.computercraft.client.gui; package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.common.ContainerHeldItem; import dan200.computercraft.shared.common.ContainerHeldItem;
import dan200.computercraft.shared.media.items.ItemPrintout; import dan200.computercraft.shared.media.items.ItemPrintout;
import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.PlayerInventory;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import static dan200.computercraft.client.render.PrintoutRenderer.*; import static dan200.computercraft.client.render.PrintoutRenderer.*;
public class GuiPrintout extends GuiContainer public class GuiPrintout extends AbstractContainerScreen<ContainerHeldItem>
{ {
private final boolean m_book; private final boolean m_book;
private final int m_pages; private final int m_pages;
@@ -23,11 +24,11 @@ public class GuiPrintout extends GuiContainer
private final TextBuffer[] m_colours; private final TextBuffer[] m_colours;
private int m_page; private int m_page;
public GuiPrintout( ContainerHeldItem container ) public GuiPrintout( ContainerHeldItem container, PlayerInventory player )
{ {
super( container ); super( container, player, container.getStack().getDisplayName() );
ySize = Y_SIZE; containerHeight = Y_SIZE;
String[] text = ItemPrintout.getText( container.getStack() ); String[] text = ItemPrintout.getText( container.getStack() );
m_text = new TextBuffer[text.length]; m_text = new TextBuffer[text.length];
@@ -63,9 +64,9 @@ public class GuiPrintout extends GuiContainer
} }
@Override @Override
public boolean mouseScrolled( double delta ) public boolean mouseScrolled( double x, double y, double delta )
{ {
if( super.mouseScrolled( delta ) ) return true; if( super.mouseScrolled( x, y, delta ) ) return true;
if( delta < 0 ) if( delta < 0 )
{ {
// Scroll up goes to the next page // Scroll up goes to the next page
@@ -84,25 +85,25 @@ public class GuiPrintout extends GuiContainer
} }
@Override @Override
public void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY ) public void drawBackground( float partialTicks, int mouseX, int mouseY )
{ {
// Draw the printout // Draw the printout
GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f ); GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.enableDepthTest(); GlStateManager.enableDepthTest();
drawBorder( guiLeft, guiTop, zLevel, m_page, m_pages, m_book ); drawBorder( left, top, blitOffset, m_page, m_pages, m_book );
drawText( guiLeft + X_TEXT_MARGIN, guiTop + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours ); drawText( left + X_TEXT_MARGIN, top + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours );
} }
@Override @Override
public void render( int mouseX, int mouseY, float partialTicks ) public void render( int mouseX, int mouseY, float partialTicks )
{ {
// We must take the background further back in order to not overlap with our printed pages. // We must take the background further back in order to not overlap with our printed pages.
zLevel--; blitOffset--;
drawDefaultBackground(); renderBackground();
zLevel++; blitOffset++;
super.render( mouseX, mouseY, partialTicks ); super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY ); drawMouseoverTooltip( mouseX, mouseY );
} }
} }

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.client.gui; package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.gui.widgets.WidgetTerminal; import dan200.computercraft.client.gui.widgets.WidgetTerminal;
import dan200.computercraft.client.gui.widgets.WidgetWrapper; import dan200.computercraft.client.gui.widgets.WidgetWrapper;
@@ -13,14 +14,15 @@ import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.turtle.blocks.TileTurtle; import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle; import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.Identifier;
import org.lwjgl.glfw.GLFW;
public class GuiTurtle extends GuiContainer public class GuiTurtle extends AbstractContainerScreen<ContainerTurtle>
{ {
private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( "computercraft", "textures/gui/turtle_normal.png" ); private static final Identifier BACKGROUND_NORMAL = new Identifier( "computercraft", "textures/gui/turtle_normal.png" );
private static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation( "computercraft", "textures/gui/turtle_advanced.png" ); private static final Identifier BACKGROUND_ADVANCED = new Identifier( "computercraft", "textures/gui/turtle_advanced.png" );
private ContainerTurtle m_container; private ContainerTurtle m_container;
@@ -30,45 +32,46 @@ public class GuiTurtle extends GuiContainer
private WidgetTerminal terminal; private WidgetTerminal terminal;
private WidgetWrapper terminalWrapper; private WidgetWrapper terminalWrapper;
public GuiTurtle( TileTurtle turtle, ContainerTurtle container ) public GuiTurtle( TileTurtle turtle, ContainerTurtle container, PlayerInventory player )
{ {
super( container ); super( container, player, turtle.getDisplayName() );
m_container = container; m_container = container;
m_family = turtle.getFamily(); m_family = turtle.getFamily();
m_computer = turtle.getClientComputer(); m_computer = turtle.getClientComputer();
xSize = 254; containerWidth = 254;
ySize = 217; containerHeight = 217;
} }
@Override @Override
protected void initGui() protected void init()
{ {
super.initGui(); super.init();
mc.keyboardListener.enableRepeatEvents( true ); minecraft.keyboard.enableRepeatEvents( true );
int termPxWidth = ComputerCraft.terminalWidth_turtle * FixedWidthFontRenderer.FONT_WIDTH; int termPxWidth = ComputerCraft.terminalWidth_turtle * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = ComputerCraft.terminalHeight_turtle * FixedWidthFontRenderer.FONT_HEIGHT; int termPxHeight = ComputerCraft.terminalHeight_turtle * FixedWidthFontRenderer.FONT_HEIGHT;
terminal = new WidgetTerminal( terminal = new WidgetTerminal(
mc, () -> m_computer, minecraft, () -> m_computer,
ComputerCraft.terminalWidth_turtle, ComputerCraft.terminalWidth_turtle,
ComputerCraft.terminalHeight_turtle, ComputerCraft.terminalHeight_turtle,
2, 2, 2, 2 2, 2, 2, 2
); );
terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + guiLeft, 2 + 8 + guiTop, termPxWidth, termPxHeight ); terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + left, 2 + 8 + top, termPxWidth, termPxHeight );
children.add( terminalWrapper ); children.add( terminalWrapper );
setFocused( terminalWrapper ); setFocused( terminalWrapper );
} }
@Override @Override
public void onGuiClosed() public void removed()
{ {
super.removed();
children.remove( terminal ); children.remove( terminal );
terminal = null; terminal = null;
mc.keyboardListener.enableRepeatEvents( false ); minecraft.keyboard.enableRepeatEvents( false );
} }
@Override @Override
@@ -87,13 +90,13 @@ public class GuiTurtle extends GuiContainer
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F ); GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
int slotX = slot % 4; int slotX = slot % 4;
int slotY = slot / 4; int slotY = slot / 4;
mc.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL ); minecraft.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
drawTexturedModalRect( guiLeft + m_container.m_turtleInvStartX - 2 + slotX * 18, guiTop + m_container.m_playerInvStartY - 2 + slotY * 18, 0, 217, 24, 24 ); blit( left + m_container.m_turtleInvStartX - 2 + slotX * 18, top + m_container.m_playerInvStartY - 2 + slotY * 18, 0, 217, 24, 24 );
} }
} }
@Override @Override
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY ) protected void drawBackground( float partialTicks, int mouseX, int mouseY )
{ {
// Draw term // Draw term
boolean advanced = m_family == ComputerFamily.Advanced; boolean advanced = m_family == ComputerFamily.Advanced;
@@ -101,8 +104,8 @@ public class GuiTurtle extends GuiContainer
// Draw border/inventory // Draw border/inventory
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F ); GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
mc.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL ); minecraft.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
drawTexturedModalRect( guiLeft, guiTop, 0, 0, xSize, ySize ); blit( left, top, 0, 0, containerWidth, containerHeight );
drawSelectionSlot( advanced ); drawSelectionSlot( advanced );
} }
@@ -110,8 +113,29 @@ public class GuiTurtle extends GuiContainer
@Override @Override
public void render( int mouseX, int mouseY, float partialTicks ) public void render( int mouseX, int mouseY, float partialTicks )
{ {
drawDefaultBackground(); renderBackground();
super.render( mouseX, mouseY, partialTicks ); super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY ); drawMouseoverTooltip( mouseX, mouseY );
}
@Override
public boolean keyPressed( int key, int scancode, int modifiers )
{
return (key == GLFW.GLFW_KEY_TAB && getFocused() == terminalWrapper && terminalWrapper.keyPressed( key, scancode, modifiers ))
|| super.keyPressed( key, scancode, modifiers );
}
@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 );
}
@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

@@ -6,6 +6,7 @@
package dan200.computercraft.client.gui.widgets; package dan200.computercraft.client.gui.widgets;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.client.FrameInfo; import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.client.gui.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.core.terminal.Terminal;
@@ -14,13 +15,12 @@ import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.IComputer; import dan200.computercraft.shared.computer.core.IComputer;
import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.Palette; import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.Minecraft; import net.minecraft.SharedConstants;
import net.minecraft.client.gui.IGuiEventListener; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.gui.Element;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.render.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.render.VertexFormats;
import net.minecraft.util.SharedConstants;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
@@ -29,16 +29,18 @@ import java.util.function.Supplier;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.BACKGROUND; import static dan200.computercraft.client.gui.FixedWidthFontRenderer.BACKGROUND;
public class WidgetTerminal implements IGuiEventListener public class WidgetTerminal implements Element
{ {
private static final float TERMINATE_TIME = 0.5f; private static final float TERMINATE_TIME = 0.5f;
private final Minecraft client; private final MinecraftClient minecraft;
private final Supplier<ClientComputer> computer; private final Supplier<ClientComputer> computer;
private final int termWidth; private final int termWidth;
private final int termHeight; private final int termHeight;
private boolean focused;
private float terminateTimer = -1; private float terminateTimer = -1;
private float rebootTimer = -1; private float rebootTimer = -1;
private float shutdownTimer = -1; private float shutdownTimer = -1;
@@ -54,9 +56,9 @@ public class WidgetTerminal implements IGuiEventListener
private final BitSet keysDown = new BitSet( 256 ); private final BitSet keysDown = new BitSet( 256 );
public WidgetTerminal( Minecraft client, Supplier<ClientComputer> computer, int termWidth, int termHeight, int leftMargin, int rightMargin, int topMargin, int bottomMargin ) public WidgetTerminal( MinecraftClient minecraft, Supplier<ClientComputer> computer, int termWidth, int termHeight, int leftMargin, int rightMargin, int topMargin, int bottomMargin )
{ {
this.client = client; this.minecraft = minecraft;
this.computer = computer; this.computer = computer;
this.termWidth = termWidth; this.termWidth = termWidth;
this.termHeight = termHeight; this.termHeight = termHeight;
@@ -98,7 +100,7 @@ public class WidgetTerminal implements IGuiEventListener
case GLFW.GLFW_KEY_V: case GLFW.GLFW_KEY_V:
// Ctrl+V for paste // Ctrl+V for paste
String clipboard = client.keyboardListener.getClipboardString(); String clipboard = minecraft.keyboard.getClipboard();
if( clipboard != null ) if( clipboard != null )
{ {
// Clip to the first occurrence of \r or \n // Clip to the first occurrence of \r or \n
@@ -118,7 +120,7 @@ public class WidgetTerminal implements IGuiEventListener
} }
// Filter the string // Filter the string
clipboard = SharedConstants.filterAllowedCharacters( clipboard ); clipboard = SharedConstants.stripInvalidChars( clipboard );
if( !clipboard.isEmpty() ) if( !clipboard.isEmpty() )
{ {
// Clip to 512 characters and queue the event // Clip to 512 characters and queue the event
@@ -250,14 +252,23 @@ public class WidgetTerminal implements IGuiEventListener
} }
@Override @Override
public boolean mouseScrolled( double delta ) public boolean mouseScrolled( double mouseX, double mouseY, double delta )
{ {
ClientComputer computer = this.computer.get(); ClientComputer computer = this.computer.get();
if( computer == null || !computer.isColour() ) return false; if( computer == null || !computer.isColour() || delta == 0 ) return false;
if( lastMouseX >= 0 && lastMouseY >= 0 && delta != 0 ) Terminal term = computer.getTerminal();
if( term != null )
{ {
queueEvent( "mouse_scroll", delta < 0 ? 1 : -1, lastMouseX + 1, lastMouseY + 1 ); int charX = (int) (mouseX / FixedWidthFontRenderer.FONT_WIDTH);
int charY = (int) (mouseY / FixedWidthFontRenderer.FONT_HEIGHT);
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
computer.mouseScroll( delta < 0 ? 1 : -1, charX + 1, charY + 1 );
lastMouseX = charX;
lastMouseY = charY;
} }
return true; return true;
@@ -284,9 +295,9 @@ public class WidgetTerminal implements IGuiEventListener
} }
@Override @Override
public void focusChanged( boolean focused ) public boolean changeFocus( boolean reverse )
{ {
if( !focused ) if( focused )
{ {
// When blurring, we should make all keys go up // When blurring, we should make all keys go up
for( int key = 0; key < keysDown.size(); key++ ) for( int key = 0; key < keysDown.size(); key++ )
@@ -305,6 +316,9 @@ public class WidgetTerminal implements IGuiEventListener
shutdownTimer = terminateTimer = rebootTimer = -1; shutdownTimer = terminateTimer = rebootTimer = -1;
} }
focused = !focused;
return true;
} }
public void draw( int originX, int originY ) public void draw( int originX, int originY )
@@ -384,15 +398,15 @@ public class WidgetTerminal implements IGuiEventListener
int width = termWidth * FixedWidthFontRenderer.FONT_WIDTH + leftMargin + rightMargin; int width = termWidth * FixedWidthFontRenderer.FONT_WIDTH + leftMargin + rightMargin;
int height = termHeight * FixedWidthFontRenderer.FONT_HEIGHT + topMargin + bottomMargin; int height = termHeight * FixedWidthFontRenderer.FONT_HEIGHT + topMargin + bottomMargin;
client.getTextureManager().bindTexture( BACKGROUND ); minecraft.getTextureManager().bindTexture( BACKGROUND );
Tessellator tesslector = Tessellator.getInstance(); Tessellator tesslector = Tessellator.getInstance();
BufferBuilder buffer = tesslector.getBuffer(); BufferBuilder buffer = tesslector.getBufferBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX ); buffer.begin( GL11.GL_QUADS, VertexFormats.POSITION_UV );
buffer.pos( x, y + height, 0 ).tex( 0 / 256.0, height / 256.0 ).endVertex(); buffer.vertex( x, y + height, 0 ).texture( 0 / 256.0, height / 256.0 ).next();
buffer.pos( x + width, y + height, 0 ).tex( width / 256.0, height / 256.0 ).endVertex(); buffer.vertex( x + width, y + height, 0 ).texture( width / 256.0, height / 256.0 ).next();
buffer.pos( x + width, y, 0 ).tex( width / 256.0, 0 / 256.0 ).endVertex(); buffer.vertex( x + width, y, 0 ).texture( width / 256.0, 0 / 256.0 ).next();
buffer.pos( x, y, 0 ).tex( 0 / 256.0, 0 / 256.0 ).endVertex(); buffer.vertex( x, y, 0 ).texture( 0 / 256.0, 0 / 256.0 ).next();
tesslector.draw(); tesslector.draw();
} }
finally finally

View File

@@ -6,17 +6,17 @@
package dan200.computercraft.client.gui.widgets; package dan200.computercraft.client.gui.widgets;
import net.minecraft.client.gui.IGuiEventListener; import net.minecraft.client.gui.Element;
public class WidgetWrapper implements IGuiEventListener public class WidgetWrapper implements Element
{ {
private final IGuiEventListener listener; private final Element listener;
private final int x; private final int x;
private final int y; private final int y;
private final int width; private final int width;
private final int height; private final int height;
public WidgetWrapper( IGuiEventListener listener, int x, int y, int width, int height ) public WidgetWrapper( Element listener, int x, int y, int width, int height )
{ {
this.listener = listener; this.listener = listener;
this.x = x; this.x = x;
@@ -26,15 +26,16 @@ public class WidgetWrapper implements IGuiEventListener
} }
@Override @Override
public void focusChanged( boolean b ) public void mouseMoved( double x, double y )
{ {
listener.focusChanged( b ); double dx = x - this.x, dy = y - this.y;
if( dx >= 0 && dx < width && dy >= 0 && dy < height ) listener.mouseMoved( dx, dy );
} }
@Override @Override
public boolean canFocus() public boolean changeFocus( boolean reverse )
{ {
return listener.canFocus(); return listener.changeFocus( reverse );
} }
@Override @Override
@@ -59,9 +60,10 @@ public class WidgetWrapper implements IGuiEventListener
} }
@Override @Override
public boolean mouseScrolled( double delta ) public boolean mouseScrolled( double x, double y, double delta )
{ {
return listener.mouseScrolled( delta ); double dx = x - this.x, dy = y - this.y;
return dx >= 0 && dx < width && dy >= 0 && dy < height && listener.mouseScrolled( dx, dy, delta );
} }
@Override @Override
@@ -101,4 +103,11 @@ public class WidgetWrapper implements IGuiEventListener
{ {
return height; 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

@@ -7,80 +7,78 @@
package dan200.computercraft.client.proxy; package dan200.computercraft.client.proxy;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.ClientRegistry;
import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.client.gui.*; import dan200.computercraft.client.gui.*;
import dan200.computercraft.client.render.TileEntityCableRenderer; import dan200.computercraft.client.render.TileEntityCableRenderer;
import dan200.computercraft.client.render.TileEntityMonitorRenderer; import dan200.computercraft.client.render.TileEntityMonitorRenderer;
import dan200.computercraft.client.render.TileEntityTurtleRenderer; import dan200.computercraft.client.render.TileEntityTurtleRenderer;
import dan200.computercraft.client.render.TurtleModelLoader;
import dan200.computercraft.shared.computer.blocks.TileComputer; import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.ClientComputer; import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer; import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
import dan200.computercraft.shared.network.container.*; import dan200.computercraft.shared.network.container.*;
import dan200.computercraft.shared.peripheral.modem.wired.TileCable; import dan200.computercraft.shared.peripheral.modem.wired.TileCable;
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
import dan200.computercraft.shared.peripheral.monitor.TileMonitor; import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import dan200.computercraft.shared.turtle.blocks.TileTurtle; import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle; import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
import net.minecraft.client.Minecraft; import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
import net.minecraft.client.gui.inventory.GuiContainer; import net.fabricmc.fabric.api.client.render.BlockEntityRendererRegistry;
import net.minecraft.entity.player.EntityPlayer; import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback;
import net.minecraftforge.api.distmarker.Dist; import net.fabricmc.fabric.api.event.client.ClientTickCallback;
import net.minecraftforge.event.world.WorldEvent; import net.minecraft.container.ArrayPropertyDelegate;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraft.inventory.BasicInventory;
import net.minecraftforge.fml.ExtensionPoint;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import java.util.function.BiFunction;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD )
public final class ComputerCraftProxyClient public final class ComputerCraftProxyClient
{ {
@SubscribeEvent public static void setup()
public static void setupClient( FMLClientSetupEvent event )
{ {
registerContainers(); registerContainers();
// Setup TESRs // Setup TESRs
ClientRegistry.bindTileEntitySpecialRenderer( TileMonitor.class, new TileEntityMonitorRenderer() ); BlockEntityRendererRegistry.INSTANCE.register( TileMonitor.class, new TileEntityMonitorRenderer() );
ClientRegistry.bindTileEntitySpecialRenderer( TileCable.class, new TileEntityCableRenderer() ); BlockEntityRendererRegistry.INSTANCE.register( TileCable.class, new TileEntityCableRenderer() );
ClientRegistry.bindTileEntitySpecialRenderer( TileTurtle.class, new TileEntityTurtleRenderer() ); BlockEntityRendererRegistry.INSTANCE.register( TileTurtle.class, new TileEntityTurtleRenderer() );
ClientRegistry.onItemColours();
ClientSpriteRegistryCallback.registerBlockAtlas( ClientRegistry::onTextureStitchEvent );
ModelLoadingRegistry.INSTANCE.registerAppender( ClientRegistry::onModelBakeEvent );
ModelLoadingRegistry.INSTANCE.registerResourceProvider( loader -> ( name, context ) ->
TurtleModelLoader.INSTANCE.accepts( name ) ? TurtleModelLoader.INSTANCE.loadModel( name ) : null
);
ClientTickCallback.EVENT.register( client -> FrameInfo.onTick() );
} }
private static void registerContainers() private static void registerContainers()
{ {
ContainerType.registerGui( TileEntityContainerType::computer, ( packet, player ) -> ContainerType.registerGui( TileEntityContainerType::computer, ( id, packet, player ) ->
new GuiComputer( (TileComputer) packet.getTileEntity( player ) ) ); GuiComputer.create( id, (TileComputer) packet.getTileEntity( player ), player.inventory ) );
ContainerType.registerGui( TileEntityContainerType::diskDrive, GuiDiskDrive::new ); ContainerType.registerGui( TileEntityContainerType::diskDrive, GuiDiskDrive::new );
ContainerType.registerGui( TileEntityContainerType::printer, GuiPrinter::new ); ContainerType.registerGui( TileEntityContainerType::printer, GuiPrinter::new );
ContainerType.registerGui( TileEntityContainerType::turtle, ( packet, player ) -> { ContainerType.registerGui( TileEntityContainerType::turtle, ( id, packet, player ) -> {
TileTurtle turtle = (TileTurtle) packet.getTileEntity( player ); TileTurtle turtle = (TileTurtle) packet.getTileEntity( player );
return new GuiTurtle( turtle, new ContainerTurtle( player.inventory, turtle.getAccess(), turtle.getClientComputer() ) ); return new GuiTurtle( turtle,
new ContainerTurtle( id, player.inventory, new BasicInventory( TileTurtle.INVENTORY_SIZE ), new ArrayPropertyDelegate( 1 ) ),
player.inventory
);
} ); } );
ContainerType.registerGui( PocketComputerContainerType::new, GuiPocketComputer::new ); ContainerType.registerGui( PocketComputerContainerType::new, GuiPocketComputer::new );
ContainerType.registerGui( PrintoutContainerType::new, GuiPrintout::new ); ContainerType.registerGui( PrintoutContainerType::new, GuiPrintout::new );
ContainerType.registerGui( ViewComputerContainerType::new, ( packet, player ) -> { ContainerType.registerGui( ViewComputerContainerType::new, ( id, packet, player ) -> {
ClientComputer computer = ComputerCraft.clientComputerRegistry.get( packet.instanceId ); ClientComputer computer = ComputerCraft.clientComputerRegistry.get( packet.instanceId );
if( computer == null ) if( computer == null )
{ {
ComputerCraft.clientComputerRegistry.add( packet.instanceId, computer = new ClientComputer( packet.instanceId ) ); ComputerCraft.clientComputerRegistry.add( packet.instanceId, computer = new ClientComputer( packet.instanceId ) );
} }
ContainerViewComputer container = new ContainerViewComputer( computer ); ContainerViewComputer container = new ContainerViewComputer( id, computer );
return new GuiComputer( container, packet.family, computer, packet.width, packet.height ); return new GuiComputer<>( container, player.inventory, packet.family, computer, packet.width, packet.height );
} );
ModLoadingContext.get().registerExtensionPoint( ExtensionPoint.GUIFACTORY, () -> packet -> {
ContainerType<?> type = ContainerType.factories.get( packet.getId() ).get();
if( packet.getAdditionalData() != null ) type.fromBytes( packet.getAdditionalData() );
@SuppressWarnings( "unchecked" )
BiFunction<ContainerType<?>, EntityPlayer, GuiContainer> factory = (BiFunction<ContainerType<?>, EntityPlayer, GuiContainer>) ContainerType.guiFactories.get( packet.getId() );
return factory.apply( type, Minecraft.getInstance().player );
} ); } );
} }
/*
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT ) @Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public static final class ForgeHandlers public static final class ForgeHandlers
{ {
@@ -93,4 +91,5 @@ public final class ComputerCraftProxyClient
} }
} }
} }
*/
} }

View File

@@ -6,26 +6,23 @@
package dan200.computercraft.client.render; package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.modem.wired.BlockCable; import dan200.computercraft.shared.peripheral.modem.wired.BlockCable;
import dan200.computercraft.shared.peripheral.modem.wired.CableShapes; import dan200.computercraft.shared.peripheral.modem.wired.CableShapes;
import dan200.computercraft.shared.util.WorldUtil; import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.render.Camera;
import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.render.WorldRenderer;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.Entity;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class CableHighlightRenderer public final class CableHighlightRenderer
{ {
private CableHighlightRenderer() private CableHighlightRenderer()
@@ -35,54 +32,43 @@ public final class CableHighlightRenderer
/** /**
* Draw an outline for a specific part of a cable "Multipart". * Draw an outline for a specific part of a cable "Multipart".
* *
* @param event The event to observe * @see WorldRenderer#drawHighlightedBlockOutline(Entity, HitResult, int, float)
* @see WorldRenderer#drawSelectionBox(EntityPlayer, RayTraceResult, int, float)
*/ */
@SubscribeEvent public static boolean drawHighlight( Camera camera, BlockHitResult hit )
public static void drawHighlight( DrawBlockHighlightEvent event )
{ {
if( event.getTarget().type != RayTraceResult.Type.BLOCK ) return; MinecraftClient mc = MinecraftClient.getInstance();
BlockPos pos = hit.getBlockPos();
World world = mc.world;
BlockPos pos = event.getTarget().getBlockPos(); BlockState state = world.getBlockState( pos );
World world = event.getPlayer().getEntityWorld();
IBlockState state = world.getBlockState( pos );
// We only care about instances with both cable and modem. // We only care about instances with both cable and modem.
if( state.getBlock() != ComputerCraft.Blocks.cable || state.get( BlockCable.MODEM ).getFacing() == null || !state.get( BlockCable.CABLE ) ) if( state.getBlock() != ComputerCraft.Blocks.cable || state.get( BlockCable.MODEM ).getFacing() == null || !state.get( BlockCable.CABLE ) )
{ {
return; return false;
} }
event.setCanceled( true );
EntityPlayer player = event.getPlayer();
Minecraft mc = Minecraft.getInstance();
float partialTicks = event.getPartialTicks();
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.blendFuncSeparate( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO ); GlStateManager.blendFuncSeparate( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO );
GlStateManager.lineWidth( Math.max( 2.5F, mc.mainWindow.getFramebufferWidth() / 1920.0F * 2.5F ) ); GlStateManager.lineWidth( Math.max( 2.5F, mc.window.getFramebufferWidth() / 1920.0F * 2.5F ) );
GlStateManager.disableTexture2D(); GlStateManager.disableTexture();
GlStateManager.depthMask( false ); GlStateManager.depthMask( false );
GlStateManager.matrixMode( GL11.GL_PROJECTION ); GlStateManager.matrixMode( GL11.GL_PROJECTION );
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.scalef( 1.0F, 1.0F, 0.999F ); GlStateManager.scalef( 1.0F, 1.0F, 0.999F );
double x = player.lastTickPosX + (player.posX - player.lastTickPosX) * partialTicks; VoxelShape shape = WorldUtil.isVecInside( CableShapes.getModemShape( state ), hit.getPos().subtract( pos.getX(), pos.getY(), pos.getZ() ) )
double y = player.lastTickPosY + (player.posY - player.lastTickPosY) * partialTicks;
double z = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialTicks;
VoxelShape shape = WorldUtil.isVecInside( CableShapes.getModemShape( state ), event.getTarget().hitVec.subtract( pos.getX(), pos.getY(), pos.getZ() ) )
? CableShapes.getModemShape( state ) ? CableShapes.getModemShape( state )
: CableShapes.getCableShape( state ); : CableShapes.getCableShape( state );
WorldRenderer.drawShape( shape, pos.getX() - x, pos.getY() - y, pos.getZ() - z, 0.0F, 0.0F, 0.0F, 0.4F ); WorldRenderer.drawShapeOutline( shape, pos.getX() - camera.getPos().getX(), pos.getY() - camera.getPos().getY(), pos.getZ() - camera.getPos().getZ(), 0.0F, 0.0F, 0.0F, 0.4F );
GlStateManager.popMatrix(); GlStateManager.popMatrix();
GlStateManager.matrixMode( GL11.GL_MODELVIEW ); GlStateManager.matrixMode( GL11.GL_MODELVIEW );
GlStateManager.depthMask( true ); GlStateManager.depthMask( true );
GlStateManager.enableTexture2D(); GlStateManager.enableTexture();
GlStateManager.disableBlend(); GlStateManager.disableBlend();
return true;
} }
} }

View File

@@ -6,13 +6,14 @@
package dan200.computercraft.client.render; package dan200.computercraft.client.render;
import net.minecraft.client.Minecraft; import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.renderer.FirstPersonRenderer; import dan200.computercraft.shared.mixed.MixedFirstPersonRenderer;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.client.render.FirstPersonRenderer;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand; import net.minecraft.util.AbsoluteHand;
import net.minecraft.util.EnumHandSide; import net.minecraft.util.Hand;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
public abstract class ItemMapLikeRenderer public abstract class ItemMapLikeRenderer
@@ -21,23 +22,23 @@ public abstract class ItemMapLikeRenderer
* The main rendering method for the item * The main rendering method for the item
* *
* @param stack The stack to render * @param stack The stack to render
* @see FirstPersonRenderer#renderMapFirstPerson(ItemStack) * @see FirstPersonRenderer#renderFirstPersonMap(ItemStack)
*/ */
protected abstract void renderItem( ItemStack stack ); protected abstract void renderItem( ItemStack stack );
protected void renderItemFirstPerson( EnumHand hand, float pitch, float equipProgress, float swingProgress, ItemStack stack ) public void renderItemFirstPerson( Hand hand, float pitch, float equipProgress, float swingProgress, ItemStack stack )
{ {
EntityPlayer player = Minecraft.getInstance().player; PlayerEntity player = MinecraftClient.getInstance().player;
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
if( hand == EnumHand.MAIN_HAND && player.getHeldItemOffhand().isEmpty() ) if( hand == Hand.MAIN_HAND && player.getOffHandStack().isEmpty() )
{ {
renderItemFirstPersonCenter( pitch, equipProgress, swingProgress, stack ); renderItemFirstPersonCenter( pitch, equipProgress, swingProgress, stack );
} }
else else
{ {
renderItemFirstPersonSide( renderItemFirstPersonSide(
hand == EnumHand.MAIN_HAND ? player.getPrimaryHand() : player.getPrimaryHand().opposite(), hand == Hand.MAIN_HAND ? player.getMainHand() : player.getMainHand().getOpposite(),
equipProgress, swingProgress, stack equipProgress, swingProgress, stack
); );
} }
@@ -51,12 +52,12 @@ public abstract class ItemMapLikeRenderer
* @param equipProgress The equip progress of this item * @param equipProgress The equip progress of this item
* @param swingProgress The swing progress of this item * @param swingProgress The swing progress of this item
* @param stack The stack to render * @param stack The stack to render
* @see FirstPersonRenderer#renderMapFirstPersonSide(float, EnumHandSide, float, ItemStack) * @see FirstPersonRenderer#method_3222(float, AbsoluteHand, float, ItemStack) // renderMapFirstPersonSide
*/ */
private void renderItemFirstPersonSide( EnumHandSide side, float equipProgress, float swingProgress, ItemStack stack ) private void renderItemFirstPersonSide( AbsoluteHand side, float equipProgress, float swingProgress, ItemStack stack )
{ {
Minecraft minecraft = Minecraft.getInstance(); MinecraftClient minecraft = MinecraftClient.getInstance();
float offset = side == EnumHandSide.RIGHT ? 1f : -1f; float offset = side == AbsoluteHand.RIGHT ? 1f : -1f;
GlStateManager.translatef( offset * 0.125f, -0.125f, 0f ); GlStateManager.translatef( offset * 0.125f, -0.125f, 0f );
// If the player is not invisible then render a single arm // If the player is not invisible then render a single arm
@@ -64,7 +65,7 @@ public abstract class ItemMapLikeRenderer
{ {
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.rotatef( offset * 10f, 0f, 0f, 1f ); GlStateManager.rotatef( offset * 10f, 0f, 0f, 1f );
minecraft.getFirstPersonRenderer().renderArmFirstPerson( equipProgress, swingProgress, side ); ((MixedFirstPersonRenderer) minecraft.getFirstPersonRenderer()).renderArmFirstPerson_CC( equipProgress, swingProgress, side );
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
@@ -93,11 +94,11 @@ public abstract class ItemMapLikeRenderer
* @param equipProgress The equip progress of this item * @param equipProgress The equip progress of this item
* @param swingProgress The swing progress of this item * @param swingProgress The swing progress of this item
* @param stack The stack to render * @param stack The stack to render
* @see FirstPersonRenderer#renderMapFirstPerson(float, float, float) * @see FirstPersonRenderer#renderFirstPersonMap(float, float, float)
*/ */
private void renderItemFirstPersonCenter( float pitch, float equipProgress, float swingProgress, ItemStack stack ) private void renderItemFirstPersonCenter( float pitch, float equipProgress, float swingProgress, ItemStack stack )
{ {
FirstPersonRenderer renderer = Minecraft.getInstance().getFirstPersonRenderer(); MixedFirstPersonRenderer renderer = (MixedFirstPersonRenderer) MinecraftClient.getInstance().getFirstPersonRenderer();
// Setup the appropriate transformations. This is just copied from the // Setup the appropriate transformations. This is just copied from the
// corresponding method in ItemRenderer. // corresponding method in ItemRenderer.
@@ -105,10 +106,10 @@ public abstract class ItemMapLikeRenderer
float tX = -0.2f * MathHelper.sin( swingProgress * (float) Math.PI ); float tX = -0.2f * MathHelper.sin( swingProgress * (float) Math.PI );
float tZ = -0.4f * MathHelper.sin( swingRt * (float) Math.PI ); float tZ = -0.4f * MathHelper.sin( swingRt * (float) Math.PI );
GlStateManager.translatef( 0f, -tX / 2f, tZ ); GlStateManager.translatef( 0f, -tX / 2f, tZ );
float pitchAngle = renderer.getMapAngleFromPitch( pitch ); float pitchAngle = renderer.getMapAngleFromPitch_CC( pitch );
GlStateManager.translatef( 0f, 0.04f + equipProgress * -1.2f + pitchAngle * -0.5f, -0.72f ); GlStateManager.translatef( 0f, 0.04f + equipProgress * -1.2f + pitchAngle * -0.5f, -0.72f );
GlStateManager.rotatef( pitchAngle * -85f, 1f, 0f, 0f ); GlStateManager.rotatef( pitchAngle * -85f, 1f, 0f, 0f );
renderer.renderArms(); renderer.renderArms_CC();
float rX = MathHelper.sin( swingRt * (float) Math.PI ); float rX = MathHelper.sin( swingRt * (float) Math.PI );
GlStateManager.rotatef( rX * 20f, 1f, 0f, 0f ); GlStateManager.rotatef( rX * 20f, 1f, 0f, 0f );
GlStateManager.scalef( 2f, 2f, 2f ); GlStateManager.scalef( 2f, 2f, 2f );

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.client.render; package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.FrameInfo; import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.client.gui.FixedWidthFontRenderer;
@@ -16,16 +17,13 @@ import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.Palette; import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.Minecraft; import net.fabricmc.api.EnvType;
import net.minecraft.client.renderer.BufferBuilder; import net.fabricmc.api.Environment;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderSpecificHandEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.*; import static dan200.computercraft.client.gui.FixedWidthFontRenderer.*;
@@ -34,29 +32,19 @@ 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 ) @Environment( EnvType.CLIENT )
public final class ItemPocketRenderer extends ItemMapLikeRenderer public final class ItemPocketRenderer extends ItemMapLikeRenderer
{ {
private static final int MARGIN = 2; private static final int MARGIN = 2;
private static final int FRAME = 12; private static final int FRAME = 12;
private static final int LIGHT_HEIGHT = 8; private static final int LIGHT_HEIGHT = 8;
private static final ItemPocketRenderer INSTANCE = new ItemPocketRenderer(); public static final ItemPocketRenderer INSTANCE = new ItemPocketRenderer();
private ItemPocketRenderer() private ItemPocketRenderer()
{ {
} }
@SubscribeEvent
public static void renderItem( RenderSpecificHandEvent event )
{
ItemStack stack = event.getItemStack();
if( !(stack.getItem() instanceof ItemPocketComputer) ) return;
event.setCanceled( true );
INSTANCE.renderItemFirstPerson( event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack() );
}
@Override @Override
protected void renderItem( ItemStack stack ) protected void renderItem( ItemStack stack )
{ {
@@ -112,13 +100,13 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
else else
{ {
// Otherwise render a plain background // Otherwise render a plain background
Minecraft.getInstance().getTextureManager().bindTexture( BACKGROUND ); MinecraftClient.getInstance().getTextureManager().bindTexture( BACKGROUND );
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBufferBuilder();
Colour black = Colour.Black; Colour black = Colour.Black;
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION ); buffer.begin( GL11.GL_QUADS, VertexFormats.POSITION );
renderTexture( buffer, 0, 0, 0, 0, width, height, black.getR(), black.getG(), black.getB() ); renderTexture( buffer, 0, 0, 0, 0, width, height, black.getR(), black.getG(), black.getB() );
tessellator.draw(); tessellator.draw();
} }
@@ -131,7 +119,7 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
private static void renderFrame( ComputerFamily family, int colour, int width, int height ) private static void renderFrame( ComputerFamily family, int colour, int width, int height )
{ {
Minecraft.getInstance().getTextureManager().bindTexture( colour != -1 MinecraftClient.getInstance().getTextureManager().bindTexture( colour != -1
? BACKGROUND_COLOUR ? BACKGROUND_COLOUR
: family == ComputerFamily.Normal ? BACKGROUND_NORMAL : BACKGROUND_ADVANCED : family == ComputerFamily.Normal ? BACKGROUND_NORMAL : BACKGROUND_ADVANCED
); );
@@ -141,8 +129,8 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
float b = (colour & 0xFF) / 255.0f; float b = (colour & 0xFF) / 255.0f;
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBufferBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR ); buffer.begin( GL11.GL_QUADS, VertexFormats.POSITION_UV_COLOR );
// Top left, middle, right // Top left, middle, right
renderTexture( buffer, -FRAME, -FRAME, 12, 28, FRAME, FRAME, r, g, b ); renderTexture( buffer, -FRAME, -FRAME, 12, 28, FRAME, FRAME, r, g, b );
@@ -173,22 +161,22 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
private static void renderLight( int colour, int width, int height ) private static void renderLight( int colour, int width, int height )
{ {
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.disableTexture2D(); GlStateManager.disableTexture();
float r = ((colour >>> 16) & 0xFF) / 255.0f; float r = ((colour >>> 16) & 0xFF) / 255.0f;
float g = ((colour >>> 8) & 0xFF) / 255.0f; float g = ((colour >>> 8) & 0xFF) / 255.0f;
float b = (colour & 0xFF) / 255.0f; float b = (colour & 0xFF) / 255.0f;
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBufferBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR ); buffer.begin( GL11.GL_QUADS, VertexFormats.POSITION_COLOR );
buffer.pos( width - LIGHT_HEIGHT * 2, height + LIGHT_HEIGHT + FRAME / 2.0f, 0.0D ).color( r, g, b, 1.0f ).endVertex(); buffer.vertex( width - LIGHT_HEIGHT * 2, height + LIGHT_HEIGHT + FRAME / 2.0f, 0.0D ).color( r, g, b, 1.0f ).next();
buffer.pos( width, height + LIGHT_HEIGHT + FRAME / 2.0f, 0.0D ).color( r, g, b, 1.0f ).endVertex(); buffer.vertex( width, height + LIGHT_HEIGHT + FRAME / 2.0f, 0.0D ).color( r, g, b, 1.0f ).next();
buffer.pos( width, height + FRAME / 2.0f, 0.0D ).color( r, g, b, 1.0f ).endVertex(); buffer.vertex( width, height + FRAME / 2.0f, 0.0D ).color( r, g, b, 1.0f ).next();
buffer.pos( width - LIGHT_HEIGHT * 2, height + FRAME / 2.0f, 0.0D ).color( r, g, b, 1.0f ).endVertex(); buffer.vertex( width - LIGHT_HEIGHT * 2, height + FRAME / 2.0f, 0.0D ).color( r, g, b, 1.0f ).next();
tessellator.draw(); tessellator.draw();
GlStateManager.enableTexture2D(); GlStateManager.enableTexture();
} }
private static void renderTerminal( Terminal terminal, boolean greyscale, int width, int height ) private static void renderTerminal( Terminal terminal, boolean greyscale, int width, int height )
@@ -246,9 +234,9 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
private static void renderTexture( BufferBuilder builder, int x, int y, int textureX, int textureY, int width, int height, int textureWidth, int textureHeight, float r, float g, float b ) private static void renderTexture( BufferBuilder builder, int x, int y, int textureX, int textureY, int width, int height, int textureWidth, int textureHeight, float r, float g, float b )
{ {
float scale = 1 / 255.0f; float scale = 1 / 255.0f;
builder.pos( x, y + height, 0 ).tex( textureX * scale, (textureY + textureHeight) * scale ).color( r, g, b, 1.0f ).endVertex(); builder.vertex( x, y + height, 0 ).texture( textureX * scale, (textureY + textureHeight) * scale ).color( r, g, b, 1.0f ).next();
builder.pos( x + width, y + height, 0 ).tex( (textureX + textureWidth) * scale, (textureY + textureHeight) * scale ).color( r, g, b, 1.0f ).endVertex(); builder.vertex( x + width, y + height, 0 ).texture( (textureX + textureWidth) * scale, (textureY + textureHeight) * scale ).color( r, g, b, 1.0f ).next();
builder.pos( x + width, y, 0 ).tex( (textureX + textureWidth) * scale, textureY * scale ).color( r, g, b, 1.0f ).endVertex(); builder.vertex( x + width, y, 0 ).texture( (textureX + textureWidth) * scale, textureY * scale ).color( r, g, b, 1.0f ).next();
builder.pos( x, y, 0 ).tex( textureX * scale, textureY * scale ).color( r, g, b, 1.0f ).endVertex(); builder.vertex( x, y, 0 ).texture( textureX * scale, textureY * scale ).color( r, g, b, 1.0f ).next();
} }
} }

View File

@@ -6,15 +6,12 @@
package dan200.computercraft.client.render; package dan200.computercraft.client.render;
import dan200.computercraft.ComputerCraft; import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.shared.media.items.ItemPrintout; import dan200.computercraft.shared.media.items.ItemPrintout;
import net.minecraft.client.renderer.GlStateManager; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.entity.decoration.ItemFrameEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderItemInFrameEvent;
import net.minecraftforge.client.event.RenderSpecificHandEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH; import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
@@ -25,15 +22,16 @@ import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENG
/** /**
* 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 ) @Environment( EnvType.CLIENT )
public final class ItemPrintoutRenderer extends ItemMapLikeRenderer public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
{ {
private static final ItemPrintoutRenderer INSTANCE = new ItemPrintoutRenderer(); public static final ItemPrintoutRenderer INSTANCE = new ItemPrintoutRenderer();
private ItemPrintoutRenderer() private ItemPrintoutRenderer()
{ {
} }
/*
@SubscribeEvent @SubscribeEvent
public static void onRenderInHand( RenderSpecificHandEvent event ) public static void onRenderInHand( RenderSpecificHandEvent event )
{ {
@@ -43,6 +41,7 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
event.setCanceled( true ); event.setCanceled( true );
INSTANCE.renderItemFirstPerson( event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack() ); INSTANCE.renderItemFirstPerson( event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack() );
} }
*/
@Override @Override
protected void renderItem( ItemStack stack ) protected void renderItem( ItemStack stack )
@@ -61,16 +60,13 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
GlStateManager.enableLighting(); GlStateManager.enableLighting();
} }
@SubscribeEvent public void renderInFrame( ItemFrameEntity entity, ItemStack stack )
public static void onRenderInFrame( RenderItemInFrameEvent event )
{ {
ItemStack stack = event.getItem();
if( !(stack.getItem() instanceof ItemPrintout) ) return;
event.setCanceled( true );
GlStateManager.disableLighting(); GlStateManager.disableLighting();
int rotation = entity.getRotation();
GlStateManager.rotatef( (float) rotation * 360.0F / 8.0F, 0.0F, 0.0F, 1.0F );
// Move a little bit forward to ensure we're not clipping with the frame // Move a little bit forward to ensure we're not clipping with the frame
GlStateManager.translatef( 0.0f, 0.0f, -0.001f ); GlStateManager.translatef( 0.0f, 0.0f, -0.001f );
GlStateManager.rotatef( 180f, 0f, 0f, 1f ); GlStateManager.rotatef( 180f, 0f, 0f, 1f );

View File

@@ -6,19 +6,13 @@
package dan200.computercraft.client.render; package dan200.computercraft.client.render;
import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.render.VertexFormatElement;
import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.render.VertexFormats;
import net.minecraft.util.EnumFacing; import net.minecraft.client.render.model.BakedQuad;
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
import net.minecraftforge.client.model.pipeline.LightUtil;
import net.minecraftforge.client.model.pipeline.VertexTransformer;
import net.minecraftforge.common.model.TRSRTransformation;
import javax.annotation.Nonnull;
import javax.vecmath.Matrix4f; import javax.vecmath.Matrix4f;
import javax.vecmath.Point3f; import javax.vecmath.Vector4f;
import javax.vecmath.Vector3f;
import java.util.List; import java.util.List;
/** /**
@@ -40,6 +34,11 @@ public final class ModelTransformer
} }
public static void transformQuadsTo( List<BakedQuad> output, List<BakedQuad> input, Matrix4f transform ) public static void transformQuadsTo( List<BakedQuad> output, List<BakedQuad> input, Matrix4f transform )
{
transformQuadsTo( VertexFormats.POSITION_COLOR_UV_NORMAL, output, input, transform );
}
public static void transformQuadsTo( VertexFormat format, List<BakedQuad> output, List<BakedQuad> input, Matrix4f transform )
{ {
if( transform == null || transform.equals( identity ) ) if( transform == null || transform.equals( identity ) )
{ {
@@ -47,224 +46,55 @@ public final class ModelTransformer
} }
else else
{ {
Matrix4f normalMatrix = new Matrix4f( transform ); for( BakedQuad quad : input ) output.add( doTransformQuad( format, quad, transform ) );
normalMatrix.invert();
normalMatrix.transpose();
for( BakedQuad quad : input ) output.add( doTransformQuad( quad, transform, normalMatrix ) );
} }
} }
public static BakedQuad transformQuad( BakedQuad input, Matrix4f transform ) public static BakedQuad transformQuad( VertexFormat format, BakedQuad input, Matrix4f transform )
{ {
if( transform == null || transform.equals( identity ) ) return input; if( transform == null || transform.equals( identity ) ) return input;
return doTransformQuad( format, input, transform );
Matrix4f normalMatrix = new Matrix4f( transform );
normalMatrix.invert();
normalMatrix.transpose();
return doTransformQuad( input, transform, normalMatrix );
} }
private static BakedQuad doTransformQuad( BakedQuad input, Matrix4f positionMatrix, Matrix4f normalMatrix ) private static BakedQuad doTransformQuad( VertexFormat format, BakedQuad quad, Matrix4f transform )
{ {
int[] vertexData = quad.getVertexData().clone();
BakedQuadBuilder builder = new BakedQuadBuilder( input.getFormat() ); int offset = 0;
NormalAwareTransformer transformer = new NormalAwareTransformer( builder, positionMatrix, normalMatrix ); BakedQuad copy = new BakedQuad( vertexData, -1, quad.getFace(), quad.getSprite() );
input.pipe( transformer ); for( int i = 0; i < format.getElementCount(); ++i ) // For each vertex element
if( transformer.areNormalsInverted() )
{ {
builder.swap( 1, 3 ); VertexFormatElement element = format.getElement( i );
transformer.areNormalsInverted(); if( element.isPosition() &&
} element.getFormat() == VertexFormatElement.Format.FLOAT &&
element.getCount() == 3 ) // When we find a position element
return builder.build();
}
/**
* A vertex transformer that tracks whether the normals have been inverted and so the vertices
* should be reordered so backface culling works as expected.
*/
private static class NormalAwareTransformer extends VertexTransformer
{ {
private final Matrix4f positionMatrix; for( int j = 0; j < 4; ++j ) // For each corner of the quad
private final Matrix4f normalMatrix;
private int vertexIndex = 0, elementIndex = 0;
private final Point3f[] before = new Point3f[4];
private final Point3f[] after = new Point3f[4];
public NormalAwareTransformer( IVertexConsumer parent, Matrix4f positionMatrix, Matrix4f normalMatrix )
{ {
super( parent ); int start = offset + j * format.getVertexSize();
this.positionMatrix = positionMatrix; if( (start % 4) == 0 )
this.normalMatrix = normalMatrix;
}
@Override
public void setQuadOrientation( @Nonnull EnumFacing orientation )
{ {
super.setQuadOrientation( orientation == null ? orientation : TRSRTransformation.rotate( positionMatrix, orientation ) ); start = start / 4;
}
@Override // Extract the position
public void put( int element, @Nonnull float... data ) Vector4f pos = new Vector4f(
{ Float.intBitsToFloat( vertexData[start] ),
switch( getVertexFormat().getElement( element ).getUsage() ) Float.intBitsToFloat( vertexData[start + 1] ),
{ Float.intBitsToFloat( vertexData[start + 2] ),
case POSITION: 1
{ );
Point3f vec = new Point3f( data );
Point3f newVec = new Point3f();
positionMatrix.transform( vec, newVec );
float[] newData = new float[4]; // Transform the position
newVec.get( newData ); transform.transform( pos );
super.put( element, newData );
// Insert the position
before[vertexIndex] = vec; vertexData[start] = Float.floatToRawIntBits( pos.x );
after[vertexIndex] = newVec; vertexData[start + 1] = Float.floatToRawIntBits( pos.y );
break; vertexData[start + 2] = Float.floatToRawIntBits( pos.z );
}
case NORMAL:
{
Vector3f vec = new Vector3f( data );
normalMatrix.transform( vec );
float[] newData = new float[4];
vec.get( newData );
super.put( element, newData );
break;
}
default:
super.put( element, data );
break;
}
elementIndex++;
if( elementIndex == getVertexFormat().getElementCount() )
{
vertexIndex++;
elementIndex = 0;
}
}
public boolean areNormalsInverted()
{
Vector3f temp1 = new Vector3f(), temp2 = new Vector3f();
Vector3f crossBefore = new Vector3f(), crossAfter = new Vector3f();
// Determine what cross product we expect to have
temp1.sub( before[1], before[0] );
temp2.sub( before[1], before[2] );
crossBefore.cross( temp1, temp2 );
normalMatrix.transform( crossBefore );
// And determine what cross product we actually have
temp1.sub( after[1], after[0] );
temp2.sub( after[1], after[2] );
crossAfter.cross( temp1, temp2 );
// If the angle between expected and actual cross product is greater than
// pi/2 radians then we will need to reorder our quads.
return Math.abs( crossBefore.angle( crossAfter ) ) >= Math.PI / 2;
}
}
/**
* A vertex consumer which is capable of building {@link BakedQuad}s.
*
* Equivalent to {@link net.minecraftforge.client.model.pipeline.UnpackedBakedQuad.Builder} but more memory
* efficient.
*
* This also provides the ability to swap vertices through {@link #swap(int, int)} to allow reordering.
*/
private static final class BakedQuadBuilder implements IVertexConsumer
{
private final VertexFormat format;
private final int[] vertexData;
private int vertexIndex = 0, elementIndex = 0;
private EnumFacing orientation;
private int quadTint;
private boolean diffuse;
private TextureAtlasSprite texture;
private BakedQuadBuilder( VertexFormat format )
{
this.format = format;
vertexData = new int[format.getSize()];
}
@Nonnull
@Override
public VertexFormat getVertexFormat()
{
return format;
}
@Override
public void setQuadTint( int tint )
{
quadTint = tint;
}
@Override
public void setQuadOrientation( @Nonnull EnumFacing orientation )
{
this.orientation = orientation;
}
@Override
public void setApplyDiffuseLighting( boolean diffuse )
{
this.diffuse = diffuse;
}
@Override
public void setTexture( @Nonnull TextureAtlasSprite texture )
{
this.texture = texture;
}
@Override
public void put( int element, @Nonnull float... data )
{
LightUtil.pack( data, vertexData, format, vertexIndex, element );
elementIndex++;
if( elementIndex == getVertexFormat().getElementCount() )
{
vertexIndex++;
elementIndex = 0;
}
}
public void swap( int a, int b )
{
int length = vertexData.length / 4;
for( int i = 0; i < length; i++ )
{
int temp = vertexData[a * length + i];
vertexData[a * length + i] = vertexData[b * length + i];
vertexData[b * length + i] = temp;
}
}
public BakedQuad build()
{
if( elementIndex != 0 || vertexIndex != 4 )
{
throw new IllegalStateException( "Got an unexpected number of elements/vertices" );
}
if( texture == null )
{
throw new IllegalStateException( "Texture has not been set" );
}
return new BakedQuad( vertexData, quadTint, orientation, texture, diffuse, format );
} }
} }
} }
offset += element.getSize();
}
return copy;
}
}

View File

@@ -6,30 +6,24 @@
package dan200.computercraft.client.render; package dan200.computercraft.client.render;
import dan200.computercraft.ComputerCraft; import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.shared.peripheral.monitor.TileMonitor; import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import net.minecraft.client.Minecraft; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.render.Camera;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.render.Tessellator;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.client.render.VertexFormats;
import net.minecraft.tileentity.TileEntity; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import java.util.EnumSet; import java.util.EnumSet;
import static net.minecraft.util.EnumFacing.*; import static net.minecraft.util.math.Direction.*;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class MonitorHighlightRenderer public final class MonitorHighlightRenderer
{ {
private static final float EXPAND = 0.002f; private static final float EXPAND = 0.002f;
@@ -38,23 +32,22 @@ public final class MonitorHighlightRenderer
{ {
} }
@SubscribeEvent public static boolean drawHighlight( Camera camera, BlockHitResult hit )
public static void drawHighlight( DrawBlockHighlightEvent event )
{ {
if( event.getTarget().type != RayTraceResult.Type.BLOCK || event.getPlayer().isSneaking() ) return; MinecraftClient mc = MinecraftClient.getInstance();
if( mc.player.isSneaking() ) return false;
World world = event.getPlayer().getEntityWorld(); BlockPos pos = hit.getBlockPos();
BlockPos pos = event.getTarget().getBlockPos(); World world = mc.world;
TileEntity tile = world.getTileEntity( pos ); BlockEntity tile = world.getBlockEntity( pos );
if( !(tile instanceof TileMonitor) ) return; if( !(tile instanceof TileMonitor) ) return false;
TileMonitor monitor = (TileMonitor) tile; TileMonitor monitor = (TileMonitor) tile;
event.setCanceled( true );
// Determine which sides are part of the external faces of the monitor, and so which need to be rendered. // Determine which sides are part of the external faces of the monitor, and so which need to be rendered.
EnumSet<EnumFacing> faces = EnumSet.allOf( EnumFacing.class ); EnumSet<Direction> faces = EnumSet.allOf( Direction.class );
EnumFacing front = monitor.getFront(); Direction front = monitor.getFront();
faces.remove( front ); faces.remove( front );
if( monitor.getXIndex() != 0 ) faces.remove( monitor.getRight().getOpposite() ); if( monitor.getXIndex() != 0 ) faces.remove( monitor.getRight().getOpposite() );
if( monitor.getXIndex() != monitor.getWidth() - 1 ) faces.remove( monitor.getRight() ); if( monitor.getXIndex() != monitor.getWidth() - 1 ) faces.remove( monitor.getRight() );
@@ -63,21 +56,16 @@ public final class MonitorHighlightRenderer
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.blendFuncSeparate( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO ); GlStateManager.blendFuncSeparate( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO );
GlStateManager.lineWidth(Math.max(2.5F, (float) Minecraft.getInstance().mainWindow.getFramebufferWidth() / 1920.0F * 2.5F)); GlStateManager.lineWidth( Math.max( 2.5F, (float) mc.window.getFramebufferWidth() / 1920.0F * 2.5F ) );
GlStateManager.disableTexture2D(); GlStateManager.disableTexture();
GlStateManager.depthMask( false ); GlStateManager.depthMask( false );
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
EntityPlayer player = event.getPlayer(); GlStateManager.translated( pos.getX() - camera.getPos().getX(), pos.getY() - camera.getPos().getY(), pos.getZ() - camera.getPos().getZ() );
double x = player.lastTickPosX + (player.posX - player.lastTickPosX) * event.getPartialTicks();
double y = player.lastTickPosY + (player.posY - player.lastTickPosY) * event.getPartialTicks();
double z = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * event.getPartialTicks();
GlStateManager.translated( -x + pos.getX(), -y + pos.getY(), -z + pos.getZ() );
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBufferBuilder();
buffer.begin( GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR ); buffer.begin( GL11.GL_LINES, VertexFormats.POSITION_COLOR );
// I wish I could think of a better way to do this // I wish I could think of a better way to do this
if( faces.contains( NORTH ) || faces.contains( WEST ) ) line( buffer, 0, 0, 0, UP ); if( faces.contains( NORTH ) || faces.contains( WEST ) ) line( buffer, 0, 0, 0, UP );
@@ -97,21 +85,23 @@ public final class MonitorHighlightRenderer
GlStateManager.popMatrix(); GlStateManager.popMatrix();
GlStateManager.depthMask( true ); GlStateManager.depthMask( true );
GlStateManager.enableTexture2D(); GlStateManager.enableTexture();
GlStateManager.disableBlend(); GlStateManager.disableBlend();
return true;
} }
private static void line( BufferBuilder buffer, int x, int y, int z, EnumFacing direction ) private static void line( BufferBuilder buffer, int x, int y, int z, Direction direction )
{ {
double minX = x == 0 ? -EXPAND : 1 + EXPAND; double minX = x == 0 ? -EXPAND : 1 + EXPAND;
double minY = y == 0 ? -EXPAND : 1 + EXPAND; double minY = y == 0 ? -EXPAND : 1 + EXPAND;
double minZ = z == 0 ? -EXPAND : 1 + EXPAND; double minZ = z == 0 ? -EXPAND : 1 + EXPAND;
buffer.pos( minX, minY, minZ ).color( 0, 0, 0, 0.4f ).endVertex(); buffer.vertex( minX, minY, minZ ).color( 0, 0, 0, 0.4f ).next();
buffer.pos( buffer.vertex(
minX + direction.getXOffset() * (1 + EXPAND * 2), minX + direction.getOffsetX() * (1 + EXPAND * 2),
minY + direction.getYOffset() * (1 + EXPAND * 2), minY + direction.getOffsetY() * (1 + EXPAND * 2),
minZ + direction.getZOffset() * (1 + EXPAND * 2) minZ + direction.getOffsetZ() * (1 + EXPAND * 2)
).color( 0, 0, 0, 0.4f ).endVertex(); ).color( 0, 0, 0, 0.4f ).next();
} }
} }

View File

@@ -6,17 +6,17 @@
package dan200.computercraft.client.render; package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.client.gui.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.util.Palette; import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.Minecraft; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.render.Tessellator;
import net.minecraft.client.renderer.GlStateManager.DestFactor; import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.renderer.GlStateManager.SourceFactor; import net.minecraft.util.Identifier;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
@@ -24,7 +24,7 @@ import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAG
public final class PrintoutRenderer public final class PrintoutRenderer
{ {
private static final ResourceLocation BG = new ResourceLocation( "computercraft", "textures/gui/printout.png" ); private static final Identifier BG = new Identifier( "computercraft", "textures/gui/printout.png" );
private static final double BG_SIZE = 256.0; private static final double BG_SIZE = 256.0;
/** /**
@@ -76,7 +76,7 @@ public final class PrintoutRenderer
{ {
GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f ); GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.enableTexture2D(); GlStateManager.enableTexture();
GlStateManager.blendFuncSeparate( SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO ); GlStateManager.blendFuncSeparate( SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO );
FixedWidthFontRenderer fontRenderer = FixedWidthFontRenderer.instance(); FixedWidthFontRenderer fontRenderer = FixedWidthFontRenderer.instance();
@@ -91,14 +91,14 @@ public final class PrintoutRenderer
{ {
GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f ); GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.enableTexture2D(); GlStateManager.enableTexture();
GlStateManager.blendFuncSeparate( SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO ); GlStateManager.blendFuncSeparate( SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO );
Minecraft.getInstance().getTextureManager().bindTexture( BG ); MinecraftClient.getInstance().getTextureManager().bindTexture( BG );
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBufferBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX ); buffer.begin( GL11.GL_QUADS, VertexFormats.POSITION_UV );
int leftPages = page; int leftPages = page;
int rightPages = pages - page - 1; int rightPages = pages - page - 1;
@@ -159,18 +159,18 @@ public final class PrintoutRenderer
private static void drawTexture( BufferBuilder buffer, double x, double y, double z, double u, double v, double width, double height ) private static void drawTexture( BufferBuilder buffer, double x, double y, double z, double u, double v, double width, double height )
{ {
buffer.pos( x, y + height, z ).tex( u / BG_SIZE, (v + height) / BG_SIZE ).endVertex(); buffer.vertex( x, y + height, z ).texture( u / BG_SIZE, (v + height) / BG_SIZE ).next();
buffer.pos( x + width, y + height, z ).tex( (u + width) / BG_SIZE, (v + height) / BG_SIZE ).endVertex(); buffer.vertex( x + width, y + height, z ).texture( (u + width) / BG_SIZE, (v + height) / BG_SIZE ).next();
buffer.pos( x + width, y, z ).tex( (u + width) / BG_SIZE, v / BG_SIZE ).endVertex(); buffer.vertex( x + width, y, z ).texture( (u + width) / BG_SIZE, v / BG_SIZE ).next();
buffer.pos( x, y, z ).tex( u / BG_SIZE, v / BG_SIZE ).endVertex(); buffer.vertex( x, y, z ).texture( u / BG_SIZE, v / BG_SIZE ).next();
} }
private static void drawTexture( BufferBuilder buffer, double x, double y, double z, double width, double height, double u, double v, double tWidth, double tHeight ) private static void drawTexture( BufferBuilder buffer, double x, double y, double z, double width, double height, double u, double v, double tWidth, double tHeight )
{ {
buffer.pos( x, y + height, z ).tex( u / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex(); buffer.vertex( x, y + height, z ).texture( u / BG_SIZE, (v + tHeight) / BG_SIZE ).next();
buffer.pos( x + width, y + height, z ).tex( (u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex(); buffer.vertex( x + width, y + height, z ).texture( (u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE ).next();
buffer.pos( x + width, y, z ).tex( (u + tWidth) / BG_SIZE, v / BG_SIZE ).endVertex(); buffer.vertex( x + width, y, z ).texture( (u + tWidth) / BG_SIZE, v / BG_SIZE ).next();
buffer.pos( x, y, z ).tex( u / BG_SIZE, v / BG_SIZE ).endVertex(); buffer.vertex( x, y, z ).texture( u / BG_SIZE, v / BG_SIZE ).next();
} }
public static double offsetAt( int page ) public static double offsetAt( int page )

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.client.render; package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.modem.wired.BlockCable; import dan200.computercraft.shared.peripheral.modem.wired.BlockCable;
import dan200.computercraft.shared.peripheral.modem.wired.CableModemVariant; import dan200.computercraft.shared.peripheral.modem.wired.CableModemVariant;
@@ -13,23 +14,19 @@ import dan200.computercraft.shared.peripheral.modem.wired.CableShapes;
import dan200.computercraft.shared.peripheral.modem.wired.TileCable; import dan200.computercraft.shared.peripheral.modem.wired.TileCable;
import dan200.computercraft.shared.util.WorldUtil; import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.render.Tessellator;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer; import net.minecraft.client.texture.Sprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.client.model.data.EmptyModelData;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -38,7 +35,7 @@ import java.util.Random;
/** /**
* Render breaking animation only over part of a {@link TileCable}. * Render breaking animation only over part of a {@link TileCable}.
*/ */
public class TileEntityCableRenderer extends TileEntityRenderer<TileCable> public class TileEntityCableRenderer extends BlockEntityRenderer<TileCable>
{ {
private static final Random random = new Random(); private static final Random random = new Random();
@@ -49,44 +46,34 @@ public class TileEntityCableRenderer extends TileEntityRenderer<TileCable>
BlockPos pos = te.getPos(); BlockPos pos = te.getPos();
Minecraft mc = Minecraft.getInstance(); MinecraftClient mc = MinecraftClient.getInstance();
RayTraceResult hit = mc.objectMouseOver; HitResult hit = mc.hitResult;
if( hit == null || !hit.getBlockPos().equals( pos ) ) return; if( !(hit instanceof BlockHitResult) || !((BlockHitResult) hit).getBlockPos().equals( pos ) ) return;
if( MinecraftForgeClient.getRenderPass() != 0 ) return;
World world = te.getWorld(); World world = te.getWorld();
IBlockState state = world.getBlockState( pos ); BlockState state = te.getCachedState();
Block block = state.getBlock(); Block block = state.getBlock();
if( block != ComputerCraft.Blocks.cable ) return; if( block != ComputerCraft.Blocks.cable ) return;
state = WorldUtil.isVecInside( CableShapes.getModemShape( state ), hit.hitVec.subtract( pos.getX(), pos.getY(), pos.getZ() ) ) state = WorldUtil.isVecInside( CableShapes.getModemShape( state ), hit.getPos().subtract( pos.getX(), pos.getY(), pos.getZ() ) )
? block.getDefaultState().with( BlockCable.MODEM, state.get( BlockCable.MODEM ) ) ? block.getDefaultState().with( BlockCable.MODEM, state.get( BlockCable.MODEM ) )
: state.with( BlockCable.MODEM, CableModemVariant.None ); : state.with( BlockCable.MODEM, CableModemVariant.None );
IBakedModel model = mc.getBlockRendererDispatcher().getModelForState( state ); BakedModel model = mc.getBlockRenderManager().getModel( state );
preRenderDamagedBlocks(); preRenderDamagedBlocks();
BufferBuilder buffer = Tessellator.getInstance().getBuffer(); BufferBuilder buffer = Tessellator.getInstance().getBufferBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.BLOCK ); buffer.begin( GL11.GL_QUADS, VertexFormats.POSITION_COLOR_UV_LMAP );
buffer.setTranslation( x - pos.getX(), y - pos.getY(), z - pos.getZ() ); buffer.setOffset( x - pos.getX(), y - pos.getY(), z - pos.getZ() );
buffer.noColor(); buffer.disableColor();
ForgeHooksClient.setRenderLayer( block.getRenderLayer() );
// See BlockRendererDispatcher#renderBlockDamage // See BlockRendererDispatcher#renderBlockDamage
TextureAtlasSprite breakingTexture = mc.getTextureMap().getSprite( DESTROY_STAGES[destroyStage] ); Sprite breakingTexture = mc.getSpriteAtlas().getSprite( DESTROY_STAGE_TEXTURES[destroyStage] );
mc.getBlockRendererDispatcher().getBlockModelRenderer().renderModel( mc.getBlockRenderManager().tesselateDamage( state, pos, breakingTexture, world );
world,
ForgeHooksClient.getDamageModel( model, breakingTexture, state, world, pos ),
state, pos, buffer, true, random, state.getPositionRandom( pos ), EmptyModelData.INSTANCE
);
ForgeHooksClient.setRenderLayer( BlockRenderLayer.SOLID ); buffer.setOffset( 0, 0, 0 );
buffer.setTranslation( 0, 0, 0 );
Tessellator.getInstance().draw(); Tessellator.getInstance().draw();
postRenderDamagedBlocks(); postRenderDamagedBlocks();

View File

@@ -6,6 +6,8 @@
package dan200.computercraft.client.render; package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GLX;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.client.FrameInfo; import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.client.gui.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.core.terminal.Terminal;
@@ -15,18 +17,16 @@ import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.DirectionUtil; import dan200.computercraft.shared.util.DirectionUtil;
import dan200.computercraft.shared.util.Palette; import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.Minecraft; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.render.Tessellator;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor> public class TileEntityMonitorRenderer extends BlockEntityRenderer<TileMonitor>
{ {
@Override @Override
public void render( TileMonitor tileEntity, double posX, double posY, double posZ, float f, int i ) public void render( TileMonitor tileEntity, double posX, double posY, double posZ, float f, int i )
@@ -64,9 +64,9 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
posZ += originPos.getZ() - monitorPos.getZ(); posZ += originPos.getZ() - monitorPos.getZ();
// Determine orientation // Determine orientation
EnumFacing dir = origin.getDirection(); Direction dir = origin.getDirection();
EnumFacing front = origin.getFront(); Direction front = origin.getFront();
float yaw = dir.getHorizontalAngle(); float yaw = dir.asRotation();
float pitch = DirectionUtil.toPitchAngle( front ); float pitch = DirectionUtil.toPitchAngle( front );
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@@ -85,16 +85,16 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
double ySize = origin.getHeight() - 2.0 * (TileMonitor.RENDER_MARGIN + TileMonitor.RENDER_BORDER); double ySize = origin.getHeight() - 2.0 * (TileMonitor.RENDER_MARGIN + TileMonitor.RENDER_BORDER);
// Get renderers // Get renderers
Minecraft mc = Minecraft.getInstance(); MinecraftClient mc = MinecraftClient.getInstance();
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder renderer = tessellator.getBuffer(); BufferBuilder renderer = tessellator.getBufferBuilder();
// Get terminal // Get terminal
boolean redraw = originTerminal.pollTerminalChanged(); boolean redraw = originTerminal.pollTerminalChanged();
// Draw the contents // Draw the contents
GlStateManager.depthMask( false ); GlStateManager.depthMask( false );
OpenGlHelper.glMultiTexCoord2f( OpenGlHelper.GL_TEXTURE1, 0xFFFF, 0xFFFF ); GLX.glMultiTexCoord2f( GLX.GL_TEXTURE1, 0xFFFF, 0xFFFF );
GlStateManager.disableLighting(); GlStateManager.disableLighting();
mc.gameRenderer.disableLightmap(); mc.gameRenderer.disableLightmap();
try try
@@ -171,7 +171,7 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
} }
} }
GlStateManager.callList( originTerminal.renderDisplayLists[0] ); GlStateManager.callList( originTerminal.renderDisplayLists[0] );
GlStateManager.resetColor(); GlStateManager.clearCurrentColor();
// Draw text // Draw text
fontRenderer.bindFont(); fontRenderer.bindFont();
@@ -199,7 +199,7 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
} }
} }
GlStateManager.callList( originTerminal.renderDisplayLists[1] ); GlStateManager.callList( originTerminal.renderDisplayLists[1] );
GlStateManager.resetColor(); GlStateManager.clearCurrentColor();
// Draw cursor // Draw cursor
fontRenderer.bindFont(); fontRenderer.bindFont();
@@ -233,7 +233,7 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
if( FrameInfo.getGlobalCursorBlink() ) if( FrameInfo.getGlobalCursorBlink() )
{ {
GlStateManager.callList( originTerminal.renderDisplayLists[2] ); GlStateManager.callList( originTerminal.renderDisplayLists[2] );
GlStateManager.resetColor(); GlStateManager.clearCurrentColor();
} }
} }
finally finally
@@ -251,11 +251,11 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
final float g = colour.getG(); final float g = colour.getG();
final float b = colour.getB(); final float b = colour.getB();
renderer.begin( GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_TEX_COLOR ); renderer.begin( GL11.GL_TRIANGLE_STRIP, VertexFormats.POSITION_UV_COLOR );
renderer.pos( -TileMonitor.RENDER_MARGIN, TileMonitor.RENDER_MARGIN, 0.0D ).tex( 0.0, 0.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( -TileMonitor.RENDER_MARGIN, TileMonitor.RENDER_MARGIN, 0.0D ).texture( 0.0, 0.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( -TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).tex( 0.0, 1.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( -TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).texture( 0.0, 1.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( xSize + TileMonitor.RENDER_MARGIN, TileMonitor.RENDER_MARGIN, 0.0D ).tex( 1.0, 0.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( xSize + TileMonitor.RENDER_MARGIN, TileMonitor.RENDER_MARGIN, 0.0D ).texture( 1.0, 0.0 ).color( r, g, b, 1.0f ).next();
renderer.pos( xSize + TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).tex( 1.0, 1.0 ).color( r, g, b, 1.0f ).endVertex(); renderer.vertex( xSize + TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).texture( 1.0, 1.0 ).color( r, g, b, 1.0f ).next();
tessellator.draw(); tessellator.draw();
} }
} }
@@ -271,11 +271,11 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
try try
{ {
mc.getTextureManager().bindTexture( FixedWidthFontRenderer.BACKGROUND ); mc.getTextureManager().bindTexture( FixedWidthFontRenderer.BACKGROUND );
renderer.begin( GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION ); renderer.begin( GL11.GL_TRIANGLE_STRIP, VertexFormats.POSITION );
renderer.pos( -TileMonitor.RENDER_MARGIN, TileMonitor.RENDER_MARGIN, 0.0 ).endVertex(); renderer.vertex( -TileMonitor.RENDER_MARGIN, TileMonitor.RENDER_MARGIN, 0.0 ).next();
renderer.pos( -TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).endVertex(); renderer.vertex( -TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).next();
renderer.pos( xSize + TileMonitor.RENDER_MARGIN, TileMonitor.RENDER_MARGIN, 0.0 ).endVertex(); renderer.vertex( xSize + TileMonitor.RENDER_MARGIN, TileMonitor.RENDER_MARGIN, 0.0 ).next();
renderer.pos( xSize + TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).endVertex(); renderer.vertex( xSize + TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).next();
tessellator.draw(); tessellator.draw();
} }
finally finally

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.client.render; package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
@@ -13,39 +14,37 @@ import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.util.DirectionUtil; import dan200.computercraft.shared.util.DirectionUtil;
import dan200.computercraft.shared.util.Holiday; import dan200.computercraft.shared.util.Holiday;
import dan200.computercraft.shared.util.HolidayUtil; import dan200.computercraft.shared.util.HolidayUtil;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.render.*;
import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.render.model.BakedModelManager;
import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.client.renderer.model.ModelManager; import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.client.renderer.model.ModelResourceLocation; import net.minecraft.util.Identifier;
import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer; import net.minecraft.util.math.Direction;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraftforge.client.ForgeHooksClient; import net.minecraft.util.math.Vec3i;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.pipeline.LightUtil;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import javax.vecmath.Matrix4f; import javax.vecmath.Matrix4f;
import java.nio.FloatBuffer;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle> public class TileEntityTurtleRenderer extends BlockEntityRenderer<TileTurtle>
{ {
private static final ModelResourceLocation NORMAL_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_normal", "inventory" ); private static final ModelIdentifier NORMAL_TURTLE_MODEL = new ModelIdentifier( "computercraft:turtle_normal", "inventory" );
private static final ModelResourceLocation ADVANCED_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_advanced", "inventory" ); private static final ModelIdentifier ADVANCED_TURTLE_MODEL = new ModelIdentifier( "computercraft:turtle_advanced", "inventory" );
private static final ModelResourceLocation COLOUR_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_colour", "inventory" ); private static final ModelIdentifier COLOUR_TURTLE_MODEL = new ModelIdentifier( "computercraft:turtle_colour", "inventory" );
private static final ModelResourceLocation ELF_OVERLAY_MODEL = new ModelResourceLocation( "computercraft:turtle_elf_overlay", "inventory" ); private static final ModelIdentifier ELF_OVERLAY_MODEL = new ModelIdentifier( "computercraft:turtle_elf_overlay", "inventory" );
private static final FloatBuffer matrixBuf = BufferUtils.createFloatBuffer( 16 );
@Override @Override
public void render( TileTurtle tileEntity, double posX, double posY, double posZ, float partialTicks, int breaking ) public void render( TileTurtle tileEntity, double posX, double posY, double posZ, float partialTicks, int breaking )
@@ -53,7 +52,7 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
if( tileEntity != null ) renderTurtleAt( tileEntity, posX, posY, posZ, partialTicks ); if( tileEntity != null ) renderTurtleAt( tileEntity, posX, posY, posZ, partialTicks );
} }
public static ModelResourceLocation getTurtleModel( ComputerFamily family, boolean coloured ) public static ModelIdentifier getTurtleModel( ComputerFamily family, boolean coloured )
{ {
switch( family ) switch( family )
{ {
@@ -65,11 +64,11 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
} }
} }
public static ModelResourceLocation getTurtleOverlayModel( ResourceLocation overlay, boolean christmas ) public static ModelIdentifier getTurtleOverlayModel( Identifier overlay, boolean christmas )
{ {
if( overlay != null ) if( overlay != null )
{ {
return new ModelResourceLocation( overlay, "inventory" ); return new ModelIdentifier( overlay, "inventory" );
} }
else if( christmas ) else if( christmas )
{ {
@@ -85,21 +84,21 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
{ {
// Render the label // Render the label
String label = turtle.createProxy().getLabel(); String label = turtle.createProxy().getLabel();
if( label != null && rendererDispatcher.cameraHitResult != null && turtle.getPos().equals( rendererDispatcher.cameraHitResult.getBlockPos() ) ) if( label != null && renderManager.hitResult != null && renderManager.hitResult instanceof BlockHitResult && turtle.getPos().equals( ((BlockHitResult) renderManager.hitResult).getBlockPos() ) )
{ {
setLightmapDisabled( true ); disableLightmap( true );
GameRenderer.drawNameplate( GameRenderer.renderFloatingText(
getFontRenderer(), label, getFontRenderer(), label,
(float) posX + 0.5F, (float) posY + 1.2F, (float) posZ + 0.5F, 0, (float) posX + 0.5F, (float) posY + 1.2F, (float) posZ + 0.5F, 0,
rendererDispatcher.entityYaw, rendererDispatcher.entityPitch, false, false renderManager.cameraEntity.getYaw(), renderManager.cameraEntity.getPitch(), false
); );
setLightmapDisabled( false ); disableLightmap( false );
} }
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
try try
{ {
IBlockState state = turtle.getBlockState(); BlockState state = turtle.getCachedState();
// Setup the transform // Setup the transform
Vec3d offset = turtle.getRenderOffset( partialTicks ); Vec3d offset = turtle.getRenderOffset( partialTicks );
float yaw = turtle.getRenderYaw( partialTicks ); float yaw = turtle.getRenderYaw( partialTicks );
@@ -111,18 +110,18 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
{ {
// Flip the model and swap the cull face as winding order will have changed. // Flip the model and swap the cull face as winding order will have changed.
GlStateManager.scalef( 1.0f, -1.0f, 1.0f ); GlStateManager.scalef( 1.0f, -1.0f, 1.0f );
GlStateManager.cullFace( GlStateManager.CullFace.FRONT ); GlStateManager.cullFace( GlStateManager.FaceSides.FRONT );
} }
GlStateManager.translatef( -0.5f, -0.5f, -0.5f ); GlStateManager.translatef( -0.5f, -0.5f, -0.5f );
// Render the turtle // Render the turtle
int colour = turtle.getColour(); int colour = turtle.getColour();
ComputerFamily family = turtle.getFamily(); ComputerFamily family = turtle.getFamily();
ResourceLocation overlay = turtle.getOverlay(); Identifier overlay = turtle.getOverlay();
renderModel( state, getTurtleModel( family, colour != -1 ), colour == -1 ? null : new int[] { colour } ); renderModel( state, getTurtleModel( family, colour != -1 ), colour == -1 ? null : new int[] { colour } );
// Render the overlay // Render the overlay
ModelResourceLocation overlayModel = getTurtleOverlayModel( ModelIdentifier overlayModel = getTurtleOverlayModel(
overlay, overlay,
HolidayUtil.getCurrentHoliday() == Holiday.Christmas HolidayUtil.getCurrentHoliday() == Holiday.Christmas
); );
@@ -149,11 +148,11 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
finally finally
{ {
GlStateManager.popMatrix(); GlStateManager.popMatrix();
GlStateManager.cullFace( GlStateManager.CullFace.BACK ); GlStateManager.cullFace( GlStateManager.FaceSides.BACK );
} }
} }
private void renderUpgrade( IBlockState state, TileTurtle turtle, TurtleSide side, float f ) private void renderUpgrade( BlockState state, TileTurtle turtle, TurtleSide side, float f )
{ {
ITurtleUpgrade upgrade = turtle.getUpgrade( side ); ITurtleUpgrade upgrade = turtle.getUpgrade( side );
if( upgrade != null ) if( upgrade != null )
@@ -166,12 +165,21 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
GlStateManager.rotatef( -toolAngle, 1.0f, 0.0f, 0.0f ); GlStateManager.rotatef( -toolAngle, 1.0f, 0.0f, 0.0f );
GlStateManager.translatef( 0.0f, -0.5f, -0.5f ); GlStateManager.translatef( 0.0f, -0.5f, -0.5f );
Pair<IBakedModel, Matrix4f> pair = upgrade.getModel( turtle.getAccess(), side ); Pair<BakedModel, Matrix4f> pair = upgrade.getModel( turtle.getAccess(), side );
if( pair != null ) if( pair != null )
{ {
if( pair.getRight() != null ) if( pair.getRight() != null )
{ {
ForgeHooksClient.multiplyCurrentGlMatrix( pair.getRight() ); matrixBuf.clear();
float[] t = new float[4];
for( int i = 0; i < 4; i++ )
{
pair.getRight().getColumn( i, t );
matrixBuf.put( t );
}
matrixBuf.flip();
GlStateManager.multMatrix( matrixBuf );
} }
if( pair.getLeft() != null ) if( pair.getLeft() != null )
{ {
@@ -186,48 +194,43 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
} }
} }
private void renderModel( IBlockState state, ModelResourceLocation modelLocation, int[] tints ) private void renderModel( BlockState state, ModelIdentifier modelLocation, int[] tints )
{ {
Minecraft mc = Minecraft.getInstance(); MinecraftClient mc = MinecraftClient.getInstance();
ModelManager modelManager = mc.getItemRenderer().getItemModelMesher().getModelManager(); BakedModelManager modelManager = mc.getItemRenderer().getModels().getModelManager();
renderModel( state, modelManager.getModel( modelLocation ), tints ); renderModel( state, modelManager.getModel( modelLocation ), tints );
} }
private void renderModel( IBlockState state, IBakedModel model, int[] tints ) private void renderModel( BlockState state, BakedModel model, int[] tints )
{ {
Random random = new Random( 0 ); Random random = new Random( 0 );
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
rendererDispatcher.textureManager.bindTexture( TextureMap.LOCATION_BLOCKS_TEXTURE ); renderManager.textureManager.bindTexture( SpriteAtlasTexture.BLOCK_ATLAS_TEX );
renderQuads( tessellator, model.getQuads( state, null, random, EmptyModelData.INSTANCE ), tints ); renderQuads( tessellator, model.getQuads( state, null, random ), tints );
for( EnumFacing facing : DirectionUtil.FACINGS ) for( Direction facing : DirectionUtil.FACINGS )
{ {
renderQuads( tessellator, model.getQuads( state, facing, random, EmptyModelData.INSTANCE ), tints ); renderQuads( tessellator, model.getQuads( state, facing, random ), tints );
} }
} }
private static void renderQuads( Tessellator tessellator, List<BakedQuad> quads, int[] tints ) private static void renderQuads( Tessellator tessellator, List<BakedQuad> quads, int[] tints )
{ {
BufferBuilder buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBufferBuilder();
VertexFormat format = DefaultVertexFormats.ITEM; VertexFormat format = VertexFormats.POSITION_COLOR_UV_NORMAL;
buffer.begin( GL11.GL_QUADS, format ); buffer.begin( GL11.GL_QUADS, format );
for( BakedQuad quad : quads ) for( BakedQuad quad : quads )
{ {
VertexFormat quadFormat = quad.getFormat();
if( quadFormat != format )
{
tessellator.draw();
format = quadFormat;
buffer.begin( GL11.GL_QUADS, format );
}
int colour = 0xFFFFFFFF; int colour = 0xFFFFFFFF;
if( quad.hasTintIndex() && tints != null ) if( quad.hasColor() && tints != null )
{ {
int index = quad.getTintIndex(); int index = quad.getColorIndex();
if( index >= 0 && index < tints.length ) colour = tints[index] | 0xFF000000; if( index >= 0 && index < tints.length ) colour = tints[index] | 0xFF000000;
} }
LightUtil.renderQuadColor( buffer, quad, colour ); buffer.putVertexData( quad.getVertexData() );
buffer.setQuadColor( colour );
Vec3i normal = quad.getFace().getVector();
buffer.postNormal( normal.getX(), normal.getY(), normal.getZ() );
} }
tessellator.draw(); tessellator.draw();
} }

View File

@@ -7,14 +7,12 @@
package dan200.computercraft.client.render; package dan200.computercraft.client.render;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.renderer.model.IUnbakedModel; import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.resources.IResourceManager; import net.minecraft.client.texture.Sprite;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.Identifier;
import net.minecraftforge.client.model.ICustomModelLoader;
import net.minecraftforge.common.model.IModelState;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -24,11 +22,11 @@ import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public final class TurtleModelLoader implements ICustomModelLoader public final class TurtleModelLoader
{ {
private static final ResourceLocation NORMAL_TURTLE_MODEL = new ResourceLocation( ComputerCraft.MOD_ID, "block/turtle_normal" ); private static final Identifier NORMAL_TURTLE_MODEL = new Identifier( ComputerCraft.MOD_ID, "block/turtle_normal" );
private static final ResourceLocation ADVANCED_TURTLE_MODEL = new ResourceLocation( ComputerCraft.MOD_ID, "block/turtle_advanced" ); private static final Identifier ADVANCED_TURTLE_MODEL = new Identifier( ComputerCraft.MOD_ID, "block/turtle_advanced" );
private static final ResourceLocation COLOUR_TURTLE_MODEL = new ResourceLocation( ComputerCraft.MOD_ID, "block/turtle_colour" ); private static final Identifier COLOUR_TURTLE_MODEL = new Identifier( ComputerCraft.MOD_ID, "block/turtle_colour" );
public static final TurtleModelLoader INSTANCE = new TurtleModelLoader(); public static final TurtleModelLoader INSTANCE = new TurtleModelLoader();
@@ -36,21 +34,14 @@ public final class TurtleModelLoader implements ICustomModelLoader
{ {
} }
@Override public boolean accepts( @Nonnull Identifier name )
public void onResourceManagerReload( @Nonnull IResourceManager manager )
{
}
@Override
public boolean accepts( @Nonnull ResourceLocation name )
{ {
return name.getNamespace().equals( ComputerCraft.MOD_ID ) return name.getNamespace().equals( ComputerCraft.MOD_ID )
&& (name.getPath().equals( "item/turtle_normal" ) || name.getPath().equals( "item/turtle_advanced" )); && (name.getPath().equals( "item/turtle_normal" ) || name.getPath().equals( "item/turtle_advanced" ));
} }
@Nonnull @Nonnull
@Override public UnbakedModel loadModel( @Nonnull Identifier name )
public IUnbakedModel loadModel( @Nonnull ResourceLocation name )
{ {
if( name.getNamespace().equals( ComputerCraft.MOD_ID ) ) if( name.getNamespace().equals( ComputerCraft.MOD_ID ) )
{ {
@@ -66,35 +57,35 @@ public final class TurtleModelLoader implements ICustomModelLoader
throw new IllegalStateException( "Loader does not accept " + name ); throw new IllegalStateException( "Loader does not accept " + name );
} }
private static final class TurtleModel implements IUnbakedModel private static final class TurtleModel implements UnbakedModel
{ {
private final ResourceLocation family; private final Identifier family;
private TurtleModel( ResourceLocation family ) {this.family = family;} private TurtleModel( Identifier family ) {this.family = family;}
@Nonnull @Nonnull
@Override @Override
public Collection<ResourceLocation> getDependencies() public Collection<Identifier> getModelDependencies()
{ {
return Arrays.asList( family, COLOUR_TURTLE_MODEL ); return Arrays.asList( family, COLOUR_TURTLE_MODEL );
} }
@Nonnull @Nonnull
@Override @Override
public Collection<ResourceLocation> getTextures( @Nonnull Function<ResourceLocation, IUnbakedModel> modelGetter, @Nonnull Set<String> missingTextureErrors ) public Collection<Identifier> getTextureDependencies( @Nonnull Function<Identifier, UnbakedModel> modelGetter, @Nonnull Set<String> missingTextureErrors )
{ {
return getDependencies().stream() return getModelDependencies().stream()
.flatMap( x -> modelGetter.apply( x ).getTextures( modelGetter, missingTextureErrors ).stream() ) .flatMap( x -> modelGetter.apply( x ).getTextureDependencies( modelGetter, missingTextureErrors ).stream() )
.collect( Collectors.toSet() ); .collect( Collectors.toSet() );
} }
@Nullable @Nullable
@Override @Override
public IBakedModel bake( @Nonnull Function<ResourceLocation, IUnbakedModel> modelGetter, @Nonnull Function<ResourceLocation, TextureAtlasSprite> spriteGetter, @Nonnull IModelState state, boolean uvlock, @Nonnull VertexFormat format ) public BakedModel bake( @Nonnull ModelLoader loader, @Nonnull Function<Identifier, Sprite> spriteGetter, @Nonnull ModelBakeSettings state )
{ {
return new TurtleSmartItemModel( return new TurtleSmartItemModel(
modelGetter.apply( family ).bake( modelGetter, spriteGetter, state, uvlock, format ), loader.getOrLoadModel( family ).bake( loader, spriteGetter, state ),
modelGetter.apply( COLOUR_TURTLE_MODEL ).bake( modelGetter, spriteGetter, state, uvlock, format ) loader.getOrLoadModel( COLOUR_TURTLE_MODEL ).bake( loader, spriteGetter, state )
); );
} }
} }

View File

@@ -6,32 +6,31 @@
package dan200.computercraft.client.render; package dan200.computercraft.client.render;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.renderer.model.ItemOverrideList; import net.minecraft.client.render.model.json.ModelItemPropertyOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.util.EnumFacing; import net.minecraft.client.texture.Sprite;
import net.minecraftforge.client.model.data.EmptyModelData; import net.minecraft.util.math.Direction;
import net.minecraftforge.client.model.data.IModelData;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.vecmath.Matrix4f; import javax.vecmath.Matrix4f;
import java.util.*; import java.util.*;
public class TurtleMultiModel implements IBakedModel public class TurtleMultiModel implements BakedModel
{ {
private final IBakedModel m_baseModel; private final BakedModel m_baseModel;
private final IBakedModel m_overlayModel; private final BakedModel m_overlayModel;
private final Matrix4f m_generalTransform; private final Matrix4f m_generalTransform;
private final IBakedModel m_leftUpgradeModel; private final BakedModel m_leftUpgradeModel;
private final Matrix4f m_leftUpgradeTransform; private final Matrix4f m_leftUpgradeTransform;
private final IBakedModel m_rightUpgradeModel; private final BakedModel m_rightUpgradeModel;
private final Matrix4f m_rightUpgradeTransform; private final Matrix4f m_rightUpgradeTransform;
private List<BakedQuad> m_generalQuads = null; private List<BakedQuad> m_generalQuads = null;
private Map<EnumFacing, List<BakedQuad>> m_faceQuads = new EnumMap<>( EnumFacing.class ); private Map<Direction, List<BakedQuad>> m_faceQuads = new EnumMap<>( Direction.class );
public TurtleMultiModel( IBakedModel baseModel, IBakedModel overlayModel, Matrix4f generalTransform, IBakedModel leftUpgradeModel, Matrix4f leftUpgradeTransform, IBakedModel rightUpgradeModel, Matrix4f rightUpgradeTransform ) public TurtleMultiModel( BakedModel baseModel, BakedModel overlayModel, Matrix4f generalTransform, BakedModel leftUpgradeModel, Matrix4f leftUpgradeTransform, BakedModel rightUpgradeModel, Matrix4f rightUpgradeTransform )
{ {
// Get the models // Get the models
m_baseModel = baseModel; m_baseModel = baseModel;
@@ -45,15 +44,7 @@ public class TurtleMultiModel implements IBakedModel
@Nonnull @Nonnull
@Override @Override
@Deprecated public List<BakedQuad> getQuads( BlockState state, Direction side, @Nonnull Random rand )
public List<BakedQuad> getQuads( IBlockState state, EnumFacing side, @Nonnull Random rand )
{
return getQuads( state, side, rand, EmptyModelData.INSTANCE );
}
@Nonnull
@Override
public List<BakedQuad> getQuads( IBlockState state, EnumFacing side, @Nonnull Random rand, @Nonnull IModelData data )
{ {
if( side != null ) if( side != null )
{ {
@@ -67,13 +58,13 @@ public class TurtleMultiModel implements IBakedModel
} }
} }
private List<BakedQuad> buildQuads( IBlockState state, EnumFacing side, Random rand ) private List<BakedQuad> buildQuads( BlockState state, Direction side, Random rand )
{ {
ArrayList<BakedQuad> quads = new ArrayList<>(); ArrayList<BakedQuad> quads = new ArrayList<>();
ModelTransformer.transformQuadsTo( quads, m_baseModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), m_generalTransform ); ModelTransformer.transformQuadsTo( quads, m_baseModel.getQuads( state, side, rand ), m_generalTransform );
if( m_overlayModel != null ) if( m_overlayModel != null )
{ {
ModelTransformer.transformQuadsTo( quads, m_overlayModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), m_generalTransform ); ModelTransformer.transformQuadsTo( quads, m_overlayModel.getQuads( state, side, rand ), m_generalTransform );
} }
if( m_leftUpgradeModel != null ) if( m_leftUpgradeModel != null )
{ {
@@ -83,7 +74,7 @@ public class TurtleMultiModel implements IBakedModel
upgradeTransform = new Matrix4f( m_generalTransform ); upgradeTransform = new Matrix4f( m_generalTransform );
upgradeTransform.mul( m_leftUpgradeTransform ); upgradeTransform.mul( m_leftUpgradeTransform );
} }
ModelTransformer.transformQuadsTo( quads, m_leftUpgradeModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform ); ModelTransformer.transformQuadsTo( quads, m_leftUpgradeModel.getQuads( state, side, rand ), upgradeTransform );
} }
if( m_rightUpgradeModel != null ) if( m_rightUpgradeModel != null )
{ {
@@ -93,49 +84,45 @@ public class TurtleMultiModel implements IBakedModel
upgradeTransform = new Matrix4f( m_generalTransform ); upgradeTransform = new Matrix4f( m_generalTransform );
upgradeTransform.mul( m_rightUpgradeTransform ); upgradeTransform.mul( m_rightUpgradeTransform );
} }
ModelTransformer.transformQuadsTo( quads, m_rightUpgradeModel.getQuads( state, side, rand , EmptyModelData.INSTANCE), upgradeTransform ); ModelTransformer.transformQuadsTo( quads, m_rightUpgradeModel.getQuads( state, side, rand ), upgradeTransform );
} }
quads.trimToSize(); quads.trimToSize();
return quads; return quads;
} }
@Override @Override
public boolean isAmbientOcclusion() public boolean useAmbientOcclusion()
{ {
return m_baseModel.isAmbientOcclusion(); return m_baseModel.useAmbientOcclusion();
} }
@Override @Override
public boolean isGui3d() public boolean hasDepthInGui()
{ {
return m_baseModel.isGui3d(); return m_baseModel.hasDepthInGui();
} }
@Override @Override
public boolean isBuiltInRenderer() public boolean isBuiltin()
{ {
return m_baseModel.isBuiltInRenderer(); return m_baseModel.isBuiltin();
} }
@Nonnull
@Override @Override
public TextureAtlasSprite getParticleTexture() public Sprite getSprite()
{ {
return m_baseModel.getParticleTexture(); return m_baseModel.getSprite();
} }
@Nonnull
@Override @Override
@Deprecated public ModelTransformation getTransformation()
public net.minecraft.client.renderer.model.ItemCameraTransforms getItemCameraTransforms()
{ {
return m_baseModel.getItemCameraTransforms(); return m_baseModel.getTransformation();
} }
@Nonnull
@Override @Override
public ItemOverrideList getOverrides() public ModelItemPropertyOverrideList getItemPropertyOverrides()
{ {
return ItemOverrideList.EMPTY; return ModelItemPropertyOverrideList.EMPTY;
} }
} }

View File

@@ -12,26 +12,31 @@ import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.shared.turtle.items.ItemTurtle; import dan200.computercraft.shared.turtle.items.ItemTurtle;
import dan200.computercraft.shared.util.Holiday; import dan200.computercraft.shared.util.Holiday;
import dan200.computercraft.shared.util.HolidayUtil; import dan200.computercraft.shared.util.HolidayUtil;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.renderer.model.*; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.render.model.BakedModelManager;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.render.model.json.ModelItemPropertyOverrideList;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing; import net.minecraft.util.Identifier;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.client.model.data.IModelData;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.vecmath.Matrix4f; import javax.vecmath.Matrix4f;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
public class TurtleSmartItemModel implements IBakedModel public class TurtleSmartItemModel implements BakedModel
{ {
private static final Matrix4f s_identity, s_flip; private static final Matrix4f s_identity, s_flip;
@@ -51,11 +56,11 @@ public class TurtleSmartItemModel implements IBakedModel
final boolean m_colour; final boolean m_colour;
final ITurtleUpgrade m_leftUpgrade; final ITurtleUpgrade m_leftUpgrade;
final ITurtleUpgrade m_rightUpgrade; final ITurtleUpgrade m_rightUpgrade;
final ResourceLocation m_overlay; final Identifier m_overlay;
final boolean m_christmas; final boolean m_christmas;
final boolean m_flip; final boolean m_flip;
TurtleModelCombination( boolean colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, ResourceLocation overlay, boolean christmas, boolean flip ) TurtleModelCombination( boolean colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, Identifier overlay, boolean christmas, boolean flip )
{ {
m_colour = colour; m_colour = colour;
m_leftUpgrade = leftUpgrade; m_leftUpgrade = leftUpgrade;
@@ -95,35 +100,35 @@ public class TurtleSmartItemModel implements IBakedModel
} }
} }
private final IBakedModel familyModel; private final BakedModel familyModel;
private final IBakedModel colourModel; private final BakedModel colourModel;
private HashMap<TurtleModelCombination, IBakedModel> m_cachedModels; private HashMap<TurtleModelCombination, BakedModel> m_cachedModels;
private ItemOverrideList m_overrides; private ModelItemPropertyOverrideList m_overrides;
public TurtleSmartItemModel( IBakedModel familyModel, IBakedModel colourModel ) public TurtleSmartItemModel( BakedModel familyModel, BakedModel colourModel )
{ {
this.familyModel = familyModel; this.familyModel = familyModel;
this.colourModel = colourModel; this.colourModel = colourModel;
m_cachedModels = new HashMap<>(); m_cachedModels = new HashMap<>();
m_overrides = new ItemOverrideList() m_overrides = new ModelItemPropertyOverrideList( null, null, null, Collections.emptyList() )
{ {
@Nonnull @Nonnull
@Override @Override
public IBakedModel getModelWithOverrides( @Nonnull IBakedModel originalModel, @Nonnull ItemStack stack, @Nullable World world, @Nullable EntityLivingBase entity ) public BakedModel apply( @Nonnull BakedModel originalModel, @Nonnull ItemStack stack, @Nullable World world, @Nullable LivingEntity entity )
{ {
ItemTurtle turtle = (ItemTurtle) stack.getItem(); ItemTurtle turtle = (ItemTurtle) stack.getItem();
int colour = turtle.getColour( stack ); int colour = turtle.getColour( stack );
ITurtleUpgrade leftUpgrade = turtle.getUpgrade( stack, TurtleSide.Left ); ITurtleUpgrade leftUpgrade = turtle.getUpgrade( stack, TurtleSide.Left );
ITurtleUpgrade rightUpgrade = turtle.getUpgrade( stack, TurtleSide.Right ); ITurtleUpgrade rightUpgrade = turtle.getUpgrade( stack, TurtleSide.Right );
ResourceLocation overlay = turtle.getOverlay( stack ); Identifier overlay = turtle.getOverlay( stack );
boolean christmas = HolidayUtil.getCurrentHoliday() == Holiday.Christmas; boolean christmas = HolidayUtil.getCurrentHoliday() == Holiday.Christmas;
String label = turtle.getLabel( stack ); String label = turtle.getLabel( stack );
boolean flip = label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" )); boolean flip = label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" ));
TurtleModelCombination combo = new TurtleModelCombination( colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip ); TurtleModelCombination combo = new TurtleModelCombination( colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip );
IBakedModel model = m_cachedModels.get( combo ); BakedModel model = m_cachedModels.get( combo );
if( model == null ) m_cachedModels.put( combo, model = buildModel( combo ) ); if( model == null ) m_cachedModels.put( combo, model = buildModel( combo ) );
return model; return model;
} }
@@ -132,22 +137,22 @@ public class TurtleSmartItemModel implements IBakedModel
@Nonnull @Nonnull
@Override @Override
public ItemOverrideList getOverrides() public ModelItemPropertyOverrideList getItemPropertyOverrides()
{ {
return m_overrides; return m_overrides;
} }
private IBakedModel buildModel( TurtleModelCombination combo ) private BakedModel buildModel( TurtleModelCombination combo )
{ {
Minecraft mc = Minecraft.getInstance(); MinecraftClient mc = MinecraftClient.getInstance();
ModelManager modelManager = mc.getItemRenderer().getItemModelMesher().getModelManager(); BakedModelManager modelManager = mc.getItemRenderer().getModels().getModelManager();
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.m_overlay, combo.m_christmas ); ModelIdentifier overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.m_overlay, combo.m_christmas );
IBakedModel baseModel = combo.m_colour ? colourModel : familyModel; BakedModel baseModel = combo.m_colour ? colourModel : familyModel;
IBakedModel overlayModel = overlayModelLocation != null ? modelManager.getModel( overlayModelLocation ) : null; BakedModel overlayModel = overlayModelLocation != null ? modelManager.getModel( overlayModelLocation ) : null;
Matrix4f transform = combo.m_flip ? s_flip : s_identity; Matrix4f transform = combo.m_flip ? s_flip : s_identity;
Pair<IBakedModel, Matrix4f> leftModel = combo.m_leftUpgrade != null ? combo.m_leftUpgrade.getModel( null, TurtleSide.Left ) : null; Pair<BakedModel, Matrix4f> leftModel = combo.m_leftUpgrade != null ? combo.m_leftUpgrade.getModel( null, TurtleSide.Left ) : null;
Pair<IBakedModel, Matrix4f> rightModel = combo.m_rightUpgrade != null ? combo.m_rightUpgrade.getModel( null, TurtleSide.Right ) : null; Pair<BakedModel, Matrix4f> rightModel = combo.m_rightUpgrade != null ? combo.m_rightUpgrade.getModel( null, TurtleSide.Right ) : null;
if( leftModel != null && rightModel != null ) if( leftModel != null && rightModel != null )
{ {
return new TurtleMultiModel( baseModel, overlayModel, transform, leftModel.getLeft(), leftModel.getRight(), rightModel.getLeft(), rightModel.getRight() ); return new TurtleMultiModel( baseModel, overlayModel, transform, leftModel.getLeft(), leftModel.getRight(), rightModel.getLeft(), rightModel.getRight() );
@@ -169,50 +174,38 @@ public class TurtleSmartItemModel implements IBakedModel
@Nonnull @Nonnull
@Override @Override
@Deprecated @Deprecated
public List<BakedQuad> getQuads( IBlockState state, EnumFacing facing, @Nonnull Random rand ) public List<BakedQuad> getQuads( BlockState state, Direction facing, Random rand )
{ {
return familyModel.getQuads( state, facing, rand ); return familyModel.getQuads( state, facing, rand );
} }
@Nonnull
@Override @Override
@Deprecated public boolean useAmbientOcclusion()
public List<BakedQuad> getQuads( IBlockState state, EnumFacing facing, @Nonnull Random rand, @Nonnull IModelData data )
{ {
return familyModel.getQuads( state, facing, rand, data ); return familyModel.useAmbientOcclusion();
} }
@Override @Override
public boolean isAmbientOcclusion() public boolean hasDepthInGui()
{ {
return familyModel.isAmbientOcclusion(); return familyModel.hasDepthInGui();
} }
@Override @Override
public boolean isGui3d() public boolean isBuiltin()
{ {
return familyModel.isGui3d(); return familyModel.isBuiltin();
} }
@Override @Override
public boolean isBuiltInRenderer() public Sprite getSprite()
{ {
return familyModel.isBuiltInRenderer(); return null;
} }
@Nonnull
@Override @Override
public TextureAtlasSprite getParticleTexture() public ModelTransformation getTransformation()
{ {
return familyModel.getParticleTexture(); return familyModel.getTransformation();
} }
@Nonnull
@Override
@Deprecated
public ItemCameraTransforms getItemCameraTransforms()
{
return familyModel.getItemCameraTransforms();
}
} }

View File

@@ -10,7 +10,7 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.peripheral.IWorkMonitor; import dan200.computercraft.api.peripheral.IWorkMonitor;
import dan200.computercraft.core.tracking.Tracking; import dan200.computercraft.core.tracking.Tracking;
import dan200.computercraft.shared.turtle.core.TurtleBrain; import dan200.computercraft.shared.turtle.core.TurtleBrain;
import net.minecraft.tileentity.TileEntity; import net.minecraft.block.entity.BlockEntity;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.ArrayDeque; import java.util.ArrayDeque;
@@ -29,7 +29,7 @@ import java.util.concurrent.TimeUnit;
* this tick. At the beginning of the tick, we execute as many {@link MainThread} tasks as possible, until our * this tick. At the beginning of the tick, we execute as many {@link MainThread} tasks as possible, until our
* time-frame or the global time frame has expired. * time-frame or the global time frame has expired.
* *
* Then, when other objects (such as {@link TileEntity}) are ticked, we update how much time we've used using * Then, when other objects (such as {@link BlockEntity}) are ticked, we update how much time we've used using
* {@link IWorkMonitor#trackWork(long, TimeUnit)}. * {@link IWorkMonitor#trackWork(long, TimeUnit)}.
* *
* Now, if anywhere during this period, we use more than our allocated time slice, the executor is marked as * Now, if anywhere during this period, we use more than our allocated time slice, the executor is marked as

View File

@@ -11,12 +11,12 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.core.apis.handles.ArrayByteChannel; import dan200.computercraft.core.apis.handles.ArrayByteChannel;
import net.minecraft.resources.IReloadableResourceManager; import net.minecraft.resource.ReloadableResourceManager;
import net.minecraft.resources.IResource; import net.minecraft.resource.Resource;
import net.minecraft.resources.IResourceManager; import net.minecraft.resource.ResourceManager;
import net.minecraft.util.ResourceLocation; import net.minecraft.resource.ResourceReloadListener;
import net.minecraftforge.resource.IResourceType; import net.minecraft.util.Identifier;
import net.minecraftforge.resource.ISelectiveResourceReloadListener; import net.minecraft.util.profiler.Profiler;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -26,8 +26,9 @@ import java.io.InputStream;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
public class ResourceMount implements IMount public class ResourceMount implements IMount
{ {
@@ -57,12 +58,12 @@ public class ResourceMount implements IMount
private final String namespace; private final String namespace;
private final String subPath; private final String subPath;
private final IReloadableResourceManager manager; private final ReloadableResourceManager manager;
@Nullable @Nullable
private FileEntry root; private FileEntry root;
public ResourceMount( String namespace, String subPath, IReloadableResourceManager manager ) public ResourceMount( String namespace, String subPath, ReloadableResourceManager manager )
{ {
this.namespace = namespace; this.namespace = namespace;
this.subPath = subPath; this.subPath = subPath;
@@ -75,8 +76,8 @@ public class ResourceMount implements IMount
private void load() private void load()
{ {
boolean hasAny = false; boolean hasAny = false;
FileEntry newRoot = new FileEntry( new ResourceLocation( namespace, subPath ) ); FileEntry newRoot = new FileEntry( new Identifier( namespace, subPath ) );
for( ResourceLocation file : manager.getAllResourceLocations( subPath, s -> true ) ) for( Identifier file : manager.findResources( subPath, s -> true ) )
{ {
if( !file.getNamespace().equals( namespace ) ) continue; if( !file.getNamespace().equals( namespace ) ) continue;
@@ -119,7 +120,7 @@ public class ResourceMount implements IMount
FileEntry nextEntry = lastEntry.children.get( part ); FileEntry nextEntry = lastEntry.children.get( part );
if( nextEntry == null ) if( nextEntry == null )
{ {
lastEntry.children.put( part, nextEntry = new FileEntry( new ResourceLocation( namespace, subPath + "/" + path ) ) ); lastEntry.children.put( part, nextEntry = new FileEntry( new Identifier( namespace, subPath + "/" + path ) ) );
} }
lastEntry = nextEntry; lastEntry = nextEntry;
@@ -163,7 +164,7 @@ public class ResourceMount implements IMount
try try
{ {
IResource resource = manager.getResource( file.identifier ); Resource resource = manager.getResource( file.identifier );
InputStream s = resource.getInputStream(); InputStream s = resource.getInputStream();
int total = 0, read = 0; int total = 0, read = 0;
do do
@@ -219,11 +220,11 @@ public class ResourceMount implements IMount
private static class FileEntry private static class FileEntry
{ {
final ResourceLocation identifier; final Identifier identifier;
Map<String, FileEntry> children; Map<String, FileEntry> children;
long size = -1; long size = -1;
FileEntry( ResourceLocation identifier ) FileEntry( Identifier identifier )
{ {
this.identifier = identifier; this.identifier = identifier;
} }
@@ -240,34 +241,37 @@ public class ResourceMount implements IMount
} }
/** /**
* A {@link ISelectiveResourceReloadListener} which reloads any associated mounts. * A {@link ResourceReloadListener} which reloads any associated mounts.
* *
* While people should really be keeping a permanent reference to this, some people construct it every * While people should really be keeping a permanent reference to this, some people construct it every
* method call, so let's make this as small as possible. * method call, so let's make this as small as possible.
*/ */
static class Listener implements ISelectiveResourceReloadListener static class Listener implements ResourceReloadListener
{ {
private static final Listener INSTANCE = new Listener(); private static final Listener INSTANCE = new Listener();
private final Set<ResourceMount> mounts = Collections.newSetFromMap( new WeakHashMap<>() ); private final Set<ResourceMount> mounts = Collections.newSetFromMap( new WeakHashMap<>() );
private final Set<IReloadableResourceManager> managers = Collections.newSetFromMap( new WeakHashMap<>() ); private final Set<ReloadableResourceManager> managers = Collections.newSetFromMap( new WeakHashMap<>() );
@Override @Override
public void onResourceManagerReload( @Nonnull IResourceManager manager ) public CompletableFuture<Void> reload( Synchronizer synchronizer, ResourceManager resourceManager, Profiler profiler, Profiler profiler1, Executor executor, Executor executor1 )
{ {
// FIXME: Remove this. We need this patch in order to prevent trying to load ReloadRequirements. return CompletableFuture.runAsync( () -> {
onResourceManagerReload( manager, x -> true ); profiler.push( "Mount reloading" );
} try
@Override
public synchronized void onResourceManagerReload( @Nonnull IResourceManager manager, @Nonnull Predicate<IResourceType> predicate )
{ {
for( ResourceMount mount : mounts ) mount.load(); for( ResourceMount mount : mounts ) mount.load();
} }
finally
synchronized void add( IReloadableResourceManager manager, ResourceMount mount )
{ {
if( managers.add( manager ) ) manager.addReloadListener( this ); profiler.pop();
}
}, executor );
}
synchronized void add( ReloadableResourceManager manager, ResourceMount mount )
{
if( managers.add( manager ) ) manager.registerListener( this );
mounts.add( mount ); mounts.add( mount );
} }
} }

View File

@@ -7,7 +7,7 @@
package dan200.computercraft.core.terminal; package dan200.computercraft.core.terminal;
import dan200.computercraft.shared.util.Palette; import dan200.computercraft.shared.util.Palette;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.CompoundTag;
public class Terminal public class Terminal
{ {
@@ -334,7 +334,7 @@ public class Terminal
m_changed = false; m_changed = false;
} }
public synchronized NBTTagCompound writeToNBT( NBTTagCompound nbt ) public synchronized CompoundTag writeToNBT( CompoundTag nbt )
{ {
nbt.putInt( "term_cursorX", m_cursorX ); nbt.putInt( "term_cursorX", m_cursorX );
nbt.putInt( "term_cursorY", m_cursorY ); nbt.putInt( "term_cursorY", m_cursorY );
@@ -354,7 +354,7 @@ public class Terminal
return nbt; return nbt;
} }
public synchronized void readFromNBT( NBTTagCompound nbt ) public synchronized void readFromNBT( CompoundTag nbt )
{ {
m_cursorX = nbt.getInt( "term_cursorX" ); m_cursorX = nbt.getInt( "term_cursorX" );
m_cursorY = nbt.getInt( "term_cursorY" ); m_cursorY = nbt.getInt( "term_cursorY" );
@@ -365,17 +365,17 @@ public class Terminal
for( int n = 0; n < m_height; n++ ) for( int n = 0; n < m_height; n++ )
{ {
m_text[n].fill( ' ' ); m_text[n].fill( ' ' );
if( nbt.contains( "term_text_" + n ) ) if( nbt.containsKey( "term_text_" + n ) )
{ {
m_text[n].write( nbt.getString( "term_text_" + n ) ); m_text[n].write( nbt.getString( "term_text_" + n ) );
} }
m_textColour[n].fill( base16.charAt( m_cursorColour ) ); m_textColour[n].fill( base16.charAt( m_cursorColour ) );
if( nbt.contains( "term_textColour_" + n ) ) if( nbt.containsKey( "term_textColour_" + n ) )
{ {
m_textColour[n].write( nbt.getString( "term_textColour_" + n ) ); m_textColour[n].write( nbt.getString( "term_textColour_" + n ) );
} }
m_backgroundColour[n].fill( base16.charAt( m_cursorBackgroundColour ) ); m_backgroundColour[n].fill( base16.charAt( m_cursorBackgroundColour ) );
if( nbt.contains( "term_textBgColour_" + n ) ) if( nbt.containsKey( "term_textBgColour_" + n ) )
{ {
m_backgroundColour[n].write( nbt.getString( "term_textBgColour_" + n ) ); m_backgroundColour[n].write( nbt.getString( "term_textBgColour_" + n ) );
} }

View File

@@ -9,8 +9,8 @@ package dan200.computercraft.shared;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider; import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider; import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -24,18 +24,18 @@ public final class BundledRedstone
private BundledRedstone() {} private BundledRedstone() {}
public static synchronized void register( @Nonnull IBundledRedstoneProvider provider ) public static void register( @Nonnull IBundledRedstoneProvider provider )
{ {
Objects.requireNonNull( provider, "provider cannot be null" ); Objects.requireNonNull( provider, "provider cannot be null" );
providers.add( provider ); providers.add( provider );
} }
public static int getDefaultOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side ) public static int getDefaultOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
{ {
return World.isValid( pos ) ? DefaultBundledRedstoneProvider.getDefaultBundledRedstoneOutput( world, pos, side ) : -1; return World.isValid( pos ) ? DefaultBundledRedstoneProvider.getDefaultBundledRedstoneOutput( world, pos, side ) : -1;
} }
private static int getUnmaskedOutput( World world, BlockPos pos, EnumFacing side ) private static int getUnmaskedOutput( World world, BlockPos pos, Direction side )
{ {
if( !World.isValid( pos ) ) return -1; if( !World.isValid( pos ) ) return -1;
@@ -60,7 +60,7 @@ public final class BundledRedstone
return combinedSignal; return combinedSignal;
} }
public static int getOutput( World world, BlockPos pos, EnumFacing side ) public static int getOutput( World world, BlockPos pos, Direction side )
{ {
int signal = getUnmaskedOutput( world, pos, side ); int signal = getUnmaskedOutput( world, pos, side );
return signal >= 0 ? signal : 0; return signal >= 0 ? signal : 0;

View File

@@ -1,344 +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;
import com.google.common.base.CaseFormat;
import com.google.common.base.Converter;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.core.apis.AddressPredicate;
import dan200.computercraft.core.apis.http.websocket.Websocket;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.config.ModConfig;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static dan200.computercraft.ComputerCraft.DEFAULT_HTTP_BLACKLIST;
import static dan200.computercraft.ComputerCraft.DEFAULT_HTTP_WHITELIST;
import static net.minecraftforge.common.ForgeConfigSpec.Builder;
import static net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD )
public final class Config
{
private static final int MODEM_MAX_RANGE = 100000;
private static final String TRANSLATION_PREFIX = "gui.computercraft.config.";
private static ConfigValue<Integer> computerSpaceLimit;
private static ConfigValue<Integer> floppySpaceLimit;
private static ConfigValue<Integer> maximumFilesOpen;
private static ConfigValue<Boolean> disableLua51Features;
private static ConfigValue<String> defaultComputerSettings;
private static ConfigValue<Boolean> debugEnabled;
private static ConfigValue<Boolean> logComputerErrors;
private static ConfigValue<Integer> computerThreads;
private static ConfigValue<Integer> maxMainGlobalTime;
private static ConfigValue<Integer> maxMainComputerTime;
private static ConfigValue<Boolean> httpEnabled;
private static ConfigValue<Boolean> httpWebsocketEnabled;
private static ConfigValue<List<? extends String>> httpWhitelist;
private static ConfigValue<List<? extends String>> httpBlacklist;
private static ConfigValue<Integer> httpTimeout;
private static ConfigValue<Integer> httpMaxRequests;
private static ConfigValue<Integer> httpMaxDownload;
private static ConfigValue<Integer> httpMaxUpload;
private static ConfigValue<Integer> httpMaxWebsockets;
private static ConfigValue<Integer> httpMaxWebsocketMessage;
private static ConfigValue<Boolean> commandBlockEnabled;
private static ConfigValue<Integer> modemRange;
private static ConfigValue<Integer> modemHighAltitudeRange;
private static ConfigValue<Integer> modemRangeDuringStorm;
private static ConfigValue<Integer> modemHighAltitudeRangeDuringStorm;
private static ConfigValue<Integer> maxNotesPerTick;
private static ConfigValue<Boolean> turtlesNeedFuel;
private static ConfigValue<Integer> turtleFuelLimit;
private static ConfigValue<Integer> advancedTurtleFuelLimit;
private static ConfigValue<Boolean> turtlesObeyBlockProtection;
private static ConfigValue<Boolean> turtlesCanPush;
private static ConfigValue<List<? extends String>> turtleDisabledActions;
private static final ForgeConfigSpec spec;
private Config() {}
static
{
Builder builder = new Builder();
{ // General computers
computerSpaceLimit = builder
.comment( "The disk space limit for computers and turtles, in bytes" )
.translation( TRANSLATION_PREFIX + "computer_space_limit" )
.define( "computer_space_limit", ComputerCraft.computerSpaceLimit );
floppySpaceLimit = builder
.comment( "The disk space limit for floppy disks, in bytes" )
.translation( TRANSLATION_PREFIX + "floppy_space_limit" )
.define( "floppy_space_limit", ComputerCraft.floppySpaceLimit );
maximumFilesOpen = builder
.comment( "Set how many files a computer can have open at the same time. Set to 0 for unlimited." )
.translation( TRANSLATION_PREFIX + "maximum_open_files" )
.defineInRange( "maximum_open_files", ComputerCraft.maximumFilesOpen, 0, Integer.MAX_VALUE );
disableLua51Features = builder
.comment( "Set this to true to disable Lua 5.1 functions that will be removed in a future update. " +
"Useful for ensuring forward compatibility of your programs now." )
.define( "disable_lua51_features", ComputerCraft.disable_lua51_features );
defaultComputerSettings = builder
.comment( "A comma separated list of default system settings to set on new computers. Example: " +
"\"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\" will disable all " +
"autocompletion" )
.define( "default_computer_settings", ComputerCraft.default_computer_settings );
debugEnabled = builder
.comment( "Enable Lua's debug library. This is sandboxed to each computer, so is generally safe to be used by players." )
.define( "debug_enabled", ComputerCraft.debug_enable );
logComputerErrors = builder
.comment( "Log exceptions thrown by peripherals and other Lua objects.\n" +
"This makes it easier for mod authors to debug problems, but may result in log spam should people use buggy methods." )
.define( "log_computer_errors", ComputerCraft.logPeripheralErrors );
}
{
builder.comment( "Controls execution behaviour of computers. This is largely intended for fine-tuning " +
"servers, and generally shouldn't need to be touched" );
builder.push( "execution" );
computerThreads = builder
.comment( "Set the number of threads computers can run on. A higher number means more computers can run " +
"at once, but may induce lag.\n" +
"Please note that some mods may not work with a thread count higher than 1. Use with caution." )
.worldRestart()
.defineInRange( "computer_threads", ComputerCraft.computer_threads, 1, Integer.MAX_VALUE );
maxMainGlobalTime = builder
.comment( "The maximum time that can be spent executing tasks in a single tick, in milliseconds.\n" +
"Note, we will quite possibly go over this limit, as there's no way to tell how long a will take " +
"- this aims to be the upper bound of the average time." )
.defineInRange( "max_main_global_time", (int) TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainGlobalTime ), 1, Integer.MAX_VALUE );
maxMainComputerTime = builder
.comment( "The ideal maximum time a computer can execute for in a tick, in milliseconds.\n" +
"Note, we will quite possibly go over this limit, as there's no way to tell how long a will take " +
"- this aims to be the upper bound of the average time." )
.defineInRange( "max_main_computer_time", (int) TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainComputerTime ), 1, Integer.MAX_VALUE );
builder.pop();
}
{ // HTTP
builder.comment( "Controls the HTTP API" );
builder.push( "http" );
httpEnabled = builder
.comment( "Enable the \"http\" API on Computers (see \"http_whitelist\" and \"http_blacklist\" for more " +
"fine grained control than this)" )
.define( "enabled", ComputerCraft.http_enable );
httpWebsocketEnabled = builder
.comment( "Enable use of http websockets. This requires the \"http_enable\" option to also be true." )
.define( "websocket_enabled", ComputerCraft.http_websocket_enable );
httpWhitelist = builder
.comment( "A list of wildcards for domains or IP ranges that can be accessed through the \"http\" API on Computers.\n" +
"Set this to \"*\" to access to the entire internet. Example: \"*.pastebin.com\" will restrict access to just subdomains of pastebin.com.\n" +
"You can use domain names (\"pastebin.com\"), wilcards (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\")." )
.defineList( "whitelist", Arrays.asList( DEFAULT_HTTP_WHITELIST ), x -> true );
httpBlacklist = builder
.comment( "A list of wildcards for domains or IP ranges that cannot be accessed through the \"http\" API on Computers.\n" +
"If this is empty then all whitelisted domains will be accessible. Example: \"*.github.com\" will block access to all subdomains of github.com.\n" +
"You can use domain names (\"pastebin.com\"), wilcards (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\")." )
.defineList( "blacklist", Arrays.asList( DEFAULT_HTTP_BLACKLIST ), x -> true );
httpTimeout = builder
.comment( "The period of time (in milliseconds) to wait before a HTTP request times out. Set to 0 for unlimited." )
.defineInRange( "timeout", ComputerCraft.httpTimeout, 0, Integer.MAX_VALUE );
httpMaxRequests = builder
.comment( "The number of http requests a computer can make at one time. Additional requests will be queued, and sent when the running requests have finished. Set to 0 for unlimited." )
.defineInRange( "max_requests", ComputerCraft.httpMaxRequests, 0, Integer.MAX_VALUE );
httpMaxDownload = builder
.comment( "The maximum size (in bytes) that a computer can download in a single request. Note that responses may receive more data than allowed, but this data will not be returned to the client." )
.defineInRange( "max_download", (int) ComputerCraft.httpMaxDownload, 0, Integer.MAX_VALUE );
httpMaxUpload = builder
.comment( "The maximum size (in bytes) that a computer can upload in a single request. This includes headers and POST text." )
.defineInRange( "max_upload", (int) ComputerCraft.httpMaxUpload, 0, Integer.MAX_VALUE );
httpMaxWebsockets = builder
.comment( "The number of websockets a computer can have open at one time. Set to 0 for unlimited." )
.defineInRange( "max_websockets", ComputerCraft.httpMaxWebsockets, 1, Integer.MAX_VALUE );
httpMaxWebsocketMessage = builder
.comment( "The maximum size (in bytes) that a computer can send or receive in one websocket packet." )
.defineInRange( "max_websocket_message", ComputerCraft.httpMaxWebsocketMessage, 0, Websocket.MAX_MESSAGE_SIZE );
builder.pop();
}
{ // Peripherals
builder.comment( "Various options relating to peripherals." );
builder.push( "peripheral" );
commandBlockEnabled = builder
.comment( "Enable Command Block peripheral support" )
.define( "command_block_enabled", ComputerCraft.enableCommandBlock );
modemRange = builder
.comment( "The range of Wireless Modems at low altitude in clear weather, in meters" )
.defineInRange( "modem_range", ComputerCraft.modem_range, 0, MODEM_MAX_RANGE );
modemHighAltitudeRange = builder
.comment( "The range of Wireless Modems at maximum altitude in clear weather, in meters" )
.defineInRange( "modem_high_altitude_range", ComputerCraft.modem_highAltitudeRange, 0, MODEM_MAX_RANGE );
modemRangeDuringStorm = builder
.comment( "The range of Wireless Modems at low altitude in stormy weather, in meters" )
.defineInRange( "modem_range_during_storm", ComputerCraft.modem_rangeDuringStorm, 0, MODEM_MAX_RANGE );
modemHighAltitudeRangeDuringStorm = builder
.comment( "The range of Wireless Modems at maximum altitude in stormy weather, in meters" )
.defineInRange( "modem_high_altitude_range_during_storm", ComputerCraft.modem_highAltitudeRangeDuringStorm, 0, MODEM_MAX_RANGE );
maxNotesPerTick = builder
.comment( "Maximum amount of notes a speaker can play at once" )
.defineInRange( "max_notes_per_tick", ComputerCraft.maxNotesPerTick, 1, Integer.MAX_VALUE );
builder.pop();
}
{ // Turtles
builder.comment( "Various options relating to turtles." );
builder.push( "turtle" );
turtlesNeedFuel = builder
.comment( "Set whether Turtles require fuel to move" )
.define( "need_fuel", ComputerCraft.turtlesNeedFuel );
turtleFuelLimit = builder
.comment( "The fuel limit for Turtles" )
.defineInRange( "normal_fuel_limit", ComputerCraft.turtleFuelLimit, 0, Integer.MAX_VALUE );
advancedTurtleFuelLimit = builder
.comment( "The fuel limit for Advanced Turtles" )
.defineInRange( "advanced_fuel_limit", ComputerCraft.advancedTurtleFuelLimit, 0, Integer.MAX_VALUE );
turtlesObeyBlockProtection = builder
.comment( "If set to true, Turtles will be unable to build, dig, or enter protected areas (such as near the server spawn point)" )
.define( "obey_block_protection", ComputerCraft.turtlesObeyBlockProtection );
turtlesCanPush = builder
.comment( "If set to true, Turtles will push entities out of the way instead of stopping if there is space to do so" )
.define( "can_push", ComputerCraft.turtlesCanPush );
turtleDisabledActions = builder
.comment( "A list of turtle actions which are disabled." )
.defineList( "disabled_actions", Collections.emptyList(), x -> x instanceof String && getAction( (String) x ) != null );
builder.pop();
}
spec = builder.build();
}
public static void load()
{
ModLoadingContext.get().registerConfig( ModConfig.Type.COMMON, spec );
}
public static void sync()
{
// General
ComputerCraft.computerSpaceLimit = computerSpaceLimit.get();
ComputerCraft.floppySpaceLimit = floppySpaceLimit.get();
ComputerCraft.maximumFilesOpen = maximumFilesOpen.get();
ComputerCraft.disable_lua51_features = disableLua51Features.get();
ComputerCraft.default_computer_settings = defaultComputerSettings.get();
ComputerCraft.debug_enable = debugEnabled.get();
ComputerCraft.computer_threads = computerThreads.get();
ComputerCraft.logPeripheralErrors = logComputerErrors.get();
// Execution
ComputerCraft.computer_threads = computerThreads.get();
ComputerCraft.maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos( maxMainGlobalTime.get() );
ComputerCraft.maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos( maxMainComputerTime.get() );
// HTTP
ComputerCraft.http_enable = httpEnabled.get();
ComputerCraft.http_websocket_enable = httpWebsocketEnabled.get();
ComputerCraft.http_whitelist = new AddressPredicate( httpWhitelist.get() );
ComputerCraft.http_blacklist = new AddressPredicate( httpBlacklist.get() );
ComputerCraft.httpTimeout = httpTimeout.get();
ComputerCraft.httpMaxRequests = httpMaxRequests.get();
ComputerCraft.httpMaxDownload = httpMaxDownload.get();
ComputerCraft.httpMaxUpload = httpMaxUpload.get();
ComputerCraft.httpMaxWebsockets = httpMaxWebsockets.get();
ComputerCraft.httpMaxWebsocketMessage = httpMaxWebsocketMessage.get();
// Peripheral
ComputerCraft.enableCommandBlock = commandBlockEnabled.get();
ComputerCraft.maxNotesPerTick = maxNotesPerTick.get();
ComputerCraft.modem_range = modemRange.get();
ComputerCraft.modem_highAltitudeRange = modemHighAltitudeRange.get();
ComputerCraft.modem_rangeDuringStorm = modemRangeDuringStorm.get();
ComputerCraft.modem_highAltitudeRangeDuringStorm = modemHighAltitudeRangeDuringStorm.get();
// Turtles
ComputerCraft.turtlesNeedFuel = turtlesNeedFuel.get();
ComputerCraft.turtleFuelLimit = turtleFuelLimit.get();
ComputerCraft.advancedTurtleFuelLimit = advancedTurtleFuelLimit.get();
ComputerCraft.turtlesObeyBlockProtection = turtlesObeyBlockProtection.get();
ComputerCraft.turtlesCanPush = turtlesCanPush.get();
ComputerCraft.turtleDisabledActions.clear();
for( String value : turtleDisabledActions.get() ) ComputerCraft.turtleDisabledActions.add( getAction( value ) );
}
@SubscribeEvent
public static void sync( ModConfig.Loading event )
{
sync();
}
@SubscribeEvent
public static void sync( ModConfig.ConfigReloading event )
{
sync();
}
private static final Converter<String, String> converter = CaseFormat.LOWER_CAMEL.converterTo( CaseFormat.UPPER_UNDERSCORE );
private static TurtleAction getAction( String value )
{
try
{
return TurtleAction.valueOf( converter.convert( value ) );
}
catch( IllegalArgumentException e )
{
return null;
}
}
}

View File

@@ -9,8 +9,8 @@ package dan200.computercraft.shared;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider; import dan200.computercraft.api.peripheral.IPeripheralProvider;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -30,12 +30,12 @@ public final class Peripherals
providers.add( provider ); providers.add( provider );
} }
public static IPeripheral getPeripheral( World world, BlockPos pos, EnumFacing side ) public static IPeripheral getPeripheral( World world, BlockPos pos, Direction side )
{ {
return World.isValid( pos ) && !world.isRemote ? getPeripheralAt( world, pos, side ) : null; return World.isValid( pos ) && !world.isClient ? getPeripheralAt( world, pos, side ) : null;
} }
private static IPeripheral getPeripheralAt( World world, BlockPos pos, EnumFacing side ) private static IPeripheral getPeripheralAt( World world, BlockPos pos, Direction side )
{ {
// Try the handlers in order: // Try the handlers in order:
for( IPeripheralProvider peripheralProvider : providers ) for( IPeripheralProvider peripheralProvider : providers )

View File

@@ -10,17 +10,13 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.InventoryUtil;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModLoadingContext;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*; import java.util.*;
public final class PocketUpgrades public final class PocketUpgrades
{ {
private static final Map<String, IPocketUpgrade> upgrades = new HashMap<>(); private static final Map<String, IPocketUpgrade> upgrades = new HashMap<>();
private static final IdentityHashMap<IPocketUpgrade, String> upgradeOwners = new IdentityHashMap<>();
private PocketUpgrades() {} private PocketUpgrades() {}
@@ -36,9 +32,6 @@ public final class PocketUpgrades
} }
upgrades.put( id, upgrade ); upgrades.put( id, upgrade );
ModContainer mc = ModLoadingContext.get().getActiveContainer();
if( mc != null && mc.getModId() != null ) upgradeOwners.put( upgrade, mc.getModId() );
} }
public static IPocketUpgrade get( String id ) public static IPocketUpgrade get( String id )
@@ -65,12 +58,6 @@ public final class PocketUpgrades
return null; return null;
} }
@Nullable
public static String getOwner( IPocketUpgrade upgrade )
{
return upgradeOwners.get( upgrade );
}
public static Iterable<IPocketUpgrade> getVanillaUpgrades() public static Iterable<IPocketUpgrade> getVanillaUpgrades()
{ {
List<IPocketUpgrade> vanilla = new ArrayList<>(); List<IPocketUpgrade> vanilla = new ArrayList<>();

View File

@@ -8,14 +8,18 @@ package dan200.computercraft.shared;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.shared.common.ColourableRecipe;
import dan200.computercraft.shared.computer.blocks.BlockComputer; import dan200.computercraft.shared.computer.blocks.BlockComputer;
import dan200.computercraft.shared.computer.blocks.TileCommandComputer; import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
import dan200.computercraft.shared.computer.blocks.TileComputer; import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.items.ItemComputer; import dan200.computercraft.shared.computer.items.ItemComputer;
import dan200.computercraft.shared.computer.recipe.ComputerUpgradeRecipe;
import dan200.computercraft.shared.media.items.ItemDisk; import dan200.computercraft.shared.media.items.ItemDisk;
import dan200.computercraft.shared.media.items.ItemPrintout; import dan200.computercraft.shared.media.items.ItemPrintout;
import dan200.computercraft.shared.media.items.ItemTreasureDisk; import dan200.computercraft.shared.media.items.ItemTreasureDisk;
import dan200.computercraft.shared.media.recipes.DiskRecipe;
import dan200.computercraft.shared.media.recipes.PrintoutRecipe;
import dan200.computercraft.shared.peripheral.diskdrive.BlockDiskDrive; import dan200.computercraft.shared.peripheral.diskdrive.BlockDiskDrive;
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive; import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
import dan200.computercraft.shared.peripheral.modem.wired.*; import dan200.computercraft.shared.peripheral.modem.wired.*;
@@ -30,239 +34,215 @@ import dan200.computercraft.shared.peripheral.speaker.TileSpeaker;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.pocket.peripherals.PocketModem; import dan200.computercraft.shared.pocket.peripherals.PocketModem;
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker; import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
import dan200.computercraft.shared.pocket.recipes.PocketComputerUpgradeRecipe;
import dan200.computercraft.shared.turtle.blocks.BlockTurtle; import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
import dan200.computercraft.shared.turtle.blocks.TileTurtle; import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.core.TurtlePlayer;
import dan200.computercraft.shared.turtle.items.ItemTurtle; import dan200.computercraft.shared.turtle.items.ItemTurtle;
import dan200.computercraft.shared.turtle.recipes.TurtleRecipe;
import dan200.computercraft.shared.turtle.recipes.TurtleUpgradeRecipe;
import dan200.computercraft.shared.turtle.upgrades.*; import dan200.computercraft.shared.turtle.upgrades.*;
import dan200.computercraft.shared.util.CreativeTabMain; import dan200.computercraft.shared.util.ImpostorRecipe;
import dan200.computercraft.shared.util.ImpostorShapelessRecipe;
import net.fabricmc.fabric.api.block.FabricBlockSettings;
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.material.Material; import net.minecraft.block.Material;
import net.minecraft.entity.EntityType; import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.init.Items; import net.minecraft.item.*;
import net.minecraft.item.Item; import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.item.ItemBlock; import net.minecraft.util.Identifier;
import net.minecraft.item.ItemGroup; import net.minecraft.util.registry.MutableRegistry;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.registries.IForgeRegistry;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD )
public final class Registry public final class Registry
{ {
private static final ItemGroup mainItemGroup = new CreativeTabMain(); private static final ItemGroup mainItemGroup = FabricItemGroupBuilder
.create( new Identifier( ComputerCraft.MOD_ID, "main" ) )
.icon( () -> new ItemStack( ComputerCraft.Items.computerNormal ) )
.build();
private Registry() private Registry()
{ {
} }
@SubscribeEvent public static void registerBlocks( MutableRegistry<Block> registry )
public static void registerBlocks( RegistryEvent.Register<Block> event )
{ {
IForgeRegistry<Block> registry = event.getRegistry();
// Computers // Computers
ComputerCraft.Blocks.computerNormal = new BlockComputer( ComputerCraft.Blocks.computerNormal = new BlockComputer(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2.0f ), FabricBlockSettings.of( Material.STONE ).hardness( 2.0f ).build(),
ComputerFamily.Normal, TileComputer.FACTORY_NORMAL ComputerFamily.Normal, TileComputer.FACTORY_NORMAL
); );
ComputerCraft.Blocks.computerAdvanced = new BlockComputer( ComputerCraft.Blocks.computerAdvanced = new BlockComputer(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2.0f ), FabricBlockSettings.of( Material.STONE ).hardness( 2.0f ).build(),
ComputerFamily.Advanced, TileComputer.FACTORY_ADVANCED ComputerFamily.Advanced, TileComputer.FACTORY_ADVANCED
); );
ComputerCraft.Blocks.computerCommand = new BlockComputer( ComputerCraft.Blocks.computerCommand = new BlockComputer(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( -1, 6000000.0F ), FabricBlockSettings.of( Material.STONE ).strength( -1, 6000000.0F ).build(),
ComputerFamily.Command, TileCommandComputer.FACTORY ComputerFamily.Command, TileCommandComputer.FACTORY
); );
registry.registerAll( registry.add( new Identifier( ComputerCraft.MOD_ID, "computer_normal" ), ComputerCraft.Blocks.computerNormal );
ComputerCraft.Blocks.computerNormal.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "computer_normal" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "computer_advanced" ), ComputerCraft.Blocks.computerAdvanced );
ComputerCraft.Blocks.computerAdvanced.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "computer_advanced" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "computer_command" ), ComputerCraft.Blocks.computerCommand );
ComputerCraft.Blocks.computerCommand.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "computer_command" ) )
);
// Turtles // Turtles
ComputerCraft.Blocks.turtleNormal = new BlockTurtle( ComputerCraft.Blocks.turtleNormal = new BlockTurtle(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2.5f ), FabricBlockSettings.of( Material.STONE ).hardness( 2.5f ).build(),
ComputerFamily.Normal, TileTurtle.FACTORY_NORMAL ComputerFamily.Normal, TileTurtle.FACTORY_NORMAL
); );
ComputerCraft.Blocks.turtleAdvanced = new BlockTurtle( ComputerCraft.Blocks.turtleAdvanced = new BlockTurtle(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2.5f ), FabricBlockSettings.of( Material.STONE ).hardness( 2.5f ).build(),
ComputerFamily.Advanced, TileTurtle.FACTORY_ADVANCED ComputerFamily.Advanced, TileTurtle.FACTORY_ADVANCED
); );
registry.registerAll( registry.add( new Identifier( ComputerCraft.MOD_ID, "turtle_normal" ), ComputerCraft.Blocks.turtleNormal );
ComputerCraft.Blocks.turtleNormal.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_normal" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "turtle_advanced" ), ComputerCraft.Blocks.turtleAdvanced );
ComputerCraft.Blocks.turtleAdvanced.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_advanced" ) )
);
// Peripherals // Peripherals
ComputerCraft.Blocks.speaker = new BlockSpeaker( ComputerCraft.Blocks.speaker = new BlockSpeaker(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2 ) FabricBlockSettings.of( Material.STONE ).hardness( 2 ).build()
); );
ComputerCraft.Blocks.diskDrive = new BlockDiskDrive( ComputerCraft.Blocks.diskDrive = new BlockDiskDrive(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2 ) FabricBlockSettings.of( Material.STONE ).hardness( 2 ).build()
); );
ComputerCraft.Blocks.monitorNormal = new BlockMonitor( ComputerCraft.Blocks.monitorNormal = new BlockMonitor(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2 ), FabricBlockSettings.of( Material.STONE ).hardness( 2 ).build(),
TileMonitor.FACTORY_NORMAL TileMonitor.FACTORY_NORMAL
); );
ComputerCraft.Blocks.monitorAdvanced = new BlockMonitor( ComputerCraft.Blocks.monitorAdvanced = new BlockMonitor(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2 ), FabricBlockSettings.of( Material.STONE ).hardness( 2 ).build(),
TileMonitor.FACTORY_ADVANCED TileMonitor.FACTORY_ADVANCED
); );
ComputerCraft.Blocks.printer = new BlockPrinter( ComputerCraft.Blocks.printer = new BlockPrinter(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2 ) FabricBlockSettings.of( Material.STONE ).hardness( 2 ).build()
); );
ComputerCraft.Blocks.wirelessModemNormal = new BlockWirelessModem( ComputerCraft.Blocks.wirelessModemNormal = new BlockWirelessModem(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2 ), FabricBlockSettings.of( Material.STONE ).hardness( 2 ).build(),
TileWirelessModem.FACTORY_NORMAL TileWirelessModem.FACTORY_NORMAL
); );
ComputerCraft.Blocks.wirelessModemAdvanced = new BlockWirelessModem( ComputerCraft.Blocks.wirelessModemAdvanced = new BlockWirelessModem(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2 ), FabricBlockSettings.of( Material.STONE ).hardness( 2 ).build(),
TileWirelessModem.FACTORY_ADVANCED TileWirelessModem.FACTORY_ADVANCED
); );
ComputerCraft.Blocks.wiredModemFull = new BlockWiredModemFull( ComputerCraft.Blocks.wiredModemFull = new BlockWiredModemFull(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 1.5f ) FabricBlockSettings.of( Material.STONE ).hardness( 1.5f ).build()
); );
ComputerCraft.Blocks.cable = new BlockCable( ComputerCraft.Blocks.cable = new BlockCable(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( 1.5f ) FabricBlockSettings.of( Material.STONE ).hardness( 1.5f ).build()
); );
registry.registerAll( registry.add( new Identifier( ComputerCraft.MOD_ID, "speaker" ), ComputerCraft.Blocks.speaker );
ComputerCraft.Blocks.speaker.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "speaker" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "disk_drive" ), ComputerCraft.Blocks.diskDrive );
ComputerCraft.Blocks.diskDrive.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "disk_drive" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "monitor_normal" ), ComputerCraft.Blocks.monitorNormal );
ComputerCraft.Blocks.monitorNormal.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "monitor_normal" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "monitor_advanced" ), ComputerCraft.Blocks.monitorAdvanced );
ComputerCraft.Blocks.monitorAdvanced.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "monitor_advanced" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "printer" ), ComputerCraft.Blocks.printer );
ComputerCraft.Blocks.printer.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "printer" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "wireless_modem_normal" ), ComputerCraft.Blocks.wirelessModemNormal );
ComputerCraft.Blocks.wirelessModemNormal.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "wireless_modem_normal" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "wireless_modem_advanced" ), ComputerCraft.Blocks.wirelessModemAdvanced );
ComputerCraft.Blocks.wirelessModemAdvanced.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "wireless_modem_advanced" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "wired_modem_full" ), ComputerCraft.Blocks.wiredModemFull );
ComputerCraft.Blocks.wiredModemFull.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "cable" ), ComputerCraft.Blocks.cable );
ComputerCraft.Blocks.cable.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "cable" ) )
);
} }
@SubscribeEvent public static void registerTileEntities( MutableRegistry<BlockEntityType<?>> registry )
public static void registerTileEntities( RegistryEvent.Register<TileEntityType<?>> event )
{ {
IForgeRegistry<TileEntityType<?>> registry = event.getRegistry();
// Computers // Computers
registry.registerAll( TileComputer.FACTORY_NORMAL, TileComputer.FACTORY_ADVANCED, TileCommandComputer.FACTORY ); registry.add( TileComputer.FACTORY_NORMAL.getId(), TileComputer.FACTORY_NORMAL );
registry.add( TileComputer.FACTORY_ADVANCED.getId(), TileComputer.FACTORY_ADVANCED );
registry.add( TileCommandComputer.FACTORY.getId(), TileCommandComputer.FACTORY );
// Turtles // Turtles
registry.registerAll( TileTurtle.FACTORY_NORMAL, TileTurtle.FACTORY_ADVANCED ); registry.add( TileTurtle.FACTORY_NORMAL.getId(), TileTurtle.FACTORY_NORMAL );
registry.add( TileTurtle.FACTORY_ADVANCED.getId(), TileTurtle.FACTORY_ADVANCED );
// Peripherals // Peripherals
registry.registerAll( registry.add( TileSpeaker.FACTORY.getId(), TileSpeaker.FACTORY );
TileSpeaker.FACTORY, registry.add( TileDiskDrive.FACTORY.getId(), TileDiskDrive.FACTORY );
TileDiskDrive.FACTORY, registry.add( TilePrinter.FACTORY.getId(), TilePrinter.FACTORY );
TileMonitor.FACTORY_NORMAL,
TileMonitor.FACTORY_ADVANCED, registry.add( TileMonitor.FACTORY_NORMAL.getId(), TileMonitor.FACTORY_NORMAL );
TilePrinter.FACTORY, registry.add( TileMonitor.FACTORY_ADVANCED.getId(), TileMonitor.FACTORY_ADVANCED );
TileWirelessModem.FACTORY_NORMAL,
TileWirelessModem.FACTORY_ADVANCED, registry.add( TileWirelessModem.FACTORY_NORMAL.getId(), TileWirelessModem.FACTORY_NORMAL );
TileWiredModemFull.FACTORY, registry.add( TileWirelessModem.FACTORY_ADVANCED.getId(), TileWirelessModem.FACTORY_ADVANCED );
TileCable.FACTORY registry.add( TileCable.FACTORY.getId(), TileCable.FACTORY );
); registry.add( TileWiredModemFull.FACTORY.getId(), TileWiredModemFull.FACTORY );
} }
private static <T extends ItemBlock> T setupItemBlock( T item ) private static void registerItemBlock( MutableRegistry<Item> registry, BlockItem item )
{ {
item.setRegistryName( item.getBlock().getRegistryName() ); registry.add( net.minecraft.util.registry.Registry.BLOCK.getId( item.getBlock() ), item );
return item;
} }
private static Item.Properties defaultItem() private static Item.Settings defaultItem()
{ {
return new Item.Properties().group( mainItemGroup ); return new Item.Settings().itemGroup( mainItemGroup );
} }
@SubscribeEvent public static void registerItems( MutableRegistry<Item> registry )
public static void registerItems( RegistryEvent.Register<Item> event )
{ {
IForgeRegistry<Item> registry = event.getRegistry();
// Computer // Computer
ComputerCraft.Items.computerNormal = new ItemComputer( ComputerCraft.Blocks.computerNormal, defaultItem() ); ComputerCraft.Items.computerNormal = new ItemComputer( ComputerCraft.Blocks.computerNormal, defaultItem() );
ComputerCraft.Items.computerAdvanced = new ItemComputer( ComputerCraft.Blocks.computerAdvanced, defaultItem() ); ComputerCraft.Items.computerAdvanced = new ItemComputer( ComputerCraft.Blocks.computerAdvanced, defaultItem() );
ComputerCraft.Items.computerCommand = new ItemComputer( ComputerCraft.Blocks.computerCommand, defaultItem() ); ComputerCraft.Items.computerCommand = new ItemComputer( ComputerCraft.Blocks.computerCommand, defaultItem() );
registry.registerAll( registerItemBlock( registry, ComputerCraft.Items.computerNormal );
setupItemBlock( ComputerCraft.Items.computerNormal ), registerItemBlock( registry, ComputerCraft.Items.computerAdvanced );
setupItemBlock( ComputerCraft.Items.computerAdvanced ), registerItemBlock( registry, ComputerCraft.Items.computerCommand );
setupItemBlock( ComputerCraft.Items.computerCommand )
);
// Turtle // Turtle
ComputerCraft.Items.turtleNormal = new ItemTurtle( ComputerCraft.Blocks.turtleNormal, defaultItem() ); ComputerCraft.Items.turtleNormal = new ItemTurtle( ComputerCraft.Blocks.turtleNormal, defaultItem() );
ComputerCraft.Items.turtleAdvanced = new ItemTurtle( ComputerCraft.Blocks.turtleAdvanced, defaultItem() ); ComputerCraft.Items.turtleAdvanced = new ItemTurtle( ComputerCraft.Blocks.turtleAdvanced, defaultItem() );
registry.registerAll(
setupItemBlock( ComputerCraft.Items.turtleNormal ), registerItemBlock( registry, ComputerCraft.Items.turtleNormal );
setupItemBlock( ComputerCraft.Items.turtleAdvanced ) registerItemBlock( registry, ComputerCraft.Items.turtleAdvanced );
);
// Pocket computer // Pocket computer
ComputerCraft.Items.pocketComputerNormal = new ItemPocketComputer( defaultItem().maxStackSize( 1 ), ComputerFamily.Normal ); ComputerCraft.Items.pocketComputerNormal = new ItemPocketComputer( defaultItem().stackSize( 1 ), ComputerFamily.Normal );
ComputerCraft.Items.pocketComputerAdvanced = new ItemPocketComputer( defaultItem().maxStackSize( 1 ), ComputerFamily.Advanced ); ComputerCraft.Items.pocketComputerAdvanced = new ItemPocketComputer( defaultItem().stackSize( 1 ), ComputerFamily.Advanced );
registry.registerAll( registry.add( new Identifier( ComputerCraft.MOD_ID, "pocket_computer_normal" ), ComputerCraft.Items.pocketComputerNormal );
ComputerCraft.Items.pocketComputerNormal.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "pocket_computer_normal" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "pocket_computer_advanced" ), ComputerCraft.Items.pocketComputerAdvanced );
ComputerCraft.Items.pocketComputerAdvanced.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "pocket_computer_advanced" ) )
);
// Floppy disk // Floppy disk
ComputerCraft.Items.disk = new ItemDisk( defaultItem().maxStackSize( 1 ) ); ComputerCraft.Items.disk = new ItemDisk( defaultItem().stackSize( 1 ) );
ComputerCraft.Items.treasureDisk = new ItemTreasureDisk( defaultItem().maxStackSize( 1 ) ); ComputerCraft.Items.treasureDisk = new ItemTreasureDisk( defaultItem().stackSize( 1 ) );
registry.registerAll( registry.add( new Identifier( ComputerCraft.MOD_ID, "disk" ), ComputerCraft.Items.disk );
ComputerCraft.Items.disk.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "disk" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "treasure_disk" ), ComputerCraft.Items.treasureDisk );
ComputerCraft.Items.treasureDisk.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "treasure_disk" ) )
);
// Printouts // Printouts
ComputerCraft.Items.printedPage = new ItemPrintout( defaultItem().maxStackSize( 1 ), ItemPrintout.Type.PAGE ); ComputerCraft.Items.printedPage = new ItemPrintout( defaultItem().stackSize( 1 ), ItemPrintout.Type.PAGE );
ComputerCraft.Items.printedPages = new ItemPrintout( defaultItem().maxStackSize( 1 ), ItemPrintout.Type.PAGES ); ComputerCraft.Items.printedPages = new ItemPrintout( defaultItem().stackSize( 1 ), ItemPrintout.Type.PAGES );
ComputerCraft.Items.printedBook = new ItemPrintout( defaultItem().maxStackSize( 1 ), ItemPrintout.Type.BOOK ); ComputerCraft.Items.printedBook = new ItemPrintout( defaultItem().stackSize( 1 ), ItemPrintout.Type.BOOK );
registry.registerAll( registry.add( new Identifier( ComputerCraft.MOD_ID, "printed_page" ), ComputerCraft.Items.printedPage );
ComputerCraft.Items.printedPage.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "printed_page" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "printed_pages" ), ComputerCraft.Items.printedPages );
ComputerCraft.Items.printedPages.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "printed_pages" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "printed_book" ), ComputerCraft.Items.printedBook );
ComputerCraft.Items.printedBook.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "printed_book" ) )
);
// Peripherals // Peripherals
registry.registerAll( registerItemBlock( registry, new BlockItem( ComputerCraft.Blocks.speaker, defaultItem() ) );
setupItemBlock( new ItemBlock( ComputerCraft.Blocks.speaker, defaultItem() ) ), registerItemBlock( registry, new BlockItem( ComputerCraft.Blocks.diskDrive, defaultItem() ) );
setupItemBlock( new ItemBlock( ComputerCraft.Blocks.diskDrive, defaultItem() ) ), registerItemBlock( registry, new BlockItem( ComputerCraft.Blocks.printer, defaultItem() ) );
setupItemBlock( new ItemBlock( ComputerCraft.Blocks.printer, defaultItem() ) ), registerItemBlock( registry, new BlockItem( ComputerCraft.Blocks.monitorNormal, defaultItem() ) );
setupItemBlock( new ItemBlock( ComputerCraft.Blocks.monitorNormal, defaultItem() ) ), registerItemBlock( registry, new BlockItem( ComputerCraft.Blocks.monitorAdvanced, defaultItem() ) );
setupItemBlock( new ItemBlock( ComputerCraft.Blocks.monitorAdvanced, defaultItem() ) ), registerItemBlock( registry, new BlockItem( ComputerCraft.Blocks.wirelessModemNormal, defaultItem() ) );
setupItemBlock( new ItemBlock( ComputerCraft.Blocks.wirelessModemNormal, defaultItem() ) ), registerItemBlock( registry, new BlockItem( ComputerCraft.Blocks.wirelessModemAdvanced, defaultItem() ) );
setupItemBlock( new ItemBlock( ComputerCraft.Blocks.wirelessModemAdvanced, defaultItem() ) ), registerItemBlock( registry, new BlockItem( ComputerCraft.Blocks.wiredModemFull, defaultItem() ) );
setupItemBlock( new ItemBlock( ComputerCraft.Blocks.wiredModemFull, defaultItem() ) )
);
ComputerCraft.Items.cable = new ItemBlockCable.Cable( ComputerCraft.Blocks.cable, defaultItem() ); ComputerCraft.Items.cable = new ItemBlockCable.Cable( ComputerCraft.Blocks.cable, defaultItem() );
ComputerCraft.Items.wiredModem = new ItemBlockCable.WiredModem( ComputerCraft.Blocks.cable, defaultItem() ); ComputerCraft.Items.wiredModem = new ItemBlockCable.WiredModem( ComputerCraft.Blocks.cable, defaultItem() );
registry.registerAll(
ComputerCraft.Items.cable.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "cable" ) ), registry.add( new Identifier( ComputerCraft.MOD_ID, "cable" ), ComputerCraft.Items.cable );
ComputerCraft.Items.wiredModem.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem" ) ) registry.add( new Identifier( ComputerCraft.MOD_ID, "wired_modem" ), ComputerCraft.Items.wiredModem );
);
registerTurtleUpgrades(); registerTurtleUpgrades();
registerPocketUpgrades(); registerPocketUpgrades();
@@ -271,31 +251,31 @@ public final class Registry
private static void registerTurtleUpgrades() private static void registerTurtleUpgrades()
{ {
// Upgrades // Upgrades
ComputerCraft.TurtleUpgrades.wirelessModemNormal = new TurtleModem( false, new ResourceLocation( ComputerCraft.MOD_ID, "wireless_modem_normal" ) ); ComputerCraft.TurtleUpgrades.wirelessModemNormal = new TurtleModem( false, new Identifier( ComputerCraft.MOD_ID, "wireless_modem_normal" ) );
TurtleUpgrades.register( ComputerCraft.TurtleUpgrades.wirelessModemNormal ); ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.wirelessModemNormal );
ComputerCraft.TurtleUpgrades.wirelessModemAdvanced = new TurtleModem( true, new ResourceLocation( ComputerCraft.MOD_ID, "wireless_modem_advanced" ) ); ComputerCraft.TurtleUpgrades.wirelessModemAdvanced = new TurtleModem( true, new Identifier( ComputerCraft.MOD_ID, "wireless_modem_advanced" ) );
ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.wirelessModemAdvanced ); ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.wirelessModemAdvanced );
ComputerCraft.TurtleUpgrades.speaker = new TurtleSpeaker( new ResourceLocation( ComputerCraft.MOD_ID, "speaker" ) ); ComputerCraft.TurtleUpgrades.speaker = new TurtleSpeaker( new Identifier( ComputerCraft.MOD_ID, "speaker" ) );
ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.speaker ); ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.speaker );
ComputerCraft.TurtleUpgrades.craftingTable = new TurtleCraftingTable( new ResourceLocation( "minecraft", "crafting_table" ) ); ComputerCraft.TurtleUpgrades.craftingTable = new TurtleCraftingTable( new Identifier( "minecraft", "crafting_table" ) );
ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.craftingTable ); ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.craftingTable );
ComputerCraft.TurtleUpgrades.diamondSword = new TurtleSword( new ResourceLocation( "minecraft", "diamond_sword" ), Items.DIAMOND_SWORD ); ComputerCraft.TurtleUpgrades.diamondSword = new TurtleSword( new Identifier( "minecraft", "diamond_sword" ), Items.DIAMOND_SWORD );
ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.diamondSword ); ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.diamondSword );
ComputerCraft.TurtleUpgrades.diamondShovel = new TurtleShovel( new ResourceLocation( "minecraft", "diamond_shovel" ), Items.DIAMOND_SHOVEL ); ComputerCraft.TurtleUpgrades.diamondShovel = new TurtleShovel( new Identifier( "minecraft", "diamond_shovel" ), Items.DIAMOND_SHOVEL );
ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.diamondShovel ); ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.diamondShovel );
ComputerCraft.TurtleUpgrades.diamondPickaxe = new TurtleTool( new ResourceLocation( "minecraft", "diamond_pickaxe" ), Items.DIAMOND_PICKAXE ); ComputerCraft.TurtleUpgrades.diamondPickaxe = new TurtleTool( new Identifier( "minecraft", "diamond_pickaxe" ), Items.DIAMOND_PICKAXE );
ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.diamondPickaxe ); ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.diamondPickaxe );
ComputerCraft.TurtleUpgrades.diamondAxe = new TurtleAxe( new ResourceLocation( "minecraft", "diamond_axe" ), Items.DIAMOND_AXE ); ComputerCraft.TurtleUpgrades.diamondAxe = new TurtleAxe( new Identifier( "minecraft", "diamond_axe" ), Items.DIAMOND_AXE );
ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.diamondAxe ); ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.diamondAxe );
ComputerCraft.TurtleUpgrades.diamondHoe = new TurtleHoe( new ResourceLocation( "minecraft", "diamond_hoe" ), Items.DIAMOND_HOE ); ComputerCraft.TurtleUpgrades.diamondHoe = new TurtleHoe( new Identifier( "minecraft", "diamond_hoe" ), Items.DIAMOND_HOE );
ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.diamondHoe ); ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.diamondHoe );
} }
@@ -306,9 +286,16 @@ public final class Registry
ComputerCraftAPI.registerPocketUpgrade( ComputerCraft.PocketUpgrades.speaker = new PocketSpeaker() ); ComputerCraftAPI.registerPocketUpgrade( ComputerCraft.PocketUpgrades.speaker = new PocketSpeaker() );
} }
@SubscribeEvent public static void registerRecipes( MutableRegistry<RecipeSerializer<?>> registry )
public static void registerEntities( RegistryEvent.Register<EntityType<?>> registry )
{ {
registry.getRegistry().register( TurtlePlayer.TYPE.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_player" ) ) ); registry.add( new Identifier( ComputerCraft.MOD_ID, "colour" ), ColourableRecipe.SERIALIZER );
registry.add( new Identifier( ComputerCraft.MOD_ID, "computer_upgrade" ), ComputerUpgradeRecipe.SERIALIZER );
registry.add( new Identifier( ComputerCraft.MOD_ID, "pocket_computer_upgrade" ), PocketComputerUpgradeRecipe.SERIALIZER );
registry.add( new Identifier( ComputerCraft.MOD_ID, "disk" ), DiskRecipe.SERIALIZER );
registry.add( new Identifier( ComputerCraft.MOD_ID, "printout" ), PrintoutRecipe.SERIALIZER );
registry.add( new Identifier( ComputerCraft.MOD_ID, "turtle" ), TurtleRecipe.SERIALIZER );
registry.add( new Identifier( ComputerCraft.MOD_ID, "turtle_upgrade" ), TurtleUpgradeRecipe.SERIALIZER );
registry.add( new Identifier( ComputerCraft.MOD_ID, "impostor_shaped" ), ImpostorRecipe.SERIALIZER );
registry.add( new Identifier( ComputerCraft.MOD_ID, "impostor_shapeless" ), ImpostorShapelessRecipe.SERIALIZER );
} }
} }

View File

@@ -6,32 +6,30 @@
package dan200.computercraft.shared; package dan200.computercraft.shared;
import com.google.common.eventbus.Subscribe;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.turtle.event.TurtleActionEvent; import dan200.computercraft.api.turtle.event.TurtleActionEvent;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID )
public final class TurtlePermissions public final class TurtlePermissions
{ {
public static boolean isBlockEnterable( World world, BlockPos pos, EntityPlayer player ) public static boolean isBlockEnterable( World world, BlockPos pos, PlayerEntity player )
{ {
MinecraftServer server = world.getServer(); MinecraftServer server = world.getServer();
return server == null || world.isRemote || !server.isBlockProtected( world, pos, player ); return server == null || world.isClient || !server.isSpawnProtected( world, pos, player );
} }
public static boolean isBlockEditable( World world, BlockPos pos, EntityPlayer player ) public static boolean isBlockEditable( World world, BlockPos pos, PlayerEntity player )
{ {
MinecraftServer server = world.getServer(); MinecraftServer server = world.getServer();
return server == null || world.isRemote || !server.isBlockProtected( world, pos, player ); return server == null || world.isClient || !server.isSpawnProtected( world, pos, player );
} }
@SubscribeEvent @Subscribe
public static void onTurtleAction( TurtleActionEvent event ) public void onTurtleAction( TurtleActionEvent event )
{ {
if( ComputerCraft.turtleDisabledActions.contains( event.getAction() ) ) if( ComputerCraft.turtleDisabledActions.contains( event.getAction() ) )
{ {

View File

@@ -11,17 +11,13 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.InventoryUtil;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModLoadingContext;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*; import java.util.*;
public final class TurtleUpgrades public final class TurtleUpgrades
{ {
private static final Map<String, ITurtleUpgrade> upgrades = new HashMap<>(); private static final Map<String, ITurtleUpgrade> upgrades = new HashMap<>();
private static final IdentityHashMap<ITurtleUpgrade, String> upgradeOwners = new IdentityHashMap<>();
private TurtleUpgrades() {} private TurtleUpgrades() {}
@@ -37,9 +33,6 @@ public final class TurtleUpgrades
} }
upgrades.put( id, upgrade ); upgrades.put( id, upgrade );
ModContainer mc = ModLoadingContext.get().getActiveContainer();
if( mc != null && mc.getModId() != null ) upgradeOwners.put( upgrade, mc.getModId() );
} }
@@ -84,12 +77,6 @@ public final class TurtleUpgrades
return vanilla; return vanilla;
} }
@Nullable
public static String getOwner( @Nonnull ITurtleUpgrade upgrade )
{
return upgradeOwners.get( upgrade );
}
public static Iterable<ITurtleUpgrade> getUpgrades() public static Iterable<ITurtleUpgrade> getUpgrades()
{ {
return Collections.unmodifiableCollection( upgrades.values() ); return Collections.unmodifiableCollection( upgrades.values() );

View File

@@ -21,16 +21,15 @@ import dan200.computercraft.shared.command.text.TableBuilder;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.network.Containers; import dan200.computercraft.shared.network.Containers;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.chat.Component;
import net.minecraft.network.play.server.SPacketPlayerPosLook; import net.minecraft.network.chat.TextComponent;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.*; import java.util.*;
@@ -45,7 +44,7 @@ import static dan200.computercraft.shared.command.builder.CommandBuilder.args;
import static dan200.computercraft.shared.command.builder.CommandBuilder.command; import static dan200.computercraft.shared.command.builder.CommandBuilder.command;
import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.choice; import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.choice;
import static dan200.computercraft.shared.command.text.ChatHelpers.*; import static dan200.computercraft.shared.command.text.ChatHelpers.*;
import static net.minecraft.command.Commands.literal; import static net.minecraft.server.command.CommandManager.literal;
public final class CommandComputerCraft public final class CommandComputerCraft
{ {
@@ -59,7 +58,7 @@ public final class CommandComputerCraft
{ {
} }
public static void register( CommandDispatcher<CommandSource> dispatcher ) public static void register( CommandDispatcher<ServerCommandSource> dispatcher )
{ {
dispatcher.register( choice( "computercraft" ) dispatcher.register( choice( "computercraft" )
.then( literal( "dump" ) .then( literal( "dump" )
@@ -67,17 +66,17 @@ public final class CommandComputerCraft
.executes( context -> { .executes( context -> {
TableBuilder table = new TableBuilder( DUMP_LIST_ID, "Computer", "On", "Position" ); TableBuilder table = new TableBuilder( DUMP_LIST_ID, "Computer", "On", "Position" );
CommandSource source = context.getSource(); ServerCommandSource source = context.getSource();
List<ServerComputer> computers = new ArrayList<>( ComputerCraft.serverComputerRegistry.getComputers() ); List<ServerComputer> computers = new ArrayList<>( ComputerCraft.serverComputerRegistry.getComputers() );
// Unless we're on a server, limit the number of rows we can send. // Unless we're on a server, limit the number of rows we can send.
World world = source.getWorld(); World world = source.getWorld();
BlockPos pos = new BlockPos( source.getPos() ); BlockPos pos = new BlockPos( source.getPosition() );
computers.sort( ( a, b ) -> { computers.sort( ( a, b ) -> {
if( a.getWorld() == b.getWorld() && a.getWorld() == world ) if( a.getWorld() == b.getWorld() && a.getWorld() == world )
{ {
return Double.compare( a.getPosition().distanceSq( pos ), b.getPosition().distanceSq( pos ) ); return Double.compare( a.getPosition().getSquaredDistance( pos ), b.getPosition().getSquaredDistance( pos ) );
} }
else if( a.getWorld() == world ) else if( a.getWorld() == world )
{ {
@@ -169,17 +168,17 @@ public final class CommandComputerCraft
if( world == null || pos == null ) throw TP_NOT_THERE.create(); if( world == null || pos == null ) throw TP_NOT_THERE.create();
Entity entity = context.getSource().assertIsEntity(); Entity entity = context.getSource().getEntityOrThrow();
if( !(entity instanceof EntityPlayerMP) ) throw TP_NOT_PLAYER.create(); if( !(entity instanceof ServerPlayerEntity) ) throw TP_NOT_PLAYER.create();
EntityPlayerMP player = (EntityPlayerMP) entity; ServerPlayerEntity player = (ServerPlayerEntity) entity;
if( player.getEntityWorld() == world ) if( player.getEntityWorld() == world )
{ {
player.connection.setPlayerLocation( pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, 0, 0, EnumSet.noneOf( SPacketPlayerPosLook.EnumFlags.class ) ); player.networkHandler.teleportRequest( pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, 0, 0, Collections.emptySet() );
} }
else else
{ {
player.teleport( (WorldServer) world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, 0, 0 ); player.teleport( (ServerWorld) world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, 0, 0 );
} }
return 1; return 1;
@@ -210,7 +209,7 @@ public final class CommandComputerCraft
.requires( UserLevel.OP ) .requires( UserLevel.OP )
.arg( "computer", oneComputer() ) .arg( "computer", oneComputer() )
.executes( context -> { .executes( context -> {
EntityPlayerMP player = context.getSource().asPlayer(); ServerPlayerEntity player = context.getSource().getPlayer();
ServerComputer computer = getComputerArgument( context, "computer" ); ServerComputer computer = getComputerArgument( context, "computer" );
Containers.openComputerGUI( player, computer ); Containers.openComputerGUI( player, computer );
return 1; return 1;
@@ -257,18 +256,18 @@ public final class CommandComputerCraft
); );
} }
private static ITextComponent linkComputer( CommandSource source, ServerComputer serverComputer, int computerId ) private static Component linkComputer( ServerCommandSource source, ServerComputer serverComputer, int computerId )
{ {
ITextComponent out = new TextComponentString( "" ); TextComponent out = new TextComponent( "" );
// Append the computer instance // Append the computer instance
if( serverComputer == null ) if( serverComputer == null )
{ {
out.appendSibling( text( "?" ) ); out.append( text( "?" ) );
} }
else else
{ {
out.appendSibling( link( out.append( link(
text( Integer.toString( serverComputer.getInstanceID() ) ), text( Integer.toString( serverComputer.getInstanceID() ) ),
"/computercraft dump " + serverComputer.getInstanceID(), "/computercraft dump " + serverComputer.getInstanceID(),
translate( "commands.computercraft.dump.action" ) translate( "commands.computercraft.dump.action" )
@@ -276,20 +275,20 @@ public final class CommandComputerCraft
} }
// And ID // And ID
out.appendText( " (id " + computerId + ")" ); out.append( " (id " + computerId + ")" );
// And, if we're a player, some useful links // And, if we're a player, some useful links
if( serverComputer != null && UserLevel.OP.test( source ) && isPlayer( source ) ) if( serverComputer != null && UserLevel.OP.test( source ) && isPlayer( source ) )
{ {
out out
.appendText( " " ) .append( " " )
.appendSibling( link( .append( link(
text( "\u261b" ), text( "\u261b" ),
"/computercraft tp " + serverComputer.getInstanceID(), "/computercraft tp " + serverComputer.getInstanceID(),
translate( "commands.computercraft.tp.action" ) translate( "commands.computercraft.tp.action" )
) ) ) )
.appendText( " " ) .append( " " )
.appendSibling( link( .append( link(
text( "\u20e2" ), text( "\u20e2" ),
"/computercraft view " + serverComputer.getInstanceID(), "/computercraft view " + serverComputer.getInstanceID(),
translate( "commands.computercraft.view.action" ) translate( "commands.computercraft.view.action" )
@@ -299,7 +298,7 @@ public final class CommandComputerCraft
return out; return out;
} }
private static ITextComponent linkPosition( CommandSource context, ServerComputer computer ) private static Component linkPosition( ServerCommandSource context, ServerComputer computer )
{ {
if( UserLevel.OP.test( context ) ) if( UserLevel.OP.test( context ) )
{ {
@@ -316,20 +315,20 @@ public final class CommandComputerCraft
} }
@Nonnull @Nonnull
private static TrackingContext getTimingContext( CommandSource source ) private static TrackingContext getTimingContext( ServerCommandSource source )
{ {
Entity entity = source.getEntity(); Entity entity = source.getEntity();
return entity instanceof EntityPlayer ? Tracking.getContext( entity.getUniqueID() ) : Tracking.getContext( SYSTEM_UUID ); return entity instanceof PlayerEntity ? Tracking.getContext( entity.getUuid() ) : Tracking.getContext( SYSTEM_UUID );
} }
private static final List<TrackingField> DEFAULT_FIELDS = Arrays.asList( TrackingField.TASKS, TrackingField.TOTAL_TIME, TrackingField.AVERAGE_TIME, TrackingField.MAX_TIME ); private static final List<TrackingField> DEFAULT_FIELDS = Arrays.asList( TrackingField.TASKS, TrackingField.TOTAL_TIME, TrackingField.AVERAGE_TIME, TrackingField.MAX_TIME );
private static int displayTimings( CommandSource source, TrackingField sortField, List<TrackingField> fields ) throws CommandSyntaxException private static int displayTimings( ServerCommandSource source, TrackingField sortField, List<TrackingField> fields ) throws CommandSyntaxException
{ {
return displayTimings( source, getTimingContext( source ).getTimings(), sortField, fields ); return displayTimings( source, getTimingContext( source ).getTimings(), sortField, fields );
} }
private static int displayTimings( CommandSource source, @Nonnull List<ComputerTracker> timings, @Nonnull TrackingField sortField, @Nonnull List<TrackingField> fields ) throws CommandSyntaxException private static int displayTimings( ServerCommandSource source, @Nonnull List<ComputerTracker> timings, @Nonnull TrackingField sortField, @Nonnull List<TrackingField> fields ) throws CommandSyntaxException
{ {
if( timings.isEmpty() ) throw NO_TIMINGS_EXCEPTION.create(); if( timings.isEmpty() ) throw NO_TIMINGS_EXCEPTION.create();
@@ -345,7 +344,7 @@ public final class CommandComputerCraft
timings.sort( Comparator.<ComputerTracker, Long>comparing( x -> x.get( sortField ) ).reversed() ); timings.sort( Comparator.<ComputerTracker, Long>comparing( x -> x.get( sortField ) ).reversed() );
ITextComponent[] headers = new ITextComponent[1 + fields.size()]; Component[] headers = new Component[1 + fields.size()];
headers[0] = translate( "commands.computercraft.track.dump.computer" ); headers[0] = translate( "commands.computercraft.track.dump.computer" );
for( int i = 0; i < fields.size(); i++ ) headers[i + 1] = translate( fields.get( i ).translationKey() ); for( int i = 0; i < fields.size(); i++ ) headers[i + 1] = translate( fields.get( i ).translationKey() );
TableBuilder table = new TableBuilder( TRACK_ID, headers ); TableBuilder table = new TableBuilder( TRACK_ID, headers );
@@ -355,9 +354,9 @@ public final class CommandComputerCraft
Computer computer = entry.getComputer(); Computer computer = entry.getComputer();
ServerComputer serverComputer = computer == null ? null : lookup.get( computer ); ServerComputer serverComputer = computer == null ? null : lookup.get( computer );
ITextComponent computerComponent = linkComputer( source, serverComputer, entry.getComputerId() ); Component computerComponent = linkComputer( source, serverComputer, entry.getComputerId() );
ITextComponent[] row = new ITextComponent[1 + fields.size()]; Component[] row = new Component[1 + fields.size()];
row[0] = computerComponent; row[0] = computerComponent;
for( int i = 0; i < fields.size(); i++ ) row[i + 1] = text( entry.getFormatted( fields.get( i ) ) ); for( int i = 0; i < fields.size(); i++ ) row[i + 1] = text( entry.getFormatted( fields.get( i ) ) );
table.row( row ); table.row( row );

View File

@@ -8,23 +8,16 @@ package dan200.computercraft.shared.command;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import dan200.computercraft.ComputerCraft; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.Minecraft; import net.minecraft.network.chat.ClickEvent;
import net.minecraft.command.CommandSource; import net.minecraft.network.chat.HoverEvent;
import net.minecraft.util.text.ITextComponent; import net.minecraft.network.chat.TextComponent;
import net.minecraft.util.text.TextComponentString; import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.util.text.event.HoverEvent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.ClientChatEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import static net.minecraft.command.Commands.argument; import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.command.Commands.literal; import static net.minecraft.server.command.CommandManager.literal;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class CommandCopy public final class CommandCopy
{ {
private static final String PREFIX = "/computercraft copy "; private static final String PREFIX = "/computercraft copy ";
@@ -33,35 +26,36 @@ public final class CommandCopy
{ {
} }
public static void register( CommandDispatcher<CommandSource> registry ) public static void register( CommandDispatcher<ServerCommandSource> registry )
{ {
registry.register( literal( "computercraft" ) registry.register( literal( "computercraft" )
.then( literal( "copy" ) ) .then( literal( "copy" ) )
.then( argument( "message", StringArgumentType.greedyString() ) ) .then( argument( "message", StringArgumentType.greedyString() ) )
.executes( context -> { .executes( context -> {
Minecraft.getInstance().keyboardListener.setClipboardString( context.getArgument( "message", String.class ) ); MinecraftClient.getInstance().keyboard.setClipboard( context.getArgument( "message", String.class ) );
return 1; return 1;
} ) } )
); );
} }
@SubscribeEvent public static boolean onClientSendMessage( String message )
public static void onClientSendMessage( ClientChatEvent event )
{ {
// Emulate the command on the client side // Emulate the command on the client side
if( event.getMessage().startsWith( PREFIX ) ) if( message.startsWith( PREFIX ) )
{ {
Minecraft.getInstance().keyboardListener.setClipboardString( event.getMessage().substring( PREFIX.length() ) ); MinecraftClient.getInstance().keyboard.setClipboard( message.substring( PREFIX.length() ) );
event.setCanceled( true ); return true;
}
} }
public static ITextComponent createCopyText( String text ) return false;
}
public static TextComponent createCopyText( String text )
{ {
TextComponentString name = new TextComponentString( text ); TextComponent name = new TextComponent( text );
name.getStyle() name.getStyle()
.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, PREFIX + text ) ) .setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, PREFIX + text ) )
.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new TextComponentTranslation( "gui.computercraft.tooltip.copy" ) ) ); .setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new TranslatableComponent( "gui.computercraft.tooltip.copy" ) ) );
return name; return name;
} }
} }

View File

@@ -9,11 +9,11 @@ package dan200.computercraft.shared.command;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder; import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.command.CommandSource; import dan200.computercraft.api.turtle.event.FakePlayer;
import net.minecraft.command.ISuggestionProvider;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.command.CommandSource;
import net.minecraftforge.common.util.FakePlayer; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
@@ -24,29 +24,29 @@ public final class CommandUtils
{ {
private CommandUtils() {} private CommandUtils() {}
public static boolean isPlayer( CommandSource output ) public static boolean isPlayer( ServerCommandSource output )
{ {
Entity sender = output.getEntity(); Entity sender = output.getEntity();
return sender instanceof EntityPlayerMP return sender instanceof ServerPlayerEntity
&& !(sender instanceof FakePlayer) && !(sender instanceof FakePlayer)
&& ((EntityPlayerMP) sender).connection != null; && ((ServerPlayerEntity) sender).networkHandler != null;
} }
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" )
public static CompletableFuture<Suggestions> suggestOnServer( CommandContext<?> context, SuggestionsBuilder builder, Function<CommandContext<CommandSource>, CompletableFuture<Suggestions>> supplier ) public static CompletableFuture<Suggestions> suggestOnServer( CommandContext<?> context, SuggestionsBuilder builder, Function<CommandContext<ServerCommandSource>, CompletableFuture<Suggestions>> supplier )
{ {
Object source = context.getSource(); Object source = context.getSource();
if( !(source instanceof ISuggestionProvider) ) if( !(source instanceof CommandSource) )
{ {
return Suggestions.empty(); return Suggestions.empty();
} }
else if( source instanceof CommandSource ) else if( source instanceof ServerCommandSource )
{ {
return supplier.apply( (CommandContext<CommandSource>) context ); return supplier.apply( (CommandContext<ServerCommandSource>) context );
} }
else else
{ {
return ((ISuggestionProvider) source).getSuggestionsFromServer( (CommandContext<ISuggestionProvider>) context, builder ); return ((CommandSource) source).getCompletions( (CommandContext<CommandSource>) context, builder );
} }
} }

View File

@@ -9,7 +9,7 @@ package dan200.computercraft.shared.command;
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType; import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.network.chat.TranslatableComponent;
public final class Exceptions public final class Exceptions
{ {
@@ -28,16 +28,16 @@ public final class Exceptions
private static SimpleCommandExceptionType translated( String key ) private static SimpleCommandExceptionType translated( String key )
{ {
return new SimpleCommandExceptionType( new TextComponentTranslation( key ) ); return new SimpleCommandExceptionType( new TranslatableComponent( key ) );
} }
private static DynamicCommandExceptionType translated1( String key ) private static DynamicCommandExceptionType translated1( String key )
{ {
return new DynamicCommandExceptionType( x -> new TextComponentTranslation( key, x ) ); return new DynamicCommandExceptionType( x -> new TranslatableComponent( key, x ) );
} }
private static Dynamic2CommandExceptionType translated2( String key ) private static Dynamic2CommandExceptionType translated2( String key )
{ {
return new Dynamic2CommandExceptionType( ( x, y ) -> new TextComponentTranslation( key, x, y ) ); return new Dynamic2CommandExceptionType( ( x, y ) -> new TranslatableComponent( key, x, y ) );
} }
} }

View File

@@ -6,17 +6,17 @@
package dan200.computercraft.shared.command; package dan200.computercraft.shared.command;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource;
import java.util.function.Predicate; import java.util.function.Predicate;
/** /**
* The level a user must be at in order to execute a command. * The level a user must be at in order to execute a command.
*/ */
public enum UserLevel implements Predicate<CommandSource> public enum UserLevel implements Predicate<ServerCommandSource>
{ {
/** /**
* Only can be used by the owner of the server: namely the server console or the player in SSP. * Only can be used by the owner of the server: namely the server console or the player in SSP.
@@ -54,16 +54,16 @@ public enum UserLevel implements Predicate<CommandSource>
} }
@Override @Override
public boolean test( CommandSource source ) public boolean test( ServerCommandSource source )
{ {
if( this == ANYONE ) return true; if( this == ANYONE ) return true;
// We *always* allow level 0 stuff, even if the // We *always* allow level 0 stuff, even if the
MinecraftServer server = source.getServer(); MinecraftServer server = source.getMinecraftServer();
Entity sender = source.getEntity(); Entity sender = source.getEntity();
if( server.isSinglePlayer() && sender instanceof EntityPlayer && if( server.isSinglePlayer() && sender instanceof PlayerEntity &&
((EntityPlayer) sender).getGameProfile().getName().equalsIgnoreCase( server.getServerModName() ) ) ((PlayerEntity) sender).getGameProfile().getName().equalsIgnoreCase( server.getUserName() ) )
{ {
if( this == OWNER || this == OWNER_OP ) return true; if( this == OWNER || this == OWNER_OP ) return true;
} }

View File

@@ -8,34 +8,34 @@ package dan200.computercraft.shared.command.arguments;
import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.ArgumentType;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import net.minecraft.command.arguments.ArgumentSerializer;
import net.minecraft.command.arguments.ArgumentTypes; import net.minecraft.command.arguments.ArgumentTypes;
import net.minecraft.command.arguments.IArgumentSerializer; import net.minecraft.command.arguments.serialize.ArgumentSerializer;
import net.minecraft.util.ResourceLocation; import net.minecraft.command.arguments.serialize.ConstantArgumentSerializer;
import net.minecraft.util.Identifier;
public final class ArgumentSerializers public final class ArgumentSerializers
{ {
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" )
private static <T extends ArgumentType<?>> void registerUnsafe( ResourceLocation id, Class<T> type, IArgumentSerializer<?> serializer ) private static <T extends ArgumentType<?>> void registerUnsafe( Identifier id, Class<T> type, ArgumentSerializer<?> serializer )
{ {
ArgumentTypes.register( id, type, (IArgumentSerializer<T>) serializer ); ArgumentTypes.register( id.toString(), type, (ArgumentSerializer<T>) serializer );
} }
private static <T extends ArgumentType<?>> void register( ResourceLocation id, Class<T> type, IArgumentSerializer<T> serializer ) private static <T extends ArgumentType<?>> void register( Identifier id, Class<T> type, ArgumentSerializer<T> serializer )
{ {
ArgumentTypes.register( id, type, serializer ); ArgumentTypes.register( id.toString(), type, serializer );
} }
private static <T extends ArgumentType<?>> void register( ResourceLocation id, T instance ) private static <T extends ArgumentType<?>> void register( Identifier id, T instance )
{ {
registerUnsafe( id, instance.getClass(), new ArgumentSerializer<>( () -> instance ) ); registerUnsafe( id, instance.getClass(), new ConstantArgumentSerializer<>( () -> instance ) );
} }
public static void register() public static void register()
{ {
register( new ResourceLocation( ComputerCraft.MOD_ID, "tracking_field" ), TrackingFieldArgumentType.trackingField() ); register( new Identifier( ComputerCraft.MOD_ID, "tracking_field" ), TrackingFieldArgumentType.trackingField() );
register( new ResourceLocation( ComputerCraft.MOD_ID, "computer" ), ComputerArgumentType.oneComputer() ); register( new Identifier( ComputerCraft.MOD_ID, "computer" ), ComputerArgumentType.oneComputer() );
register( new ResourceLocation( ComputerCraft.MOD_ID, "computers" ), ComputersArgumentType.class, new ComputersArgumentType.Serializer() ); register( new Identifier( ComputerCraft.MOD_ID, "computers" ), ComputersArgumentType.class, new ComputersArgumentType.Serializer() );
registerUnsafe( new ResourceLocation( ComputerCraft.MOD_ID, "repeat" ), RepeatArgumentType.class, new RepeatArgumentType.Serializer() ); registerUnsafe( new Identifier( ComputerCraft.MOD_ID, "repeat" ), RepeatArgumentType.class, new RepeatArgumentType.Serializer() );
} }
} }

View File

@@ -14,7 +14,7 @@ import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder; import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import dan200.computercraft.shared.command.arguments.ComputersArgumentType.ComputersSupplier; import dan200.computercraft.shared.command.arguments.ComputersArgumentType.ComputersSupplier;
import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.computer.core.ServerComputer;
import net.minecraft.command.CommandSource; import net.minecraft.server.command.ServerCommandSource;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -30,7 +30,7 @@ public final class ComputerArgumentType implements ArgumentType<ComputerArgument
return INSTANCE; return INSTANCE;
} }
public static ServerComputer getComputerArgument( CommandContext<CommandSource> context, String name ) throws CommandSyntaxException public static ServerComputer getComputerArgument( CommandContext<ServerCommandSource> context, String name ) throws CommandSyntaxException
{ {
return context.getArgument( name, ComputerSupplier.class ).unwrap( context.getSource() ); return context.getArgument( name, ComputerSupplier.class ).unwrap( context.getSource() );
} }
@@ -89,6 +89,6 @@ public final class ComputerArgumentType implements ArgumentType<ComputerArgument
@FunctionalInterface @FunctionalInterface
public interface ComputerSupplier public interface ComputerSupplier
{ {
ServerComputer unwrap( CommandSource source ) throws CommandSyntaxException; ServerComputer unwrap( ServerCommandSource source ) throws CommandSyntaxException;
} }
} }

View File

@@ -16,9 +16,9 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.computer.core.ServerComputer;
import net.minecraft.command.CommandSource; import net.minecraft.command.arguments.serialize.ArgumentSerializer;
import net.minecraft.command.arguments.IArgumentSerializer; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.network.PacketBuffer; import net.minecraft.util.PacketByteBuf;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.*; import java.util.*;
@@ -50,7 +50,7 @@ public final class ComputersArgumentType implements ArgumentType<ComputersArgume
return SOME; return SOME;
} }
public static Collection<ServerComputer> getComputersArgument( CommandContext<CommandSource> context, String name ) throws CommandSyntaxException public static Collection<ServerComputer> getComputersArgument( CommandContext<ServerCommandSource> context, String name ) throws CommandSyntaxException
{ {
return context.getArgument( name, ComputersSupplier.class ).unwrap( context.getSource() ); return context.getArgument( name, ComputersSupplier.class ).unwrap( context.getSource() );
} }
@@ -172,24 +172,24 @@ public final class ComputersArgumentType implements ArgumentType<ComputersArgume
); );
} }
public static class Serializer implements IArgumentSerializer<ComputersArgumentType> public static class Serializer implements ArgumentSerializer<ComputersArgumentType>
{ {
@Override @Override
public void write( @Nonnull ComputersArgumentType arg, @Nonnull PacketBuffer buf ) public void toPacket( @Nonnull ComputersArgumentType arg, @Nonnull PacketByteBuf buf )
{ {
buf.writeBoolean( arg.requireSome ); buf.writeBoolean( arg.requireSome );
} }
@Nonnull @Nonnull
@Override @Override
public ComputersArgumentType read( @Nonnull PacketBuffer buf ) public ComputersArgumentType fromPacket( @Nonnull PacketByteBuf buf )
{ {
return buf.readBoolean() ? SOME : MANY; return buf.readBoolean() ? SOME : MANY;
} }
@Override @Override
public void write( @Nonnull ComputersArgumentType arg, @Nonnull JsonObject json ) public void toJson( @Nonnull ComputersArgumentType arg, @Nonnull JsonObject json )
{ {
json.addProperty( "requireSome", arg.requireSome ); json.addProperty( "requireSome", arg.requireSome );
} }
@@ -198,10 +198,10 @@ public final class ComputersArgumentType implements ArgumentType<ComputersArgume
@FunctionalInterface @FunctionalInterface
public interface ComputersSupplier public interface ComputersSupplier
{ {
Collection<ServerComputer> unwrap( CommandSource source ) throws CommandSyntaxException; Collection<ServerComputer> unwrap( ServerCommandSource source ) throws CommandSyntaxException;
} }
public static Set<ServerComputer> unwrap( CommandSource source, Collection<ComputersSupplier> suppliers ) throws CommandSyntaxException public static Set<ServerComputer> unwrap( ServerCommandSource source, Collection<ComputersSupplier> suppliers ) throws CommandSyntaxException
{ {
Set<ServerComputer> computers = new HashSet<>(); Set<ServerComputer> computers = new HashSet<>();
for( ComputersSupplier supplier : suppliers ) computers.addAll( supplier.unwrap( source ) ); for( ComputersSupplier supplier : suppliers ) computers.addAll( supplier.unwrap( source ) );

View File

@@ -16,10 +16,10 @@ import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder; import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.command.arguments.ArgumentTypes; import net.minecraft.command.arguments.ArgumentTypes;
import net.minecraft.command.arguments.IArgumentSerializer; import net.minecraft.command.arguments.serialize.ArgumentSerializer;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.chat.Component;
import net.minecraft.util.text.ITextComponent; import net.minecraft.network.chat.TextComponent;
import net.minecraft.util.text.TextComponentString; import net.minecraft.util.PacketByteBuf;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
@@ -126,41 +126,41 @@ public final class RepeatArgumentType<T, U> implements ArgumentType<List<T>>
return child.getExamples(); return child.getExamples();
} }
public static class Serializer implements IArgumentSerializer<RepeatArgumentType<?, ?>> public static class Serializer implements ArgumentSerializer<RepeatArgumentType<?, ?>>
{ {
@Override @Override
public void write( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull PacketBuffer buf ) public void toPacket( RepeatArgumentType<?, ?> arg, PacketByteBuf buf )
{ {
buf.writeBoolean( arg.flatten ); buf.writeBoolean( arg.flatten );
ArgumentTypes.serialize( buf, arg.child ); ArgumentTypes.toPacket( buf, arg.child );
buf.writeTextComponent( getMessage( arg ) ); buf.writeTextComponent( getMessage( arg ) );
} }
@Nonnull @Nonnull
@Override @Override
@SuppressWarnings( { "unchecked", "rawtypes" } ) @SuppressWarnings( { "unchecked", "rawtypes" } )
public RepeatArgumentType<?, ?> read( @Nonnull PacketBuffer buf ) public RepeatArgumentType<?, ?> fromPacket( @Nonnull PacketByteBuf buf )
{ {
boolean isList = buf.readBoolean(); boolean isList = buf.readBoolean();
ArgumentType<?> child = ArgumentTypes.deserialize( buf ); ArgumentType<?> child = ArgumentTypes.fromPacket( buf );
ITextComponent message = buf.readTextComponent(); Component message = buf.readTextComponent();
BiConsumer<List<Object>, ?> appender = isList ? ( list, x ) -> list.addAll( (Collection) x ) : List::add; BiConsumer<List<Object>, ?> appender = isList ? ( list, x ) -> list.addAll( (Collection) x ) : List::add;
return new RepeatArgumentType( child, appender, isList, new SimpleCommandExceptionType( message ) ); return new RepeatArgumentType( child, appender, isList, new SimpleCommandExceptionType( message ) );
} }
@Override @Override
public void write( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull JsonObject json ) public void toJson( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull JsonObject json )
{ {
json.addProperty( "flatten", arg.flatten ); json.addProperty( "flatten", arg.flatten );
json.addProperty( "child", "<<cannot serialize>>" ); // TODO: Potentially serialize this using reflection. json.addProperty( "child", "<<cannot serialize>>" ); // TODO: Potentially serialize this using reflection.
json.addProperty( "error", ITextComponent.Serializer.toJson( getMessage( arg ) ) ); json.addProperty( "error", TextComponent.Serializer.toJsonString( getMessage( arg ) ) );
} }
private static ITextComponent getMessage( RepeatArgumentType<?, ?> arg ) private static TextComponent getMessage( RepeatArgumentType<?, ?> arg )
{ {
Message message = arg.some.create().getRawMessage(); Message message = arg.some.create().getRawMessage();
if( message instanceof ITextComponent ) return (ITextComponent) message; if( message instanceof TextComponent ) return (TextComponent) message;
return new TextComponentString( message.getString() ); return new TextComponent( message.getString() );
} }
} }
} }

View File

@@ -13,7 +13,7 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import dan200.computercraft.shared.command.arguments.RepeatArgumentType; import dan200.computercraft.shared.command.arguments.RepeatArgumentType;
import net.minecraft.command.CommandSource; import net.minecraft.server.command.ServerCommandSource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -33,14 +33,14 @@ public class CommandBuilder<S> implements CommandNodeBuilder<S, Command<S>>
private List<ArgumentBuilder<S, ?>> args = new ArrayList<>(); private List<ArgumentBuilder<S, ?>> args = new ArrayList<>();
private Predicate<S> requires; private Predicate<S> requires;
public static CommandBuilder<CommandSource> args() public static CommandBuilder<ServerCommandSource> args()
{ {
return new CommandBuilder<>(); return new CommandBuilder<>();
} }
public static CommandBuilder<CommandSource> command( String literal ) public static CommandBuilder<ServerCommandSource> command( String literal )
{ {
CommandBuilder<CommandSource> builder = new CommandBuilder<>(); CommandBuilder<ServerCommandSource> builder = new CommandBuilder<>();
builder.args.add( literal( literal ) ); builder.args.add( literal( literal ) );
return builder; return builder;
} }

View File

@@ -13,11 +13,11 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode; import com.mojang.brigadier.tree.LiteralCommandNode;
import net.minecraft.command.CommandSource; import net.minecraft.ChatFormat;
import net.minecraft.util.text.ITextComponent; import net.minecraft.network.chat.ClickEvent;
import net.minecraft.util.text.TextComponentString; import net.minecraft.network.chat.Component;
import net.minecraft.util.text.TextFormatting; import net.minecraft.network.chat.TextComponent;
import net.minecraft.util.text.event.ClickEvent; import net.minecraft.server.command.ServerCommandSource;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
@@ -30,7 +30,7 @@ import static dan200.computercraft.shared.command.text.ChatHelpers.translate;
* An alternative to {@link LiteralArgumentBuilder} which also provides a {@code /... help} command, and defaults * An alternative to {@link LiteralArgumentBuilder} which also provides a {@code /... help} command, and defaults
* to that command when no arguments are given. * to that command when no arguments are given.
*/ */
public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<CommandSource> public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<ServerCommandSource>
{ {
private final Collection<HelpingArgumentBuilder> children = new ArrayList<>(); private final Collection<HelpingArgumentBuilder> children = new ArrayList<>();
@@ -45,13 +45,13 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
} }
@Override @Override
public LiteralArgumentBuilder<CommandSource> executes( final Command<CommandSource> command ) public LiteralArgumentBuilder<ServerCommandSource> executes( final Command<ServerCommandSource> command )
{ {
throw new IllegalStateException( "Cannot use executes on a HelpingArgumentBuilder" ); throw new IllegalStateException( "Cannot use executes on a HelpingArgumentBuilder" );
} }
@Override @Override
public LiteralArgumentBuilder<CommandSource> then( final ArgumentBuilder<CommandSource, ?> argument ) public LiteralArgumentBuilder<ServerCommandSource> then( final ArgumentBuilder<ServerCommandSource, ?> argument )
{ {
if( getRedirect() != null ) throw new IllegalStateException( "Cannot add children to a redirected node" ); if( getRedirect() != null ) throw new IllegalStateException( "Cannot add children to a redirected node" );
@@ -72,7 +72,7 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
} }
@Override @Override
public LiteralArgumentBuilder<CommandSource> then( CommandNode<CommandSource> argument ) public LiteralArgumentBuilder<ServerCommandSource> then( CommandNode<ServerCommandSource> argument )
{ {
if( !(argument instanceof LiteralCommandNode) ) if( !(argument instanceof LiteralCommandNode) )
{ {
@@ -82,33 +82,33 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
} }
@Override @Override
public LiteralCommandNode<CommandSource> build() public LiteralCommandNode<ServerCommandSource> build()
{ {
return buildImpl( getLiteral().replace( '-', '_' ), getLiteral() ); return buildImpl( getLiteral().replace( '-', '_' ), getLiteral() );
} }
private LiteralCommandNode<CommandSource> build( @Nonnull String id, @Nonnull String command ) private LiteralCommandNode<ServerCommandSource> build( @Nonnull String id, @Nonnull String command )
{ {
return buildImpl( id + "." + getLiteral().replace( '-', '_' ), command + " " + getLiteral() ); return buildImpl( id + "." + getLiteral().replace( '-', '_' ), command + " " + getLiteral() );
} }
private LiteralCommandNode<CommandSource> buildImpl( String id, String command ) private LiteralCommandNode<ServerCommandSource> buildImpl( String id, String command )
{ {
HelpCommand helpCommand = new HelpCommand( id, command ); HelpCommand helpCommand = new HelpCommand( id, command );
LiteralCommandNode<CommandSource> node = new LiteralCommandNode<>( getLiteral(), helpCommand, getRequirement(), getRedirect(), getRedirectModifier(), isFork() ); LiteralCommandNode<ServerCommandSource> node = new LiteralCommandNode<>( getLiteral(), helpCommand, getRequirement(), getRedirect(), getRedirectModifier(), isFork() );
helpCommand.node = node; helpCommand.node = node;
// Set up a /... help command // Set up a /... help command
LiteralArgumentBuilder<CommandSource> helpNode = LiteralArgumentBuilder.<CommandSource>literal( "help" ) LiteralArgumentBuilder<ServerCommandSource> helpNode = LiteralArgumentBuilder.<ServerCommandSource>literal( "help" )
.requires( x -> getArguments().stream().anyMatch( y -> y.getRequirement().test( x ) ) ) .requires( x -> getArguments().stream().anyMatch( y -> y.getRequirement().test( x ) ) )
.executes( helpCommand ); .executes( helpCommand );
// Add all normal command children to this and the help node // Add all normal command children to this and the help node
for( CommandNode<CommandSource> child : getArguments() ) for( CommandNode<ServerCommandSource> child : getArguments() )
{ {
node.addChild( child ); node.addChild( child );
helpNode.then( LiteralArgumentBuilder.<CommandSource>literal( child.getName() ) helpNode.then( LiteralArgumentBuilder.<ServerCommandSource>literal( child.getName() )
.requires( child.getRequirement() ) .requires( child.getRequirement() )
.executes( helpForChild( child, id, command ) ) .executes( helpForChild( child, id, command ) )
.build() .build()
@@ -118,9 +118,9 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
// And add alternative versions of which forward instead // And add alternative versions of which forward instead
for( HelpingArgumentBuilder childBuilder : children ) for( HelpingArgumentBuilder childBuilder : children )
{ {
LiteralCommandNode<CommandSource> child = childBuilder.build( id, command ); LiteralCommandNode<ServerCommandSource> child = childBuilder.build( id, command );
node.addChild( child ); node.addChild( child );
helpNode.then( LiteralArgumentBuilder.<CommandSource>literal( child.getName() ) helpNode.then( LiteralArgumentBuilder.<ServerCommandSource>literal( child.getName() )
.requires( child.getRequirement() ) .requires( child.getRequirement() )
.executes( helpForChild( child, id, command ) ) .executes( helpForChild( child, id, command ) )
.redirect( child.getChild( "help" ) ) .redirect( child.getChild( "help" ) )
@@ -133,15 +133,15 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
return node; return node;
} }
private static final TextFormatting HEADER = TextFormatting.LIGHT_PURPLE; private static final ChatFormat HEADER = ChatFormat.LIGHT_PURPLE;
private static final TextFormatting SYNOPSIS = TextFormatting.AQUA; private static final ChatFormat SYNOPSIS = ChatFormat.AQUA;
private static final TextFormatting NAME = TextFormatting.GREEN; private static final ChatFormat NAME = ChatFormat.GREEN;
private static final class HelpCommand implements Command<CommandSource> private static final class HelpCommand implements Command<ServerCommandSource>
{ {
private final String id; private final String id;
private final String command; private final String command;
LiteralCommandNode<CommandSource> node; LiteralCommandNode<ServerCommandSource> node;
private HelpCommand( String id, String command ) private HelpCommand( String id, String command )
{ {
@@ -150,14 +150,14 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
} }
@Override @Override
public int run( CommandContext<CommandSource> context ) public int run( CommandContext<ServerCommandSource> context )
{ {
context.getSource().sendFeedback( getHelp( context, node, id, command ), false ); context.getSource().sendFeedback( getHelp( context, node, id, command ), false );
return 0; return 0;
} }
} }
private static Command<CommandSource> helpForChild( CommandNode<CommandSource> node, String id, String command ) private static Command<ServerCommandSource> helpForChild( CommandNode<ServerCommandSource> node, String id, String command )
{ {
return context -> { return context -> {
context.getSource().sendFeedback( getHelp( context, node, id + "." + node.getName().replace( '-', '_' ), command + " " + node.getName() ), false ); context.getSource().sendFeedback( getHelp( context, node, id + "." + node.getName().replace( '-', '_' ), command + " " + node.getName() ), false );
@@ -165,39 +165,39 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
}; };
} }
private static ITextComponent getHelp( CommandContext<CommandSource> context, CommandNode<CommandSource> node, String id, String command ) private static Component getHelp( CommandContext<ServerCommandSource> context, CommandNode<ServerCommandSource> node, String id, String command )
{ {
// An ugly hack to extract usage information from the dispatcher. We generate a temporary node, generate // An ugly hack to extract usage information from the dispatcher. We generate a temporary node, generate
// the shorthand usage, and emit that. // the shorthand usage, and emit that.
CommandDispatcher<CommandSource> dispatcher = context.getSource().getServer().getCommandManager().getDispatcher(); CommandDispatcher<ServerCommandSource> dispatcher = context.getSource().getMinecraftServer().getCommandManager().getDispatcher();
CommandNode<CommandSource> temp = new LiteralCommandNode<>( "_", null, x -> true, null, null, false ); CommandNode<ServerCommandSource> temp = new LiteralCommandNode<>( "_", null, x -> true, null, null, false );
temp.addChild( node ); temp.addChild( node );
String usage = dispatcher.getSmartUsage( temp, context.getSource() ).get( node ).substring( node.getName().length() ); String usage = dispatcher.getSmartUsage( temp, context.getSource() ).get( node ).substring( node.getName().length() );
ITextComponent output = new TextComponentString( "" ) Component output = new TextComponent( "" )
.appendSibling( coloured( "/" + command + usage, HEADER ) ) .append( coloured( "/" + command + usage, HEADER ) )
.appendText( " " ) .append( " " )
.appendSibling( coloured( translate( "commands." + id + ".synopsis" ), SYNOPSIS ) ) .append( coloured( translate( "commands." + id + ".synopsis" ), SYNOPSIS ) )
.appendText( "\n" ) .append( "\n" )
.appendSibling( translate( "commands." + id + ".desc" ) ); .append( translate( "commands." + id + ".desc" ) );
for( CommandNode<CommandSource> child : node.getChildren() ) for( CommandNode<ServerCommandSource> child : node.getChildren() )
{ {
if( !child.getRequirement().test( context.getSource() ) || !(child instanceof LiteralCommandNode) ) if( !child.getRequirement().test( context.getSource() ) || !(child instanceof LiteralCommandNode) )
{ {
continue; continue;
} }
output.appendText( "\n" ); output.append( "\n" );
ITextComponent component = coloured( child.getName(), NAME ); Component component = coloured( child.getName(), NAME );
component.getStyle().setClickEvent( new ClickEvent( component.getStyle().setClickEvent( new ClickEvent(
ClickEvent.Action.SUGGEST_COMMAND, ClickEvent.Action.SUGGEST_COMMAND,
"/" + command + " " + child.getName() "/" + command + " " + child.getName()
) ); ) );
output.appendSibling( component ); output.append( component );
output.appendText( " - " ).appendSibling( translate( "commands." + id + "." + child.getName() + ".synopsis" ) ); output.append( " - " ).append( translate( "commands." + id + "." + child.getName() + ".synopsis" ) );
} }
return output; return output;

View File

@@ -6,83 +6,82 @@
package dan200.computercraft.shared.command.text; package dan200.computercraft.shared.command.text;
import net.minecraft.ChatFormat;
import net.minecraft.network.chat.*;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.*;
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 public final class ChatHelpers
{ {
private static final TextFormatting HEADER = TextFormatting.LIGHT_PURPLE; private static final ChatFormat HEADER = ChatFormat.LIGHT_PURPLE;
private ChatHelpers() {} private ChatHelpers() {}
public static ITextComponent coloured( String text, TextFormatting colour ) public static Component coloured( String text, ChatFormat colour )
{ {
ITextComponent component = new TextComponentString( text == null ? "" : text ); TextComponent component = new TextComponent( text == null ? "" : text );
component.getStyle().setColor( colour ); component.getStyle().setColor( colour );
return component; return component;
} }
public static <T extends ITextComponent> T coloured( T component, TextFormatting colour ) public static <T extends Component> T coloured( T component, ChatFormat colour )
{ {
component.getStyle().setColor( colour ); component.getStyle().setColor( colour );
return component; return component;
} }
public static ITextComponent text( String text ) public static Component text( String text )
{ {
return new TextComponentString( text == null ? "" : text ); return new TextComponent( text == null ? "" : text );
} }
public static ITextComponent translate( String text ) public static Component translate( String text )
{ {
return new TextComponentTranslation( text == null ? "" : text ); return new TranslatableComponent( text == null ? "" : text );
} }
public static ITextComponent translate( String text, Object... args ) public static Component translate( String text, Object... args )
{ {
return new TextComponentTranslation( text == null ? "" : text, args ); return new TranslatableComponent( text == null ? "" : text, args );
} }
public static ITextComponent list( ITextComponent... children ) public static Component list( Component... children )
{ {
ITextComponent component = new TextComponentString( "" ); Component component = new TextComponent( "" );
for( ITextComponent child : children ) for( Component child : children )
{ {
component.appendSibling( child ); component.append( child );
} }
return component; return component;
} }
public static ITextComponent position( BlockPos pos ) public static Component position( BlockPos pos )
{ {
if( pos == null ) return translate( "commands.computercraft.generic.no_position" ); if( pos == null ) return translate( "commands.computercraft.generic.no_position" );
return translate( "commands.computercraft.generic.position", pos.getX(), pos.getY(), pos.getZ() ); return translate( "commands.computercraft.generic.position", pos.getX(), pos.getY(), pos.getZ() );
} }
public static ITextComponent bool( boolean value ) public static Component bool( boolean value )
{ {
return value return value
? coloured( translate( "commands.computercraft.generic.yes" ), TextFormatting.GREEN ) ? coloured( translate( "commands.computercraft.generic.yes" ), ChatFormat.GREEN )
: coloured( translate( "commands.computercraft.generic.no" ), TextFormatting.RED ); : coloured( translate( "commands.computercraft.generic.no" ), ChatFormat.RED );
} }
public static ITextComponent link( ITextComponent component, String command, ITextComponent toolTip ) public static Component link( Component component, String command, Component toolTip )
{ {
Style style = component.getStyle(); Style style = component.getStyle();
if( style.getColor() == null ) style.setColor( TextFormatting.YELLOW ); if( style.getColor() == null ) style.setColor( ChatFormat.YELLOW );
style.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, command ) ); style.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, command ) );
style.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, toolTip ) ); style.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, toolTip ) );
return component; return component;
} }
public static ITextComponent header( String text ) public static Component header( String text )
{ {
return coloured( text, HEADER ); return coloured( text, HEADER );
} }

View File

@@ -6,29 +6,29 @@
package dan200.computercraft.shared.command.text; package dan200.computercraft.shared.command.text;
import net.minecraft.command.CommandSource; import net.minecraft.network.chat.Component;
import net.minecraft.util.text.ITextComponent; import net.minecraft.network.chat.TextComponent;
import net.minecraft.util.text.TextComponentString; import net.minecraft.server.command.ServerCommandSource;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class ServerTableFormatter implements TableFormatter public class ServerTableFormatter implements TableFormatter
{ {
private final CommandSource source; private final ServerCommandSource source;
public ServerTableFormatter( CommandSource source ) public ServerTableFormatter( ServerCommandSource source )
{ {
this.source = source; this.source = source;
} }
@Override @Override
@Nullable @Nullable
public ITextComponent getPadding( ITextComponent component, int width ) public Component getPadding( Component component, int width )
{ {
int extraWidth = width - getWidth( component ); int extraWidth = width - getWidth( component );
if( extraWidth <= 0 ) return null; if( extraWidth <= 0 ) return null;
return new TextComponentString( StringUtils.repeat( ' ', extraWidth ) ); return new TextComponent( StringUtils.repeat( ' ', extraWidth ) );
} }
@Override @Override
@@ -38,13 +38,13 @@ public class ServerTableFormatter implements TableFormatter
} }
@Override @Override
public int getWidth( ITextComponent component ) public int getWidth( Component component )
{ {
return component.getString().length(); return component.getText().length();
} }
@Override @Override
public void writeLine( int id, ITextComponent component ) public void writeLine( int id, Component component )
{ {
source.sendFeedback( component, false ); source.sendFeedback( component, false );
} }

View File

@@ -9,9 +9,9 @@ package dan200.computercraft.shared.command.text;
import dan200.computercraft.shared.command.CommandUtils; import dan200.computercraft.shared.command.CommandUtils;
import dan200.computercraft.shared.network.NetworkHandler; import dan200.computercraft.shared.network.NetworkHandler;
import dan200.computercraft.shared.network.client.ChatTableClientMessage; import dan200.computercraft.shared.network.client.ChatTableClientMessage;
import net.minecraft.command.CommandSource; import net.minecraft.network.chat.Component;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.util.text.ITextComponent; import net.minecraft.server.network.ServerPlayerEntity;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -22,11 +22,11 @@ public class TableBuilder
{ {
private final int id; private final int id;
private int columns = -1; private int columns = -1;
private final ITextComponent[] headers; private final Component[] headers;
private final ArrayList<ITextComponent[]> rows = new ArrayList<>(); private final ArrayList<Component[]> rows = new ArrayList<>();
private int additional; private int additional;
public TableBuilder( int id, @Nonnull ITextComponent... headers ) public TableBuilder( int id, @Nonnull Component... headers )
{ {
if( id < 0 ) throw new IllegalArgumentException( "ID must be positive" ); if( id < 0 ) throw new IllegalArgumentException( "ID must be positive" );
this.id = id; this.id = id;
@@ -45,13 +45,13 @@ public class TableBuilder
{ {
if( id < 0 ) throw new IllegalArgumentException( "ID must be positive" ); if( id < 0 ) throw new IllegalArgumentException( "ID must be positive" );
this.id = id; this.id = id;
this.headers = new ITextComponent[headers.length]; this.headers = new Component[headers.length];
columns = headers.length; columns = headers.length;
for( int i = 0; i < headers.length; i++ ) this.headers[i] = ChatHelpers.header( headers[i] ); for( int i = 0; i < headers.length; i++ ) this.headers[i] = ChatHelpers.header( headers[i] );
} }
public void row( @Nonnull ITextComponent... row ) public void row( @Nonnull Component... row )
{ {
if( columns == -1 ) columns = row.length; if( columns == -1 ) columns = row.length;
if( row.length != columns ) throw new IllegalArgumentException( "Row is the incorrect length" ); if( row.length != columns ) throw new IllegalArgumentException( "Row is the incorrect length" );
@@ -85,13 +85,13 @@ public class TableBuilder
} }
@Nullable @Nullable
public ITextComponent[] getHeaders() public Component[] getHeaders()
{ {
return headers; return headers;
} }
@Nonnull @Nonnull
public List<ITextComponent[]> getRows() public List<Component[]> getRows()
{ {
return rows; return rows;
} }
@@ -120,12 +120,12 @@ public class TableBuilder
} }
} }
public void display( CommandSource source ) public void display( ServerCommandSource source )
{ {
if( CommandUtils.isPlayer( source ) ) if( CommandUtils.isPlayer( source ) )
{ {
trim( 18 ); trim( 18 );
NetworkHandler.sendToPlayer( (EntityPlayerMP) source.getEntity(), new ChatTableClientMessage( this ) ); NetworkHandler.sendToPlayer( (ServerPlayerEntity) source.getEntity(), new ChatTableClientMessage( this ) );
} }
else else
{ {

View File

@@ -6,9 +6,9 @@
package dan200.computercraft.shared.command.text; package dan200.computercraft.shared.command.text;
import net.minecraft.util.text.ITextComponent; import net.minecraft.ChatFormat;
import net.minecraft.util.text.TextComponentString; import net.minecraft.network.chat.Component;
import net.minecraft.util.text.TextFormatting; import net.minecraft.network.chat.TextComponent;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -18,8 +18,8 @@ import static dan200.computercraft.shared.command.text.ChatHelpers.translate;
public interface TableFormatter public interface TableFormatter
{ {
ITextComponent SEPARATOR = coloured( "| ", TextFormatting.GRAY ); Component SEPARATOR = coloured( "| ", ChatFormat.GRAY );
ITextComponent HEADER = coloured( "=", TextFormatting.GRAY ); Component HEADER = coloured( "=", ChatFormat.GRAY );
/** /**
* Get additional padding for the component * Get additional padding for the component
@@ -29,7 +29,7 @@ public interface TableFormatter
* @return The padding for this component, or {@code null} if none is needed. * @return The padding for this component, or {@code null} if none is needed.
*/ */
@Nullable @Nullable
ITextComponent getPadding( ITextComponent component, int width ); Component getPadding( Component component, int width );
/** /**
* Get the minimum padding between each column * Get the minimum padding between each column
@@ -38,9 +38,9 @@ public interface TableFormatter
*/ */
int getColumnPadding(); int getColumnPadding();
int getWidth( ITextComponent component ); int getWidth( Component component );
void writeLine( int id, ITextComponent component ); void writeLine( int id, Component component );
default int display( TableBuilder table ) default int display( TableBuilder table )
{ {
@@ -50,13 +50,13 @@ public interface TableFormatter
int columns = table.getColumns(); int columns = table.getColumns();
int[] maxWidths = new int[columns]; int[] maxWidths = new int[columns];
ITextComponent[] headers = table.getHeaders(); Component[] headers = table.getHeaders();
if( headers != null ) if( headers != null )
{ {
for( int i = 0; i < columns; i++ ) maxWidths[i] = getWidth( headers[i] ); for( int i = 0; i < columns; i++ ) maxWidths[i] = getWidth( headers[i] );
} }
for( ITextComponent[] row : table.getRows() ) for( Component[] row : table.getRows() )
{ {
for( int i = 0; i < row.length; i++ ) for( int i = 0; i < row.length; i++ )
{ {
@@ -77,15 +77,15 @@ public interface TableFormatter
if( headers != null ) if( headers != null )
{ {
TextComponentString line = new TextComponentString( "" ); TextComponent line = new TextComponent( "" );
for( int i = 0; i < columns - 1; i++ ) for( int i = 0; i < columns - 1; i++ )
{ {
line.appendSibling( headers[i] ); line.append( headers[i] );
ITextComponent padding = getPadding( headers[i], maxWidths[i] ); Component padding = getPadding( headers[i], maxWidths[i] );
if( padding != null ) line.appendSibling( padding ); if( padding != null ) line.append( padding );
line.appendSibling( SEPARATOR ); line.append( SEPARATOR );
} }
line.appendSibling( headers[columns - 1] ); line.append( headers[columns - 1] );
writeLine( rowId++, line ); writeLine( rowId++, line );
@@ -93,26 +93,26 @@ public interface TableFormatter
// it a tad prettier. // it a tad prettier.
int rowCharWidth = getWidth( HEADER ); int rowCharWidth = getWidth( HEADER );
int rowWidth = totalWidth / rowCharWidth + (totalWidth % rowCharWidth == 0 ? 0 : 1); int rowWidth = totalWidth / rowCharWidth + (totalWidth % rowCharWidth == 0 ? 0 : 1);
writeLine( rowId++, coloured( StringUtils.repeat( HEADER.getString(), rowWidth ), TextFormatting.GRAY ) ); writeLine( rowId++, coloured( StringUtils.repeat( HEADER.getText(), rowWidth ), ChatFormat.GRAY ) );
} }
for( ITextComponent[] row : table.getRows() ) for( Component[] row : table.getRows() )
{ {
TextComponentString line = new TextComponentString( "" ); TextComponent line = new TextComponent( "" );
for( int i = 0; i < columns - 1; i++ ) for( int i = 0; i < columns - 1; i++ )
{ {
line.appendSibling( row[i] ); line.append( row[i] );
ITextComponent padding = getPadding( row[i], maxWidths[i] ); Component padding = getPadding( row[i], maxWidths[i] );
if( padding != null ) line.appendSibling( padding ); if( padding != null ) line.append( padding );
line.appendSibling( SEPARATOR ); line.append( SEPARATOR );
} }
line.appendSibling( row[columns - 1] ); line.append( row[columns - 1] );
writeLine( rowId++, line ); writeLine( rowId++, line );
} }
if( table.getAdditional() > 0 ) if( table.getAdditional() > 0 )
{ {
writeLine( rowId++, coloured( translate( "commands.computercraft.generic.additional_rows", table.getAdditional() ), TextFormatting.AQUA ) ); writeLine( rowId++, coloured( translate( "commands.computercraft.generic.additional_rows", table.getAdditional() ), ChatFormat.AQUA ) );
} }
return rowId - table.getId(); return rowId - table.getId();

View File

@@ -6,86 +6,75 @@
package dan200.computercraft.shared.common; package dan200.computercraft.shared.common;
import dan200.computercraft.shared.util.NamedBlockEntityType;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.BlockEntityProvider;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.util.EnumFacing; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.EnumHand; import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; import net.minecraft.world.BlockView;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Random; import java.util.Random;
public abstract class BlockGeneric extends Block public abstract class BlockGeneric extends Block implements BlockEntityProvider
{ {
private final TileEntityType<? extends TileGeneric> type; private final BlockEntityType<? extends TileGeneric> type;
public BlockGeneric( Properties settings, TileEntityType<? extends TileGeneric> type ) public BlockGeneric( Settings settings, NamedBlockEntityType<? extends TileGeneric> type )
{ {
super( settings ); super( settings );
this.type = type; this.type = type;
type.setBlock( this );
} }
@Override @Override
@Deprecated @Deprecated
public final void onReplaced( @Nonnull IBlockState block, @Nonnull World world, @Nonnull BlockPos pos, IBlockState replace, boolean bool ) public final void onBlockRemoved( @Nonnull BlockState block, @Nonnull World world, @Nonnull BlockPos pos, BlockState replace, boolean bool )
{ {
if( block.getBlock() == replace.getBlock() ) return; if( block.getBlock() == replace.getBlock() ) return;
TileEntity tile = world.getTileEntity( pos ); BlockEntity tile = world.getBlockEntity( pos );
super.onReplaced( block, world, pos, replace, bool ); super.onBlockRemoved( block, world, pos, replace, bool );
world.removeTileEntity( pos ); world.removeBlockEntity( pos );
if( tile instanceof TileGeneric ) ((TileGeneric) tile).destroy(); if( tile instanceof TileGeneric ) ((TileGeneric) tile).destroy();
} }
@Override @Override
@Deprecated @Deprecated
public final boolean onBlockActivated( IBlockState state, World world, BlockPos pos, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ ) public final boolean activate( BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit )
{ {
TileEntity tile = world.getTileEntity( pos ); BlockEntity tile = world.getBlockEntity( pos );
return tile instanceof TileGeneric && ((TileGeneric) tile).onActivate( player, hand, side, hitX, hitY, hitZ ); return tile instanceof TileGeneric && ((TileGeneric) tile).onActivate( player, hand, hit );
} }
@Override @Override
@Deprecated @Deprecated
@SuppressWarnings( "deprecation" ) public final void neighborUpdate( BlockState state, World world, BlockPos pos, Block neighbourBlock, BlockPos neighbourPos, boolean flag )
public final void neighborChanged( IBlockState state, World world, BlockPos pos, Block neighbourBlock, BlockPos neighbourPos )
{ {
TileEntity tile = world.getTileEntity( pos ); super.neighborUpdate( state, world, pos, neighbourBlock, neighbourPos, flag );
BlockEntity tile = world.getBlockEntity( pos );
if( tile instanceof TileGeneric ) ((TileGeneric) tile).onNeighbourChange( neighbourPos ); if( tile instanceof TileGeneric ) ((TileGeneric) tile).onNeighbourChange( neighbourPos );
} }
@Override
public final void onNeighborChange( IBlockState state, IWorldReader world, BlockPos pos, BlockPos neighbour )
{
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TileGeneric ) ((TileGeneric) tile).onNeighbourTileEntityChange( neighbour );
}
@Override @Override
@Deprecated @Deprecated
public void tick( IBlockState state, World world, BlockPos pos, Random rand ) public void onScheduledTick( BlockState state, World world, BlockPos pos, Random rand )
{ {
TileEntity te = world.getTileEntity( pos ); BlockEntity te = world.getBlockEntity( pos );
if( te instanceof TileGeneric ) ((TileGeneric) te).blockTick(); if( te instanceof TileGeneric ) ((TileGeneric) te).blockTick();
} }
@Override
public boolean hasTileEntity( IBlockState state )
{
return true;
}
@Nullable @Nullable
@Override @Override
public TileEntity createTileEntity( @Nonnull IBlockState state, @Nonnull IBlockReader world ) public BlockEntity createBlockEntity( BlockView blockView )
{ {
return type.create(); return type.instantiate();
} }
} }

View File

@@ -7,7 +7,7 @@
package dan200.computercraft.shared.common; package dan200.computercraft.shared.common;
import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.core.terminal.Terminal;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.CompoundTag;
public class ClientTerminal implements ITerminal public class ClientTerminal implements ITerminal
{ {
@@ -47,12 +47,12 @@ public class ClientTerminal implements ITerminal
return m_colour; return m_colour;
} }
public void readDescription( NBTTagCompound nbt ) public void readDescription( CompoundTag nbt )
{ {
m_colour = nbt.getBoolean( "colour" ); m_colour = nbt.getBoolean( "colour" );
if( nbt.contains( "terminal" ) ) if( nbt.containsKey( "terminal" ) )
{ {
NBTTagCompound terminal = nbt.getCompound( "terminal" ); CompoundTag terminal = nbt.getCompound( "terminal" );
resizeTerminal( terminal.getInt( "term_width" ), terminal.getInt( "term_height" ) ); resizeTerminal( terminal.getInt( "term_width" ), terminal.getInt( "term_height" ) );
m_terminal.readFromNBT( terminal ); m_terminal.readFromNBT( terminal );
} }

View File

@@ -6,36 +6,35 @@
package dan200.computercraft.shared.common; package dan200.computercraft.shared.common;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.util.AbstractRecipe;
import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.ColourTracker; import dan200.computercraft.shared.util.ColourTracker;
import dan200.computercraft.shared.util.ColourUtils; import dan200.computercraft.shared.util.ColourUtils;
import net.minecraft.inventory.IInventory; import net.minecraft.inventory.CraftingInventory;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipeSerializer; import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.item.crafting.RecipeSerializers; import net.minecraft.recipe.SpecialCraftingRecipe;
import net.minecraft.util.ResourceLocation; import net.minecraft.recipe.SpecialRecipeSerializer;
import net.minecraft.util.DyeColor;
import net.minecraft.util.Identifier;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class ColourableRecipe extends AbstractRecipe public class ColourableRecipe extends SpecialCraftingRecipe
{ {
public ColourableRecipe( ResourceLocation id ) public ColourableRecipe( Identifier id )
{ {
super( id ); super( id );
} }
@Override @Override
public boolean matches( @Nonnull IInventory inv, @Nonnull World world ) public boolean matches( @Nonnull CraftingInventory inv, @Nonnull World world )
{ {
boolean hasColourable = false; boolean hasColourable = false;
boolean hasDye = false; boolean hasDye = false;
for( int i = 0; i < inv.getSizeInventory(); i++ ) for( int i = 0; i < inv.getInvSize(); i++ )
{ {
ItemStack stack = inv.getStackInSlot( i ); ItemStack stack = inv.getInvStack( i );
if( stack.isEmpty() ) continue; if( stack.isEmpty() ) continue;
if( stack.getItem() instanceof IColouredItem ) if( stack.getItem() instanceof IColouredItem )
@@ -58,15 +57,15 @@ public class ColourableRecipe extends AbstractRecipe
@Nonnull @Nonnull
@Override @Override
public ItemStack getCraftingResult( @Nonnull IInventory inv ) public ItemStack craft( @Nonnull CraftingInventory inv )
{ {
ItemStack colourable = ItemStack.EMPTY; ItemStack colourable = ItemStack.EMPTY;
ColourTracker tracker = new ColourTracker(); ColourTracker tracker = new ColourTracker();
for( int i = 0; i < inv.getSizeInventory(); i++ ) for( int i = 0; i < inv.getInvSize(); i++ )
{ {
ItemStack stack = inv.getStackInSlot( i ); ItemStack stack = inv.getInvStack( i );
if( stack.isEmpty() ) continue; if( stack.isEmpty() ) continue;
@@ -76,7 +75,7 @@ public class ColourableRecipe extends AbstractRecipe
} }
else else
{ {
EnumDyeColor dye = ColourUtils.getStackColour( stack ); DyeColor dye = ColourUtils.getStackColour( stack );
if( dye == null ) continue; if( dye == null ) continue;
Colour colour = Colour.fromInt( 15 - dye.getId() ); Colour colour = Colour.fromInt( 15 - dye.getId() );
@@ -89,19 +88,17 @@ public class ColourableRecipe extends AbstractRecipe
} }
@Override @Override
public boolean canFit( int x, int y ) public boolean fits( int x, int y )
{ {
return x >= 2 && y >= 2; return x >= 2 && y >= 2;
} }
@Override @Override
@Nonnull @Nonnull
public IRecipeSerializer<?> getSerializer() public RecipeSerializer<?> getSerializer()
{ {
return SERIALIZER; return SERIALIZER;
} }
public static final IRecipeSerializer<?> SERIALIZER = new RecipeSerializers.SimpleSerializer<>( public static final RecipeSerializer<?> SERIALIZER = new SpecialRecipeSerializer<>( ColourableRecipe::new );
ComputerCraft.MOD_ID + ":colour", ColourableRecipe::new
);
} }

View File

@@ -7,22 +7,23 @@
package dan200.computercraft.shared.common; package dan200.computercraft.shared.common;
import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.InventoryUtil;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.container.Container;
import net.minecraft.inventory.Container; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand; import net.minecraft.util.Hand;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class ContainerHeldItem extends Container public class ContainerHeldItem extends Container
{ {
private final ItemStack m_stack; private final ItemStack m_stack;
private final EnumHand m_hand; private final Hand m_hand;
public ContainerHeldItem( EntityPlayer player, EnumHand hand ) public ContainerHeldItem( int id, PlayerEntity player, Hand hand )
{ {
super( null, id );
m_hand = hand; m_hand = hand;
m_stack = InventoryUtil.copyItem( player.getHeldItem( hand ) ); m_stack = InventoryUtil.copyItem( player.getStackInHand( hand ) );
} }
@Nonnull @Nonnull
@@ -32,11 +33,11 @@ public class ContainerHeldItem extends Container
} }
@Override @Override
public boolean canInteractWith( @Nonnull EntityPlayer player ) public boolean canUse( @Nonnull PlayerEntity player )
{ {
if( !player.isAlive() ) return false; if( !player.isAlive() ) return false;
ItemStack stack = player.getHeldItem( m_hand ); ItemStack stack = player.getStackInHand( m_hand );
return stack == m_stack || !stack.isEmpty() && !m_stack.isEmpty() && stack.getItem() == m_stack.getItem(); return stack == m_stack || !stack.isEmpty() && !m_stack.isEmpty() && stack.getItem() == m_stack.getItem();
} }
} }

View File

@@ -8,8 +8,8 @@ package dan200.computercraft.shared.common;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider; import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -17,12 +17,12 @@ import javax.annotation.Nonnull;
public class DefaultBundledRedstoneProvider implements IBundledRedstoneProvider public class DefaultBundledRedstoneProvider implements IBundledRedstoneProvider
{ {
@Override @Override
public int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side ) public int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
{ {
return getDefaultBundledRedstoneOutput( world, pos, side ); return getDefaultBundledRedstoneOutput( world, pos, side );
} }
public static int getDefaultBundledRedstoneOutput( World world, BlockPos pos, EnumFacing side ) public static int getDefaultBundledRedstoneOutput( World world, BlockPos pos, Direction side )
{ {
Block block = world.getBlockState( pos ).getBlock(); Block block = world.getBlockState( pos ).getBlock();
if( block instanceof IBundledRedstoneBlock ) if( block instanceof IBundledRedstoneBlock )

View File

@@ -6,13 +6,13 @@
package dan200.computercraft.shared.common; package dan200.computercraft.shared.common;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
public interface IBundledRedstoneBlock public interface IBundledRedstoneBlock
{ {
boolean getBundledRedstoneConnectivity( World world, BlockPos pos, EnumFacing side ); boolean getBundledRedstoneConnectivity( World world, BlockPos pos, Direction side );
int getBundledRedstoneOutput( World world, BlockPos pos, EnumFacing side ); int getBundledRedstoneOutput( World world, BlockPos pos, Direction side );
} }

View File

@@ -7,7 +7,7 @@
package dan200.computercraft.shared.common; package dan200.computercraft.shared.common;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.CompoundTag;
public interface IColouredItem public interface IColouredItem
{ {
@@ -27,15 +27,15 @@ public interface IColouredItem
static int getColourBasic( ItemStack stack ) static int getColourBasic( ItemStack stack )
{ {
NBTTagCompound tag = stack.getTag(); CompoundTag tag = stack.getTag();
return tag != null && tag.contains( NBT_COLOUR ) ? tag.getInt( NBT_COLOUR ) : -1; return tag != null && tag.containsKey( NBT_COLOUR ) ? tag.getInt( NBT_COLOUR ) : -1;
} }
static void setColourBasic( ItemStack stack, int colour ) static void setColourBasic( ItemStack stack, int colour )
{ {
if( colour == -1 ) if( colour == -1 )
{ {
NBTTagCompound tag = stack.getTag(); CompoundTag tag = stack.getTag();
if( tag != null ) tag.remove( NBT_COLOUR ); if( tag != null ) tag.remove( NBT_COLOUR );
} }
else else

View File

@@ -7,7 +7,7 @@
package dan200.computercraft.shared.common; package dan200.computercraft.shared.common;
import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.core.terminal.Terminal;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.CompoundTag;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@@ -86,12 +86,12 @@ public class ServerTerminal implements ITerminal
// Networking stuff // Networking stuff
public void writeDescription( NBTTagCompound nbt ) public void writeDescription( CompoundTag nbt )
{ {
nbt.putBoolean( "colour", m_colour ); nbt.putBoolean( "colour", m_colour );
if( m_terminal != null ) if( m_terminal != null )
{ {
NBTTagCompound terminal = new NBTTagCompound(); CompoundTag terminal = new CompoundTag();
terminal.putInt( "term_width", m_terminal.getWidth() ); terminal.putInt( "term_width", m_terminal.getWidth() );
terminal.putInt( "term_height", m_terminal.getHeight() ); terminal.putInt( "term_height", m_terminal.getHeight() );
m_terminal.writeToNBT( terminal ); m_terminal.writeToNBT( terminal );

View File

@@ -6,22 +6,21 @@
package dan200.computercraft.shared.common; package dan200.computercraft.shared.common;
import net.minecraft.block.state.IBlockState; import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.block.BlockState;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.network.NetworkManager; import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.network.play.server.SPacketUpdateTileEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.tileentity.TileEntity; import net.minecraft.nbt.CompoundTag;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Hand;
import net.minecraft.util.EnumFacing; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public abstract class TileGeneric extends TileEntity public abstract class TileGeneric extends BlockEntity implements BlockEntityClientSerializable
{ {
public TileGeneric( TileEntityType<? extends TileGeneric> type ) public TileGeneric( BlockEntityType<? extends TileGeneric> type )
{ {
super( type ); super( type );
} }
@@ -34,12 +33,12 @@ public abstract class TileGeneric extends TileEntity
{ {
markDirty(); markDirty();
BlockPos pos = getPos(); BlockPos pos = getPos();
IBlockState state = getBlockState(); BlockState state = getCachedState();
getWorld().markBlockRangeForRenderUpdate( pos, pos ); getWorld().scheduleBlockRender( pos );
getWorld().notifyBlockUpdate( pos, state, state, 3 ); getWorld().updateListeners( pos, state, state, 3 );
} }
public boolean onActivate( EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ ) public boolean onActivate( PlayerEntity player, Hand hand, BlockHitResult hit )
{ {
return false; return false;
} }
@@ -56,58 +55,40 @@ public abstract class TileGeneric extends TileEntity
{ {
} }
protected double getInteractRange( EntityPlayer player ) protected double getInteractRange( PlayerEntity player )
{ {
return 8.0; return 8.0;
} }
public boolean isUsable( EntityPlayer player, boolean ignoreRange ) public boolean isUsable( PlayerEntity player, boolean ignoreRange )
{ {
if( player == null || !player.isAlive() || getWorld().getTileEntity( getPos() ) != this ) return false; if( player == null || !player.isAlive() || getWorld().getBlockEntity( getPos() ) != this ) return false;
if( ignoreRange ) return true; if( ignoreRange ) return true;
double range = getInteractRange( player ); double range = getInteractRange( player );
BlockPos pos = getPos(); BlockPos pos = getPos();
return player.getEntityWorld() == getWorld() && return player.getEntityWorld() == getWorld() &&
player.getDistanceSq( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ) <= range * range; player.squaredDistanceTo( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ) <= range * range;
} }
protected void writeDescription( @Nonnull NBTTagCompound nbt ) protected void writeDescription( @Nonnull CompoundTag nbt )
{ {
} }
protected void readDescription( @Nonnull NBTTagCompound nbt ) protected void readDescription( @Nonnull CompoundTag nbt )
{ {
} }
@Nonnull
@Override
public final SPacketUpdateTileEntity getUpdatePacket()
{
NBTTagCompound nbt = new NBTTagCompound();
writeDescription( nbt );
return new SPacketUpdateTileEntity( pos, 0, nbt );
}
@Override @Override
public final void onDataPacket( NetworkManager net, SPacketUpdateTileEntity packet ) public final CompoundTag toClientTag( CompoundTag tag )
{ {
if( packet.getTileEntityType() == 0 ) readDescription( packet.getNbtCompound() );
}
@Nonnull
@Override
public NBTTagCompound getUpdateTag()
{
NBTTagCompound tag = super.getUpdateTag();
writeDescription( tag ); writeDescription( tag );
return tag; return tag;
} }
@Override @Override
public void handleUpdateTag( @Nonnull NBTTagCompound tag ) public final void fromClientTag( CompoundTag tag )
{ {
super.handleUpdateTag( tag );
readDescription( tag ); readDescription( tag );
} }
} }

View File

@@ -16,16 +16,16 @@ import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.shared.computer.blocks.TileCommandComputer; import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
import dan200.computercraft.shared.util.NBTUtil; import dan200.computercraft.shared.util.NBTUtil;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.BlockState;
import net.minecraft.command.CommandSource; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.command.Commands; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.state.IProperty; import net.minecraft.server.command.CommandManager;
import net.minecraft.tileentity.TileEntity; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.state.property.Property;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.registries.ForgeRegistries;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Collections; import java.util.Collections;
@@ -76,17 +76,17 @@ public class CommandAPI implements ILuaAPI
private Object[] doCommand( String command ) private Object[] doCommand( String command )
{ {
MinecraftServer server = m_computer.getWorld().getServer(); MinecraftServer server = m_computer.getWorld().getServer();
if( server == null || !server.isCommandBlockEnabled() ) if( server == null || !server.areCommandBlocksEnabled() )
{ {
return new Object[] { false, createOutput( "Command blocks disabled by server" ) }; return new Object[] { false, createOutput( "Command blocks disabled by server" ) };
} }
Commands commandManager = server.getCommandManager(); CommandManager commandManager = server.getCommandManager();
TileCommandComputer.CommandReceiver receiver = m_computer.getReceiver(); TileCommandComputer.CommandReceiver receiver = m_computer.getReceiver();
try try
{ {
receiver.clearOutput(); receiver.clearOutput();
int result = commandManager.handleCommand( m_computer.getSource(), command ); int result = commandManager.execute( m_computer.getSource(), command );
return new Object[] { result > 0, receiver.copyOutput() }; return new Object[] { result > 0, receiver.copyOutput() };
} }
catch( Throwable t ) catch( Throwable t )
@@ -99,31 +99,31 @@ public class CommandAPI implements ILuaAPI
private static Object getBlockInfo( World world, BlockPos pos ) private static Object getBlockInfo( World world, BlockPos pos )
{ {
// Get the details of the block // Get the details of the block
IBlockState state = world.getBlockState( pos ); BlockState state = world.getBlockState( pos );
Block block = state.getBlock(); Block block = state.getBlock();
Map<Object, Object> table = new HashMap<>(); Map<Object, Object> table = new HashMap<>();
table.put( "name", ForgeRegistries.BLOCKS.getKey( block ).toString() ); table.put( "name", Registry.BLOCK.getId( block ).toString() );
Map<Object, Object> stateTable = new HashMap<>(); Map<Object, Object> stateTable = new HashMap<>();
for( ImmutableMap.Entry<IProperty<?>, Comparable<?>> entry : state.getValues().entrySet() ) for( ImmutableMap.Entry<Property<?>, Comparable<?>> entry : state.getEntries().entrySet() )
{ {
IProperty<?> property = entry.getKey(); Property<?> property = entry.getKey();
stateTable.put( property.getName(), getPropertyValue( property, entry.getValue() ) ); stateTable.put( property.getName(), getPropertyValue( property, entry.getValue() ) );
} }
table.put( "state", stateTable ); table.put( "state", stateTable );
TileEntity tile = world.getTileEntity( pos ); BlockEntity tile = world.getBlockEntity( pos );
if( tile != null ) table.put( "nbt", NBTUtil.toLua( tile.write( new NBTTagCompound() ) ) ); if( tile != null ) table.put( "nbt", NBTUtil.toLua( tile.toTag( new CompoundTag() ) ) );
return table; return table;
} }
@SuppressWarnings( { "unchecked", "rawtypes" } ) @SuppressWarnings( { "unchecked", "rawtypes" } )
private static Object getPropertyValue( IProperty property, Comparable value ) private static Object getPropertyValue( Property property, Comparable value )
{ {
if( value instanceof String || value instanceof Number || value instanceof Boolean ) return value; if( value instanceof String || value instanceof Number || value instanceof Boolean ) return value;
return property.getName( value ); return property.getValueAsString( value );
} }
@Override @Override
@@ -149,7 +149,7 @@ public class CommandAPI implements ILuaAPI
MinecraftServer server = m_computer.getWorld().getServer(); MinecraftServer server = m_computer.getWorld().getServer();
if( server == null ) return new Object[] { Collections.emptyMap() }; if( server == null ) return new Object[] { Collections.emptyMap() };
CommandNode<CommandSource> node = server.getCommandManager().getDispatcher().getRoot(); CommandNode<ServerCommandSource> node = server.getCommandManager().getDispatcher().getRoot();
for( int j = 0; j < arguments.length; j++ ) for( int j = 0; j < arguments.length; j++ )
{ {
String name = getString( arguments, j ); String name = getString( arguments, j );

View File

@@ -9,16 +9,16 @@ package dan200.computercraft.shared.computer.blocks;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ComputerState; import dan200.computercraft.shared.computer.core.ComputerState;
import dan200.computercraft.shared.computer.items.ComputerItemFactory; import dan200.computercraft.shared.computer.items.ComputerItemFactory;
import dan200.computercraft.shared.util.NamedBlockEntityType;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.state.DirectionProperty; import net.minecraft.state.StateFactory;
import net.minecraft.state.EnumProperty; import net.minecraft.state.property.DirectionProperty;
import net.minecraft.state.StateContainer; import net.minecraft.state.property.EnumProperty;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.property.Properties;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.math.Direction;
import net.minecraft.util.EnumFacing;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -26,28 +26,28 @@ import javax.annotation.Nullable;
public class BlockComputer extends BlockComputerBase<TileComputer> public class BlockComputer extends BlockComputerBase<TileComputer>
{ {
public static final EnumProperty<ComputerState> STATE = EnumProperty.create( "state", ComputerState.class ); public static final EnumProperty<ComputerState> STATE = EnumProperty.create( "state", ComputerState.class );
public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; public static final DirectionProperty FACING = Properties.FACING_HORIZONTAL;
public BlockComputer( Properties settings, ComputerFamily family, TileEntityType<? extends TileComputer> type ) public BlockComputer( Settings settings, ComputerFamily family, NamedBlockEntityType<? extends TileComputer> type )
{ {
super( settings, family, type ); super( settings, family, type );
setDefaultState( getDefaultState() setDefaultState( getDefaultState()
.with( FACING, EnumFacing.NORTH ) .with( FACING, Direction.NORTH )
.with( STATE, ComputerState.OFF ) .with( STATE, ComputerState.OFF )
); );
} }
@Override @Override
protected void fillStateContainer( StateContainer.Builder<Block, IBlockState> builder ) protected void appendProperties( StateFactory.Builder<Block, BlockState> builder )
{ {
builder.add( FACING, STATE ); builder.add( FACING, STATE );
} }
@Nullable @Nullable
@Override @Override
public IBlockState getStateForPlacement( BlockItemUseContext placement ) public BlockState getPlacementState( ItemPlacementContext placement )
{ {
return getDefaultState().with( FACING, placement.getPlacementHorizontalFacing().getOpposite() ); return getDefaultState().with( FACING, placement.getPlayerHorizontalFacing().getOpposite() );
} }
@Nonnull @Nonnull

View File

@@ -6,33 +6,36 @@
package dan200.computercraft.shared.computer.blocks; package dan200.computercraft.shared.computer.blocks;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.core.computer.ComputerSide; import dan200.computercraft.core.computer.ComputerSide;
import dan200.computercraft.shared.common.BlockGeneric; import dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.common.IBundledRedstoneBlock; import dan200.computercraft.shared.common.IBundledRedstoneBlock;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.computer.items.IComputerItem; import dan200.computercraft.shared.computer.items.IComputerItem;
import net.minecraft.block.state.IBlockState; import dan200.computercraft.shared.util.NamedBlockEntityType;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.block.BlockState;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.fluid.IFluidState; import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Identifier;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Direction;
import net.minecraft.world.IBlockReader; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.loot.context.LootContext;
import net.minecraft.world.loot.context.LootContextParameters;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.List;
public abstract class BlockComputerBase<T extends TileComputerBase> extends BlockGeneric implements IBundledRedstoneBlock public abstract class BlockComputerBase<T extends TileComputerBase> extends BlockGeneric implements IBundledRedstoneBlock
{ {
private static final Identifier COMPUTER_DROP = new Identifier( ComputerCraft.MOD_ID, "computer" );
private final ComputerFamily family; private final ComputerFamily family;
protected BlockComputerBase( Properties settings, ComputerFamily family, TileEntityType<? extends T> type ) protected BlockComputerBase( Settings settings, ComputerFamily family, NamedBlockEntityType<? extends T> type )
{ {
super( settings, type ); super( settings, type );
this.family = family; this.family = family;
@@ -40,26 +43,26 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
@Override @Override
@Deprecated @Deprecated
public void onBlockAdded( IBlockState state, World world, BlockPos pos, IBlockState oldState ) public void onBlockAdded( BlockState state, World world, BlockPos pos, BlockState oldState, boolean flag )
{ {
super.onBlockAdded( state, world, pos, oldState ); super.onBlockAdded( state, world, pos, oldState, flag );
TileEntity tile = world.getTileEntity( pos ); BlockEntity tile = world.getBlockEntity( pos );
if( tile instanceof TileComputerBase ) ((TileComputerBase) tile).updateInput(); if( tile instanceof TileComputerBase ) ((TileComputerBase) tile).updateInput();
} }
@Override @Override
@Deprecated @Deprecated
public boolean canProvidePower( IBlockState state ) public boolean emitsRedstonePower( BlockState state )
{ {
return true; return true;
} }
@Override @Override
@Deprecated @Deprecated
public int getStrongPower( IBlockState state, IBlockReader world, BlockPos pos, EnumFacing incomingSide ) public int getStrongRedstonePower( BlockState state, BlockView world, BlockPos pos, Direction incomingSide )
{ {
TileEntity entity = world.getTileEntity( pos ); BlockEntity entity = world.getBlockEntity( pos );
if( !(entity instanceof TileComputerBase) ) return 0; if( !(entity instanceof TileComputerBase) ) return 0;
TileComputerBase computerEntity = (TileComputerBase) entity; TileComputerBase computerEntity = (TileComputerBase) entity;
@@ -80,21 +83,21 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
@Override @Override
@Deprecated @Deprecated
public int getWeakPower( IBlockState state, IBlockReader world, BlockPos pos, EnumFacing incomingSide ) public int getWeakRedstonePower( BlockState state, BlockView world, BlockPos pos, Direction incomingSide )
{ {
return getStrongPower( state, world, pos, incomingSide ); return getStrongRedstonePower( state, world, pos, incomingSide );
} }
@Override @Override
public boolean getBundledRedstoneConnectivity( World world, BlockPos pos, EnumFacing side ) public boolean getBundledRedstoneConnectivity( World world, BlockPos pos, Direction side )
{ {
return true; return true;
} }
@Override @Override
public int getBundledRedstoneOutput( World world, BlockPos pos, EnumFacing side ) public int getBundledRedstoneOutput( World world, BlockPos pos, Direction side )
{ {
TileEntity entity = world.getTileEntity( pos ); BlockEntity entity = world.getBlockEntity( pos );
if( !(entity instanceof TileComputerBase) ) return 0; if( !(entity instanceof TileComputerBase) ) return 0;
TileComputerBase computerEntity = (TileComputerBase) entity; TileComputerBase computerEntity = (TileComputerBase) entity;
@@ -107,63 +110,37 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
@Nonnull @Nonnull
@Override @Override
public ItemStack getPickBlock( IBlockState state, RayTraceResult target, IBlockReader world, BlockPos pos, EntityPlayer player ) public ItemStack getPickStack( BlockView world, BlockPos pos, BlockState state )
{ {
TileEntity tile = world.getTileEntity( pos ); BlockEntity tile = world.getBlockEntity( pos );
if( tile instanceof TileComputerBase ) if( tile instanceof TileComputerBase )
{ {
ItemStack result = getItem( (TileComputerBase) tile ); ItemStack result = getItem( (TileComputerBase) tile );
if( !result.isEmpty() ) return result; if( !result.isEmpty() ) return result;
} }
return super.getPickBlock( state, target, world, pos, player ); return super.getPickStack( world, pos, state );
} }
@Override @Override
@Deprecated @Deprecated
public final void dropBlockAsItemWithChance( @Nonnull IBlockState state, World world, @Nonnull BlockPos pos, float change, int fortune ) public List<ItemStack> getDroppedStacks( BlockState state, LootContext.Builder builder )
{ {
// TODO: Find a way of doing creative block drops
builder.putDrop( COMPUTER_DROP, ( context, consumer ) -> {
BlockEntity tile = context.get( LootContextParameters.BLOCK_ENTITY );
if( tile instanceof TileComputerBase ) consumer.accept( getItem( (TileComputerBase) tile ) );
} );
return super.getDroppedStacks( state, builder );
} }
@Override @Override
public final void getDrops( IBlockState state, NonNullList<ItemStack> drops, World world, BlockPos pos, int fortune ) public void onPlaced( World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack )
{ {
TileEntity tile = world.getTileEntity( pos ); super.onPlaced( world, pos, state, placer, stack );
if( tile instanceof TileComputerBase )
{
ItemStack stack = getItem( (TileComputerBase) tile );
if( !stack.isEmpty() ) drops.add( stack );
}
}
@Override BlockEntity tile = world.getBlockEntity( pos );
public boolean removedByPlayer( IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest, IFluidState fluid ) if( !world.isClient && tile instanceof IComputerTile && stack.getItem() instanceof IComputerItem )
{
if( !world.isRemote )
{
// We drop the item here instead of doing it in the harvest method, as we
// need to drop it for creative players too.
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TileComputerBase )
{
TileComputerBase computer = (TileComputerBase) tile;
if( !player.abilities.isCreativeMode || computer.getLabel() != null )
{
spawnAsEntity( world, pos, getItem( computer ) );
}
}
}
return super.removedByPlayer( state, world, pos, player, willHarvest, fluid );
}
@Override
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack )
{
super.onBlockPlacedBy( world, pos, state, placer, stack );
TileEntity tile = world.getTileEntity( pos );
if( !world.isRemote && tile instanceof IComputerTile && stack.getItem() instanceof IComputerItem )
{ {
IComputerTile computer = (IComputerTile) tile; IComputerTile computer = (IComputerTile) tile;
IComputerItem item = (IComputerItem) stack.getItem(); IComputerItem item = (IComputerItem) stack.getItem();

View File

@@ -11,31 +11,30 @@ import dan200.computercraft.shared.computer.apis.CommandAPI;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.util.NamedBlockEntityType; import dan200.computercraft.shared.util.NamedBlockEntityType;
import net.minecraft.command.CommandSource; import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.command.ICommandSource; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.server.command.CommandOutput;
import net.minecraft.util.ResourceLocation; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Vec2f; import net.minecraft.util.math.Vec2f;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.WorldServer;
import javax.annotation.Nonnull;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class TileCommandComputer extends TileComputer public class TileCommandComputer extends TileComputer
{ {
public static final NamedBlockEntityType<TileCommandComputer> FACTORY = NamedBlockEntityType.create( public static final NamedBlockEntityType<TileCommandComputer> FACTORY = NamedBlockEntityType.create(
new ResourceLocation( ComputerCraft.MOD_ID, "command_computer" ), new Identifier( ComputerCraft.MOD_ID, "command_computer" ),
f -> new TileCommandComputer( ComputerFamily.Command, f ) f -> new TileCommandComputer( ComputerFamily.Command, f )
); );
public class CommandReceiver implements ICommandSource public class CommandReceiver implements CommandOutput
{ {
private final Map<Integer, String> output = new HashMap<>(); private final Map<Integer, String> output = new HashMap<>();
@@ -55,25 +54,25 @@ public class TileCommandComputer extends TileComputer
} }
@Override @Override
public void sendMessage( @Nonnull ITextComponent textComponent ) public void sendMessage( Component textComponent )
{ {
output.put( output.size() + 1, textComponent.getString() ); output.put( output.size() + 1, textComponent.getText() );
} }
@Override @Override
public boolean shouldReceiveFeedback() public boolean sendCommandFeedback()
{ {
return getWorld().getGameRules().getBoolean( "sendCommandFeedback" ); return getWorld().getGameRules().getBoolean( "sendCommandFeedback" );
} }
@Override @Override
public boolean shouldReceiveErrors() public boolean shouldTrackOutput()
{ {
return true; return true;
} }
@Override @Override
public boolean allowLogging() public boolean shouldBroadcastConsoleToOps()
{ {
return getWorld().getGameRules().getBoolean( "commandBlockOutput" ); return getWorld().getGameRules().getBoolean( "commandBlockOutput" );
} }
@@ -81,7 +80,7 @@ public class TileCommandComputer extends TileComputer
private final CommandReceiver receiver; private final CommandReceiver receiver;
public TileCommandComputer( ComputerFamily family, TileEntityType<? extends TileCommandComputer> type ) public TileCommandComputer( ComputerFamily family, BlockEntityType<? extends TileCommandComputer> type )
{ {
super( family, type ); super( family, type );
receiver = new CommandReceiver(); receiver = new CommandReceiver();
@@ -92,7 +91,7 @@ public class TileCommandComputer extends TileComputer
return receiver; return receiver;
} }
public CommandSource getSource() public ServerCommandSource getSource()
{ {
ServerComputer computer = getServerComputer(); ServerComputer computer = getServerComputer();
String name = "@"; String name = "@";
@@ -102,10 +101,10 @@ public class TileCommandComputer extends TileComputer
if( label != null ) name = label; if( label != null ) name = label;
} }
return new CommandSource( receiver, return new ServerCommandSource( receiver,
new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ), Vec2f.ZERO, new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ), Vec2f.ZERO,
(WorldServer) getWorld(), 2, (ServerWorld) getWorld(), 2,
name, new TextComponentString( name ), name, new TextComponent( name ),
getWorld().getServer(), null getWorld().getServer(), null
); );
} }
@@ -119,17 +118,17 @@ public class TileCommandComputer extends TileComputer
} }
@Override @Override
public boolean isUsable( EntityPlayer player, boolean ignoreRange ) public boolean isUsable( PlayerEntity player, boolean ignoreRange )
{ {
MinecraftServer server = player.getServer(); MinecraftServer server = player.getServer();
if( server == null || !server.isCommandBlockEnabled() ) if( server == null || !server.areCommandBlocksEnabled() )
{ {
player.sendStatusMessage( new TextComponentTranslation( "advMode.notEnabled" ), true ); player.addChatMessage( new TranslatableComponent( "advMode.notEnabled" ), true );
return false; return false;
} }
else if( !player.canUseCommandBlock() ) else if( !player.isCreativeLevelTwoOp() )
{ {
player.sendStatusMessage( new TextComponentTranslation( "advMode.notAllowed" ), true ); player.addChatMessage( new TranslatableComponent( "advMode.notAllowed" ), true );
return false; return false;
} }
else else

View File

@@ -13,27 +13,27 @@ import dan200.computercraft.shared.computer.core.ComputerState;
import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.network.Containers; import dan200.computercraft.shared.network.Containers;
import dan200.computercraft.shared.util.NamedBlockEntityType; import dan200.computercraft.shared.util.NamedBlockEntityType;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.EnumFacing; import net.minecraft.util.Identifier;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Direction;
public class TileComputer extends TileComputerBase public class TileComputer extends TileComputerBase
{ {
public static final NamedBlockEntityType<TileComputer> FACTORY_NORMAL = NamedBlockEntityType.create( public static final NamedBlockEntityType<TileComputer> FACTORY_NORMAL = NamedBlockEntityType.create(
new ResourceLocation( ComputerCraft.MOD_ID, "computer_normal" ), new Identifier( ComputerCraft.MOD_ID, "computer_normal" ),
f -> new TileComputer( ComputerFamily.Normal, f ) f -> new TileComputer( ComputerFamily.Normal, f )
); );
public static final NamedBlockEntityType<TileComputer> FACTORY_ADVANCED = NamedBlockEntityType.create( public static final NamedBlockEntityType<TileComputer> FACTORY_ADVANCED = NamedBlockEntityType.create(
new ResourceLocation( ComputerCraft.MOD_ID, "computer_advanced" ), new Identifier( ComputerCraft.MOD_ID, "computer_advanced" ),
f -> new TileComputer( ComputerFamily.Advanced, f ) f -> new TileComputer( ComputerFamily.Advanced, f )
); );
private ComputerProxy m_proxy; private ComputerProxy m_proxy;
public TileComputer( ComputerFamily family, TileEntityType<? extends TileComputer> type ) public TileComputer( ComputerFamily family, BlockEntityType<? extends TileComputer> type )
{ {
super( type, family ); super( type, family );
} }
@@ -69,26 +69,26 @@ public class TileComputer extends TileComputerBase
} }
@Override @Override
public void openGUI( EntityPlayer player ) public void openGUI( PlayerEntity player )
{ {
Containers.openComputerGUI( player, this ); Containers.openComputerGUI( player, this );
} }
public boolean isUsableByPlayer( EntityPlayer player ) public boolean isUsableByPlayer( PlayerEntity player )
{ {
return isUsable( player, false ); return isUsable( player, false );
} }
@Override @Override
public EnumFacing getDirection() public Direction getDirection()
{ {
return getBlockState().get( BlockComputer.FACING ); return getCachedState().get( BlockComputer.FACING );
} }
@Override @Override
protected void updateBlockState( ComputerState newState ) protected void updateBlockState( ComputerState newState )
{ {
IBlockState existing = getBlockState(); BlockState existing = getCachedState();
if( existing.get( BlockComputer.STATE ) != newState ) if( existing.get( BlockComputer.STATE ) != newState )
{ {
getWorld().setBlockState( getPos(), existing.with( BlockComputer.STATE, newState ), 3 ); getWorld().setBlockState( getPos(), existing.with( BlockComputer.STATE, newState ), 3 );

View File

@@ -20,28 +20,29 @@ import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.util.DirectionUtil; import dan200.computercraft.shared.util.DirectionUtil;
import dan200.computercraft.shared.util.RedstoneUtil; import dan200.computercraft.shared.util.RedstoneUtil;
import joptsimple.internal.Strings; import joptsimple.internal.Strings;
import net.minecraft.block.BlockRedstoneWire; import net.minecraft.block.BlockState;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.Blocks;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.block.RedstoneWireBlock;
import net.minecraft.init.Blocks; import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.init.Items; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.item.Items;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.EnumFacing; import net.minecraft.network.chat.Component;
import net.minecraft.util.EnumHand; import net.minecraft.network.chat.TextComponent;
import net.minecraft.util.INameable; import net.minecraft.util.Hand;
import net.minecraft.util.ITickable; import net.minecraft.util.Nameable;
import net.minecraft.util.Tickable;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.math.Direction;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Objects; import java.util.Objects;
public abstract class TileComputerBase extends TileGeneric implements IComputerTile, ITickable, IPeripheralTile, INameable public abstract class TileComputerBase extends TileGeneric implements IComputerTile, Tickable, IPeripheralTile, Nameable
{ {
private static final String NBT_ID = "ComputerId"; private static final String NBT_ID = "ComputerId";
private static final String NBT_LABEL = "Label"; private static final String NBT_LABEL = "Label";
@@ -57,7 +58,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
private final ComputerFamily family; private final ComputerFamily family;
public TileComputerBase( TileEntityType<? extends TileGeneric> type, ComputerFamily family ) public TileComputerBase( BlockEntityType<? extends TileGeneric> type, ComputerFamily family )
{ {
super( type ); super( type );
this.family = family; this.family = family;
@@ -67,7 +68,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
{ {
if( m_instanceID >= 0 ) if( m_instanceID >= 0 )
{ {
if( !getWorld().isRemote ) ComputerCraft.serverComputerRegistry.remove( m_instanceID ); if( !getWorld().isClient ) ComputerCraft.serverComputerRegistry.remove( m_instanceID );
m_instanceID = -1; m_instanceID = -1;
} }
} }
@@ -76,50 +77,52 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
public void destroy() public void destroy()
{ {
unload(); unload();
for( EnumFacing dir : DirectionUtil.FACINGS ) for( Direction dir : DirectionUtil.FACINGS )
{ {
RedstoneUtil.propagateRedstoneOutput( getWorld(), getPos(), dir ); RedstoneUtil.propagateRedstoneOutput( getWorld(), getPos(), dir );
} }
} }
/*
@Override @Override
public void onChunkUnloaded() public void onChunkUnloaded()
{ {
unload(); unload();
} }
*/
@Override @Override
public void remove() public void invalidate()
{ {
unload(); unload();
super.remove(); super.invalidate();
} }
public abstract void openGUI( EntityPlayer player ); public abstract void openGUI( PlayerEntity player );
protected boolean canNameWithTag( EntityPlayer player ) protected boolean canNameWithTag( PlayerEntity player )
{ {
return false; return false;
} }
@Override @Override
public boolean onActivate( EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ ) public boolean onActivate( PlayerEntity player, Hand hand, BlockHitResult hit )
{ {
ItemStack currentItem = player.getHeldItem( hand ); ItemStack currentItem = player.getStackInHand( hand );
if( !currentItem.isEmpty() && currentItem.getItem() == Items.NAME_TAG && canNameWithTag( player ) && currentItem.hasDisplayName() ) if( !currentItem.isEmpty() && currentItem.getItem() == Items.NAME_TAG && canNameWithTag( player ) && currentItem.hasDisplayName() )
{ {
// Label to rename computer // Label to rename computer
if( !getWorld().isRemote ) if( !getWorld().isClient )
{ {
setLabel( currentItem.getDisplayName().getString() ); setLabel( currentItem.getDisplayName().getText() );
currentItem.shrink( 1 ); currentItem.subtractAmount( 1 );
} }
return true; return true;
} }
else if( !player.isSneaking() ) else if( !player.isSneaking() )
{ {
// Regular right click to activate computer // Regular right click to activate computer
if( !getWorld().isRemote && isUsable( player, false ) ) if( !getWorld().isClient && isUsable( player, false ) )
{ {
createServerComputer().turnOn(); createServerComputer().turnOn();
openGUI( player ); openGUI( player );
@@ -144,7 +147,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
@Override @Override
public void tick() public void tick()
{ {
if( !getWorld().isRemote ) if( !getWorld().isClient )
{ {
ServerComputer computer = createServerComputer(); ServerComputer computer = createServerComputer();
if( computer == null ) return; if( computer == null ) return;
@@ -182,24 +185,24 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
@Nonnull @Nonnull
@Override @Override
public NBTTagCompound write( NBTTagCompound nbt ) public CompoundTag toTag( CompoundTag nbt )
{ {
// Save ID, label and power state // Save ID, label and power state
if( m_computerID >= 0 ) nbt.putInt( NBT_ID, m_computerID ); if( m_computerID >= 0 ) nbt.putInt( NBT_ID, m_computerID );
if( m_label != null ) nbt.putString( NBT_LABEL, m_label ); if( m_label != null ) nbt.putString( NBT_LABEL, m_label );
nbt.putBoolean( NBT_ON, m_on ); nbt.putBoolean( NBT_ON, m_on );
return super.write( nbt ); return super.toTag( nbt );
} }
@Override @Override
public void read( NBTTagCompound nbt ) public void fromTag( CompoundTag nbt )
{ {
super.read( nbt ); super.fromTag( nbt );
// Load ID, label and power state // Load ID, label and power state
m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1; m_computerID = nbt.containsKey( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
m_label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null; m_label = nbt.containsKey( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null;
m_on = m_startOn = nbt.getBoolean( NBT_ON ); m_on = m_startOn = nbt.getBoolean( NBT_ON );
} }
@@ -208,9 +211,9 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
return false; return false;
} }
protected abstract EnumFacing getDirection(); protected abstract Direction getDirection();
protected ComputerSide remapToLocalSide( EnumFacing globalSide ) protected ComputerSide remapToLocalSide( Direction globalSide )
{ {
return remapLocalSide( DirectionUtil.toLocal( getDirection(), globalSide ) ); return remapLocalSide( DirectionUtil.toLocal( getDirection(), globalSide ) );
} }
@@ -220,9 +223,9 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
return localSide; return localSide;
} }
private void updateSideInput( ServerComputer computer, EnumFacing dir, BlockPos offset ) private void updateSideInput( ServerComputer computer, Direction dir, BlockPos offset )
{ {
EnumFacing offsetSide = dir.getOpposite(); Direction offsetSide = dir.getOpposite();
ComputerSide localDir = remapToLocalSide( dir ); ComputerSide localDir = remapToLocalSide( dir );
computer.setRedstoneInput( localDir, getRedstoneInput( world, offset, dir ) ); computer.setRedstoneInput( localDir, getRedstoneInput( world, offset, dir ) );
@@ -240,29 +243,29 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
* @param pos The position of the neighbour * @param pos The position of the neighbour
* @param side The side we are reading from * @param side The side we are reading from
* @return The effective redstone power * @return The effective redstone power
* @see net.minecraft.block.BlockRedstoneDiode#calculateInputStrength(World, BlockPos, IBlockState) * @see net.minecraft.block.RedstoneBlock#method_9991(World, BlockPos, BlockState)
*/ */
protected static int getRedstoneInput( World world, BlockPos pos, EnumFacing side ) protected static int getRedstoneInput( World world, BlockPos pos, Direction side )
{ {
int power = world.getRedstonePower( pos, side ); int power = world.getEmittedRedstonePower( pos, side );
if( power >= 15 ) return power; if( power >= 15 ) return power;
IBlockState neighbour = world.getBlockState( pos ); BlockState neighbour = world.getBlockState( pos );
return neighbour.getBlock() == Blocks.REDSTONE_WIRE return neighbour.getBlock() == Blocks.REDSTONE_WIRE
? Math.max( power, neighbour.get( BlockRedstoneWire.POWER ) ) ? Math.max( power, neighbour.get( RedstoneWireBlock.POWER ) )
: power; : power;
} }
public void updateInput() public void updateInput()
{ {
if( getWorld() == null || getWorld().isRemote ) return; if( getWorld() == null || getWorld().isClient ) return;
// Update all sides // Update all sides
ServerComputer computer = getServerComputer(); ServerComputer computer = getServerComputer();
if( computer == null ) return; if( computer == null ) return;
BlockPos pos = computer.getPosition(); BlockPos pos = computer.getPosition();
for( EnumFacing dir : DirectionUtil.FACINGS ) for( Direction dir : DirectionUtil.FACINGS )
{ {
updateSideInput( computer, dir, pos.offset( dir ) ); updateSideInput( computer, dir, pos.offset( dir ) );
} }
@@ -270,13 +273,13 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
private void updateInput( BlockPos neighbour ) private void updateInput( BlockPos neighbour )
{ {
if( getWorld() == null || getWorld().isRemote ) return; if( getWorld() == null || getWorld().isClient ) return;
ServerComputer computer = getServerComputer(); ServerComputer computer = getServerComputer();
if( computer == null ) return; if( computer == null ) return;
BlockPos pos = computer.getPosition(); BlockPos pos = computer.getPosition();
for( EnumFacing dir : DirectionUtil.FACINGS ) for( Direction dir : DirectionUtil.FACINGS )
{ {
BlockPos offset = pos.offset( dir ); BlockPos offset = pos.offset( dir );
if( offset.equals( neighbour ) ) if( offset.equals( neighbour ) )
@@ -294,7 +297,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
{ {
// Update redstone // Update redstone
updateBlock(); updateBlock();
for( EnumFacing dir : DirectionUtil.FACINGS ) for( Direction dir : DirectionUtil.FACINGS )
{ {
RedstoneUtil.propagateRedstoneOutput( getWorld(), getPos(), dir ); RedstoneUtil.propagateRedstoneOutput( getWorld(), getPos(), dir );
} }
@@ -319,7 +322,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
@Override @Override
public final void setComputerID( int id ) public final void setComputerID( int id )
{ {
if( getWorld().isRemote || m_computerID == id ) return; if( getWorld().isClient || m_computerID == id ) return;
m_computerID = id; m_computerID = id;
ServerComputer computer = getServerComputer(); ServerComputer computer = getServerComputer();
@@ -330,7 +333,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
@Override @Override
public final void setLabel( String label ) public final void setLabel( String label )
{ {
if( getWorld().isRemote || Objects.equals( m_label, label ) ) return; if( getWorld().isClient || Objects.equals( m_label, label ) ) return;
m_label = label; m_label = label;
ServerComputer computer = getServerComputer(); ServerComputer computer = getServerComputer();
@@ -346,7 +349,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
public ServerComputer createServerComputer() public ServerComputer createServerComputer()
{ {
if( getWorld().isRemote ) return null; if( getWorld().isClient ) return null;
boolean changed = false; boolean changed = false;
if( m_instanceID < 0 ) if( m_instanceID < 0 )
@@ -371,12 +374,12 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
public ServerComputer getServerComputer() public ServerComputer getServerComputer()
{ {
return getWorld().isRemote ? null : ComputerCraft.serverComputerRegistry.get( m_instanceID ); return getWorld().isClient ? null : ComputerCraft.serverComputerRegistry.get( m_instanceID );
} }
public ClientComputer createClientComputer() public ClientComputer createClientComputer()
{ {
if( !getWorld().isRemote || m_instanceID < 0 ) return null; if( !getWorld().isClient || m_instanceID < 0 ) return null;
ClientComputer computer = ComputerCraft.clientComputerRegistry.get( m_instanceID ); ClientComputer computer = ComputerCraft.clientComputerRegistry.get( m_instanceID );
if( computer == null ) if( computer == null )
@@ -388,13 +391,13 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
public ClientComputer getClientComputer() public ClientComputer getClientComputer()
{ {
return getWorld().isRemote ? ComputerCraft.clientComputerRegistry.get( m_instanceID ) : null; return getWorld().isClient ? ComputerCraft.clientComputerRegistry.get( m_instanceID ) : null;
} }
// Networking stuff // Networking stuff
@Override @Override
protected void writeDescription( @Nonnull NBTTagCompound nbt ) protected void writeDescription( @Nonnull CompoundTag nbt )
{ {
super.writeDescription( nbt ); super.writeDescription( nbt );
@@ -404,12 +407,12 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
} }
@Override @Override
protected void readDescription( @Nonnull NBTTagCompound nbt ) protected void readDescription( @Nonnull CompoundTag nbt )
{ {
super.readDescription( nbt ); super.readDescription( nbt );
m_instanceID = nbt.contains( NBT_INSTANCE ) ? nbt.getInt( NBT_INSTANCE ) : -1; m_instanceID = nbt.containsKey( NBT_INSTANCE ) ? nbt.getInt( NBT_INSTANCE ) : -1;
m_label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null; m_label = nbt.containsKey( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null;
m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1; m_computerID = nbt.containsKey( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
} }
protected void transferStateFrom( TileComputerBase copy ) protected void transferStateFrom( TileComputerBase copy )
@@ -429,16 +432,16 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
@Nullable @Nullable
@Override @Override
public IPeripheral getPeripheral( @Nonnull EnumFacing side ) public IPeripheral getPeripheral( @Nonnull Direction side )
{ {
return new ComputerPeripheral( "computer", createProxy() ); return new ComputerPeripheral( "computer", createProxy() );
} }
@Nonnull @Nonnull
@Override @Override
public ITextComponent getName() public Component getName()
{ {
return hasCustomName() ? new TextComponentString( m_label ) : getBlockState().getBlock().getNameTextComponent(); return hasCustomName() ? new TextComponent( m_label ) : getCachedState().getBlock().getTextComponent();
} }
@Override @Override
@@ -449,8 +452,8 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
@Nullable @Nullable
@Override @Override
public ITextComponent getCustomName() public Component getCustomName()
{ {
return hasCustomName() ? new TextComponentString( m_label ) : null; return hasCustomName() ? new TextComponent( m_label ) : null;
} }
} }

View File

@@ -10,7 +10,7 @@ import com.google.common.base.Objects;
import dan200.computercraft.shared.common.ClientTerminal; import dan200.computercraft.shared.common.ClientTerminal;
import dan200.computercraft.shared.network.NetworkHandler; import dan200.computercraft.shared.network.NetworkHandler;
import dan200.computercraft.shared.network.server.*; import dan200.computercraft.shared.network.server.*;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.CompoundTag;
public class ClientComputer extends ClientTerminal implements IComputer public class ClientComputer extends ClientTerminal implements IComputer
{ {
@@ -19,7 +19,7 @@ public class ClientComputer extends ClientTerminal implements IComputer
private boolean m_on = false; private boolean m_on = false;
private boolean m_blinking = false; private boolean m_blinking = false;
private boolean m_changed = true; private boolean m_changed = true;
private NBTTagCompound m_userData = null; private CompoundTag m_userData = null;
private boolean m_changedLastFrame = false; private boolean m_changedLastFrame = false;
@@ -40,7 +40,7 @@ public class ClientComputer extends ClientTerminal implements IComputer
return m_changedLastFrame; return m_changedLastFrame;
} }
public NBTTagCompound getUserData() public CompoundTag getUserData()
{ {
return m_userData; return m_userData;
} }
@@ -135,11 +135,11 @@ public class ClientComputer extends ClientTerminal implements IComputer
NetworkHandler.sendToServer( new MouseEventServerMessage( m_instanceID, MouseEventServerMessage.TYPE_SCROLL, direction, x, y ) ); NetworkHandler.sendToServer( new MouseEventServerMessage( m_instanceID, MouseEventServerMessage.TYPE_SCROLL, direction, x, y ) );
} }
public void setState( ComputerState state, NBTTagCompound userData ) public void setState( ComputerState state, CompoundTag userData )
{ {
boolean oldOn = m_on; boolean oldOn = m_on;
boolean oldBlinking = m_blinking; boolean oldBlinking = m_blinking;
NBTTagCompound oldUserData = m_userData; CompoundTag oldUserData = m_userData;
m_on = state != ComputerState.OFF; m_on = state != ComputerState.OFF;
m_blinking = state == ComputerState.BLINKING; m_blinking = state == ComputerState.BLINKING;

View File

@@ -6,11 +6,11 @@
package dan200.computercraft.shared.computer.core; package dan200.computercraft.shared.computer.core;
import net.minecraft.util.IStringSerializable; import net.minecraft.util.StringIdentifiable;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public enum ComputerState implements IStringSerializable public enum ComputerState implements StringIdentifiable
{ {
OFF( "off" ), OFF( "off" ),
ON( "on" ), ON( "on" ),
@@ -25,7 +25,7 @@ public enum ComputerState implements IStringSerializable
@Nonnull @Nonnull
@Override @Override
public String getName() public String asString()
{ {
return name; return name;
} }

View File

@@ -22,14 +22,13 @@ import dan200.computercraft.shared.network.NetworkMessage;
import dan200.computercraft.shared.network.client.ComputerDataClientMessage; import dan200.computercraft.shared.network.client.ComputerDataClientMessage;
import dan200.computercraft.shared.network.client.ComputerDeletedClientMessage; import dan200.computercraft.shared.network.client.ComputerDeletedClientMessage;
import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage; import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.SharedConstants;
import net.minecraft.inventory.Container; import net.minecraft.container.Container;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import net.minecraftforge.versions.mcp.MCPVersion;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.io.InputStream; import java.io.InputStream;
@@ -43,7 +42,7 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
private final ComputerFamily m_family; private final ComputerFamily m_family;
private final Computer m_computer; private final Computer m_computer;
private NBTTagCompound m_userData; private CompoundTag m_userData;
private boolean m_changed; private boolean m_changed;
private boolean m_changedLastFrame; private boolean m_changedLastFrame;
@@ -134,11 +133,11 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
m_computer.unload(); m_computer.unload();
} }
public NBTTagCompound getUserData() public CompoundTag getUserData()
{ {
if( m_userData == null ) if( m_userData == null )
{ {
m_userData = new NBTTagCompound(); m_userData = new CompoundTag();
} }
return m_userData; return m_userData;
} }
@@ -155,26 +154,28 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
protected NetworkMessage createTerminalPacket() protected NetworkMessage createTerminalPacket()
{ {
NBTTagCompound tagCompound = new NBTTagCompound(); CompoundTag tagCompound = new CompoundTag();
writeDescription( tagCompound ); writeDescription( tagCompound );
return new ComputerTerminalClientMessage( getInstanceID(), tagCompound ); return new ComputerTerminalClientMessage( getInstanceID(), tagCompound );
} }
public void broadcastState( boolean force ) public void broadcastState( boolean force )
{ {
MinecraftServer server = m_world == null ? null : m_world.getServer();
if( server == null ) return;
if( hasOutputChanged() || force ) if( hasOutputChanged() || force )
{ {
// Send computer state to all clients // Send computer state to all clients
NetworkHandler.sendToAllPlayers( createComputerPacket() ); NetworkHandler.sendToAllPlayers( server, createComputerPacket() );
} }
if( hasTerminalChanged() || force ) if( hasTerminalChanged() || force )
{ {
// Send terminal state to clients who are currently interacting with the computer. // Send terminal state to clients who are currently interacting with the computer.
MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
NetworkMessage packet = null; NetworkMessage packet = null;
for( EntityPlayer player : server.getPlayerList().getPlayers() ) for( PlayerEntity player : server.getPlayerManager().getPlayerList() )
{ {
if( isInteracting( player ) ) if( isInteracting( player ) )
{ {
@@ -185,13 +186,13 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
} }
} }
public void sendComputerState( EntityPlayer player ) public void sendComputerState( PlayerEntity player )
{ {
// Send state to client // Send state to client
NetworkHandler.sendToPlayer( player, createComputerPacket() ); NetworkHandler.sendToPlayer( player, createComputerPacket() );
} }
public void sendTerminalState( EntityPlayer player ) public void sendTerminalState( PlayerEntity player )
{ {
// Send terminal state to client // Send terminal state to client
NetworkHandler.sendToPlayer( player, createTerminalPacket() ); NetworkHandler.sendToPlayer( player, createTerminalPacket() );
@@ -200,7 +201,9 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
public void broadcastDelete() public void broadcastDelete()
{ {
// Send deletion to client // Send deletion to client
NetworkHandler.sendToAllPlayers( new ComputerDeletedClientMessage( getInstanceID() ) ); MinecraftServer server = m_world == null ? null : m_world.getServer();
if( server == null ) return;
NetworkHandler.sendToAllPlayers( server, new ComputerDeletedClientMessage( getInstanceID() ) );
} }
public void setID( int id ) public void setID( int id )
@@ -311,13 +314,13 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
@Override @Override
public double getTimeOfDay() public double getTimeOfDay()
{ {
return (m_world.getGameTime() + 6000) % 24000 / 1000.0; return (m_world.getTime() + 6000) % 24000 / 1000.0;
} }
@Override @Override
public int getDay() public int getDay()
{ {
return (int) ((m_world.getGameTime() + 6000) / 24000) + 1; return (int) ((m_world.getTime() + 6000) / 24000) + 1;
} }
@Override @Override
@@ -347,7 +350,7 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
@Override @Override
public String getHostString() public String getHostString()
{ {
return "ComputerCraft ${version} (Minecraft " + MCPVersion.getMCVersion() + ")"; return "ComputerCraft ${version} (Minecraft " + SharedConstants.getGameVersion() + ")";
} }
@Override @Override
@@ -357,18 +360,18 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
} }
@Nullable @Nullable
public IContainerComputer getContainer( EntityPlayer player ) public IContainerComputer getContainer( PlayerEntity player )
{ {
if( player == null ) return null; if( player == null ) return null;
Container container = player.openContainer; Container container = player.container;
if( !(container instanceof IContainerComputer) ) return null; if( !(container instanceof IContainerComputer) ) return null;
IContainerComputer computerContainer = (IContainerComputer) container; IContainerComputer computerContainer = (IContainerComputer) container;
return computerContainer.getComputer() != this ? null : computerContainer; return computerContainer.getComputer() != this ? null : computerContainer;
} }
protected boolean isInteracting( EntityPlayer player ) protected boolean isInteracting( PlayerEntity player )
{ {
return getContainer( player ) != null; return getContainer( player ) != null;
} }

View File

@@ -10,8 +10,8 @@ import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.IComputer; import dan200.computercraft.shared.computer.core.IComputer;
import dan200.computercraft.shared.computer.core.IContainerComputer; import dan200.computercraft.shared.computer.core.IContainerComputer;
import dan200.computercraft.shared.computer.core.InputState; import dan200.computercraft.shared.computer.core.InputState;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.container.Container;
import net.minecraft.inventory.Container; import net.minecraft.entity.player.PlayerEntity;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -21,13 +21,14 @@ public class ContainerComputer extends Container implements IContainerComputer
private final TileComputer computer; private final TileComputer computer;
private final InputState input = new InputState( this ); private final InputState input = new InputState( this );
public ContainerComputer( TileComputer computer ) public ContainerComputer( int id, TileComputer computer )
{ {
super( null, id );
this.computer = computer; this.computer = computer;
} }
@Override @Override
public boolean canInteractWith( @Nonnull EntityPlayer player ) public boolean canUse( @Nonnull PlayerEntity player )
{ {
return computer.isUsableByPlayer( player ); return computer.isUsableByPlayer( player );
} }
@@ -47,9 +48,9 @@ public class ContainerComputer extends Container implements IContainerComputer
} }
@Override @Override
public void onContainerClosed( EntityPlayer player ) public void close( PlayerEntity player )
{ {
super.onContainerClosed( player ); super.close( player );
input.close(); input.close();
} }
} }

View File

@@ -8,10 +8,10 @@ package dan200.computercraft.shared.computer.inventory;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.computer.core.*; import dan200.computercraft.shared.computer.core.*;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.container.Container;
import net.minecraft.inventory.Container; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.TextComponentTranslation;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -21,8 +21,9 @@ public class ContainerViewComputer extends Container implements IContainerComput
private final IComputer computer; private final IComputer computer;
private final InputState input = new InputState( this ); private final InputState input = new InputState( this );
public ContainerViewComputer( IComputer computer ) public ContainerViewComputer( int id, IComputer computer )
{ {
super( null, id );
this.computer = computer; this.computer = computer;
} }
@@ -34,7 +35,7 @@ public class ContainerViewComputer extends Container implements IContainerComput
} }
@Override @Override
public boolean canInteractWith( @Nonnull EntityPlayer player ) public boolean canUse( @Nonnull PlayerEntity player )
{ {
if( computer instanceof ServerComputer ) if( computer instanceof ServerComputer )
{ {
@@ -50,14 +51,14 @@ public class ContainerViewComputer extends Container implements IContainerComput
if( serverComputer.getFamily() == ComputerFamily.Command ) if( serverComputer.getFamily() == ComputerFamily.Command )
{ {
MinecraftServer server = player.getServer(); MinecraftServer server = player.getServer();
if( server == null || !server.isCommandBlockEnabled() ) if( server == null || !server.areCommandBlocksEnabled() )
{ {
player.sendStatusMessage( new TextComponentTranslation( "advMode.notEnabled" ), false ); player.addChatMessage( new TranslatableComponent( "advMode.notEnabled" ), false );
return false; return false;
} }
else if( !player.canUseCommandBlock() ) else if( !player.isCreativeLevelTwoOp() )
{ {
player.sendStatusMessage( new TextComponentTranslation( "advMode.notAllowed" ), false ); player.addChatMessage( new TranslatableComponent( "advMode.notAllowed" ), false );
return false; return false;
} }
} }
@@ -74,9 +75,9 @@ public class ContainerViewComputer extends Container implements IContainerComput
} }
@Override @Override
public void onContainerClosed( EntityPlayer player ) public void close( PlayerEntity player )
{ {
super.onContainerClosed( player ); super.close( player );
input.close(); input.close();
} }
} }

View File

@@ -8,7 +8,7 @@ package dan200.computercraft.shared.computer.items;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.CompoundTag;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -18,8 +18,8 @@ public interface IComputerItem
default int getComputerID( @Nonnull ItemStack stack ) default int getComputerID( @Nonnull ItemStack stack )
{ {
NBTTagCompound nbt = stack.getTag(); CompoundTag nbt = stack.getTag();
return nbt != null && nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1; return nbt != null && nbt.containsKey( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
} }
default String getLabel( @Nonnull ItemStack stack ) default String getLabel( @Nonnull ItemStack stack )

View File

@@ -9,13 +9,13 @@ package dan200.computercraft.shared.computer.items;
import dan200.computercraft.shared.computer.blocks.BlockComputer; import dan200.computercraft.shared.computer.blocks.BlockComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.text.TextComponentString; import net.minecraft.network.chat.TextComponent;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class ItemComputer extends ItemComputerBase public class ItemComputer extends ItemComputerBase
{ {
public ItemComputer( BlockComputer block, Properties settings ) public ItemComputer( BlockComputer block, Settings settings )
{ {
super( block, settings ); super( block, settings );
} }
@@ -24,7 +24,7 @@ public class ItemComputer extends ItemComputerBase
{ {
ItemStack result = new ItemStack( this ); ItemStack result = new ItemStack( this );
if( id >= 0 ) result.getOrCreateTag().putInt( NBT_ID, id ); if( id >= 0 ) result.getOrCreateTag().putInt( NBT_ID, id );
if( label != null ) result.setDisplayName( new TextComponentString( label ) ); if( label != null ) result.setDisplayName( new TextComponent( label ) );
return result; return result;
} }

View File

@@ -12,39 +12,39 @@ import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.media.IMedia; import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.shared.computer.blocks.BlockComputerBase; import dan200.computercraft.shared.computer.blocks.BlockComputerBase;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import net.minecraft.client.util.ITooltipFlag; import net.minecraft.ChatFormat;
import net.minecraft.item.ItemBlock; import net.minecraft.client.item.TooltipContext;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent; import net.minecraft.network.chat.Component;
import net.minecraft.util.text.TextComponentString; import net.minecraft.network.chat.TextComponent;
import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.List; import java.util.List;
public abstract class ItemComputerBase extends ItemBlock implements IComputerItem, IMedia public abstract class ItemComputerBase extends BlockItem implements IComputerItem, IMedia
{ {
private final ComputerFamily family; private final ComputerFamily family;
public ItemComputerBase( BlockComputerBase<?> block, Properties settings ) public ItemComputerBase( BlockComputerBase<?> block, Settings settings )
{ {
super( block, settings ); super( block, settings );
family = block.getFamily(); family = block.getFamily();
} }
@Override @Override
public void addInformation( @Nonnull ItemStack stack, @Nullable World world, @Nonnull List<ITextComponent> list, @Nonnull ITooltipFlag options ) public void buildTooltip( @Nonnull ItemStack stack, @Nullable World world, @Nonnull List<Component> list, @Nonnull TooltipContext options )
{ {
if( options.isAdvanced() ) if( options.isAdvanced() )
{ {
int id = getComputerID( stack ); int id = getComputerID( stack );
if( id >= 0 ) if( id >= 0 )
{ {
list.add( new TextComponentTranslation( "gui.computercraft.tooltip.computer_id", id ) list.add( new TranslatableComponent( "gui.computercraft.tooltip.computer_id", id )
.applyTextStyle( TextFormatting.GRAY ) ); .applyFormat( ChatFormat.GRAY ) );
} }
} }
} }
@@ -52,7 +52,7 @@ public abstract class ItemComputerBase extends ItemBlock implements IComputerIte
@Override @Override
public String getLabel( @Nonnull ItemStack stack ) public String getLabel( @Nonnull ItemStack stack )
{ {
return IComputerItem.super.getLabel( stack ); return stack.hasDisplayName() ? stack.getDisplayName().getString() : null;
} }
@Override @Override
@@ -68,11 +68,11 @@ public abstract class ItemComputerBase extends ItemBlock implements IComputerIte
{ {
if( label != null ) if( label != null )
{ {
stack.setDisplayName( new TextComponentString( label ) ); stack.setDisplayName( new TextComponent( label ) );
} }
else else
{ {
stack.clearCustomName(); stack.removeDisplayName();
} }
return true; return true;
} }

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