Compare commits

..

1 Commits

Author SHA1 Message Date
Sebastian Hartte 53f7046f93 Metrics WIP 2020-09-10 18:55:22 +02:00
559 changed files with 2039 additions and 2589 deletions
+1 -2
View File
@@ -2,8 +2,7 @@ name: 'Build PRs'
on: on:
pull_request: pull_request:
branches: branches: [ master ]
- '*'
jobs: jobs:
build: build:
+3 -4
View File
@@ -25,9 +25,9 @@ A Mod about Matter, Energy and using them to conquer the world..
## Contacts ## Contacts
* [Website](http://ae-mod.info/) * [Website](http://ae-mod.info/)
* [Discord](https://discord.gg/GygKjjm)
* [GitHub](https://github.com/AppliedEnergistics/Applied-Energistics-2)
* [IRC #appliedenergistics on esper.net](http://webchat.esper.net/?channels=appliedenergistics&prompt=1) * [IRC #appliedenergistics on esper.net](http://webchat.esper.net/?channels=appliedenergistics&prompt=1)
* [GitHub](https://github.com/AppliedEnergistics/Applied-Energistics-2)
* [Discord](https://discord.gg/GygKjjm)
## License ## License
@@ -38,7 +38,7 @@ A Mod about Matter, Energy and using them to conquer the world..
- (c) 2013 - 2020 AlgorithmX2 et al - (c) 2013 - 2020 AlgorithmX2 et al
- [![License](https://img.shields.io/badge/License-LGPLv3-blue.svg?style=flat-square)](https://raw.githubusercontent.com/AppliedEnergistics/Applied-Energistics-2/rv2/LICENSE) - [![License](https://img.shields.io/badge/License-LGPLv3-blue.svg?style=flat-square)](https://raw.githubusercontent.com/AppliedEnergistics/Applied-Energistics-2/rv2/LICENSE)
* Textures and Models * Textures and Models
- (c) 2020, [Ridanisaurus Rid](https://github.com/Ridanisaurus/), (c) 2013 - 2020 AlgorithmX2 et al - (c) 2013 - 2020 AlgorithmX2 et al
- [![License](https://img.shields.io/badge/License-CC%20BY--NC--SA%203.0-yellow.svg?style=flat-square)](https://creativecommons.org/licenses/by-nc-sa/3.0/) - [![License](https://img.shields.io/badge/License-CC%20BY--NC--SA%203.0-yellow.svg?style=flat-square)](https://creativecommons.org/licenses/by-nc-sa/3.0/)
* Text and Translations * Text and Translations
- [![License](https://img.shields.io/badge/License-No%20Restriction-green.svg?style=flat-square)](https://creativecommons.org/publicdomain/zero/1.0/) - [![License](https://img.shields.io/badge/License-No%20Restriction-green.svg?style=flat-square)](https://creativecommons.org/publicdomain/zero/1.0/)
@@ -185,5 +185,4 @@ Thanks to
* Notch et al for Minecraft * Notch et al for Minecraft
* Lex et al for MinecraftForge * Lex et al for MinecraftForge
* AlgorithmX2 for AppliedEnergistics2 * AlgorithmX2 for AppliedEnergistics2
* [Ridanisaurus Rid](https://github.com/Ridanisaurus/) for the new 2020 textures
* all [contributors](https://github.com/AppliedEnergistics/Applied-Energistics-2/graphs/contributors) * all [contributors](https://github.com/AppliedEnergistics/Applied-Energistics-2/graphs/contributors)
+23 -159
View File
@@ -30,10 +30,11 @@ buildscript {
} }
plugins { plugins {
id "maven-publish" id "maven-publish"
id "com.diffplug.gradle.spotless" version "4.3.0" id "com.diffplug.gradle.spotless" version "4.3.0"
id "com.matthewprenger.cursegradle" version "1.4.0" id "com.matthewprenger.cursegradle" version "1.4.0"
id "idea" id "org.sonarqube" version "2.8"
id "jacoco"
} }
apply plugin: 'net.minecraftforge.gradle' apply plugin: 'net.minecraftforge.gradle'
@@ -44,32 +45,8 @@ repositories {
mavenLocal() mavenLocal()
jcenter() jcenter()
mavenCentral() mavenCentral()
maven { // modmaven, maven proxy
name 'modmaven'
url "https://modmaven.k-4u.nl/"
}
} }
dependencies {
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
// compile against provided APIs
compileOnly "mezz.jei:jei-${jei_minecraft_version}:${jei_version}:api"
compileOnly "mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}:api"
// Runtime, Mods
runtimeOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}:${jei_version}")
runtimeOnly fg.deobf("mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}")
// unit test dependencies
testCompile "junit:junit:4.13"
// Annotation Processors
annotationProcessor 'org.spongepowered:mixin:0.8:processor'
}
group = artifact_group
archivesBaseName = artifact_basename
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8
compileJava { compileJava {
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8
@@ -81,8 +58,7 @@ tasks.withType(JavaCompile) {
options.encoding = 'UTF-8' options.encoding = 'UTF-8'
} }
/////////////////// // Create version number
// Version Number
version = version_major + "." + version_minor + "." + version_patch version = version_major + "." + version_minor + "." + version_patch
ext.pr = System.getenv('PR_NUMBER') ?: "" ext.pr = System.getenv('PR_NUMBER') ?: ""
@@ -100,8 +76,10 @@ if (ext.release) {
version = ext.release version = ext.release
} }
ext.isAlpha = project.version.contains("alpha")
ext.isBeta = project.version.contains("beta") // Maven group and artifact name
group = artifact_group
archivesBaseName = artifact_basename
sourceSets { sourceSets {
api api
@@ -125,8 +103,9 @@ configurations {
apiCompile.extendsFrom(compile) apiCompile.extendsFrom(compile)
} }
//////////////////// apply from: 'gradle/scripts/dependencies.gradle'
// Forge/Minecraft apply from: 'gradle/scripts/spotless.gradle'
minecraft { minecraft {
mappings channel: "snapshot", version: project.mcp_mappings mappings channel: "snapshot", version: project.mcp_mappings
@@ -157,9 +136,6 @@ minecraft {
data { data {
property 'forge.logging.console.level', 'debug' property 'forge.logging.console.level', 'debug'
workingDirectory project.file('run') workingDirectory project.file('run')
// ForgeGradle will just force-exit the Gradle Daemon which fails our builds in case
// a daemon is used for any reason.
forceExit false
args '--mod', 'appliedenergistics2', '--all', '--output', file('src/generated/resources/') args '--mod', 'appliedenergistics2', '--all', '--output', file('src/generated/resources/')
mods { mods {
appliedenergistics2 { appliedenergistics2 {
@@ -171,14 +147,18 @@ minecraft {
} }
} }
///////////
// Mixins
mixin { mixin {
add sourceSets.main, "appliedenergistics2.mixins.refmap.json" add sourceSets.main, "appliedenergistics2.mixins.refmap.json"
} }
//////////////// jar {
// Jar Signing manifest {
attributes([
"MixinConfigs": "appliedenergistics2.mixins.json"
])
}
}
def signProps = [:] def signProps = [:]
if (System.getenv("KEY_STORE_FILE")) { if (System.getenv("KEY_STORE_FILE")) {
signProps['keyStore'] = System.getenv("KEY_STORE_FILE") signProps['keyStore'] = System.getenv("KEY_STORE_FILE")
@@ -201,75 +181,9 @@ task signJar(type: net.minecraftforge.gradle.common.task.SignJar, dependsOn: 're
} }
} }
////////////// apply from: 'gradle/scripts/artifacts.gradle'
// Aritfacts apply from: 'gradle/scripts/curseforge.gradle'
processResources {
exclude '.cache'
}
jar {
finalizedBy 'reobfJar'
finalizedBy 'signJar'
from sourceSets.main.output.classesDirs
from sourceSets.api.output.classesDirs
from sourceSets.main.output.resourcesDir
from sourceSets.api.output.resourcesDir
manifest {
attributes([
"Specification-Title": "Applied Energistics 2",
"Specification-Vendor": "TeamAppliedEnergistics",
"Specification-Version": "${project.version}",
"Implementation-Title": "${project.name}",
"Implementation-Version": "${project.version}",
"Implementation-Vendor" :"TeamAppliedEnergistics",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
"MixinConfigs": "appliedenergistics2.mixins.json"
])
}
}
task javadocs(type: Javadoc) {
classpath = sourceSets.main.compileClasspath
source = sourceSets.api.java
include "appeng/api/**"
options.addStringOption('Xdoclint:none', '-quiet')
options.encoding = 'UTF-8'
options.charSet = 'UTF-8'
}
task javadocJar(type: Jar, dependsOn: javadocs) {
classifier = "javadoc"
from javadoc.destinationDir
}
task sourcesJar(type: Jar) {
classifier = "sources"
from sourceSets.main.allJava
from sourceSets.api.allJava
}
task apiJar(type: Jar) {
classifier = "api"
from sourceSets.api.output
include "appeng/api/**"
// TODO: when FG bug is fixed, remove allJava from the api jar.
// https://github.com/MinecraftForge/ForgeGradle/issues/369
// Gradle should be able to pull them from the -sources jar.
from sourceSets.api.allJava
}
artifacts {
archives javadocJar
archives sourcesJar
archives apiJar
}
//////////////////
// Maven publish
publishing { publishing {
publications { publications {
maven(MavenPublication) { maven(MavenPublication) {
@@ -308,53 +222,3 @@ publishing {
} }
} }
} }
/////////////
// Spotless
spotless {
java {
target 'src/*/java/appeng/**/*.java'
indentWithSpaces()
eclipse().configFile 'codeformat/codeformat.xml'
importOrderFile 'codeformat/ae2.importorder'
}
format 'json', {
target 'src/*/resources/**/*.json'
targetExclude 'src/generated/resources/**'
prettier().config(['parser': 'json'])
}
}
////////////////
// Curse Forge
if (System.getenv("CURSEFORGE")) {
def cfReleaseType = "release"
if (ext.isAlpha) {
cfReleaseType = "alpha"
} else if (ext.isBeta) {
cfReleaseType = "beta"
}
curseforge {
apiKey = System.getenv("CURSEFORGE")
project {
id = project.curseforge_project
changelogType = "markdown"
changelog = System.getenv("CHANGELOG") ?: "Please visit our [releases](https://github.com/AppliedEnergistics/Applied-Energistics-2/releases) for a changelog"
releaseType = cfReleaseType
}
}
}
////////////////
// IntelliJ Project Import
// The Mixin annotation process does not have an obfuscation source when running through the IntelliJ compiler,
// thus we have to prevent it from being activated as part of importing this Gradle project into IntelliJ.
if (System.getProperty("idea.sync.active") == "true") {
afterEvaluate {
tasks.withType(JavaCompile).all {
it.options.annotationProcessorPath = files()
}
}
}
+3 -3
View File
@@ -9,9 +9,9 @@ artifact_basename=appliedenergistics2
# Minecraft Versions # # Minecraft Versions #
######################################################### #########################################################
minecraft_release=1.16 minecraft_release=1.16
minecraft_version=1.16.3 minecraft_version=1.16.2
mcp_mappings=20200916-1.16.2 mcp_mappings=20200723-1.16.1
forge_version=34.0.8 forge_version=33.0.42
######################################################### #########################################################
# Provided APIs # # Provided APIs #
+81
View File
@@ -0,0 +1,81 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
processResources {
exclude '.cache'
}
jar {
finalizedBy 'reobfJar'
finalizedBy 'signJar'
from sourceSets.main.output.classesDirs
from sourceSets.api.output.classesDirs
from sourceSets.main.output.resourcesDir
from sourceSets.api.output.resourcesDir
manifest {
attributes([
"Specification-Title": "Applied Energistics 2",
"Specification-Vendor": "TeamAppliedEnergistics",
"Specification-Version": "${project.version}",
"Implementation-Title": "${project.name}",
"Implementation-Version": "${project.version}",
"Implementation-Vendor" :"TeamAppliedEnergistics",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
])
}
}
task javadocs(type: Javadoc) {
classpath = sourceSets.main.compileClasspath
source = sourceSets.api.java
include "appeng/api/**"
options.addStringOption('Xdoclint:none', '-quiet')
options.encoding = 'UTF-8'
options.charSet = 'UTF-8'
}
task javadocJar(type: Jar, dependsOn: javadocs) {
classifier = "javadoc"
from javadoc.destinationDir
}
task sourcesJar(type: Jar) {
classifier = "sources"
from sourceSets.main.allJava
from sourceSets.api.allJava
}
task apiJar(type: Jar) {
classifier = "api"
from sourceSets.api.output
include "appeng/api/**"
// TODO: when FG bug is fixed, remove allJava from the api jar.
// https://github.com/MinecraftForge/ForgeGradle/issues/369
// Gradle should be able to pull them from the -sources jar.
from sourceSets.api.allJava
}
artifacts {
archives javadocJar
archives sourcesJar
archives apiJar
}
+39
View File
@@ -0,0 +1,39 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2020, TeamAppliedEnergistics, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*g GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
def isAlpha = project.version.contains("alpha")
def isBeta = project.version.contains("beta")
def cfReleaseType = "release"
if (isAlpha) {
cfReleaseType = "alpha"
} else if (isBeta) {
cfReleaseType = "beta"
}
if (System.getenv("CURSEFORGE")) {
curseforge {
apiKey = System.getenv("CURSEFORGE")
project {
id = project.curseforge_project
changelogType = "markdown"
changelog = System.getenv("CHANGELOG") ?: "Please visit our [releases](https://github.com/AppliedEnergistics/Applied-Energistics-2/releases) for a changelog"
releaseType = cfReleaseType
}
}
}
+42
View File
@@ -0,0 +1,42 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
repositories {
mavenLocal()
maven { // modmaven, maven proxy
name 'modmaven'
url "https://modmaven.k-4u.nl/"
}
}
dependencies {
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
// compile against provided APIs
compileOnly "mezz.jei:jei-${jei_minecraft_version}:${jei_version}:api"
compileOnly "mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}:api"
// Runtime, Mods
runtimeOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}:${jei_version}")
runtimeOnly fg.deobf("mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}")
//runtimeOnly fg.deobf("team.chisel.ctm:CTM:${ctm_version}")
// unit test dependencies
testCompile "junit:junit:4.13"
}
+32
View File
@@ -0,0 +1,32 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2020, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*g GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
spotless {
java {
target 'src/*/java/appeng/**/*.java'
indentWithSpaces()
eclipse().configFile 'codeformat/codeformat.xml'
importOrderFile 'codeformat/ae2.importorder'
}
format 'json', {
target 'src/*/resources/**/*.json'
targetExclude 'src/generated/resources/**'
prettier().config(['parser': 'json'])
}
}
Binary file not shown.
+1 -1
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-5.6.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
@@ -28,9 +28,4 @@ public enum GridNotification {
* the visible connections for this node have changed, useful for cable. * the visible connections for this node have changed, useful for cable.
*/ */
CONNECTIONS_CHANGED, CONNECTIONS_CHANGED,
/**
* the owner of the grid node has changed, and the node needs to be re-saved
*/
OWNER_CHANGED
} }
@@ -87,8 +87,7 @@ public interface IGridBlock {
AEColor getGridColor(); AEColor getGridColor();
/** /**
* Called by the {@link IGridNode} to notify its {@link IGridBlock} about * Notifies your IGridBlock that changes were made to your connections
* events.
*/ */
void onGridNotification(@Nonnull GridNotification notification); void onGridNotification(@Nonnull GridNotification notification);
@@ -46,19 +46,19 @@ public class DimensionalCoord extends WorldCoord {
public DimensionalCoord(final TileEntity tileEntity) { public DimensionalCoord(final TileEntity tileEntity) {
super(tileEntity); super(tileEntity);
this.world = tileEntity.getWorld(); this.world = tileEntity.getWorld();
this.dimension = this.world.getDimensionType(); this.dimension = this.world.func_230315_m_();
} }
public DimensionalCoord(final World world, final int x, final int y, final int z) { public DimensionalCoord(final World world, final int x, final int y, final int z) {
super(x, y, z); super(x, y, z);
this.world = world; this.world = world;
this.dimension = world.getDimensionType(); this.dimension = world.func_230315_m_();
} }
public DimensionalCoord(final World world, final BlockPos pos) { public DimensionalCoord(final World world, final BlockPos pos) {
super(pos); super(pos);
this.world = world; this.world = world;
this.dimension = world.getDimensionType(); this.dimension = world.func_230315_m_();
} }
@Override @Override
@@ -39,8 +39,6 @@ import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.DyeColor; import net.minecraft.item.DyeColor;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.state.IntegerProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
@@ -84,12 +82,8 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusTileEntity> implement
private static final ICableBusContainer NULL_CABLE_BUS = new NullCableBusContainer(); private static final ICableBusContainer NULL_CABLE_BUS = new NullCableBusContainer();
private static final IntegerProperty LIGHT_LEVEL = IntegerProperty.create("light_level", 0, 15);
public CableBusBlock() { public CableBusBlock() {
super(defaultProps(AEMaterials.GLASS).notSolid().noDrops().variableOpacity() super(defaultProps(AEMaterials.GLASS).notSolid().noDrops().variableOpacity());
.setLightLevel(state -> state.get(LIGHT_LEVEL)));
setDefaultState(getDefaultState().with(LIGHT_LEVEL, 0));
} }
@Override @Override
@@ -132,9 +126,11 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusTileEntity> implement
} }
@Override @Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) { public int getLightValue(final BlockState state, final IBlockReader world, final BlockPos pos) {
super.fillStateContainer(builder); if (state.getBlock() != this) {
builder.add(LIGHT_LEVEL); return state.getBlock().getLightValue(state, world, pos);
}
return this.cb(world, pos).getLightValue();
} }
@Override @Override
@@ -390,13 +386,4 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusTileEntity> implement
} }
} }
@Override
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, CableBusTileEntity te) {
if (currentState.getBlock() != this) {
return currentState;
}
int lightLevel = te.getCableBus().getLightValue();
return super.updateBlockStateFromTileEntity(currentState, te).with(LIGHT_LEVEL, lightLevel);
}
} }
@@ -35,9 +35,7 @@ import appeng.tile.networking.EnergyCellTileEntity;
public class EnergyCellBlock extends AEBaseTileBlock<EnergyCellTileEntity> { public class EnergyCellBlock extends AEBaseTileBlock<EnergyCellTileEntity> {
public static final int MAX_FULLNESS = 4; public static final IntegerProperty ENERGY_STORAGE = IntegerProperty.create("fullness", 0, 7);
public static final IntegerProperty ENERGY_STORAGE = IntegerProperty.create("fullness", 0, MAX_FULLNESS);
public EnergyCellBlock() { public EnergyCellBlock() {
super(defaultProps(AEMaterials.GLASS)); super(defaultProps(AEMaterials.GLASS));
@@ -167,7 +167,7 @@ class PaintSplotchesBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return false; return false;
} }
@@ -203,7 +203,7 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return false; return false;
} }
@@ -160,7 +160,7 @@ class BlockDefinitionBuilder implements IBlockBuilder {
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void setup() { public void setup() {
ItemModelsProperties.registerProperty(item, new ResourceLocation("appliedenergistics2:fill_level"), ItemModelsProperties.func_239418_a_(item, new ResourceLocation("appliedenergistics2:fill_level"),
(is, world, entity) -> { (is, world, entity) -> {
double curPower = chargeable.getAECurrentPower(is); double curPower = chargeable.getAECurrentPower(is);
double maxPower = chargeable.getAEMaxPower(is); double maxPower = chargeable.getAEMaxPower(is);
@@ -106,7 +106,6 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
private Stopwatch dbl_clickTimer = Stopwatch.createStarted(); private Stopwatch dbl_clickTimer = Stopwatch.createStarted();
private ItemStack dbl_whichItem = ItemStack.EMPTY; private ItemStack dbl_whichItem = ItemStack.EMPTY;
private Slot bl_clicked; private Slot bl_clicked;
private boolean handlingRightClick;
protected final List<CustomSlotWidget> guiSlots = new ArrayList<>(); protected final List<CustomSlotWidget> guiSlots = new ArrayList<>();
public AEBaseScreen(T container, PlayerInventory playerInventory, ITextComponent title) { public AEBaseScreen(T container, PlayerInventory playerInventory, ITextComponent title) {
@@ -147,7 +146,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
RenderSystem.popMatrix(); RenderSystem.popMatrix();
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
this.renderHoveredTooltip(matrixStack, mouseX, mouseY); this.func_230459_a_(matrixStack, mouseX, mouseY);
for (final Object c : this.buttons) { for (final Object c : this.buttons) {
if (c instanceof ITooltip) { if (c instanceof ITooltip) {
@@ -230,7 +229,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
if (this.getScrollBar() != null) { if (this.getScrollBar() != null) {
this.getScrollBar().draw(matrixStack, this); this.getScrollBar().draw(this);
} }
this.drawFG(matrixStack, ox, oy, x, y); this.drawFG(matrixStack, ox, oy, x, y);
@@ -276,18 +275,12 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) { public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
this.drag_click.clear(); this.drag_click.clear();
// Forward right-clicks as-if they were left-clicks
if (btn == 1) { if (btn == 1) {
handlingRightClick = true; for (final Object o : this.buttons) {
try { final Widget widget = (Widget) o;
for (final Object o : this.buttons) { if (widget.isMouseOver(xCoord, yCoord)) {
final Widget widget = (Widget) o; return super.mouseClicked(xCoord, yCoord, 0);
if (widget.isMouseOver(xCoord, yCoord)) {
return super.mouseClicked(xCoord, yCoord, 0);
}
} }
} finally {
handlingRightClick = false;
} }
} }
@@ -298,36 +291,22 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
} }
} }
// Forward left mouse button down events to the scrollbar if (this.getScrollBar() != null) {
if (btn == 0 && this.getScrollBar() != null) { this.getScrollBar().click(xCoord - this.guiLeft, yCoord - this.guiTop);
if (this.getScrollBar().mouseDown(xCoord - this.guiLeft, yCoord - this.guiTop)) {
return true;
}
} }
return super.mouseClicked(xCoord, yCoord, btn); return super.mouseClicked(xCoord, yCoord, btn);
} }
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
// Forward left mouse button up events to the scrollbar
if (button == 0 && this.getScrollBar() != null) {
if (this.getScrollBar().mouseUp(mouseX - this.guiLeft, mouseY - this.guiTop)) {
return true;
}
}
return super.mouseReleased(mouseX, mouseY, button);
}
@Override @Override
public boolean mouseDragged(double mouseX, double mouseY, int mouseButton, double dragX, double dragY) { public boolean mouseDragged(double mouseX, double mouseY, int mouseButton, double dragX, double dragY) {
final Slot slot = this.getSlot((int) mouseX, (int) mouseY); final Slot slot = this.getSlot((int) mouseX, (int) mouseY);
final ItemStack itemstack = getPlayer().inventory.getItemStack(); final ItemStack itemstack = getPlayer().inventory.getItemStack();
if (this.getScrollBar() != null) { if (this.getScrollBar() != null) {
// FIXME: Coordinate system of mouseX/mouseY is unclear // FIXME: Coordinate system of mouseX/mouseY is unclear
this.getScrollBar().mouseDragged((int) mouseX - this.guiLeft, (int) mouseY - this.guiTop); this.getScrollBar().click((int) mouseX - this.guiLeft, (int) mouseY - this.guiTop);
} }
if (slot instanceof FakeSlot && !itemstack.isEmpty()) { if (slot instanceof FakeSlot && !itemstack.isEmpty()) {
@@ -602,7 +581,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
if (slot instanceof SlotME) { if (slot instanceof SlotME) {
final IAEItemStack item = ((SlotME) slot).getAEStack(); final IAEItemStack item = ((SlotME) slot).getAEStack();
if (item != null) { if (item != null) {
this.container.setTargetStack(item); ((AEBaseContainer) this.container).setTargetStack(item);
final InventoryAction direction = wheel > 0 ? InventoryAction.ROLL_DOWN : InventoryAction.ROLL_UP; final InventoryAction direction = wheel > 0 ? InventoryAction.ROLL_DOWN : InventoryAction.ROLL_UP;
final int times = (int) Math.abs(wheel); final int times = (int) Math.abs(wheel);
final int inventorySize = this.getInventorySlots().size(); final int inventorySize = this.getInventorySlots().size();
@@ -635,7 +614,15 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
} }
protected ITextComponent getGuiDisplayName(final ITextComponent in) { protected ITextComponent getGuiDisplayName(final ITextComponent in) {
return title.getString().isEmpty() ? in : title; return this.hasCustomInventoryName() ? new StringTextComponent(this.getInventoryName()) : in;
}
private boolean hasCustomInventoryName() {
return this.container.getCustomName() != null;
}
private String getInventoryName() {
return this.container.getCustomName();
} }
/** /**
@@ -809,11 +796,6 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
public void tick() { public void tick() {
super.tick(); super.tick();
if (this.getScrollBar() != null) {
this.getScrollBar().tick();
}
for (IGuiEventListener child : children) { for (IGuiEventListener child : children) {
if (child instanceof ITickingWidget) { if (child instanceof ITickingWidget) {
((ITickingWidget) child).tick(); ((ITickingWidget) child).tick();
@@ -821,12 +803,4 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
} }
} }
/**
* Returns true while the current event being handled is a click of the right
* mouse button.
*/
public boolean isHandlingRightClick() {
return handlingRightClick;
}
} }
@@ -55,23 +55,35 @@ final class AESubScreen {
IPriorityHost priorityHost = (IPriorityHost) containerTarget; IPriorityHost priorityHost = (IPriorityHost) containerTarget;
this.previousContainerIcon = priorityHost.getItemStackRepresentation(); this.previousContainerIcon = priorityHost.getItemStackRepresentation();
this.previousContainerType = ChestContainer.TYPE; this.previousContainerType = ChestContainer.TYPE;
} else if (containerTarget instanceof IPriorityHost) { }
else if (containerTarget instanceof IPriorityHost) {
IPriorityHost priorityHost = (IPriorityHost) containerTarget; IPriorityHost priorityHost = (IPriorityHost) containerTarget;
this.previousContainerIcon = priorityHost.getItemStackRepresentation(); this.previousContainerIcon = priorityHost.getItemStackRepresentation();
this.previousContainerType = priorityHost.getContainerType(); this.previousContainerType = priorityHost.getContainerType();
} else if (containerTarget instanceof WirelessTerminalGuiObject) { }
else if (containerTarget instanceof WirelessTerminalGuiObject) {
this.previousContainerIcon = definitions.items().wirelessTerminal().maybeStack(1).orElse(ItemStack.EMPTY); this.previousContainerIcon = definitions.items().wirelessTerminal().maybeStack(1).orElse(ItemStack.EMPTY);
this.previousContainerType = WirelessTermContainer.TYPE; this.previousContainerType = WirelessTermContainer.TYPE;
} else if (containerTarget instanceof TerminalPart) { }
else if (containerTarget instanceof TerminalPart) {
this.previousContainerIcon = parts.terminal().maybeStack(1).orElse(ItemStack.EMPTY); this.previousContainerIcon = parts.terminal().maybeStack(1).orElse(ItemStack.EMPTY);
this.previousContainerType = MEMonitorableContainer.TYPE; this.previousContainerType = MEMonitorableContainer.TYPE;
} else if (containerTarget instanceof CraftingTerminalPart) { }
else if (containerTarget instanceof CraftingTerminalPart) {
this.previousContainerIcon = parts.craftingTerminal().maybeStack(1).orElse(ItemStack.EMPTY); this.previousContainerIcon = parts.craftingTerminal().maybeStack(1).orElse(ItemStack.EMPTY);
this.previousContainerType = CraftingTermContainer.TYPE; this.previousContainerType = CraftingTermContainer.TYPE;
} else if (containerTarget instanceof PatternTerminalPart) { }
else if (containerTarget instanceof PatternTerminalPart) {
this.previousContainerIcon = parts.patternTerminal().maybeStack(1).orElse(ItemStack.EMPTY); this.previousContainerIcon = parts.patternTerminal().maybeStack(1).orElse(ItemStack.EMPTY);
this.previousContainerType = PatternTermContainer.TYPE; this.previousContainerType = PatternTermContainer.TYPE;
} else { }
else {
this.previousContainerIcon = null; this.previousContainerIcon = null;
this.previousContainerType = null; this.previousContainerType = null;
} }
@@ -48,28 +48,22 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
public void init() { public void init() {
super.init(); super.init();
this.amountToCraft = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.CRAFT_ITEM_COUNT); this.amountToCraft = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.CRAFT_ITEM_COUNT, value -> {
});
this.amountToCraft.setValue(1); this.amountToCraft.setValue(1);
this.amountToCraft.setTextFieldBounds(62, 57, 50); this.amountToCraft.setTextFieldBounds(62, 57, 50);
this.amountToCraft.setMinValue(1); this.amountToCraft.setMinValue(1);
this.amountToCraft.setHideValidationIcon(true);
this.amountToCraft.addButtons(children::add, this::addButton); this.amountToCraft.addButtons(children::add, this::addButton);
this.next = this.addButton( this.next = this.addButton(
new Button(this.guiLeft + 128, this.guiTop + 51, 38, 20, GuiText.Next.text(), this::confirm)); new Button(this.guiLeft + 128, this.guiTop + 51, 38, 20, GuiText.Next.text(), this::confirm));
this.amountToCraft.setOnConfirm(() -> this.confirm(this.next));
subGui.addBackButton(this::addButton, 154, 0); subGui.addBackButton(this::addButton, 154, 0);
changeFocus(true);
} }
private void confirm(Button button) { private void confirm(Button button) {
int amount = this.amountToCraft.getIntValue().orElse(0); NetworkHandler.instance()
if (amount <= 0) { .sendToServer(new CraftRequestPacket((int) this.amountToCraft.getValue(), hasShiftDown()));
return;
}
NetworkHandler.instance().sendToServer(new CraftRequestPacket(amount, hasShiftDown()));
} }
@Override @Override
@@ -86,9 +80,23 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
this.bindTexture("guis/craft_amt.png"); this.bindTexture("guis/craft_amt.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset()); GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
this.next.active = this.amountToCraft.getIntValue().orElse(0) > 0; this.next.active = this.amountToCraft.getValue() > 0;
this.amountToCraft.render(matrixStack, offsetX, offsetY, partialTicks); this.amountToCraft.render(matrixStack, offsetX, offsetY, partialTicks);
} }
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (keyCode == 28) {
this.next.onPress();
return true;
} else {
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
}
protected String getBackground() {
return "guis/craftAmt.png";
}
} }
@@ -27,8 +27,6 @@ import com.google.common.base.Joiner;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import org.lwjgl.glfw.GLFW;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings; import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
@@ -78,6 +76,10 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
this.setScrollBar(scrollbar); this.setScrollBar(scrollbar);
} }
boolean isAutoStart() {
return this.container.isAutoStart();
}
@Override @Override
public void init() { public void init() {
super.init(); super.init();
@@ -88,14 +90,13 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
this.addButton(this.start); this.addButton(this.start);
this.selectCPU = new Button(this.guiLeft + (219 - 180) / 2, this.guiTop + this.ySize - 68, 180, 20, this.selectCPU = new Button(this.guiLeft + (219 - 180) / 2, this.guiTop + this.ySize - 68, 180, 20,
getNextCpuButtonLabel(), btn -> selectNextCpu()); new StringTextComponent(GuiText.CraftingCPU.getLocal() + ": " + GuiText.Automatic),
btn -> selectNextCpu());
this.selectCPU.active = false; this.selectCPU.active = false;
this.addButton(this.selectCPU); this.addButton(this.selectCPU);
addButton(new Button(this.guiLeft + 6, this.guiTop + this.ySize - 25, 50, 20, GuiText.Cancel.text(), addButton(new Button(this.guiLeft + 6, this.guiTop + this.ySize - 25, 50, 20, GuiText.Cancel.text(),
btn -> subGui.goBack())); btn -> subGui.goBack()));
this.setScrollBar();
} }
@Override @Override
@@ -136,22 +137,22 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
} }
private void updateCPUButtonText() { private void updateCPUButtonText() {
this.selectCPU.setMessage(getNextCpuButtonLabel()); String btnTextText = GuiText.CraftingCPU.getLocal() + ": " + GuiText.Automatic.getLocal();
} if (this.container.getSelectedCpu() >= 0)// && status.selectedCpu < status.cpus.size() )
{
if (this.container.getName() != null) {
final String name = this.container.getName().getStringTruncated(20);
btnTextText = GuiText.CraftingCPU.getLocal() + ": " + name;
} else {
btnTextText = GuiText.CraftingCPU.getLocal() + ": #" + this.container.getSelectedCpu();
}
}
private ITextComponent getNextCpuButtonLabel() {
if (this.container.hasNoCPU()) { if (this.container.hasNoCPU()) {
return GuiText.NoCraftingCPUs.text(); btnTextText = GuiText.NoCraftingCPUs.getLocal();
} }
ITextComponent cpuName; this.selectCPU.setMessage(new StringTextComponent(btnTextText));
if (this.container.cpuName == null) {
cpuName = GuiText.Automatic.text();
} else {
cpuName = this.container.cpuName;
}
return GuiText.CraftingCPU.withSuffix(": ").append(cpuName);
} }
private boolean isSimulation() { private boolean isSimulation() {
@@ -444,7 +445,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
@Override @Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) { public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) { if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { if (keyCode == 28) {
this.start(); this.start();
return true; return true;
} }
@@ -453,7 +454,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
} }
private void selectNextCpu() { private void selectNextCpu() {
final boolean backwards = isHandlingRightClick(); final boolean backwards = minecraft.mouseHelper.isRightDown();
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next")); NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
} }
@@ -16,6 +16,10 @@
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>. * along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/ */
/**
*
*/
package appeng.client.gui.implementations; package appeng.client.gui.implementations;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
@@ -23,6 +27,7 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import appeng.container.implementations.CraftingStatusContainer; import appeng.container.implementations.CraftingStatusContainer;
import appeng.core.localization.GuiText; import appeng.core.localization.GuiText;
@@ -45,13 +50,14 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
public void init() { public void init() {
super.init(); super.init();
this.selectCPU = new Button(this.guiLeft + 8, this.guiTop + this.ySize - 25, 150, 20, getNextCpuButtonLabel(), this.selectCPU = new Button(this.guiLeft + 8, this.guiTop + this.ySize - 25, 150, 20,
new StringTextComponent(GuiText.CraftingCPU.getLocal() + ": " + GuiText.NoCraftingCPUs),
btn -> selectNextCpu()); btn -> selectNextCpu());
this.addButton(this.selectCPU); this.addButton(this.selectCPU);
subGui.addBackButton(btn -> { subGui.addBackButton(btn -> {
addButton(btn); addButton(btn);
btn.setHideEdge(true); btn.setHideEdge(13);
}, 213, -4); }, 213, -4);
} }
@@ -62,14 +68,23 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
} }
private void updateCPUButtonText() { private void updateCPUButtonText() {
this.selectCPU.setMessage(getNextCpuButtonLabel()); String btnTextText = GuiText.NoCraftingJobs.getLocal();
}
private ITextComponent getNextCpuButtonLabel() { if (this.container.selectedCpu >= 0)// && status.selectedCpu < status.cpus.size() )
if (this.container.noCPU) { {
return GuiText.NoCraftingJobs.text(); if (this.container.myName != null) {
final String name = this.container.myName.getStringTruncated(20);
btnTextText = GuiText.CPUs.getLocal() + ": " + name;
} else {
btnTextText = GuiText.CPUs.getLocal() + ": #" + this.container.selectedCpu;
}
} }
return GuiText.CraftingCPU.withSuffix(": ").append(container.cpuName);
if (this.container.noCPU) {
btnTextText = GuiText.NoCraftingJobs.getLocal();
}
this.selectCPU.setMessage(new StringTextComponent(btnTextText));
} }
@Override @Override
@@ -77,8 +92,9 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
return in; // the cup name is on the button return in; // the cup name is on the button
} }
// FIXME: Extract to separate class? Shared with GuiCraftConfirm
private void selectNextCpu() { private void selectNextCpu() {
final boolean backwards = isHandlingRightClick(); final boolean backwards = minecraft.mouseHelper.isRightDown();
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next")); NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
} }
@@ -90,7 +90,7 @@ public class InterfaceScreen extends UpgradeableScreen<InterfaceContainer> {
} }
private void selectNextInterfaceMode() { private void selectNextInterfaceMode() {
final boolean backwards = isHandlingRightClick(); final boolean backwards = getMinecraft().mouseHelper.isRightDown();
NetworkHandler.instance().sendToServer(new ConfigButtonPacket(Settings.INTERFACE_TERMINAL, backwards)); NetworkHandler.instance().sendToServer(new ConfigButtonPacket(Settings.INTERFACE_TERMINAL, backwards));
} }
@@ -71,7 +71,8 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
public InterfaceTerminalScreen(InterfaceTerminalContainer container, PlayerInventory playerInventory, public InterfaceTerminalScreen(InterfaceTerminalContainer container, PlayerInventory playerInventory,
ITextComponent title) { ITextComponent title) {
super(container, playerInventory, title); super(container, playerInventory, title);
this.setScrollBar(new Scrollbar().setLeft(175).setTop(18).setHeight(106)); final Scrollbar scrollbar = new Scrollbar();
this.setScrollBar(scrollbar);
this.xSize = 195; this.xSize = 195;
this.ySize = 222; this.ySize = 222;
} }
@@ -80,6 +81,10 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
public void init() { public void init() {
super.init(); super.init();
this.getScrollBar().setLeft(175);
this.getScrollBar().setHeight(106);
this.getScrollBar().setTop(18);
this.searchField = new AETextField(this.font, this.guiLeft + 104, this.guiTop + 4, 65, 12); this.searchField = new AETextField(this.font, this.guiLeft + 104, this.guiTop + 4, 65, 12);
this.searchField.setEnableBackgroundDrawing(false); this.searchField.setEnableBackgroundDrawing(false);
this.searchField.setMaxStringLength(25); this.searchField.setMaxStringLength(25);
@@ -211,7 +216,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
try { try {
final long id = Long.parseLong(key.substring(1), Character.MAX_RADIX); final long id = Long.parseLong(key.substring(1), Character.MAX_RADIX);
final CompoundNBT invData = in.getCompound(key); final CompoundNBT invData = in.getCompound(key);
ITextComponent un = ITextComponent.Serializer.getComponentFromJson(invData.getString("un")); ITextComponent un = ITextComponent.Serializer.func_240643_a_(invData.getString("un"));
final ClientDCInternalInv current = this.getById(id, invData.getLong("sortBy"), un); final ClientDCInternalInv current = this.getById(id, invData.getLong("sortBy"), un);
for (int x = 0; x < current.getInventory().getSlots(); x++) { for (int x = 0; x < current.getInventory().getSlots(); x++) {
@@ -35,6 +35,8 @@ import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton; import appeng.client.gui.widgets.SettingToggleButton;
import appeng.container.implementations.LevelEmitterContainer; import appeng.container.implementations.LevelEmitterContainer;
import appeng.core.localization.GuiText; import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer> { public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer> {
@@ -50,18 +52,15 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
public void init() { public void init() {
super.init(); super.init();
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_ITEM_COUNT); this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_ITEM_COUNT,
this::onLevelChange);
this.level.setTextFieldBounds(25, 44, 75); this.level.setTextFieldBounds(25, 44, 75);
this.level.addButtons(children::add, this::addButton); this.level.addButtons(children::add, this::addButton);
this.level.setValue(container.getReportingValue()); container.setTextField(this.level);
this.level.setOnChange(this::saveReportingValue);
this.level.setOnConfirm(this::closeScreen);
this.changeFocus(true);
} }
private void saveReportingValue() { private void onLevelChange(long level) {
this.level.getLongValue().ifPresent(container::setReportingValue); NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", String.valueOf(level)));
} }
@Override @Override
@@ -51,7 +51,6 @@ import appeng.client.gui.widgets.SettingToggleButton;
import appeng.client.gui.widgets.TabButton; import appeng.client.gui.widgets.TabButton;
import appeng.client.me.InternalSlotME; import appeng.client.me.InternalSlotME;
import appeng.client.me.ItemRepo; import appeng.client.me.ItemRepo;
import appeng.client.render.StackSizeRenderer;
import appeng.container.implementations.CraftingStatusContainer; import appeng.container.implementations.CraftingStatusContainer;
import appeng.container.implementations.MEMonitorableContainer; import appeng.container.implementations.MEMonitorableContainer;
import appeng.container.slot.AppEngSlot; import appeng.container.slot.AppEngSlot;
@@ -238,7 +237,7 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
if (this.viewCell || this instanceof WirelessTermScreen) { if (this.viewCell || this instanceof WirelessTermScreen) {
this.craftingStatusBtn = this.addButton(new TabButton(this.guiLeft + 170, this.guiTop - 4, 2 + 11 * 16, this.craftingStatusBtn = this.addButton(new TabButton(this.guiLeft + 170, this.guiTop - 4, 2 + 11 * 16,
GuiText.CraftingStatus.text(), this.itemRenderer, btn -> showCraftingStatus())); GuiText.CraftingStatus.text(), this.itemRenderer, btn -> showCraftingStatus()));
this.craftingStatusBtn.setHideEdge(true); this.craftingStatusBtn.setHideEdge(13);
} }
this.isAutoFocus = SearchBoxMode.AUTOSEARCH == searchMode || SearchBoxMode.JEI_AUTOSEARCH == searchMode this.isAutoFocus = SearchBoxMode.AUTOSEARCH == searchMode || SearchBoxMode.JEI_AUTOSEARCH == searchMode
@@ -284,8 +283,6 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
craftingGridOffsetX -= 25; craftingGridOffsetX -= 25;
craftingGridOffsetY -= 6; craftingGridOffsetY -= 6;
this.setScrollBar();
} }
@Override @Override
@@ -296,16 +293,6 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
this.currentMouseX = mouseX; this.currentMouseX = mouseX;
this.currentMouseY = mouseY; this.currentMouseY = mouseY;
// Show the number of active crafting jobs
if (this.craftingStatusBtn != null && container.activeCraftingJobs != -1) {
// The stack size renderer expects a 16x16 slot, while the button is normally
// bigger
int x = this.craftingStatusBtn.x + (this.craftingStatusBtn.getWidth() - 16) / 2;
int y = this.craftingStatusBtn.y + (this.craftingStatusBtn.getHeightRealms() - 16) / 2;
StackSizeRenderer.renderSizeLabel(font, x - this.guiLeft, y - this.guiTop,
String.valueOf(container.activeCraftingJobs));
}
} }
@Override @Override
@@ -370,7 +357,6 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
if (this.searchField != null) { if (this.searchField != null) {
this.searchField.render(matrixStack, mouseX, mouseY, partialTicks); this.searchField.render(matrixStack, mouseX, mouseY, partialTicks);
} }
} }
protected String getBackground() { protected String getBackground() {
@@ -2,60 +2,43 @@ package appeng.client.gui.implementations;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.LongConsumer;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.IGuiEventListener; import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import appeng.client.gui.AEBaseScreen; import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.NumberEntryType; import appeng.client.gui.NumberEntryType;
import appeng.client.gui.widgets.ConfirmableTextField; import appeng.client.gui.widgets.ITickingWidget;
import appeng.client.gui.widgets.ValidationIcon; import appeng.client.gui.widgets.NumberBox;
import appeng.core.AEConfig; import appeng.core.AEConfig;
/** /**
* A utility widget that consists of a text-field to enter a number with * A utility widget that consists of a text-field to enter a number with
* attached buttons to increment/decrement the number in fixed intervals. * attached buttons to increment/decrement the number in fixed intervals.
*/ */
public class NumberEntryWidget extends AbstractGui { public class NumberEntryWidget implements ITickingWidget {
private static final ITextComponent INVALID_NUMBER = new TranslationTextComponent(
"gui.appliedenergistics2.validation.InvalidNumber");
private static final String NUMBER_LESS_THAN_MIN_VALUE = "gui.appliedenergistics2.validation.NumberLessThanMinValue";
private static final ITextComponent PLUS = new StringTextComponent("+"); private static final ITextComponent PLUS = new StringTextComponent("+");
private static final ITextComponent MINUS = new StringTextComponent("-"); private static final ITextComponent MINUS = new StringTextComponent("-");
private static final int TEXT_COLOR_ERROR = 0xFF1900;
private static final int TEXT_COLOR_NORMAL = 0xFFFFFF;
private final AEBaseScreen<?> parent; private final AEBaseScreen<?> parent;
private final int x; private final int x;
private final int y; private final int y;
private final ConfirmableTextField textField; private final NumberBox level;
private final NumberEntryType type; private final NumberEntryType type;
private List<Button> buttons; private List<Button> buttons;
private long minValue;
private ValidationIcon validationIcon;
// Called when the value changes public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type,
private Runnable onChange; LongConsumer changeListener) {
// Called when the user presses enter while there's a valid number in the field
private Runnable onConfirm;
private boolean hideValidationIcon;
public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type) {
this.parent = parent; this.parent = parent;
this.x = x; this.x = x;
this.y = y; this.y = y;
@@ -64,51 +47,28 @@ public class NumberEntryWidget extends AbstractGui {
FontRenderer font = parent.getMinecraft().fontRenderer; FontRenderer font = parent.getMinecraft().fontRenderer;
int inputX = parent.getGuiLeft() + x; int inputX = parent.getGuiLeft() + x;
int inputY = parent.getGuiTop() + y; int inputY = parent.getGuiTop() + y;
this.textField = new ConfirmableTextField(font, inputX, inputY, width, font.FONT_HEIGHT, this.level = new NumberBox(font, inputX, inputY, width, font.FONT_HEIGHT, type.getInputType(), changeListener);
StringTextComponent.EMPTY); this.level.setEnableBackgroundDrawing(false);
this.textField.setEnableBackgroundDrawing(false); this.level.setMaxStringLength(16);
this.textField.setMaxStringLength(16); this.level.setTextColor(0xFFFFFF);
this.textField.setTextColor(TEXT_COLOR_NORMAL); this.level.setVisible(true);
this.textField.setVisible(true); this.level.setFocused2(true);
this.textField.setFocused2(true); parent.setFocusedDefault(this.level);
parent.setFocusedDefault(this.textField);
this.textField.setResponder(text -> {
validate();
if (onChange != null) {
this.onChange.run();
}
});
this.textField.setOnConfirm(() -> {
// Only confirm if it's actually valid
if (this.onConfirm != null && getLongValue().isPresent()) {
this.onConfirm.run();
}
});
validate();
}
public void setOnConfirm(Runnable callback) {
this.onConfirm = callback;
}
public void setOnChange(Runnable callback) {
this.onChange = callback;
} }
public void setActive(boolean active) { public void setActive(boolean active) {
this.textField.setEnabled(active); this.level.setEnabled(active);
this.buttons.forEach(b -> b.active = active); this.buttons.forEach(b -> b.active = active);
} }
public void setTextFieldBounds(int x, int y, int width) { public void setTextFieldBounds(int x, int y, int width) {
this.textField.x = parent.getGuiLeft() + x; this.level.x = parent.getGuiLeft() + x;
this.textField.y = parent.getGuiTop() + y; this.level.y = parent.getGuiTop() + y;
this.textField.setWidth(width); this.level.setWidth(width);
} }
public void setMinValue(long minValue) { public void setMinValue(long minValue) {
this.minValue = minValue; this.level.setMinValue(minValue);
validate();
} }
public void addButtons(Consumer<IGuiEventListener> addChildren, Consumer<Button> addButton) { public void addButtons(Consumer<IGuiEventListener> addChildren, Consumer<Button> addButton) {
@@ -121,116 +81,54 @@ public class NumberEntryWidget extends AbstractGui {
int left = parent.getGuiLeft() + x; int left = parent.getGuiLeft() + x;
int top = parent.getGuiTop() + y; int top = parent.getGuiTop() + y;
List<Button> buttons = new ArrayList<>(9); List<Button> buttons = new ArrayList<>(8);
buttons.add(new Button(left, top, 22, 20, makeLabel(PLUS, a), btn -> addQty(a))); buttons.add(new Button(left, top, 22, 20, makeLabel(PLUS, a), btn -> addQty(a)));
buttons.add(new Button(left + 28, top, 28, 20, makeLabel(PLUS, b), btn -> addQty(b))); buttons.add(new Button(left + 28, top, 28, 20, makeLabel(PLUS, b), btn -> addQty(b)));
buttons.add(new Button(left + 62, top, 32, 20, makeLabel(PLUS, c), btn -> addQty(c))); buttons.add(new Button(left + 62, top, 32, 20, makeLabel(PLUS, c), btn -> addQty(c)));
buttons.add(new Button(left + 100, top, 38, 20, makeLabel(PLUS, d), btn -> addQty(d))); buttons.add(new Button(left + 100, top, 38, 20, makeLabel(PLUS, d), btn -> addQty(d)));
// Need to add these now for sensible tab-order
buttons.forEach(addButton);
// Placing this here will give a sensible tab order // Placing this here will give a sensible tab order
addChildren.accept(this.textField); addChildren.accept(this.level);
buttons.add(new Button(left, top + 42, 22, 20, makeLabel(MINUS, a), btn -> addQty(-a))); buttons.add(new Button(left, top + 42, 22, 20, makeLabel(MINUS, a), btn -> addQty(-a)));
buttons.add(new Button(left + 28, top + 42, 28, 20, makeLabel(MINUS, b), btn -> addQty(-b))); buttons.add(new Button(left + 28, top + 42, 28, 20, makeLabel(MINUS, b), btn -> addQty(-b)));
buttons.add(new Button(left + 62, top + 42, 32, 20, makeLabel(MINUS, c), btn -> addQty(-c))); buttons.add(new Button(left + 62, top + 42, 32, 20, makeLabel(MINUS, c), btn -> addQty(-c)));
buttons.add(new Button(left + 100, top + 42, 38, 20, makeLabel(MINUS, d), btn -> addQty(-d))); buttons.add(new Button(left + 100, top + 42, 38, 20, makeLabel(MINUS, d), btn -> addQty(-d)));
// This element is not focusable
if (!hideValidationIcon) {
this.validationIcon = new ValidationIcon(left + 104, top + 27);
buttons.add(this.validationIcon);
}
// Add the rest to the tab order
buttons.subList(4, buttons.size()).forEach(addButton);
this.buttons = buttons; this.buttons = buttons;
this.buttons.forEach(addButton);
// we need to re-validate because the icon may now be present and needs it's
// initial state
this.validate();
}
/**
* Returns the integer value currently in the text-field, if it is a valid
* number and is within the allowed min/max value.
*/
public OptionalInt getIntValue() {
String text = textField.getText().trim();
try {
int value = Integer.parseInt(text, 10);
if (value < minValue) {
return OptionalInt.empty();
}
return OptionalInt.of(value);
} catch (NumberFormatException ignored) {
return OptionalInt.empty();
}
}
/**
* Returns the long value currently in the text-field, if it is a valid number
* and is within the allowed min/max value.
*/
public OptionalLong getLongValue() {
String text = textField.getText().trim();
try {
long value = Long.parseLong(text, 10);
if (value < minValue) {
return OptionalLong.empty();
}
return OptionalLong.of(value);
} catch (NumberFormatException ignored) {
return OptionalLong.empty();
}
}
public void setValue(long value) {
this.textField.setText(String.valueOf(Math.max(minValue, value)));
this.textField.setCursorPositionEnd();
this.textField.setSelectionPos(0);
validate();
} }
private void addQty(final long i) { private void addQty(final long i) {
getLongValue().ifPresent(currentValue -> setValue(currentValue + i)); long currentValue = this.level.getValue();
long minValue = this.level.getMinValue();
this.level.setText(String.valueOf(Math.max(minValue, currentValue + i)));
} }
public void render(MatrixStack matrices, int mouseX, int mouseY, float partialTicks) { public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
this.textField.render(matrices, mouseX, mouseY, partialTicks); this.level.render(matrixStack, mouseX, mouseY, partialTicks);
} }
private void validate() { public void setValue(long value, boolean skipNotify) {
List<ITextComponent> validationErrors = new ArrayList<>(); this.level.setValue(value, skipNotify);
}
String text = textField.getText().trim(); public void setValue(long value) {
try { setValue(value, false);
long value = Long.parseLong(text, 10); }
if (value < minValue) {
validationErrors.add(new TranslationTextComponent(NUMBER_LESS_THAN_MIN_VALUE, minValue));
}
} catch (NumberFormatException ignored) {
validationErrors.add(INVALID_NUMBER);
}
boolean valid = validationErrors.isEmpty(); public long getValue() {
this.textField.setTextColor(valid ? TEXT_COLOR_NORMAL : TEXT_COLOR_ERROR); return level.getValue();
if (this.validationIcon != null) { }
this.validationIcon.setValid(valid);
this.validationIcon.setTooltip(validationErrors); @Override
} public void tick() {
this.level.tick();
} }
private ITextComponent makeLabel(ITextComponent prefix, int amount) { private ITextComponent makeLabel(ITextComponent prefix, int amount) {
return prefix.copyRaw().appendString(String.valueOf(amount)); return prefix.copyRaw().appendString(String.valueOf(amount));
} }
public void setHideValidationIcon(boolean hideValidationIcon) {
this.hideValidationIcon = hideValidationIcon;
}
} }
@@ -18,8 +18,6 @@
package appeng.client.gui.implementations; package appeng.client.gui.implementations;
import java.util.OptionalInt;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
@@ -29,6 +27,8 @@ import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.NumberEntryType; import appeng.client.gui.NumberEntryType;
import appeng.container.implementations.PriorityContainer; import appeng.container.implementations.PriorityContainer;
import appeng.core.localization.GuiText; import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class PriorityScreen extends AEBaseScreen<PriorityContainer> { public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
@@ -39,38 +39,24 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
public PriorityScreen(PriorityContainer container, PlayerInventory playerInventory, ITextComponent title) { public PriorityScreen(PriorityContainer container, PlayerInventory playerInventory, ITextComponent title) {
super(container, playerInventory, title); super(container, playerInventory, title);
this.subGui = new AESubScreen(this, container.getPriorityHost()); this.subGui = new AESubScreen(this, container.getPriorityHost());
// This is the effective size of the background image
xSize = 175;
ySize = 128;
} }
@Override @Override
public void init() { public void init() {
super.init(); super.init();
this.priority = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.PRIORITY); this.priority = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.PRIORITY, this::onPriorityChange);
this.priority.setTextFieldBounds(62, 57, 50); this.priority.setTextFieldBounds(62, 57, 50);
this.priority.setMinValue(Integer.MIN_VALUE); this.priority.setMinValue(Integer.MIN_VALUE);
this.priority.setValue(this.container.getPriorityValue()); container.setTextField(this.priority);
this.priority.addButtons(children::add, this::addButton); this.priority.addButtons(children::add, this::addButton);
this.subGui.addBackButton(this::addButton, 154, 0); this.subGui.addBackButton(this::addButton, 154, 0);
this.priority.setOnChange(this::savePriority);
this.priority.setOnConfirm(() -> {
savePriority();
this.subGui.goBack();
});
changeFocus(true);
} }
private void savePriority() { private void onPriorityChange(long priority) {
OptionalInt priority = this.priority.getIntValue(); NetworkHandler.instance()
if (priority.isPresent()) { .sendToServer(new ConfigValuePacket("PriorityHost.Priority", String.valueOf(priority)));
container.setPriority(priority.getAsInt());
}
} }
@Override @Override
@@ -82,10 +68,13 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
@Override @Override
public void drawBG(MatrixStack matrixStack, final int offsetX, final int offsetY, final int mouseX, public void drawBG(MatrixStack matrixStack, final int offsetX, final int offsetY, final int mouseX,
final int mouseY, float partialTicks) { final int mouseY, float partialTicks) {
this.bindTexture("guis/priority.png"); this.bindTexture(getBackground());
blit(matrixStack, offsetX, offsetY, 0, 0, this.xSize, this.ySize); blit(matrixStack, offsetX, offsetY, 0, 0, this.xSize, this.ySize);
this.priority.render(matrixStack, mouseX, mouseY, partialTicks); this.priority.render(matrixStack, mouseX, mouseY, partialTicks);
} }
protected String getBackground() {
return "guis/priority.png";
}
} }
@@ -1,51 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.widgets;
import org.lwjgl.glfw.GLFW;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.util.text.ITextComponent;
public class ConfirmableTextField extends TextFieldWidget {
private Runnable onConfirm;
public ConfirmableTextField(FontRenderer fontRenderer, int x, int y, int width, int height, ITextComponent text) {
super(fontRenderer, x, y, width, height, text);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (canWrite() && (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER)) {
if (this.onConfirm != null) {
this.onConfirm.run();
}
return true;
}
return super.keyPressed(keyCode, scanCode, modifiers);
}
public void setOnConfirm(Runnable onConfirm) {
this.onConfirm = onConfirm;
}
}
@@ -1,96 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.widgets;
import java.time.Duration;
/**
* This class can be used to implement repeating events such as holding down a
* button to fire an event repeatedly while the button is still being held, or
* repeatedly scrolling down a page, while the mouse is held down on the
* scrollbar.
*/
public class EventRepeater {
/**
* -1 if no repeat event is scheduled. Otherwise contains the
* {@link System#nanoTime()} at which the next event should occur.
*/
private long nextEventTime = -1;
private EventCallback eventCallback = null;
private final long eventDelay; // In nanoseconds
private final long eventInterval; // In nanoseconds
public EventRepeater(Duration delay, Duration interval) {
this.eventDelay = delay.toNanos();
this.eventInterval = interval.toNanos();
}
public void tick() {
if (this.eventCallback == null) {
return; // No event scheduled
}
// Use nanoTime here because it is monotonically increasing, while
// System.currentTimeMillis is not
long nanoTime = System.nanoTime();
if (nanoTime < this.nextEventTime) {
return; // Event time not reached
}
// Before triggering, recompute the next event, since
// the event callback itself may reschedule/cancel, and
// we should not overwrite that
this.nextEventTime = nanoTime + this.eventInterval;
this.eventCallback.trigger();
}
/**
* Schedule the given callback to be called after a given initial delay, and
* then after the given interval repeatedly.
*
* <p>
* Replaces any previously queued callback.
*/
public void repeat(EventCallback callback) {
long time = System.nanoTime();
this.eventCallback = callback;
this.nextEventTime = time + eventDelay;
}
public boolean isRepeating() {
return this.eventCallback != null;
}
/**
* Stop repeating the event.
*/
public void stop() {
this.eventCallback = null;
}
@FunctionalInterface
public interface EventCallback {
void trigger();
}
}
@@ -22,7 +22,6 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
@@ -36,10 +35,6 @@ public abstract class IconButton extends Button implements ITooltip {
private boolean halfSize = false; private boolean halfSize = false;
private boolean disableClickSound = false;
private boolean disableBackground = false;
public IconButton(final int x, final int y, IPressable onPress) { public IconButton(final int x, final int y, IPressable onPress) {
super(x, y, 16, 16, StringTextComponent.EMPTY, onPress); super(x, y, 16, 16, StringTextComponent.EMPTY, onPress);
} }
@@ -49,13 +44,6 @@ public abstract class IconButton extends Button implements ITooltip {
this.active = vis; this.active = vis;
} }
@Override
public void playDownSound(SoundHandler soundHandler) {
if (!disableClickSound) {
super.playDownSound(soundHandler);
}
}
@Override @Override
public void renderButton(MatrixStack matrixStack, final int mouseX, final int mouseY, float partial) { public void renderButton(MatrixStack matrixStack, final int mouseX, final int mouseY, float partial) {
@@ -86,9 +74,7 @@ public abstract class IconButton extends Button implements ITooltip {
final int uv_y = iconIndex / 16; final int uv_y = iconIndex / 16;
final int uv_x = iconIndex - uv_y * 16; final int uv_x = iconIndex - uv_y * 16;
if (!disableBackground) { GuiUtils.drawTexturedModalRect(0, 0, 256 - 16, 256 - 16, 16, 16, 0);
GuiUtils.drawTexturedModalRect(0, 0, 256 - 16, 256 - 16, 16, 16, 0);
}
GuiUtils.drawTexturedModalRect(0, 0, uv_x * 16, uv_y * 16, 16, 16, 0); GuiUtils.drawTexturedModalRect(0, 0, uv_x * 16, uv_y * 16, 16, 16, 0);
RenderSystem.popMatrix(); RenderSystem.popMatrix();
} else { } else {
@@ -101,18 +87,12 @@ public abstract class IconButton extends Button implements ITooltip {
final int uv_y = iconIndex / 16; final int uv_y = iconIndex / 16;
final int uv_x = iconIndex - uv_y * 16; final int uv_x = iconIndex - uv_y * 16;
if (!disableBackground) { GuiUtils.drawTexturedModalRect(this.x, this.y, 256 - 16, 256 - 16, 16, 16, 0);
GuiUtils.drawTexturedModalRect(this.x, this.y, 256 - 16, 256 - 16, 16, 16, 0);
}
GuiUtils.drawTexturedModalRect(this.x, this.y, uv_x * 16, uv_y * 16, 16, 16, 0); GuiUtils.drawTexturedModalRect(this.x, this.y, uv_x * 16, uv_y * 16, 16, 16, 0);
} }
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
if (isHovered()) {
renderToolTip(matrixStack, mouseX, mouseY);
}
} }
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
} }
protected abstract int getIconIndex(); protected abstract int getIconIndex();
@@ -155,20 +135,4 @@ public abstract class IconButton extends Button implements ITooltip {
this.halfSize = halfSize; this.halfSize = halfSize;
} }
public boolean isDisableClickSound() {
return disableClickSound;
}
public void setDisableClickSound(boolean disableClickSound) {
this.disableClickSound = disableClickSound;
}
public boolean isDisableBackground() {
return disableBackground;
}
public void setDisableBackground(boolean disableBackground) {
this.disableBackground = disableBackground;
}
} }
@@ -0,0 +1,153 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.widgets;
import java.util.function.LongConsumer;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.util.text.StringTextComponent;
public class NumberBox extends TextFieldWidget {
private final LongConsumer changeListener;
private long lastValue;
private long minValue = 0;
private long maxValue;
public NumberBox(final FontRenderer fontRenderer, final int x, final int y, final int width, final int height,
final Class<?> type, LongConsumer changeListener) {
super(fontRenderer, x, y, width, height, new StringTextComponent("0"));
this.setText("0");
setResponder(this::handleTextChanged);
this.lastValue = 0;
this.changeListener = changeListener;
if (type == int.class || type == Integer.class) {
maxValue = Integer.MAX_VALUE;
} else {
maxValue = Long.MAX_VALUE;
}
}
// NOTE: This method MUST NOT BE NAMED like a method in the superclass because
// of a ForgeGradle remapping bug
// since it'll not remap this method's name, but it will remap the name of the
// method reference above.
private void handleTextChanged(String text) {
if (text.isEmpty()) {
setText("0"); // Will call onTextChanged recursively
return;
}
boolean canBeNegative = canBeNegative();
if (canBeNegative && text.equals("-")) {
// Allow this as a special case to make typing in a negative number easier
return;
}
StringBuilder sanitized = new StringBuilder(text);
boolean encounteredNonZero = false;
for (int i = 0; i < sanitized.length(); i++) {
char ch = sanitized.charAt(i);
if (canBeNegative && i == 0 && ch == '-') {
continue; // Allow leading minus sign
}
if (ch >= '1' && ch <= '9') {
encounteredNonZero = true;
continue;
}
if (ch != '0' || !encounteredNonZero) {
sanitized.deleteCharAt(i--);
}
}
if (sanitized.length() == 0) {
sanitized.append('0');
}
String sanitizedStr = sanitized.toString();
if (!sanitizedStr.equals(text)) {
setText(sanitizedStr); // Will call onTextChanged recursively
return;
}
if (getValue() < minValue) {
setText(String.valueOf(minValue)); // Will call onTextChanged recursively
return;
}
if (getValue() > maxValue) {
setText(String.valueOf(maxValue)); // Will call onTextChanged recursively
return;
}
reportChange();
}
private void reportChange() {
long value = getValue();
if (value != lastValue) {
lastValue = value;
changeListener.accept(value);
}
}
public void setValue(long value, boolean skipNotify) {
// This check avoid changing the cursor position needlessly
if (value == this.getValue()) {
return;
}
if (skipNotify) {
lastValue = value;
}
setText(String.valueOf(value));
}
public long getValue() {
if (getText().equals("-") && canBeNegative()) {
return lastValue; // Allow this as a special case to type in a negative number more easily
}
return Long.parseLong(getText());
}
@Override
public boolean keyPressed(int p_keyPressed_1_, int p_keyPressed_2_, int p_keyPressed_3_) {
if (super.keyPressed(p_keyPressed_1_, p_keyPressed_2_, p_keyPressed_3_)) {
return true;
}
// Swallow key presses for numbers because they would otherwise trigger the
// hotbar swapping unintentionally
return isFocused() && p_keyPressed_1_ >= '0' && p_keyPressed_1_ <= '9';
}
public void setMinValue(long minValue) {
this.minValue = minValue;
}
public long getMinValue() {
return minValue;
}
private boolean canBeNegative() {
return minValue < 0;
}
}
@@ -18,75 +18,17 @@
package appeng.client.gui.widgets; package appeng.client.gui.widgets;
import java.time.Duration; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.matrix.MatrixStack; import net.minecraftforge.fml.client.gui.GuiUtils;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.renderer.Rectangle2d;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import appeng.client.gui.AEBaseScreen; import appeng.client.gui.AEBaseScreen;
/** public class Scrollbar implements IScrollSource {
* Implements a vertical scrollbar using Vanilla's scrollbar handle texture from
* the creative tab.
* <p>
* It is expected that the background of the UI contains a pre-baked scrollbar
* track border, and that the exact rectangle of that track is set on this
* object via {@link #setLeft(int)}, {@link #setTop(int)} and
* {@link #setHeight(int)}. While the width of the track can also be set, the
* drawn handle will use vanilla's sprite width (see {@link #HANDLE_WIDTH}.
*/
public class Scrollbar extends AbstractGui implements IScrollSource {
/**
* Width of the scrollbar handle sprite in the source texture.
*/
private static final int HANDLE_WIDTH = 12;
/**
* Height of the scrollbar handle sprite in the source texture.
*/
private static final int HANDLE_HEIGHT = 15;
/**
* Texture containing the scrollbar handle sprites.
*/
private static final ResourceLocation TEXTURE = new ResourceLocation("minecraft",
"textures/gui/container/creative_inventory/tabs.png");
/**
* Rectangle in the source texture that contains the sprite for an enabled
* handle.
*/
private static final Rectangle2d ENABLED = new Rectangle2d(232, 0, HANDLE_WIDTH, HANDLE_HEIGHT);
/**
* Rectangle in the source texture that contains the sprite for a disabled
* handle.
*/
private static final Rectangle2d DISABLED = new Rectangle2d(232 + HANDLE_WIDTH, 0, HANDLE_WIDTH, HANDLE_HEIGHT);
/**
* The screen x-coordinate of the scrollbar's inner track.
*/
private int displayX = 0; private int displayX = 0;
/**
* The screen y-coordinate of the scrollbar's inner track.
*/
private int displayY = 0; private int displayY = 0;
private int width = 12;
/**
* The inner width of the scrollbar track.
*/
private int width = HANDLE_WIDTH;
/**
* The inner height of the scrollbar track.
*/
private int height = 16; private int height = 16;
private int pageSize = 1; private int pageSize = 1;
@@ -94,58 +36,18 @@ public class Scrollbar extends AbstractGui implements IScrollSource {
private int minScroll = 0; private int minScroll = 0;
private int currentScroll = 0; private int currentScroll = 0;
/** public void draw(final AEBaseScreen<?> g) {
* True if the scrollbar's handle is currently being dragged. g.bindTexture("minecraft", "gui/container/creative_inventory/tabs.png");
*/ RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
private boolean dragging;
/**
* The y-coordinate relative to the upper edge of the scrollbar handle, where
* the user pressed the mouse button to drag. While dragging, this is applied as
* an offset to the effective scrollbar position.
*/
private int dragYOffset;
private final EventRepeater eventRepeater = new EventRepeater(Duration.ofMillis(250), Duration.ofMillis(150));
/**
* Draws the handle of the scrollbar.
* <p>
* The GUI is assumed to already contain a prebaked scrollbar track in its
* background.
*/
public void draw(MatrixStack matrices, final AEBaseScreen<?> g) {
setBlitOffset(g.getBlitOffset());
// Draw the track (nice for debugging)
// fill(matrices, displayX, displayY, this.displayX + width, this.displayY +
// height, 0xffff0000);
g.bindTexture(TEXTURE);
int yOffset;
Rectangle2d sourceRect;
if (this.getRange() == 0) { if (this.getRange() == 0) {
yOffset = 0; GuiUtils.drawTexturedModalRect(this.displayX, this.displayY, 232 + this.width, 0, this.width, 15,
sourceRect = DISABLED; g.getBlitOffset());
} else { } else {
yOffset = getHandleYOffset(); final int offset = (this.currentScroll - this.minScroll) * (this.height - 15) / this.getRange();
sourceRect = ENABLED; GuiUtils.drawTexturedModalRect(this.displayX, offset + this.displayY, 232, 0, this.width, 15,
g.getBlitOffset());
} }
blit(matrices, this.displayX, this.displayY + yOffset, sourceRect.getX(), sourceRect.getY(),
sourceRect.getWidth(), sourceRect.getHeight());
}
/**
* Returns the y-position of the scrollbar handle in relation to the upper edge
* of the scrollbar's track.
*/
private int getHandleYOffset() {
if (getRange() == 0) {
return 0;
}
int availableHeight = this.height - HANDLE_HEIGHT;
return (this.currentScroll - this.minScroll) * availableHeight / this.getRange();
} }
private int getRange() { private int getRange() {
@@ -209,96 +111,24 @@ public class Scrollbar extends AbstractGui implements IScrollSource {
return this.currentScroll; return this.currentScroll;
} }
public boolean mouseDown(double x, double y) { public void click(final double x, final double y) {
this.dragging = false; if (this.getRange() == 0) {
// Clicks to the left or right of the scrollbar don't do anything
if (x < displayX || x >= displayX + width) {
return false;
}
// Clicks to the top or bottom don't do anything either
int relY = (int) Math.round(y - displayY);
if (relY < 0 || relY >= height) {
return false;
}
// Do nothing when there's no range, but swallow the event
if (getRange() == 0) {
return true;
}
int handleYOffset = getHandleYOffset();
if (relY < handleYOffset) {
// Clicks above the handle will page up, repeatedly
pageUp();
eventRepeater.repeat(this::pageUp);
} else if (relY < handleYOffset + HANDLE_HEIGHT) {
// Clicks on the handle will initiate dragging it
this.dragging = true;
this.dragYOffset = relY - handleYOffset;
} else {
// Clicks below the handle will page down, repeatedly
pageDown();
eventRepeater.repeat(this::pageDown);
}
return true;
}
public boolean mouseUp(double x, double y) {
this.dragging = false;
this.eventRepeater.stop();
return false;
}
public void mouseDragged(double x, double y) {
if (this.getRange() == 0 || !this.dragging || this.eventRepeater.isRepeating()) {
return; return;
} }
// Compute the position of the mouse (adjusted for where it grabbed the handle, if (x > this.displayX && x <= this.displayX + this.width) {
// so as if it grabbed if (y > this.displayY && y <= this.displayY + this.height) {
// the upper edge of it) within the scrollable area of the track (minus the this.currentScroll = (int) (y - this.displayY);
// handle height). this.currentScroll = this.minScroll + ((this.currentScroll * 2 * this.getRange() / this.height));
double handleUpperEdgeY = y - this.displayY - this.dragYOffset; this.currentScroll = (this.currentScroll + 1) >> 1;
double availableHeight = this.height - HANDLE_HEIGHT; this.applyRange();
double position = MathHelper.clamp(handleUpperEdgeY / availableHeight, 0.0, 1.0); }
}
this.currentScroll = this.minScroll + (int) Math.round(position * this.getRange());
this.applyRange();
} }
public void wheel(double delta) { public void wheel(double delta) {
// Do nothing when there's no range
if (getRange() == 0) {
return;
}
delta = Math.max(Math.min(-delta, 1), -1); delta = Math.max(Math.min(-delta, 1), -1);
this.currentScroll += delta * this.pageSize; this.currentScroll += delta * this.pageSize;
this.applyRange(); this.applyRange();
} }
/**
* Ticks the scrollbar for the purposes of input-repeats (since mouse-downs are
* not repeat-triggered), used to repeatedly page-up or page-down when the mouse
* is held in the area above or below the scrollbar handle.
*/
public void tick() {
this.eventRepeater.tick();
}
private void pageUp() {
this.currentScroll -= this.pageSize;
this.applyRange();
}
private void pageDown() {
this.currentScroll += this.pageSize;
this.applyRange();
}
} }
@@ -25,7 +25,6 @@ import java.util.function.Predicate;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
@@ -48,7 +47,6 @@ import appeng.api.config.StorageFilter;
import appeng.api.config.TerminalStyle; import appeng.api.config.TerminalStyle;
import appeng.api.config.ViewItems; import appeng.api.config.ViewItems;
import appeng.api.config.YesNo; import appeng.api.config.YesNo;
import appeng.client.gui.AEBaseScreen;
import appeng.core.localization.ButtonToolTips; import appeng.core.localization.ButtonToolTips;
import appeng.util.EnumCycler; import appeng.util.EnumCycler;
@@ -91,11 +89,9 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
registerApp(16 * 7, Settings.CONDENSER_OUTPUT, CondenserOutput.TRASH, ButtonToolTips.CondenserOutput, registerApp(16 * 7, Settings.CONDENSER_OUTPUT, CondenserOutput.TRASH, ButtonToolTips.CondenserOutput,
ButtonToolTips.Trash); ButtonToolTips.Trash);
registerApp(16 * 7 + 1, Settings.CONDENSER_OUTPUT, CondenserOutput.MATTER_BALLS, registerApp(16 * 7 + 1, Settings.CONDENSER_OUTPUT, CondenserOutput.MATTER_BALLS,
ButtonToolTips.CondenserOutput, ButtonToolTips.CondenserOutput, ButtonToolTips.MatterBalls);
ButtonToolTips.MatterBalls.text(CondenserOutput.MATTER_BALLS.requiredPower));
registerApp(16 * 7 + 2, Settings.CONDENSER_OUTPUT, CondenserOutput.SINGULARITY, registerApp(16 * 7 + 2, Settings.CONDENSER_OUTPUT, CondenserOutput.SINGULARITY,
ButtonToolTips.CondenserOutput, ButtonToolTips.CondenserOutput, ButtonToolTips.Singularity);
ButtonToolTips.Singularity.text(CondenserOutput.SINGULARITY.requiredPower));
registerApp(16 * 9 + 1, Settings.ACCESS, AccessRestriction.READ, ButtonToolTips.IOMode, registerApp(16 * 9 + 1, Settings.ACCESS, AccessRestriction.READ, ButtonToolTips.IOMode,
ButtonToolTips.Read); ButtonToolTips.Read);
@@ -234,13 +230,7 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
} }
private void triggerPress() { private void triggerPress() {
boolean backwards = false; boolean backwards = Minecraft.getInstance().mouseHelper.isRightDown();
// This isn't great, but we don't get any information about right-clicks
// otherwise
Screen currentScreen = Minecraft.getInstance().currentScreen;
if (currentScreen instanceof AEBaseScreen) {
backwards = ((AEBaseScreen<?>) currentScreen).isHandlingRightClick();
}
onPress.handle(this, backwards); onPress.handle(this, backwards);
} }
@@ -33,7 +33,7 @@ public class TabButton extends Button implements ITooltip {
public static final ResourceLocation TEXTURE_STATES = new ResourceLocation("appliedenergistics2", public static final ResourceLocation TEXTURE_STATES = new ResourceLocation("appliedenergistics2",
"textures/guis/states.png"); "textures/guis/states.png");
private final ItemRenderer itemRenderer; private final ItemRenderer itemRenderer;
private boolean hideEdge; private int hideEdge = 0;
private int myIcon = -1; private int myIcon = -1;
private ItemStack myItem; private ItemStack myItem;
@@ -71,17 +71,14 @@ public class TabButton extends Button implements ITooltip {
RenderSystem.enableAlphaTest(); RenderSystem.enableAlphaTest();
// Selects the button border from the sprite-sheet, where each type occupies a int uv_x = (this.hideEdge > 0 ? 11 : 13);
// 2x2 slot
int uv_x = 8 + (this.hideEdge ? 0 : 2);
int uv_y = 12 + (this.isFocused() ? 2 : 0);
final int offsetX = this.hideEdge ? 1 : 0; final int offsetX = this.hideEdge > 0 ? 1 : 0;
blit(matrixStack, this.x, this.y, uv_x * 16, uv_y * 16, 25, 22); blit(matrixStack, this.x, this.y, uv_x * 16, 0, 25, 22);
if (this.myIcon >= 0) { if (this.myIcon >= 0) {
uv_y = this.myIcon / 16; final int uv_y = this.myIcon / 16;
uv_x = this.myIcon - uv_y * 16; uv_x = this.myIcon - uv_y * 16;
blit(matrixStack, offsetX + this.x + 3, this.y + 3, uv_x * 16, uv_y * 16, 16, 16); blit(matrixStack, offsetX + this.x + 3, this.y + 3, uv_x * 16, uv_y * 16, 16, 16);
@@ -131,11 +128,11 @@ public class TabButton extends Button implements ITooltip {
return this.visible; return this.visible;
} }
public boolean getHideEdge() { public int getHideEdge() {
return this.hideEdge; return this.hideEdge;
} }
public void setHideEdge(final boolean hideEdge) { public void setHideEdge(final int hideEdge) {
this.hideEdge = hideEdge; this.hideEdge = hideEdge;
} }
} }
@@ -1,65 +0,0 @@
package appeng.client.gui.widgets;
import java.util.ArrayList;
import java.util.List;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.text.ITextComponent;
/**
* Displays a small icon that shows validation errors for some input control.
*/
public class ValidationIcon extends IconButton {
private final List<ITextComponent> tooltip = new ArrayList<>();
private boolean valid;
public ValidationIcon(int x, int y) {
super(x, y, btn -> {
});
setDisableBackground(true);
setDisableClickSound(true);
setHalfSize(true);
}
public void setValid(boolean valid) {
setVisibility(!valid);
if (valid) {
this.tooltip.clear();
}
}
public void setTooltip(List<ITextComponent> lines) {
this.tooltip.clear();
this.tooltip.addAll(lines);
}
@Override
protected int getIconIndex() {
return 16 * 8;
}
@Override
public boolean changeFocus(boolean flag) {
return false; // Cannot focus this element
}
@Override
public void renderToolTip(MatrixStack matrices, int mouseX, int mouseY) {
if (this.tooltip.isEmpty()) {
return;
}
Minecraft client = Minecraft.getInstance();
Screen screen = client.currentScreen;
if (screen == null) {
return;
}
screen.func_243308_b(matrices, this.tooltip, x, y);
}
}
@@ -47,8 +47,8 @@ public abstract class DelegateBakedModel implements IBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return baseModel.isSideLit(); return baseModel.func_230044_c_();
} }
@Override @Override
@@ -60,7 +60,7 @@ public class DummyFluidBakedModel implements IBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return false; return false;
} }
@@ -73,8 +73,8 @@ public class DummyFluidDispatcherBakedModel extends DelegateBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return getBaseModel().isSideLit(); return getBaseModel().func_230044_c_();
} }
@Override @Override
@@ -86,7 +86,7 @@ public class DummyFluidDispatcherBakedModel extends DelegateBakedModel {
public ItemOverrideList getOverrides() { public ItemOverrideList getOverrides() {
return new ItemOverrideList() { return new ItemOverrideList() {
@Override @Override
public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, ClientWorld world, public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, ClientWorld world,
LivingEntity entity) { LivingEntity entity) {
if (!(stack.getItem() instanceof FluidDummyItem)) { if (!(stack.getItem() instanceof FluidDummyItem)) {
return originalModel; return originalModel;
@@ -80,7 +80,7 @@ public class FacadeBakedItemModel extends DelegateBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return false; return false;
} }
@@ -50,7 +50,7 @@ public class FacadeDispatcherBakedModel extends DelegateBakedModel {
public ItemOverrideList getOverrides() { public ItemOverrideList getOverrides() {
return new ItemOverrideList() { return new ItemOverrideList() {
@Override @Override
public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, ClientWorld world, public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, ClientWorld world,
LivingEntity entity) { LivingEntity entity) {
if (!(stack.getItem() instanceof FacadeItem)) { if (!(stack.getItem() instanceof FacadeItem)) {
return originalModel; return originalModel;
@@ -18,6 +18,7 @@
package appeng.client.render.cablebus; package appeng.client.render.cablebus;
import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.EnumMap; import java.util.EnumMap;
@@ -51,12 +52,21 @@ import net.minecraftforge.client.model.data.IModelData;
import appeng.api.parts.IPartModel; import appeng.api.parts.IPartModel;
import appeng.api.util.AECableType; import appeng.api.util.AECableType;
import appeng.api.util.AEColor; import appeng.api.util.AEColor;
import appeng.metrics.Metrics;
public class CableBusBakedModel implements IBakedModel { public class CableBusBakedModel implements IBakedModel {
// The number of quads overall that will be cached // The number of quads overall that will be cached
private static final int CACHE_QUAD_COUNT = 5000; private static final int CACHE_QUAD_COUNT = 5000;
// Keep a weak-ref to the last created cache for reporting metrics
private static WeakReference<LoadingCache<CableBusRenderState, List<BakedQuad>>> cacheForMetrics = new WeakReference<>(
null);
static {
Metrics.cache("cable_bus_model_cache", () -> cacheForMetrics.get());
}
private final LoadingCache<CableBusRenderState, List<BakedQuad>> cableModelCache; private final LoadingCache<CableBusRenderState, List<BakedQuad>> cableModelCache;
private final CableBuilder cableBuilder; private final CableBuilder cableBuilder;
@@ -74,6 +84,7 @@ public class CableBusBakedModel implements IBakedModel {
this.partModels = partModels; this.partModels = partModels;
this.particleTexture = particleTexture; this.particleTexture = particleTexture;
this.cableModelCache = CacheBuilder.newBuilder()// this.cableModelCache = CacheBuilder.newBuilder()//
.recordStats()//
.maximumWeight(CACHE_QUAD_COUNT)// .maximumWeight(CACHE_QUAD_COUNT)//
.weigher((Weigher<CableBusRenderState, List<BakedQuad>>) (key, value) -> value.size())// .weigher((Weigher<CableBusRenderState, List<BakedQuad>>) (key, value) -> value.size())//
.build(new CacheLoader<CableBusRenderState, List<BakedQuad>>() { .build(new CacheLoader<CableBusRenderState, List<BakedQuad>>() {
@@ -84,6 +95,7 @@ public class CableBusBakedModel implements IBakedModel {
return model; return model;
} }
}); });
cacheForMetrics = new WeakReference<>(cableModelCache);
} }
@Override @Override
@@ -331,7 +343,7 @@ public class CableBusBakedModel implements IBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return false;// TODO return false;// TODO
} }
@@ -100,7 +100,7 @@ public class P2PTunnelFrequencyBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return false;// TODO return false;// TODO
} }
@@ -113,7 +113,7 @@ abstract class CraftingCubeBakedModel implements IDynamicBakedModel {
return quads; return quads;
} }
private void addRing(CubeBuilder builder, Direction side, EnumSet<Direction> connections) { private void addRing(CubeBuilder builder, @Nullable Direction side, EnumSet<Direction> connections) {
// Fill in the corners // Fill in the corners
builder.setTexture(this.ringCorner); builder.setTexture(this.ringCorner);
this.addCornerCap(builder, connections, side, Direction.UP, Direction.EAST, Direction.NORTH); this.addCornerCap(builder, connections, side, Direction.UP, Direction.EAST, Direction.NORTH);
@@ -276,7 +276,7 @@ abstract class CraftingCubeBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return false; return false;
} }
@@ -86,8 +86,8 @@ public class EncodedPatternBakedModel extends DelegateBakedModel {
// This determines diffuse lighting in the UI, and since we want to render // This determines diffuse lighting in the UI, and since we want to render
// the outputModel in the UI, we need to use it's setting here // the outputModel in the UI, we need to use it's setting here
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return outputModel.isSideLit(); return outputModel.func_230044_c_();
} }
} }
@@ -112,7 +112,7 @@ public class EncodedPatternBakedModel extends DelegateBakedModel {
@Nullable @Nullable
@Override @Override
public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, @Nullable ClientWorld world, public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, @Nullable ClientWorld world,
@Nullable LivingEntity entity) { @Nullable LivingEntity entity) {
boolean shiftHeld = Screen.hasShiftDown(); boolean shiftHeld = Screen.hasShiftDown();
if (shiftHeld) { if (shiftHeld) {
@@ -122,12 +122,12 @@ public class EncodedPatternBakedModel extends DelegateBakedModel {
IBakedModel realModel = Minecraft.getInstance().getItemRenderer().getItemModelMesher() IBakedModel realModel = Minecraft.getInstance().getItemRenderer().getItemModelMesher()
.getItemModel(output); .getItemModel(output);
// Give the item model a chance to handle the overrides as well // Give the item model a chance to handle the overrides as well
realModel = realModel.getOverrides().getOverrideModel(realModel, output, world, entity); realModel = realModel.getOverrides().func_239290_a_(realModel, output, world, entity);
return new ShiftHoldingModelWrapper(getBaseModel(), realModel); return new ShiftHoldingModelWrapper(getBaseModel(), realModel);
} }
} }
return getBaseModel().getOverrides().getOverrideModel(originalModel, stack, world, entity); return getBaseModel().getOverrides().func_239290_a_(originalModel, stack, world, entity);
} }
} }
@@ -107,7 +107,7 @@ public class AutoRotatingBakedModel extends DelegateBakedModel {
// when piping it // when piping it
// to the AO lighter, thus fixing our problem. // to the AO lighter, thus fixing our problem.
BakedQuad packedQuad = new BakedQuad(unpackedQuad.getVertexData(), quad.getTintIndex(), BakedQuad packedQuad = new BakedQuad(unpackedQuad.getVertexData(), quad.getTintIndex(),
unpackedQuad.getFace(), quad.getSprite(), quad.applyDiffuseLighting()); unpackedQuad.getFace(), quad.func_187508_a(), quad.func_239287_f_());
rotated.add(packedQuad); rotated.add(packedQuad);
} }
return rotated; return rotated;
@@ -120,7 +120,7 @@ class BiometricCardBakedModel implements IBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return false;// TODO return false;// TODO
} }
@@ -143,7 +143,7 @@ class BiometricCardBakedModel implements IBakedModel {
public ItemOverrideList getOverrides() { public ItemOverrideList getOverrides() {
return new ItemOverrideList() { return new ItemOverrideList() {
@Override @Override
public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, ClientWorld world, public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, ClientWorld world,
LivingEntity entity) { LivingEntity entity) {
String username = ""; String username = "";
if (stack.getItem() instanceof IBiometricCard) { if (stack.getItem() instanceof IBiometricCard) {
@@ -50,19 +50,19 @@ class ColorApplicatorBakedModel implements IBakedModel {
for (BakedQuad quad : quads) { for (BakedQuad quad : quads) {
int tint; int tint;
if (quad.getSprite() == texDark) { if (quad.func_187508_a() == texDark) {
tint = 1; tint = 1;
} else if (quad.getSprite() == texMedium) { } else if (quad.func_187508_a() == texMedium) {
tint = 2; tint = 2;
} else if (quad.getSprite() == texBright) { } else if (quad.func_187508_a() == texBright) {
tint = 3; tint = 3;
} else { } else {
result.add(quad); result.add(quad);
continue; continue;
} }
BakedQuad newQuad = new BakedQuad(quad.getVertexData(), tint, quad.getFace(), quad.getSprite(), BakedQuad newQuad = new BakedQuad(quad.getVertexData(), tint, quad.getFace(), quad.func_187508_a(),
quad.applyDiffuseLighting()); quad.func_239287_f_());
result.add(newQuad); result.add(newQuad);
} }
@@ -88,7 +88,7 @@ class ColorApplicatorBakedModel implements IBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return false;// TODO return false;// TODO
} }
@@ -157,7 +157,7 @@ class GlassBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
// TODO: Forge: Auto-generated method stub // TODO: Forge: Auto-generated method stub
return false; return false;
} }
@@ -105,7 +105,7 @@ class MemoryCardBakedModel implements IBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return false;// TODO return false;// TODO
} }
@@ -128,7 +128,7 @@ class MemoryCardBakedModel implements IBakedModel {
public ItemOverrideList getOverrides() { public ItemOverrideList getOverrides() {
return new ItemOverrideList() { return new ItemOverrideList() {
@Override @Override
public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, ClientWorld world, public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, ClientWorld world,
LivingEntity entity) { LivingEntity entity) {
try { try {
if (stack.getItem() instanceof IMemoryCard) { if (stack.getItem() instanceof IMemoryCard) {
@@ -122,7 +122,7 @@ public class SkyCompassBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return false; return false;
} }
@@ -149,7 +149,7 @@ public class SkyCompassBakedModel implements IDynamicBakedModel {
*/ */
return new ItemOverrideList() { return new ItemOverrideList() {
@Override @Override
public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, @Nullable ClientWorld world, public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, @Nullable ClientWorld world,
@Nullable LivingEntity entity) { @Nullable LivingEntity entity) {
// FIXME: This check prevents compasses being held by OTHERS from getting the // FIXME: This check prevents compasses being held by OTHERS from getting the
// rotation, BUT do we actually still need this??? // rotation, BUT do we actually still need this???
@@ -181,7 +181,7 @@ class SpatialPylonBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean isSideLit() { public boolean func_230044_c_() {
return false; return false;
} }
@@ -149,7 +149,7 @@ public class ChestTileEntityRenderer extends TileEntityRenderer<ChestTileEntity>
for (int i = 0; i < quads.size(); i++) { for (int i = 0; i < quads.size(); i++) {
BakedQuad quad = quads.get(i); BakedQuad quad = quads.get(i);
quads.set(i, new BakedQuad(quad.getVertexData(), quad.getTintIndex(), r.rotate(quad.getFace()), quads.set(i, new BakedQuad(quad.getVertexData(), quad.getTintIndex(), r.rotate(quad.getFace()),
quad.getSprite(), quad.applyDiffuseLighting())); quad.func_187508_a(), quad.func_239287_f_()));
} }
return quads; return quads;
@@ -65,8 +65,10 @@ import appeng.container.slot.PlayerInvSlot;
import appeng.core.AELog; import appeng.core.AELog;
import appeng.core.Api; import appeng.core.Api;
import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.core.sync.packets.InventoryActionPacket; import appeng.core.sync.packets.InventoryActionPacket;
import appeng.core.sync.packets.TargetItemStackPacket; import appeng.core.sync.packets.TargetItemStackPacket;
import appeng.helpers.ICustomNameObject;
import appeng.helpers.InventoryAction; import appeng.helpers.InventoryAction;
import appeng.me.helpers.PlayerSource; import appeng.me.helpers.PlayerSource;
import appeng.util.InventoryAdaptor; import appeng.util.InventoryAdaptor;
@@ -84,9 +86,11 @@ public abstract class AEBaseContainer extends Container {
private final IGuiItemObject obj; private final IGuiItemObject obj;
private final HashMap<Integer, SyncData> syncData = new HashMap<>(); private final HashMap<Integer, SyncData> syncData = new HashMap<>();
private boolean isContainerValid = true; private boolean isContainerValid = true;
private String customName;
private ContainerLocator locator; private ContainerLocator locator;
private IMEInventoryHandler<IAEItemStack> cellInv; private IMEInventoryHandler<IAEItemStack> cellInv;
private IEnergySource powerSrc; private IEnergySource powerSrc;
private boolean sentCustomName;
private int ticksSinceCheck = 900; private int ticksSinceCheck = 900;
private IAEItemStack clientRequestedTargetItem = null; private IAEItemStack clientRequestedTargetItem = null;
@@ -293,7 +297,9 @@ public abstract class AEBaseContainer extends Container {
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (isServer()) { this.sendCustomName();
if (Platform.isServer()) {
if (this.tileEntity != null if (this.tileEntity != null
&& this.tileEntity.getWorld().getTileEntity(this.tileEntity.getPos()) != this.tileEntity) { && this.tileEntity.getWorld().getTileEntity(this.tileEntity.getPos()) != this.tileEntity) {
this.setValidContainer(false); this.setValidContainer(false);
@@ -860,6 +866,43 @@ public abstract class AEBaseContainer extends Container {
this.detectAndSendChanges(); this.detectAndSendChanges();
} }
private void sendCustomName() {
// FIXME: Trash this, this is handled by NamedContainerProvider now
if (!this.sentCustomName) {
this.sentCustomName = true;
if (Platform.isServer()) {
ICustomNameObject name = null;
if (this.part instanceof ICustomNameObject) {
name = (ICustomNameObject) this.part;
}
if (this.tileEntity instanceof ICustomNameObject) {
name = (ICustomNameObject) this.tileEntity;
}
if (this.obj instanceof ICustomNameObject) {
name = (ICustomNameObject) this.obj;
}
if (this instanceof ICustomNameObject) {
name = (ICustomNameObject) this;
}
if (name != null) {
if (name.hasCustomInventoryName()) {
this.setCustomName(name.getCustomInventoryName().getString());
}
if (this.getCustomName() != null) {
NetworkHandler.instance().sendTo(new ConfigValuePacket("CustomName", this.getCustomName()),
(ServerPlayerEntity) this.getPlayerInventory().player);
}
}
}
}
}
public void swapSlotContents(final int slotA, final int slotB) { public void swapSlotContents(final int slotA, final int slotB) {
final Slot a = this.getSlot(slotA); final Slot a = this.getSlot(slotA);
final Slot b = this.getSlot(slotB); final Slot b = this.getSlot(slotB);
@@ -949,6 +992,14 @@ public abstract class AEBaseContainer extends Container {
this.cellInv = cellInv; this.cellInv = cellInv;
} }
public String getCustomName() {
return this.customName;
}
public void setCustomName(final String customName) {
this.customName = customName;
}
public PlayerInventory getPlayerInventory() { public PlayerInventory getPlayerInventory() {
return this.invPlayer; return this.invPlayer;
} }
@@ -977,18 +1028,4 @@ public abstract class AEBaseContainer extends Container {
this.powerSrc = powerSrc; this.powerSrc = powerSrc;
} }
/**
* Returns whether this container instance lives on the client.
*/
protected boolean isClient() {
return invPlayer.player.getEntityWorld().isRemote();
}
/**
* Returns whether this container instance lives on the server.
*/
protected boolean isServer() {
return !isClient();
}
} }
@@ -69,7 +69,7 @@ public final class ContainerLocator {
private final AEPartLocation side; private final AEPartLocation side;
private ContainerLocator(Type type, int itemIndex, World world, BlockPos blockPos, AEPartLocation side) { private ContainerLocator(Type type, int itemIndex, World world, BlockPos blockPos, AEPartLocation side) {
this(type, itemIndex, world.getDimensionKey().getLocation(), blockPos, side); this(type, itemIndex, world.func_234923_W_().func_240901_a_(), blockPos, side);
} }
private ContainerLocator(Type type, int itemIndex, ResourceLocation worldId, BlockPos blockPos, private ContainerLocator(Type type, int itemIndex, ResourceLocation worldId, BlockPos blockPos,
@@ -89,8 +89,6 @@ public class SyncData {
NetworkHandler.instance().sendTo(new ConfigValuePacket("SyncDat." + this.channel, json), NetworkHandler.instance().sendTo(new ConfigValuePacket("SyncDat." + this.channel, json),
(ServerPlayerEntity) o); (ServerPlayerEntity) o);
} }
this.clientVersion = val;
return;
} }
// Types other than ITextComponent must be non-null // Types other than ITextComponent must be non-null
@@ -129,7 +127,7 @@ public class SyncData {
String json = (String) val; String json = (String) val;
ITextComponent text = null; ITextComponent text = null;
if (!json.isEmpty()) { if (!json.isEmpty()) {
text = ITextComponent.Serializer.getComponentFromJson((String) val); text = ITextComponent.Serializer.func_240643_a_((String) val);
} }
this.updateTextComponent(text); this.updateTextComponent(text);
} else { } else {
@@ -49,6 +49,7 @@ import appeng.container.slot.RestrictedInputSlot;
import appeng.core.Api; import appeng.core.Api;
import appeng.tile.misc.CellWorkbenchTileEntity; import appeng.tile.misc.CellWorkbenchTileEntity;
import appeng.util.EnumCycler; import appeng.util.EnumCycler;
import appeng.util.Platform;
import appeng.util.helpers.ItemHandlerUtil; import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.inv.WrapperSupplierItemHandler; import appeng.util.inv.WrapperSupplierItemHandler;
import appeng.util.iterators.NullIterator; import appeng.util.iterators.NullIterator;
@@ -142,7 +143,7 @@ public class CellWorkbenchContainer extends UpgradeableContainer {
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
final ItemStack is = this.workBench.getInventoryByName("cell").getStackInSlot(0); final ItemStack is = this.workBench.getInventoryByName("cell").getStackInSlot(0);
if (isServer()) { if (Platform.isServer()) {
for (final IContainerListener listener : this.listeners) { for (final IContainerListener listener : this.listeners) {
if (this.prevStack != is) { if (this.prevStack != is) {
// if the bars changed an item was probably made, so just send shit! // if the bars changed an item was probably made, so just send shit!
@@ -33,6 +33,7 @@ import appeng.container.interfaces.IProgressProvider;
import appeng.container.slot.OutputSlot; import appeng.container.slot.OutputSlot;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.tile.misc.CondenserTileEntity; import appeng.tile.misc.CondenserTileEntity;
import appeng.util.Platform;
public class CondenserContainer extends AEBaseContainer implements IProgressProvider { public class CondenserContainer extends AEBaseContainer implements IProgressProvider {
@@ -74,13 +75,13 @@ public class CondenserContainer extends AEBaseContainer implements IProgressProv
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (isServer()) { if (Platform.isServer()) {
final double maxStorage = this.condenser.getStorage(); final double maxStorage = this.condenser.getStorage();
final double requiredEnergy = this.condenser.getRequiredPower(); final double requiredEnergy = this.condenser.getRequiredPower();
this.requiredEnergy = requiredEnergy == 0 ? (int) maxStorage : (int) Math.min(requiredEnergy, maxStorage); this.requiredEnergy = requiredEnergy == 0 ? (int) maxStorage : (int) Math.min(requiredEnergy, maxStorage);
this.storedPower = (int) this.condenser.getStoredPower(); this.storedPower = (int) this.condenser.getStoredPower();
this.output = (CondenserOutput) this.condenser.getConfigManager().getSetting(Settings.CONDENSER_OUTPUT); this.setOutput((CondenserOutput) this.condenser.getConfigManager().getSetting(Settings.CONDENSER_OUTPUT));
} }
super.detectAndSendChanges(); super.detectAndSendChanges();
@@ -100,4 +101,7 @@ public class CondenserContainer extends AEBaseContainer implements IProgressProv
return this.output; return this.output;
} }
private void setOutput(final CondenserOutput output) {
this.output = output;
}
} }
@@ -1,7 +1,5 @@
package appeng.container.implementations; package appeng.container.implementations;
import java.util.function.Function;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity;
@@ -13,6 +11,8 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.fml.network.NetworkHooks;
import appeng.api.config.SecurityPermissions; import appeng.api.config.SecurityPermissions;
@@ -43,8 +43,6 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
private final SecurityPermissions requiredPermission; private final SecurityPermissions requiredPermission;
private Function<I, ITextComponent> containerTitleStrategy = this::getDefaultContainerTitle;
public ContainerHelper(ContainerFactory<C, I> factory, Class<I> interfaceClass) { public ContainerHelper(ContainerFactory<C, I> factory, Class<I> interfaceClass) {
this(factory, interfaceClass, null); this(factory, interfaceClass, null);
} }
@@ -56,47 +54,19 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
this.factory = factory; this.factory = factory;
} }
/**
* Specifies a custom strategy for obtaining a custom container name.
*
* The stratgy should return {@link StringTextComponent#EMPTY} if there's no
* custom name.
*/
public ContainerHelper<C, I> withContainerTitle(Function<I, ITextComponent> containerTitleStrategy) {
this.containerTitleStrategy = containerTitleStrategy;
return this;
}
/** /**
* Opens a container that is based around a single tile entity. The tile * Opens a container that is based around a single tile entity. The tile
* entity's position is encoded in the packet buffer. * entity's position is encoded in the packet buffer.
*/ */
public C fromNetwork(int windowId, PlayerInventory inv, PacketBuffer packetBuf) { public C fromNetwork(int windowId, PlayerInventory inv, PacketBuffer packetBuf) {
return fromNetwork(windowId, inv, packetBuf, (accessObj, container, buffer) -> {
});
}
/**
* Same as {@link #open}, but allows or additional data to be read from the
* packet, and passed onto the container.
*/
public C fromNetwork(int windowId, PlayerInventory inv, PacketBuffer packetBuf,
InitialDataDeserializer<C, I> initialDataDeserializer) {
I host = getHostFromLocator(inv.player, ContainerLocator.read(packetBuf)); I host = getHostFromLocator(inv.player, ContainerLocator.read(packetBuf));
if (host != null) { if (host != null) {
C container = factory.create(windowId, inv, host); return factory.create(windowId, inv, host);
initialDataDeserializer.deserializeInitialData(host, container, packetBuf);
return container;
} }
return null; return null;
} }
public boolean open(PlayerEntity player, ContainerLocator locator) { public boolean open(PlayerEntity player, ContainerLocator locator) {
return open(player, locator, (accessObj, buffer) -> {
});
}
public boolean open(PlayerEntity player, ContainerLocator locator, InitialDataSerializer<I> initialDataSerializer) {
if (!(player instanceof ServerPlayerEntity)) { if (!(player instanceof ServerPlayerEntity)) {
// Cannot open containers on the client or for non-players // Cannot open containers on the client or for non-players
// FIXME logging? // FIXME logging?
@@ -113,7 +83,7 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
return false; return false;
} }
ITextComponent title = containerTitleStrategy.apply(accessInterface); ITextComponent title = findContainerTitle(player.world, locator, accessInterface);
INamedContainerProvider container = new SimpleNamedContainerProvider((wnd, p, pl) -> { INamedContainerProvider container = new SimpleNamedContainerProvider((wnd, p, pl) -> {
C c = factory.create(wnd, p, accessInterface); C c = factory.create(wnd, p, accessInterface);
@@ -122,14 +92,34 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
c.setLocator(locator); c.setLocator(locator);
return c; return c;
}, title); }, title);
NetworkHooks.openGui((ServerPlayerEntity) player, container, buffer -> { NetworkHooks.openGui((ServerPlayerEntity) player, container, locator::write);
locator.write(buffer);
initialDataSerializer.serializeInitialData(accessInterface, buffer);
});
return true; return true;
} }
private ITextComponent findContainerTitle(World world, ContainerLocator locator, I accessInterface) {
if (accessInterface instanceof ICustomNameObject) {
ICustomNameObject customNameObject = (ICustomNameObject) accessInterface;
if (customNameObject.hasCustomInventoryName()) {
return customNameObject.getCustomInventoryName();
}
}
// Use block name at position
// FIXME: this is not right, we'd need to check the part's item stack, or custom
// naming interface impl
// FIXME: Should move this up, because at this point, it's hard to know where
// the terminal host came from (part or tile)
if (locator.hasBlockPos()) {
return new TranslationTextComponent(
world.getBlockState(locator.getBlockPos()).getBlock().getTranslationKey());
}
return new StringTextComponent("Unknown");
}
private I getHostFromLocator(PlayerEntity player, ContainerLocator locator) { private I getHostFromLocator(PlayerEntity player, ContainerLocator locator) {
if (locator.hasItemIndex()) { if (locator.hasItemIndex()) {
return getHostFromPlayerInventory(player, locator); return getHostFromPlayerInventory(player, locator);
@@ -206,24 +196,6 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
C create(int windowId, PlayerInventory playerInv, I accessObj); C create(int windowId, PlayerInventory playerInv, I accessObj);
} }
/**
* Strategy used to serialize initial data for opening the container on the
* client-side into the packet that is sent to the client.
*/
@FunctionalInterface
public interface InitialDataSerializer<I> {
void serializeInitialData(I host, PacketBuffer buffer);
}
/**
* Strategy used to deserialize initial data for opening the container on the
* client-side from the packet received by the server.
*/
@FunctionalInterface
public interface InitialDataDeserializer<C, I> {
void deserializeInitialData(I host, C container, PacketBuffer buffer);
}
private boolean checkPermission(PlayerEntity player, Object accessInterface) { private boolean checkPermission(PlayerEntity player, Object accessInterface) {
if (requiredPermission != null) { if (requiredPermission != null) {
@@ -234,15 +206,4 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
} }
private ITextComponent getDefaultContainerTitle(I accessInterface) {
if (accessInterface instanceof ICustomNameObject) {
ICustomNameObject customNameObject = (ICustomNameObject) accessInterface;
if (customNameObject.hasCustomInventoryName()) {
return customNameObject.getCustomInventoryName();
}
}
return StringTextComponent.EMPTY;
}
} }
@@ -19,8 +19,14 @@
package appeng.container.implementations; package appeng.container.implementations;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableSet;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity;
@@ -60,8 +66,9 @@ import appeng.me.helpers.PlayerSource;
import appeng.parts.reporting.CraftingTerminalPart; import appeng.parts.reporting.CraftingTerminalPart;
import appeng.parts.reporting.PatternTerminalPart; import appeng.parts.reporting.PatternTerminalPart;
import appeng.parts.reporting.TerminalPart; import appeng.parts.reporting.TerminalPart;
import appeng.util.Platform;
public class CraftConfirmContainer extends AEBaseContainer implements CraftingCPUCyclingContainer { public class CraftConfirmContainer extends AEBaseContainer {
public static ContainerType<CraftConfirmContainer> TYPE; public static ContainerType<CraftConfirmContainer> TYPE;
@@ -76,51 +83,98 @@ public class CraftConfirmContainer extends AEBaseContainer implements CraftingCP
return helper.open(player, locator); return helper.open(player, locator);
} }
private final CraftingCPUCycler cpuCycler; private final ArrayList<CraftingCPURecord> cpus = new ArrayList<>();
private ICraftingCPU selectedCpu;
private Future<ICraftingJob> job; private Future<ICraftingJob> job;
private ICraftingJob result; private ICraftingJob result;
@GuiSync(0) @GuiSync(0)
public long bytesUsed; public long bytesUsed;
@GuiSync(3)
public boolean autoStart = false;
@GuiSync(4)
public boolean simulation = true;
// Indicates whether any CPUs are available
@GuiSync(6)
public boolean noCPU = true;
// Properties of the currently selected crafting CPU, this can be null
// if no CPUs are available, or if an automatic one is selected
@GuiSync(1) @GuiSync(1)
public long cpuBytesAvail; public long cpuBytesAvail;
@GuiSync(2) @GuiSync(2)
public int cpuCoProcessors; public int cpuCoProcessors;
@GuiSync(3)
public boolean autoStart = false;
@GuiSync(4)
public boolean simulation = true;
@GuiSync(5)
public int selectedCpu = -1;
@GuiSync(6)
public boolean noCPU = true;
@GuiSync(7) @GuiSync(7)
public ITextComponent cpuName; public ITextComponent myName;
public CraftConfirmContainer(int id, PlayerInventory ip, ITerminalHost te) { public CraftConfirmContainer(int id, PlayerInventory ip, ITerminalHost te) {
super(TYPE, id, ip, te); super(TYPE, id, ip, te);
this.cpuCycler = new CraftingCPUCycler(this::cpuMatches, this::onCPUSelectionChanged);
// A player can select no crafting CPU to use a suitable one automatically
this.cpuCycler.setAllowNoSelection(true);
} }
@Override public void cycleCpu(final boolean next) {
public void cycleSelectedCPU(final boolean next) { if (next) {
this.cpuCycler.cycleCpu(next); this.setSelectedCpu(this.getSelectedCpu() + 1);
} else {
this.setSelectedCpu(this.getSelectedCpu() - 1);
}
if (this.getSelectedCpu() < -1) {
this.setSelectedCpu(this.cpus.size() - 1);
} else if (this.getSelectedCpu() >= this.cpus.size()) {
this.setSelectedCpu(-1);
}
if (this.getSelectedCpu() == -1) {
this.setCpuAvailableBytes(0);
this.setCpuCoProcessors(0);
this.setName(null);
} else {
CraftingCPURecord cpu = this.cpus.get(this.getSelectedCpu());
this.setName(cpu.getName());
this.setCpuAvailableBytes(cpu.getSize());
this.setCpuCoProcessors(cpu.getProcessors());
}
} }
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (isClient()) { if (Platform.isClient()) {
return; return;
} }
this.cpuCycler.detectAndSendChanges(this.getGrid()); final ICraftingGrid cc = this.getGrid().getCache(ICraftingGrid.class);
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
int matches = 0;
boolean changed = false;
for (final ICraftingCPU c : cpuSet) {
boolean found = false;
for (final CraftingCPURecord ccr : this.cpus) {
if (ccr.getCpu() == c) {
found = true;
break;
}
}
final boolean matched = this.cpuMatches(c);
if (matched) {
matches++;
}
if (found == !matched) {
changed = true;
}
}
if (changed || this.cpus.size() != matches) {
this.cpus.clear();
for (final ICraftingCPU c : cpuSet) {
if (this.cpuMatches(c)) {
this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c));
}
}
this.sendCPUs();
}
this.setNoCPU(this.cpus.isEmpty());
super.detectAndSendChanges(); super.detectAndSendChanges();
@@ -224,6 +278,22 @@ public class CraftConfirmContainer extends AEBaseContainer implements CraftingCP
return c.getAvailableStorage() >= this.getUsedBytes() && !c.isBusy(); return c.getAvailableStorage() >= this.getUsedBytes() && !c.isBusy();
} }
private void sendCPUs() {
Collections.sort(this.cpus);
if (this.getSelectedCpu() >= this.cpus.size()) {
this.setSelectedCpu(-1);
this.setCpuAvailableBytes(0);
this.setCpuCoProcessors(0);
this.setName(null);
} else if (this.getSelectedCpu() != -1) {
CraftingCPURecord cpu = this.cpus.get(this.getSelectedCpu());
this.setName(cpu.getName());
this.setCpuAvailableBytes(cpu.getSize());
this.setCpuCoProcessors(cpu.getProcessors());
}
}
public void startJob() { public void startJob() {
ContainerType<?> originalGui = null; ContainerType<?> originalGui = null;
@@ -246,7 +316,9 @@ public class CraftConfirmContainer extends AEBaseContainer implements CraftingCP
if (this.result != null && !this.isSimulation()) { if (this.result != null && !this.isSimulation()) {
final ICraftingGrid cc = this.getGrid().getCache(ICraftingGrid.class); final ICraftingGrid cc = this.getGrid().getCache(ICraftingGrid.class);
final ICraftingLink g = cc.submitJob(this.result, null, this.selectedCpu, true, this.getActionSrc()); final ICraftingLink g = cc.submitJob(this.result, null,
this.getSelectedCpu() == -1 ? null : this.cpus.get(this.getSelectedCpu()).getCpu(), true,
this.getActionSrc());
this.setAutoStart(false); this.setAutoStart(false);
if (g != null && originalGui != null && this.getLocator() != null) { if (g != null && originalGui != null && this.getLocator() != null) {
ContainerOpener.openContainer(originalGui, getPlayerInventory().player, getLocator()); ContainerOpener.openContainer(originalGui, getPlayerInventory().player, getLocator());
@@ -276,22 +348,6 @@ public class CraftConfirmContainer extends AEBaseContainer implements CraftingCP
} }
} }
private void onCPUSelectionChanged(CraftingCPURecord cpuRecord, boolean cpusAvailable) {
noCPU = !cpusAvailable;
if (cpuRecord == null) {
cpuBytesAvail = 0;
cpuCoProcessors = 0;
cpuName = null;
selectedCpu = null;
} else {
cpuBytesAvail = cpuRecord.getSize();
cpuCoProcessors = cpuRecord.getProcessors();
cpuName = cpuRecord.getName();
selectedCpu = cpuRecord.getCpu();
}
}
public World getWorld() { public World getWorld() {
return this.getPlayerInv().player.world; return this.getPlayerInv().player.world;
} }
@@ -316,18 +372,42 @@ public class CraftConfirmContainer extends AEBaseContainer implements CraftingCP
return this.cpuBytesAvail; return this.cpuBytesAvail;
} }
private void setCpuAvailableBytes(final long cpuBytesAvail) {
this.cpuBytesAvail = cpuBytesAvail;
}
public int getCpuCoProcessors() { public int getCpuCoProcessors() {
return this.cpuCoProcessors; return this.cpuCoProcessors;
} }
private void setCpuCoProcessors(final int cpuCoProcessors) {
this.cpuCoProcessors = cpuCoProcessors;
}
public int getSelectedCpu() {
return this.selectedCpu;
}
private void setSelectedCpu(final int selectedCpu) {
this.selectedCpu = selectedCpu;
}
public ITextComponent getName() { public ITextComponent getName() {
return this.cpuName; return this.myName;
}
private void setName(@Nullable final ITextComponent myName) {
this.myName = myName;
} }
public boolean hasNoCPU() { public boolean hasNoCPU() {
return this.noCPU; return this.noCPU;
} }
private void setNoCPU(final boolean noCPU) {
this.noCPU = noCPU;
}
public boolean isSimulation() { public boolean isSimulation() {
return this.simulation; return this.simulation;
} }
@@ -26,7 +26,7 @@ import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.inventory.container.IContainerListener; import net.minecraft.inventory.container.IContainerListener;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.ITextComponent;
import appeng.api.config.SecurityPermissions; import appeng.api.config.SecurityPermissions;
import appeng.api.networking.IGrid; import appeng.api.networking.IGrid;
@@ -46,28 +46,24 @@ import appeng.core.Api;
import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket; import appeng.core.sync.packets.ConfigValuePacket;
import appeng.core.sync.packets.MEInventoryUpdatePacket; import appeng.core.sync.packets.MEInventoryUpdatePacket;
import appeng.helpers.ICustomNameObject;
import appeng.me.cluster.implementations.CraftingCPUCluster; import appeng.me.cluster.implementations.CraftingCPUCluster;
import appeng.tile.crafting.CraftingTileEntity; import appeng.tile.crafting.CraftingTileEntity;
import appeng.util.Platform;
public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorHandlerReceiver<IAEItemStack> { public class CraftingCPUContainer extends AEBaseContainer
implements IMEMonitorHandlerReceiver<IAEItemStack>, ICustomNameObject {
public static ContainerType<CraftingCPUContainer> TYPE; public static ContainerType<CraftingCPUContainer> TYPE;
private static final ContainerHelper<CraftingCPUContainer, CraftingTileEntity> helper = new ContainerHelper<>( private static final ContainerHelper<CraftingCPUContainer, CraftingTileEntity> helper = new ContainerHelper<>(
CraftingCPUContainer::new, CraftingTileEntity.class, SecurityPermissions.CRAFT) CraftingCPUContainer::new, CraftingTileEntity.class, SecurityPermissions.CRAFT);
.withContainerTitle(craftingTileEntity -> {
// Use the cluster's custom name instead of the right-clicked block entities one
CraftingCPUCluster cluster = craftingTileEntity.getCluster();
if (cluster != null && cluster.getName() != null) {
return cluster.getName();
}
return StringTextComponent.EMPTY;
});
private final IItemList<IAEItemStack> list = Api.instance().storage().getStorageChannel(IItemStorageChannel.class) private final IItemList<IAEItemStack> list = Api.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList(); .createList();
private final IGrid network; private IGrid network;
private CraftingCPUCluster monitor = null; private CraftingCPUCluster monitor = null;
private ITextComponent cpuName = null;
@GuiSync(0) @GuiSync(0)
public long eta = -1; public long eta = -1;
@@ -81,16 +77,14 @@ public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorH
final IActionHost host = (IActionHost) (te instanceof IActionHost ? te : null); final IActionHost host = (IActionHost) (te instanceof IActionHost ? te : null);
if (host != null && host.getActionableNode() != null) { if (host != null && host.getActionableNode() != null) {
this.network = host.getActionableNode().getGrid(); this.setNetwork(host.getActionableNode().getGrid());
} else {
this.network = null;
} }
if (te instanceof CraftingTileEntity) { if (te instanceof CraftingTileEntity) {
this.setCPU(((CraftingTileEntity) te).getCluster()); this.setCPU(((CraftingTileEntity) te).getCluster());
} }
if (this.getNetwork() == null && isServer()) { if (this.getNetwork() == null && Platform.isServer()) {
this.setValidContainer(false); this.setValidContainer(false);
} }
} }
@@ -120,13 +114,15 @@ public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorH
} }
if (c instanceof CraftingCPUCluster) { if (c instanceof CraftingCPUCluster) {
this.monitor = (CraftingCPUCluster) c; this.cpuName = c.getName();
this.setMonitor((CraftingCPUCluster) c);
this.list.resetStatus(); this.list.resetStatus();
this.getMonitor().getListOfItem(this.list, CraftingItemList.ALL); this.getMonitor().getListOfItem(this.list, CraftingItemList.ALL);
this.getMonitor().addListener(this, null); this.getMonitor().addListener(this, null);
this.setEstimatedTime(0); this.setEstimatedTime(0);
} else { } else {
this.monitor = null; this.setMonitor(null);
this.cpuName = null;
this.setEstimatedTime(-1); this.setEstimatedTime(-1);
} }
} }
@@ -157,7 +153,7 @@ public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorH
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (isServer() && this.getMonitor() != null && !this.list.isEmpty()) { if (Platform.isServer() && this.getMonitor() != null && !this.list.isEmpty()) {
try { try {
if (this.getEstimatedTime() >= 0) { if (this.getEstimatedTime() >= 0) {
final long elapsedTime = this.getMonitor().getElapsedTime(); final long elapsedTime = this.getMonitor().getElapsedTime();
@@ -222,6 +218,16 @@ public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorH
} }
@Override
public ITextComponent getCustomInventoryName() {
return this.cpuName;
}
@Override
public boolean hasCustomInventoryName() {
return this.cpuName != null;
}
public long getEstimatedTime() { public long getEstimatedTime() {
return this.eta; return this.eta;
} }
@@ -234,8 +240,15 @@ public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorH
return this.monitor; return this.monitor;
} }
private void setMonitor(final CraftingCPUCluster monitor) {
this.monitor = monitor;
}
IGrid getNetwork() { IGrid getNetwork() {
return this.network; return this.network;
} }
private void setNetwork(final IGrid network) {
this.network = network;
}
} }
@@ -1,131 +0,0 @@
package appeng.container.implementations;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import com.google.common.collect.ImmutableSet;
import net.minecraft.util.text.StringTextComponent;
import appeng.api.networking.IGrid;
import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.networking.crafting.ICraftingGrid;
/**
* Utility class for dialogs that can cycle through crafting CPUs
*/
class CraftingCPUCycler {
@FunctionalInterface
public interface ChangeListener {
void onChange(CraftingCPURecord selectedCpu, boolean cpusAvailable);
}
private final Predicate<ICraftingCPU> cpuFilter;
private final ChangeListener changeListener;
private final List<CraftingCPURecord> cpus = new ArrayList<>();
private int selectedCpu = -1;
private boolean initialDataSent = false;
private boolean allowNoSelection;
public CraftingCPUCycler(Predicate<ICraftingCPU> cpuFilter, ChangeListener changeListener) {
this.cpuFilter = cpuFilter;
this.changeListener = changeListener;
}
public void detectAndSendChanges(IGrid network) {
final ICraftingGrid cc = network.getCache(ICraftingGrid.class);
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
int matches = 0;
boolean changed = !initialDataSent;
initialDataSent = true;
for (final ICraftingCPU c : cpuSet) {
boolean found = false;
for (final CraftingCPURecord ccr : this.cpus) {
if (ccr.getCpu() == c) {
found = true;
break;
}
}
final boolean matched = this.cpuFilter.test(c);
if (matched) {
matches++;
}
if (found == !matched) {
changed = true;
}
}
if (changed || this.cpus.size() != matches) {
this.cpus.clear();
for (final ICraftingCPU c : cpuSet) {
if (this.cpuFilter.test(c)) {
this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c));
}
}
// Sort and assign numeric IDs in case they have no names
Collections.sort(this.cpus);
for (int i = 0; i < this.cpus.size(); i++) {
CraftingCPURecord cpu = cpus.get(i);
if (cpu.getName() == null) {
cpu.setName(new StringTextComponent("#" + (i + 1)));
}
}
this.notifyListener();
}
}
public void cycleCpu(final boolean next) {
if (next) {
this.selectedCpu++;
} else {
this.selectedCpu--;
}
// If "no CPU" is a valid selection, then -1 is the first potential item
int lowerLimit = this.allowNoSelection ? -1 : 0;
if (this.selectedCpu < lowerLimit) {
this.selectedCpu = this.cpus.size() - 1;
} else if (this.selectedCpu >= this.cpus.size()) {
this.selectedCpu = lowerLimit;
}
this.notifyListener();
}
public boolean isAllowNoSelection() {
return allowNoSelection;
}
public void setAllowNoSelection(boolean allowNoSelection) {
this.allowNoSelection = allowNoSelection;
}
private void notifyListener() {
if (this.selectedCpu >= this.cpus.size()) {
this.selectedCpu = -1;
}
// Force the selected CPU to the first available CPU unless no-selection is
// explicitly allowed
if (!this.allowNoSelection && this.selectedCpu == -1 && !this.cpus.isEmpty()) {
this.selectedCpu = 0;
}
if (this.selectedCpu != -1) {
this.changeListener.onChange(this.cpus.get(this.selectedCpu), true);
} else {
this.changeListener.onChange(null, !this.cpus.isEmpty());
}
}
}
@@ -1,12 +0,0 @@
package appeng.container.implementations;
/**
* Implemented on screens that show information about a crafting CPU and allow
* the CPU to be cycled. Is triggered by receiving a config value packet with
* name <code>Terminal.Cpu</code>.
*/
public interface CraftingCPUCyclingContainer {
void cycleSelectedCPU(boolean forward);
}
@@ -25,16 +25,16 @@ import net.minecraft.util.text.ITextComponent;
import appeng.api.networking.crafting.ICraftingCPU; import appeng.api.networking.crafting.ICraftingCPU;
public class CraftingCPURecord implements Comparable<CraftingCPURecord> { public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
private final ITextComponent myName;
private final ICraftingCPU cpu; private final ICraftingCPU cpu;
private final long size; private final long size;
private final int processors; private final int processors;
private ITextComponent name;
public CraftingCPURecord(final long size, final int coProcessors, final ICraftingCPU server) { public CraftingCPURecord(final long size, final int coProcessors, final ICraftingCPU server) {
this.size = size; this.size = size;
this.processors = coProcessors; this.processors = coProcessors;
this.cpu = server; this.cpu = server;
this.name = server.getName(); this.myName = server.getName();
} }
@Override @Override
@@ -50,6 +50,10 @@ public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
return this.cpu; return this.cpu;
} }
ITextComponent getName() {
return this.myName;
}
int getProcessors() { int getProcessors() {
return this.processors; return this.processors;
} }
@@ -57,13 +61,4 @@ public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
long getSize() { long getSize() {
return this.size; return this.size;
} }
public ITextComponent getName() {
return name;
}
public void setName(ITextComponent name) {
this.name = name;
}
} }
@@ -18,6 +18,12 @@
package appeng.container.implementations; package appeng.container.implementations;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.google.common.collect.ImmutableSet;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
@@ -25,13 +31,14 @@ import net.minecraft.network.PacketBuffer;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import appeng.api.config.SecurityPermissions; import appeng.api.config.SecurityPermissions;
import appeng.api.networking.IGrid;
import appeng.api.networking.crafting.ICraftingCPU; import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.storage.ITerminalHost; import appeng.api.storage.ITerminalHost;
import appeng.container.ContainerLocator; import appeng.container.ContainerLocator;
import appeng.container.guisync.GuiSync; import appeng.container.guisync.GuiSync;
import appeng.util.Platform;
public class CraftingStatusContainer extends CraftingCPUContainer implements CraftingCPUCyclingContainer { public class CraftingStatusContainer extends CraftingCPUContainer {
public static ContainerType<CraftingStatusContainer> TYPE; public static ContainerType<CraftingStatusContainer> TYPE;
@@ -46,13 +53,13 @@ public class CraftingStatusContainer extends CraftingCPUContainer implements Cra
return helper.open(player, locator); return helper.open(player, locator);
} }
private final CraftingCPUCycler cpuCycler = new CraftingCPUCycler(this::cpuMatches, this::onCPUSelectionChanged); private final List<CraftingCPURecord> cpus = new ArrayList<>();
@GuiSync(5)
public int selectedCpu = -1;
@GuiSync(6) @GuiSync(6)
public boolean noCPU = true; public boolean noCPU = true;
@GuiSync(7) @GuiSync(7)
public ITextComponent cpuName; public ITextComponent myName;
public CraftingStatusContainer(int id, final PlayerInventory ip, final ITerminalHost te) { public CraftingStatusContainer(int id, final PlayerInventory ip, final ITerminalHost te) {
super(TYPE, id, ip, te); super(TYPE, id, ip, te);
@@ -60,9 +67,43 @@ public class CraftingStatusContainer extends CraftingCPUContainer implements Cra
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
IGrid network = this.getNetwork(); if (Platform.isServer() && this.getNetwork() != null) {
if (isServer() && network != null) { final ICraftingGrid cc = this.getNetwork().getCache(ICraftingGrid.class);
cpuCycler.detectAndSendChanges(network); final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
int matches = 0;
boolean changed = false;
for (final ICraftingCPU c : cpuSet) {
boolean found = false;
for (final CraftingCPURecord ccr : this.cpus) {
if (ccr.getCpu() == c) {
found = true;
}
}
final boolean matched = this.cpuMatches(c);
if (matched) {
matches++;
}
if (found == !matched) {
changed = true;
}
}
if (changed || this.cpus.size() != matches) {
this.cpus.clear();
for (final ICraftingCPU c : cpuSet) {
if (this.cpuMatches(c)) {
this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c));
}
}
this.sendCPUs();
}
this.noCPU = this.cpus.isEmpty();
} }
super.detectAndSendChanges(); super.detectAndSendChanges();
@@ -72,20 +113,52 @@ public class CraftingStatusContainer extends CraftingCPUContainer implements Cra
return c.isBusy(); return c.isBusy();
} }
private void onCPUSelectionChanged(CraftingCPURecord cpuRecord, boolean cpusAvailable) { private void sendCPUs() {
noCPU = !cpusAvailable; Collections.sort(this.cpus);
if (cpuRecord == null) {
cpuName = null; if (this.selectedCpu >= this.cpus.size()) {
setCPU(null); this.selectedCpu = -1;
this.myName = null;
} else if (this.selectedCpu != -1) {
this.myName = this.cpus.get(this.selectedCpu).getName();
}
if (this.selectedCpu == -1 && this.cpus.size() > 0) {
this.selectedCpu = 0;
}
if (this.selectedCpu != -1) {
if (this.cpus.get(this.selectedCpu).getCpu() != this.getMonitor()) {
this.setCPU(this.cpus.get(this.selectedCpu).getCpu());
}
} else { } else {
cpuName = cpuRecord.getName(); this.setCPU(null);
setCPU(cpuRecord.getCpu());
} }
} }
@Override public void cycleCpu(final boolean next) {
public void cycleSelectedCPU(boolean forward) { if (next) {
this.cpuCycler.cycleCpu(forward); this.selectedCpu++;
} } else {
this.selectedCpu--;
}
if (this.selectedCpu < -1) {
this.selectedCpu = this.cpus.size() - 1;
} else if (this.selectedCpu >= this.cpus.size()) {
this.selectedCpu = -1;
}
if (this.selectedCpu == -1 && this.cpus.size() > 0) {
this.selectedCpu = 0;
}
if (this.selectedCpu == -1) {
this.myName = null;
this.setCPU(null);
} else {
this.myName = this.cpus.get(this.selectedCpu).getName();
this.setCPU(this.cpus.get(this.selectedCpu).getCpu());
}
}
} }
@@ -35,6 +35,7 @@ import appeng.container.slot.FakeTypeOnlySlot;
import appeng.container.slot.OptionalTypeOnlyFakeSlot; import appeng.container.slot.OptionalTypeOnlyFakeSlot;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.parts.automation.FormationPlanePart; import appeng.parts.automation.FormationPlanePart;
import appeng.util.Platform;
public class FormationPlaneContainer extends UpgradeableContainer { public class FormationPlaneContainer extends UpgradeableContainer {
@@ -106,7 +107,7 @@ public class FormationPlaneContainer extends UpgradeableContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (isServer()) { if (Platform.isServer()) {
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE)); this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
this.setPlaceMode((YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.PLACE_BLOCK)); this.setPlaceMode((YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.PLACE_BLOCK));
} }
@@ -34,6 +34,7 @@ import appeng.container.guisync.GuiSync;
import appeng.container.slot.OutputSlot; import appeng.container.slot.OutputSlot;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.tile.storage.IOPortTileEntity; import appeng.tile.storage.IOPortTileEntity;
import appeng.util.Platform;
public class IOPortContainer extends UpgradeableContainer { public class IOPortContainer extends UpgradeableContainer {
@@ -110,7 +111,7 @@ public class IOPortContainer extends UpgradeableContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (isServer()) { if (Platform.isServer()) {
this.setOperationMode( this.setOperationMode(
(OperationMode) this.getUpgradeable().getConfigManager().getSetting(Settings.OPERATION_MODE)); (OperationMode) this.getUpgradeable().getConfigManager().getSetting(Settings.OPERATION_MODE));
this.setFullMode( this.setFullMode(
@@ -35,6 +35,7 @@ import appeng.container.slot.RestrictedInputSlot;
import appeng.core.Api; import appeng.core.Api;
import appeng.tile.misc.InscriberRecipes; import appeng.tile.misc.InscriberRecipes;
import appeng.tile.misc.InscriberTileEntity; import appeng.tile.misc.InscriberTileEntity;
import appeng.util.Platform;
/** /**
* @author AlgorithmX2 * @author AlgorithmX2
@@ -118,7 +119,7 @@ public class InscriberContainer extends UpgradeableContainer implements IProgres
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.standardDetectAndSendChanges(); this.standardDetectAndSendChanges();
if (isServer()) { if (Platform.isServer()) {
this.maxProcessingTime = this.ti.getMaxProcessingTime(); this.maxProcessingTime = this.ti.getMaxProcessingTime();
this.processingTime = this.ti.getProcessingTime(); this.processingTime = this.ti.getProcessingTime();
} }
@@ -52,6 +52,7 @@ import appeng.parts.reporting.InterfaceTerminalPart;
import appeng.tile.inventory.AppEngInternalInventory; import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.misc.InterfaceTileEntity; import appeng.tile.misc.InterfaceTileEntity;
import appeng.util.InventoryAdaptor; import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.helpers.ItemHandlerUtil; import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.inv.AdaptorItemHandler; import appeng.util.inv.AdaptorItemHandler;
import appeng.util.inv.WrapperCursorItemHandler; import appeng.util.inv.WrapperCursorItemHandler;
@@ -87,7 +88,7 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
public InterfaceTerminalContainer(int id, final PlayerInventory ip, final InterfaceTerminalPart anchor) { public InterfaceTerminalContainer(int id, final PlayerInventory ip, final InterfaceTerminalPart anchor) {
super(TYPE, id, ip, anchor); super(TYPE, id, ip, anchor);
if (isServer()) { if (Platform.isServer()) {
this.grid = anchor.getActionableNode().getGrid(); this.grid = anchor.getActionableNode().getGrid();
} }
@@ -96,7 +97,7 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (isClient()) { if (Platform.isClient()) {
return; return;
} }
@@ -22,6 +22,8 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import appeng.api.config.FuzzyMode; import appeng.api.config.FuzzyMode;
@@ -30,13 +32,13 @@ import appeng.api.config.RedstoneMode;
import appeng.api.config.SecurityPermissions; import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings; import appeng.api.config.Settings;
import appeng.api.config.YesNo; import appeng.api.config.YesNo;
import appeng.client.gui.implementations.NumberEntryWidget;
import appeng.container.ContainerLocator; import appeng.container.ContainerLocator;
import appeng.container.guisync.GuiSync; import appeng.container.guisync.GuiSync;
import appeng.container.slot.FakeTypeOnlySlot; import appeng.container.slot.FakeTypeOnlySlot;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.parts.automation.LevelEmitterPart; import appeng.parts.automation.LevelEmitterPart;
import appeng.util.Platform;
public class LevelEmitterContainer extends UpgradeableContainer { public class LevelEmitterContainer extends UpgradeableContainer {
@@ -46,46 +48,38 @@ public class LevelEmitterContainer extends UpgradeableContainer {
LevelEmitterContainer::new, LevelEmitterPart.class, SecurityPermissions.BUILD); LevelEmitterContainer::new, LevelEmitterPart.class, SecurityPermissions.BUILD);
public static LevelEmitterContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer buf) { public static LevelEmitterContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer buf) {
return helper.fromNetwork(windowId, inv, buf, (host, container, buffer) -> { return helper.fromNetwork(windowId, inv, buf);
container.reportingValue = buffer.readVarLong();
});
} }
public static boolean open(PlayerEntity player, ContainerLocator locator) { public static boolean open(PlayerEntity player, ContainerLocator locator) {
return helper.open(player, locator, (host, buffer) -> { return helper.open(player, locator);
buffer.writeVarLong(host.getReportingValue());
});
} }
private final LevelEmitterPart lvlEmitter; private final LevelEmitterPart lvlEmitter;
@OnlyIn(Dist.CLIENT)
private NumberEntryWidget textField;
@GuiSync(2) @GuiSync(2)
public LevelType lvType; public LevelType lvType;
@GuiSync(3) @GuiSync(3)
public long EmitterValue = -1;
@GuiSync(4)
public YesNo cmType; public YesNo cmType;
// Only synced once on container-open, and only used on client
private long reportingValue;
public LevelEmitterContainer(int id, final PlayerInventory ip, final LevelEmitterPart te) { public LevelEmitterContainer(int id, final PlayerInventory ip, final LevelEmitterPart te) {
super(TYPE, id, ip, te); super(TYPE, id, ip, te);
this.lvlEmitter = te; this.lvlEmitter = te;
} }
public long getReportingValue() { @OnlyIn(Dist.CLIENT)
return reportingValue; public void setTextField(final NumberEntryWidget level) {
this.textField = level;
this.textField.setValue(this.EmitterValue);
} }
public void setReportingValue(long reportingValue) { public void setLevel(final long l, final PlayerEntity player) {
if (isClient()) { this.lvlEmitter.setReportingValue(l);
if (reportingValue != this.reportingValue) { this.EmitterValue = l;
this.reportingValue = reportingValue;
NetworkHandler.instance()
.sendToServer(new ConfigValuePacket("LevelEmitter.Value", String.valueOf(reportingValue)));
}
} else {
this.lvlEmitter.setReportingValue(reportingValue);
}
} }
@Override @Override
@@ -121,6 +115,7 @@ public class LevelEmitterContainer extends UpgradeableContainer {
@Override @Override
public int availableUpgrades() { public int availableUpgrades() {
return 1; return 1;
} }
@@ -128,7 +123,8 @@ public class LevelEmitterContainer extends UpgradeableContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (isServer()) { if (Platform.isServer()) {
this.EmitterValue = this.lvlEmitter.getReportingValue();
this.setCraftingMode( this.setCraftingMode(
(YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.CRAFT_VIA_REDSTONE)); (YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.CRAFT_VIA_REDSTONE));
this.setLevelMode((LevelType) this.getUpgradeable().getConfigManager().getSetting(Settings.LEVEL_TYPE)); this.setLevelMode((LevelType) this.getUpgradeable().getConfigManager().getSetting(Settings.LEVEL_TYPE));
@@ -140,6 +136,15 @@ public class LevelEmitterContainer extends UpgradeableContainer {
this.standardDetectAndSendChanges(); this.standardDetectAndSendChanges();
} }
@Override
public void onUpdate(final String field, final Object oldValue, final Object newValue) {
if (field.equals("EmitterValue")) {
if (this.textField != null) {
this.textField.setValue(this.EmitterValue);
}
}
}
@Override @Override
public YesNo getCraftingMode() { public YesNo getCraftingMode() {
return this.cmType; return this.cmType;
@@ -157,5 +162,4 @@ public class LevelEmitterContainer extends UpgradeableContainer {
private void setLevelMode(final LevelType lvType) { private void setLevelMode(final LevelType lvType) {
this.lvType = lvType; this.lvType = lvType;
} }
} }
@@ -46,8 +46,6 @@ import appeng.api.implementations.tiles.IViewCellStorage;
import appeng.api.networking.IGrid; import appeng.api.networking.IGrid;
import appeng.api.networking.IGridHost; import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode; import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.energy.IEnergyGrid; import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergySource; import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.security.IActionHost; import appeng.api.networking.security.IActionHost;
@@ -75,6 +73,7 @@ import appeng.core.sync.packets.MEInventoryUpdatePacket;
import appeng.me.helpers.ChannelPowerSrc; import appeng.me.helpers.ChannelPowerSrc;
import appeng.util.ConfigManager; import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost; import appeng.util.IConfigManagerHost;
import appeng.util.Platform;
public class MEMonitorableContainer extends AEBaseContainer public class MEMonitorableContainer extends AEBaseContainer
implements IConfigManagerHost, IConfigurableObject, IMEMonitorHandlerReceiver<IAEItemStack> { implements IConfigManagerHost, IConfigurableObject, IMEMonitorHandlerReceiver<IAEItemStack> {
@@ -102,13 +101,6 @@ public class MEMonitorableContainer extends AEBaseContainer
public boolean canAccessViewCells = false; public boolean canAccessViewCells = false;
@GuiSync(98) @GuiSync(98)
public boolean hasPower = false; public boolean hasPower = false;
/**
* The number of active crafting jobs in the network. -1 means unknown and will
* hide the label on the screen.
*/
@GuiSync(100)
public int activeCraftingJobs = -1;
private IConfigManagerHost gui; private IConfigManagerHost gui;
private IConfigManager serverCM; private IConfigManager serverCM;
private IGridNode networkNode; private IGridNode networkNode;
@@ -130,7 +122,7 @@ public class MEMonitorableContainer extends AEBaseContainer
this.clientCM.registerSetting(Settings.VIEW_MODE, ViewItems.ALL); this.clientCM.registerSetting(Settings.VIEW_MODE, ViewItems.ALL);
this.clientCM.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING); this.clientCM.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING);
if (isServer()) { if (Platform.isServer()) {
this.serverCM = monitorable.getConfigManager(); this.serverCM = monitorable.getConfigManager();
this.monitor = monitorable this.monitor = monitorable
@@ -191,14 +183,12 @@ public class MEMonitorableContainer extends AEBaseContainer
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (isServer()) { if (Platform.isServer()) {
if (this.monitor != this.host if (this.monitor != this.host
.getInventory(Api.instance().storage().getStorageChannel(IItemStorageChannel.class))) { .getInventory(Api.instance().storage().getStorageChannel(IItemStorageChannel.class))) {
this.setValidContainer(false); this.setValidContainer(false);
} }
this.updateActiveCraftingJobs();
for (final Settings set : this.serverCM.getSettings()) { for (final Settings set : this.serverCM.getSettings()) {
final Enum<?> sideLocal = this.serverCM.getSetting(set); final Enum<?> sideLocal = this.serverCM.getSetting(set);
final Enum<?> sideRemote = this.clientCM.getSetting(set); final Enum<?> sideRemote = this.clientCM.getSetting(set);
@@ -296,38 +286,8 @@ public class MEMonitorableContainer extends AEBaseContainer
this.queueInventory(c); this.queueInventory(c);
} }
private void updateActiveCraftingJobs() {
IGridNode hostNode = networkNode;
if (hostNode == null) {
// Wireless terminals do not directly expose the target grid (even though they
// have one)
if (host instanceof IActionHost) {
hostNode = ((IActionHost) host).getActionableNode();
}
}
IGrid grid = null;
if (hostNode != null) {
grid = hostNode.getGrid();
}
if (grid == null) {
// No grid to query crafting jobs from
this.activeCraftingJobs = -1;
return;
}
int activeJobs = 0;
ICraftingGrid craftingGrid = grid.getCache(ICraftingGrid.class);
for (ICraftingCPU cpus : craftingGrid.getCpus()) {
if (cpus.isBusy()) {
activeJobs++;
}
}
this.activeCraftingJobs = activeJobs;
}
private void queueInventory(final IContainerListener c) { private void queueInventory(final IContainerListener c) {
if (isServer() && c instanceof PlayerEntity && this.monitor != null) { if (Platform.isServer() && c instanceof PlayerEntity && this.monitor != null) {
try { try {
MEInventoryUpdatePacket piu = new MEInventoryUpdatePacket(); MEInventoryUpdatePacket piu = new MEInventoryUpdatePacket();
final IItemList<IAEItemStack> monitorCache = this.monitor.getStorageList(); final IItemList<IAEItemStack> monitorCache = this.monitor.getStorageList();
@@ -396,7 +356,7 @@ public class MEMonitorableContainer extends AEBaseContainer
@Override @Override
public IConfigManager getConfigManager() { public IConfigManager getConfigManager() {
if (isServer()) { if (Platform.isServer()) {
return this.serverCM; return this.serverCM;
} }
return this.clientCM; return this.clientCM;
@@ -41,6 +41,7 @@ import appeng.container.slot.RestrictedInputSlot;
import appeng.core.Api; import appeng.core.Api;
import appeng.items.misc.EncodedPatternItem; import appeng.items.misc.EncodedPatternItem;
import appeng.tile.crafting.MolecularAssemblerTileEntity; import appeng.tile.crafting.MolecularAssemblerTileEntity;
import appeng.util.Platform;
public class MolecularAssemblerContainer extends UpgradeableContainer implements IProgressProvider { public class MolecularAssemblerContainer extends UpgradeableContainer implements IProgressProvider {
@@ -146,7 +147,7 @@ public class MolecularAssemblerContainer extends UpgradeableContainer implements
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (isServer()) { if (Platform.isServer()) {
this.setRedStoneMode( this.setRedStoneMode(
(RedstoneMode) this.getUpgradeable().getConfigManager().getSetting(Settings.REDSTONE_CONTROLLED)); (RedstoneMode) this.getUpgradeable().getConfigManager().getSetting(Settings.REDSTONE_CONTROLLED));
} }
@@ -43,6 +43,7 @@ import appeng.container.guisync.GuiSync;
import appeng.core.Api; import appeng.core.Api;
import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.MEInventoryUpdatePacket; import appeng.core.sync.packets.MEInventoryUpdatePacket;
import appeng.util.Platform;
import appeng.util.item.AEItemStack; import appeng.util.item.AEItemStack;
public class NetworkStatusContainer extends AEBaseContainer { public class NetworkStatusContainer extends AEBaseContainer {
@@ -82,7 +83,7 @@ public class NetworkStatusContainer extends AEBaseContainer {
} }
} }
if (this.network == null && isServer()) { if (this.network == null && Platform.isServer()) {
this.setValidContainer(false); this.setValidContainer(false);
} }
} }
@@ -99,7 +100,7 @@ public class NetworkStatusContainer extends AEBaseContainer {
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.delay++; this.delay++;
if (isServer() && this.delay > 15 && this.network != null) { if (Platform.isServer() && this.delay > 15 && this.network != null) {
this.delay = 0; this.delay = 0;
final IEnergyGrid eg = this.network.getCache(IEnergyGrid.class); final IEnergyGrid eg = this.network.getCache(IEnergyGrid.class);
@@ -291,9 +291,9 @@ public class PatternTermContainer extends MEMonitorableContainer
@Override @Override
public boolean isSlotEnabled(final int idx) { public boolean isSlotEnabled(final int idx) {
if (idx == 1) { if (idx == 1) {
return isServer() ? !this.getPatternTerminal().isCraftingRecipe() : !this.isCraftingMode(); return Platform.isServer() ? !this.getPatternTerminal().isCraftingRecipe() : !this.isCraftingMode();
} else if (idx == 2) { } else if (idx == 2) {
return isServer() ? this.getPatternTerminal().isCraftingRecipe() : this.isCraftingMode(); return Platform.isServer() ? this.getPatternTerminal().isCraftingRecipe() : this.isCraftingMode();
} else { } else {
return false; return false;
} }
@@ -395,7 +395,7 @@ public class PatternTermContainer extends MEMonitorableContainer
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
super.detectAndSendChanges(); super.detectAndSendChanges();
if (isServer()) { if (Platform.isServer()) {
if (this.isCraftingMode() != this.getPatternTerminal().isCraftingRecipe()) { if (this.isCraftingMode() != this.getPatternTerminal().isCraftingRecipe()) {
this.setCraftingMode(this.getPatternTerminal().isCraftingRecipe()); this.setCraftingMode(this.getPatternTerminal().isCraftingRecipe());
this.updateOrderOfOutputSlots(); this.updateOrderOfOutputSlots();
@@ -417,7 +417,7 @@ public class PatternTermContainer extends MEMonitorableContainer
@Override @Override
public void onSlotChange(final Slot s) { public void onSlotChange(final Slot s) {
if (s == this.patternSlotOUT && isServer()) { if (s == this.patternSlotOUT && Platform.isServer()) {
for (final IContainerListener listener : this.listeners) { for (final IContainerListener listener : this.listeners) {
for (final Slot slot : this.inventorySlots) { for (final Slot slot : this.inventorySlots) {
if (slot instanceof OptionalFakeSlot || slot instanceof FakeCraftingMatrixSlot) { if (slot instanceof OptionalFakeSlot || slot instanceof FakeCraftingMatrixSlot) {
@@ -431,7 +431,7 @@ public class PatternTermContainer extends MEMonitorableContainer
this.detectAndSendChanges(); this.detectAndSendChanges();
} }
if (s == this.craftSlot && isClient()) { if (s == this.craftSlot && Platform.isClient()) {
this.getAndUpdateOutput(); this.getAndUpdateOutput();
} }
} }
@@ -23,14 +23,17 @@ import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.config.SecurityPermissions; import appeng.api.config.SecurityPermissions;
import appeng.api.parts.IPart; import appeng.api.parts.IPart;
import appeng.client.gui.implementations.NumberEntryWidget;
import appeng.container.AEBaseContainer; import appeng.container.AEBaseContainer;
import appeng.container.ContainerLocator; import appeng.container.ContainerLocator;
import appeng.core.sync.network.NetworkHandler; import appeng.container.guisync.GuiSync;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.helpers.IPriorityHost; import appeng.helpers.IPriorityHost;
import appeng.util.Platform;
public class PriorityContainer extends AEBaseContainer { public class PriorityContainer extends AEBaseContainer {
@@ -40,53 +43,60 @@ public class PriorityContainer extends AEBaseContainer {
PriorityContainer::new, IPriorityHost.class, SecurityPermissions.BUILD); PriorityContainer::new, IPriorityHost.class, SecurityPermissions.BUILD);
public static PriorityContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer buf) { public static PriorityContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer buf) {
return helper.fromNetwork(windowId, inv, buf, (host, container, buffer) -> { return helper.fromNetwork(windowId, inv, buf);
container.priorityValue = buffer.readVarInt();
});
} }
public static boolean open(PlayerEntity player, ContainerLocator locator) { public static boolean open(PlayerEntity player, ContainerLocator locator) {
return helper.open(player, locator, (host, buffer) -> buffer.writeVarInt(host.getPriority())); return helper.open(player, locator);
} }
private final IPriorityHost priHost; private final IPriorityHost priHost;
private int priorityValue; @OnlyIn(Dist.CLIENT)
private NumberEntryWidget textField;
@GuiSync(2)
public long PriorityValue = -1;
public PriorityContainer(int id, final PlayerInventory ip, final IPriorityHost te) { public PriorityContainer(int id, final PlayerInventory ip, final IPriorityHost te) {
super(TYPE, id, ip, (TileEntity) (te instanceof TileEntity ? te : null), super(TYPE, id, ip, (TileEntity) (te instanceof TileEntity ? te : null),
(IPart) (te instanceof IPart ? te : null)); (IPart) (te instanceof IPart ? te : null));
this.priHost = te; this.priHost = te;
this.priorityValue = te.getPriority();
} }
public void setPriority(final int newValue) { @OnlyIn(Dist.CLIENT)
if (newValue != priorityValue) { public void setTextField(final NumberEntryWidget level) {
if (isClient()) { this.textField = level;
// If for whatever reason the client enters the value first, do not update based this.textField.setValue(this.PriorityValue, true);
// on incoming server data }
this.priorityValue = newValue;
NetworkHandler.instance() public void setPriority(final int newValue, final PlayerEntity player) {
.sendToServer(new ConfigValuePacket("PriorityHost.Priority", String.valueOf(newValue))); this.priHost.setPriority(newValue);
} else { this.PriorityValue = newValue;
this.priHost.setPriority(newValue);
this.priorityValue = newValue;
}
}
} }
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
super.detectAndSendChanges(); super.detectAndSendChanges();
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (Platform.isServer()) {
this.PriorityValue = this.priHost.getPriority();
}
} }
public int getPriorityValue() { @Override
return priorityValue; public void onUpdate(final String field, final Object oldValue, final Object newValue) {
if (field.equals("PriorityValue")) {
if (this.textField != null) {
this.textField.setValue(this.PriorityValue, true);
}
}
super.onUpdate(field, oldValue, newValue);
} }
public IPriorityHost getPriorityHost() { public IPriorityHost getPriorityHost() {
return this.priHost; return this.priHost;
} }
} }
@@ -38,6 +38,7 @@ import appeng.core.Api;
import appeng.items.contents.QuartzKnifeObj; import appeng.items.contents.QuartzKnifeObj;
import appeng.items.materials.MaterialItem; import appeng.items.materials.MaterialItem;
import appeng.tile.inventory.AppEngInternalInventory; import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.Platform;
public class QuartzKnifeContainer extends AEBaseContainer { public class QuartzKnifeContainer extends AEBaseContainer {
@@ -147,7 +148,7 @@ public class QuartzKnifeContainer extends AEBaseContainer {
} }
private void makePlate() { private void makePlate() {
if (isServer()) { if (Platform.isServer()) {
if (!this.getItemHandler().extractItem(0, 1, false).isEmpty()) { if (!this.getItemHandler().extractItem(0, 1, false).isEmpty()) {
final ItemStack item = QuartzKnifeContainer.this.toolInv.getItemStack(); final ItemStack item = QuartzKnifeContainer.this.toolInv.getItemStack();
final ItemStack before = item.copy(); final ItemStack before = item.copy();
@@ -35,6 +35,7 @@ import appeng.container.guisync.GuiSync;
import appeng.container.slot.OutputSlot; import appeng.container.slot.OutputSlot;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.tile.spatial.SpatialIOPortTileEntity; import appeng.tile.spatial.SpatialIOPortTileEntity;
import appeng.util.Platform;
public class SpatialIOPortContainer extends AEBaseContainer { public class SpatialIOPortContainer extends AEBaseContainer {
@@ -64,7 +65,7 @@ public class SpatialIOPortContainer extends AEBaseContainer {
public SpatialIOPortContainer(int id, final PlayerInventory ip, final SpatialIOPortTileEntity spatialIOPort) { public SpatialIOPortContainer(int id, final PlayerInventory ip, final SpatialIOPortTileEntity spatialIOPort) {
super(TYPE, id, ip, spatialIOPort, null); super(TYPE, id, ip, spatialIOPort, null);
if (isServer()) { if (Platform.isServer()) {
this.network = spatialIOPort.getGridNode(AEPartLocation.INTERNAL).getGrid(); this.network = spatialIOPort.getGridNode(AEPartLocation.INTERNAL).getGrid();
} }
@@ -88,7 +89,7 @@ public class SpatialIOPortContainer extends AEBaseContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (isServer()) { if (Platform.isServer()) {
this.delay++; this.delay++;
if (this.delay > 15 && this.network != null) { if (this.delay > 15 && this.network != null) {
this.delay = 0; this.delay = 0;
@@ -44,6 +44,7 @@ import appeng.container.slot.OptionalTypeOnlyFakeSlot;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.core.Api; import appeng.core.Api;
import appeng.parts.misc.StorageBusPart; import appeng.parts.misc.StorageBusPart;
import appeng.util.Platform;
import appeng.util.helpers.ItemHandlerUtil; import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.iterators.NullIterator; import appeng.util.iterators.NullIterator;
@@ -123,7 +124,7 @@ public class StorageBusContainer extends UpgradeableContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (isServer()) { if (Platform.isServer()) {
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE)); this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
this.setReadWriteMode( this.setReadWriteMode(
(AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS)); (AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS));
@@ -51,6 +51,7 @@ import appeng.container.slot.RestrictedInputSlot;
import appeng.items.contents.NetworkToolViewer; import appeng.items.contents.NetworkToolViewer;
import appeng.items.tools.NetworkToolItem; import appeng.items.tools.NetworkToolItem;
import appeng.parts.automation.ExportBusPart; import appeng.parts.automation.ExportBusPart;
import appeng.util.Platform;
public class UpgradeableContainer extends AEBaseContainer implements IOptionalSlotHost { public class UpgradeableContainer extends AEBaseContainer implements IOptionalSlotHost {
@@ -198,7 +199,7 @@ public class UpgradeableContainer extends AEBaseContainer implements IOptionalSl
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (isServer()) { if (Platform.isServer()) {
final IConfigManager cm = this.getUpgradeable().getConfigManager(); final IConfigManager cm = this.getUpgradeable().getConfigManager();
this.loadSettingsFromHost(cm); this.loadSettingsFromHost(cm);
} }
@@ -29,6 +29,7 @@ import appeng.container.guisync.GuiSync;
import appeng.container.interfaces.IProgressProvider; import appeng.container.interfaces.IProgressProvider;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.tile.misc.VibrationChamberTileEntity; import appeng.tile.misc.VibrationChamberTileEntity;
import appeng.util.Platform;
public class VibrationChamberContainer extends AEBaseContainer implements IProgressProvider { public class VibrationChamberContainer extends AEBaseContainer implements IProgressProvider {
@@ -64,7 +65,7 @@ public class VibrationChamberContainer extends AEBaseContainer implements IProgr
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (isServer()) { if (Platform.isServer()) {
this.remainingBurnTime = this.vibrationChamber.getMaxBurnTime() <= 0 ? 0 this.remainingBurnTime = this.vibrationChamber.getMaxBurnTime() <= 0 ? 0
: (int) (100.0 * this.vibrationChamber.getBurnTime() / this.vibrationChamber.getMaxBurnTime()); : (int) (100.0 * this.vibrationChamber.getBurnTime() / this.vibrationChamber.getMaxBurnTime());
this.burnSpeed = this.remainingBurnTime <= 0 ? 0 : this.vibrationChamber.getBurnSpeed(); this.burnSpeed = this.remainingBurnTime <= 0 ? 0 : this.vibrationChamber.getBurnSpeed();
@@ -28,6 +28,7 @@ import appeng.container.ContainerLocator;
import appeng.core.AEConfig; import appeng.core.AEConfig;
import appeng.core.localization.PlayerMessages; import appeng.core.localization.PlayerMessages;
import appeng.helpers.WirelessTerminalGuiObject; import appeng.helpers.WirelessTerminalGuiObject;
import appeng.util.Platform;
public class WirelessTermContainer extends MEPortableCellContainer { public class WirelessTermContainer extends MEPortableCellContainer {
@@ -56,7 +57,7 @@ public class WirelessTermContainer extends MEPortableCellContainer {
super.detectAndSendChanges(); super.detectAndSendChanges();
if (!this.wirelessTerminalGUIObject.rangeCheck()) { if (!this.wirelessTerminalGUIObject.rangeCheck()) {
if (isServer() && this.isValidContainer()) { if (Platform.isServer() && this.isValidContainer()) {
this.getPlayerInv().player.sendMessage(PlayerMessages.OutOfRange.get(), Util.DUMMY_UUID); this.getPlayerInv().player.sendMessage(PlayerMessages.OutOfRange.get(), Util.DUMMY_UUID);
} }
+12 -1
View File
@@ -404,6 +404,10 @@ public final class AEConfig {
return COMMON.improvedFluidMultiplier.get().floatValue(); return COMMON.improvedFluidMultiplier.get().floatValue();
} }
public int getPrometheusMetricsServerPort() {
return COMMON.prometheusMetricsServer.get();
}
// Setters keep visibility as low as possible. // Setters keep visibility as low as possible.
private static class ClientConfig { private static class ClientConfig {
@@ -474,6 +478,7 @@ public final class AEConfig {
public final BooleanValue removeCrashingItemsOnLoad; public final BooleanValue removeCrashingItemsOnLoad;
public final ConfigValue<Integer> formationPlaneEntityLimit; public final ConfigValue<Integer> formationPlaneEntityLimit;
public final ConfigValue<Integer> craftingCalculationTimePerTick; public final ConfigValue<Integer> craftingCalculationTimePerTick;
public final ConfigValue<Integer> prometheusMetricsServer;
// Spatial IO/Dimension // Spatial IO/Dimension
public final ConfigValue<Double> spatialPowerExponent; public final ConfigValue<Double> spatialPowerExponent;
@@ -558,6 +563,12 @@ public final class AEConfig {
.define("removeCrashingItemsOnLoad", false); .define("removeCrashingItemsOnLoad", false);
builder.pop(); builder.pop();
builder.push("metrics");
prometheusMetricsServer = builder.comment(
"Enables the Prometheus Metrics exporting endpoint on 127.0.0.1 on this port number. 0 to disable.")
.define("prometheusMetricsServer", 0);
builder.pop();
builder.push("automation"); builder.push("automation");
formationPlaneEntityLimit = builder.comment("TODO").define("formationPlaneEntityLimit", 128); formationPlaneEntityLimit = builder.comment("TODO").define("formationPlaneEntityLimit", 128);
builder.pop(); builder.pop();
@@ -595,7 +606,7 @@ public final class AEConfig {
this.spawnChargedChance = builder.defineInRange("spawnChargedChance", 0.08, 0.0, 1.0); this.spawnChargedChance = builder.defineInRange("spawnChargedChance", 0.08, 0.0, 1.0);
this.meteoriteMaximumSpawnHeight = builder.define("meteoriteMaximumSpawnHeight", 180); this.meteoriteMaximumSpawnHeight = builder.define("meteoriteMaximumSpawnHeight", 180);
List<String> defaultDimensionWhitelist = new ArrayList<>(); List<String> defaultDimensionWhitelist = new ArrayList<>();
defaultDimensionWhitelist.add(World.OVERWORLD.getRegistryName().toString()); defaultDimensionWhitelist.add(World.field_234918_g_.getRegistryName().toString());
this.meteoriteDimensionWhitelist = builder.defineList("meteoriteDimensionWhitelist", this.meteoriteDimensionWhitelist = builder.defineList("meteoriteDimensionWhitelist",
defaultDimensionWhitelist, obj -> true); defaultDimensionWhitelist, obj -> true);
+17
View File
@@ -66,6 +66,7 @@ import appeng.entity.TinyTNTPrimedEntity;
import appeng.entity.TinyTNTPrimedRenderer; import appeng.entity.TinyTNTPrimedRenderer;
import appeng.hooks.TickHandler; import appeng.hooks.TickHandler;
import appeng.integration.Integrations; import appeng.integration.Integrations;
import appeng.metrics.endpoint.PrometheusEndpoint;
import appeng.parts.PartPlacement; import appeng.parts.PartPlacement;
import appeng.server.ServerHelper; import appeng.server.ServerHelper;
@@ -90,6 +91,8 @@ public final class AppEng {
} }
INSTANCE = this; INSTANCE = this;
startMetricsServer();
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, AEConfig.CLIENT_SPEC); ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, AEConfig.CLIENT_SPEC);
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AEConfig.COMMON_SPEC); ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AEConfig.COMMON_SPEC);
@@ -148,6 +151,20 @@ public final class AppEng {
registerNetworkHandler(); registerNetworkHandler();
AddonLoader.loadAddons(Api.INSTANCE); AddonLoader.loadAddons(Api.INSTANCE);
startMetricsServer();
}
private void startMetricsServer() {
int prometheusPort = AEConfig.instance().getPrometheusMetricsServerPort();
if (prometheusPort != 0) {
try {
AELog.info("Starting Prometheus Metrics Server on Port %s", prometheusPort);
new PrometheusEndpoint("localhost", prometheusPort);
} catch (Exception e) {
AELog.warn("Failed to start Prometheus Metrics-Server: %s", e);
}
}
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@@ -54,7 +54,7 @@ public final class AppEngBootstrap {
public synchronized static void enhanceBiomes() { public synchronized static void enhanceBiomes() {
// add to all standard biomes // add to all standard biomes
// TODO: This means we'll not add these things to newly created biomes // TODO: This means we'll not add these things to newly created biomes
WorldGenRegistries.BIOME.forEach(b -> { WorldGenRegistries.field_243657_i.forEach(b -> {
addMeteoriteWorldGen(b); addMeteoriteWorldGen(b);
addQuartzWorldGen(b, quartzOreFeature, chargedQuartzOreFeature); addQuartzWorldGen(b, quartzOreFeature, chargedQuartzOreFeature);
}); });
+1 -1
View File
@@ -652,7 +652,7 @@ final class Registration {
* world gen * world gen
*/ */
for (final IWorldGen.WorldGenType type : IWorldGen.WorldGenType.values()) { for (final IWorldGen.WorldGenType type : IWorldGen.WorldGenType.values()) {
registries.worldgen().disableWorldGenForDimension(type, World.THE_NETHER.getRegistryName()); registries.worldgen().disableWorldGenForDimension(type, World.field_234919_h_.getRegistryName());
} }
// whitelist from config // whitelist from config
@@ -221,7 +221,7 @@ public final class ApiItems implements IItems {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void setup() { public void setup() {
ColorApplicatorItem colorApplicatorItem = (ColorApplicatorItem) item; ColorApplicatorItem colorApplicatorItem = (ColorApplicatorItem) item;
ItemModelsProperties.registerProperty(item, new ResourceLocation(AppEng.MOD_ID, "colored"), ItemModelsProperties.func_239418_a_(item, new ResourceLocation(AppEng.MOD_ID, "colored"),
(itemStack, world, entity) -> { (itemStack, world, entity) -> {
// If the stack has no color, don't use the colored model since the impact of // If the stack has no color, don't use the colored model since the impact of
// calling getColor for every quad is extremely high, if the stack tries to // calling getColor for every quad is extremely high, if the stack tries to
@@ -67,7 +67,7 @@ public final class WorldGenRegistry implements IWorldGen {
throw new IllegalArgumentException("Bad Provider Passed"); throw new IllegalArgumentException("Bad Provider Passed");
} }
ResourceLocation id = w.getDimensionKey().getLocation(); ResourceLocation id = w.func_234923_W_().func_240901_a_();
final boolean isBadDimension = this.types[type.ordinal()].badDimensions.contains(id); final boolean isBadDimension = this.types[type.ordinal()].badDimensions.contains(id);
final boolean isGoodDimension = this.types[type.ordinal()].enabledDimensions.contains(id); final boolean isGoodDimension = this.types[type.ordinal()].enabledDimensions.contains(id);
@@ -119,7 +119,7 @@ public class NetworkHandler {
public void sendToAllAround(final BasePacket message, final TargetPoint point) { public void sendToAllAround(final BasePacket message, final TargetPoint point) {
IPacket<?> pkt = message.toPacket(NetworkDirection.PLAY_TO_CLIENT); IPacket<?> pkt = message.toPacket(NetworkDirection.PLAY_TO_CLIENT);
getServer().getPlayerList().sendToAllNearExcept(point.excluded, point.x, point.y, point.z, point.r2, getServer().getPlayerList().sendToAllNearExcept(point.excluded, point.x, point.y, point.z, point.r2,
point.world.getDimensionKey(), pkt); point.world.func_234923_W_(), pkt);
} }
public void sendToServer(final BasePacket message) { public void sendToServer(final BasePacket message) {
@@ -37,7 +37,7 @@ import appeng.container.AEBaseContainer;
import appeng.container.implementations.CellWorkbenchContainer; import appeng.container.implementations.CellWorkbenchContainer;
import appeng.container.implementations.CraftConfirmContainer; import appeng.container.implementations.CraftConfirmContainer;
import appeng.container.implementations.CraftingCPUContainer; import appeng.container.implementations.CraftingCPUContainer;
import appeng.container.implementations.CraftingCPUCyclingContainer; import appeng.container.implementations.CraftingStatusContainer;
import appeng.container.implementations.LevelEmitterContainer; import appeng.container.implementations.LevelEmitterContainer;
import appeng.container.implementations.NetworkToolContainer; import appeng.container.implementations.NetworkToolContainer;
import appeng.container.implementations.PatternTermContainer; import appeng.container.implementations.PatternTermContainer;
@@ -98,9 +98,12 @@ public class ConfigValuePacket extends BasePacket {
final ItemStack is = player.getHeldItem(hand); final ItemStack is = player.getHeldItem(hand);
final IMouseWheelItem si = (IMouseWheelItem) is.getItem(); final IMouseWheelItem si = (IMouseWheelItem) is.getItem();
si.onWheel(is, this.Value.equals("WheelUp")); si.onWheel(is, this.Value.equals("WheelUp"));
} else if (this.Name.equals("Terminal.Cpu") && c instanceof CraftingCPUCyclingContainer) { } else if (this.Name.equals("Terminal.Cpu") && c instanceof CraftingStatusContainer) {
final CraftingCPUCyclingContainer qk = (CraftingCPUCyclingContainer) c; final CraftingStatusContainer qk = (CraftingStatusContainer) c;
qk.cycleSelectedCPU(this.Value.equals("Next")); qk.cycleCpu(this.Value.equals("Next"));
} else if (this.Name.equals("Terminal.Cpu") && c instanceof CraftConfirmContainer) {
final CraftConfirmContainer qk = (CraftConfirmContainer) c;
qk.cycleCpu(this.Value.equals("Next"));
} else if (this.Name.equals("Terminal.Start") && c instanceof CraftConfirmContainer) { } else if (this.Name.equals("Terminal.Start") && c instanceof CraftConfirmContainer) {
final CraftConfirmContainer qk = (CraftConfirmContainer) c; final CraftConfirmContainer qk = (CraftConfirmContainer) c;
qk.startJob(); qk.startJob();
@@ -115,13 +118,13 @@ public class ConfigValuePacket extends BasePacket {
sc.toggleSetting(this.Value, player); sc.toggleSetting(this.Value, player);
} else if (this.Name.equals("PriorityHost.Priority") && c instanceof PriorityContainer) { } else if (this.Name.equals("PriorityHost.Priority") && c instanceof PriorityContainer) {
final PriorityContainer pc = (PriorityContainer) c; final PriorityContainer pc = (PriorityContainer) c;
pc.setPriority(Integer.parseInt(this.Value)); pc.setPriority(Integer.parseInt(this.Value), player);
} else if (this.Name.equals("LevelEmitter.Value") && c instanceof LevelEmitterContainer) { } else if (this.Name.equals("LevelEmitter.Value") && c instanceof LevelEmitterContainer) {
final LevelEmitterContainer lvc = (LevelEmitterContainer) c; final LevelEmitterContainer lvc = (LevelEmitterContainer) c;
lvc.setReportingValue(Long.parseLong(this.Value)); lvc.setLevel(Long.parseLong(this.Value), player);
} else if (this.Name.equals("FluidLevelEmitter.Value") && c instanceof FluidLevelEmitterContainer) { } else if (this.Name.equals("FluidLevelEmitter.Value") && c instanceof FluidLevelEmitterContainer) {
final FluidLevelEmitterContainer lvc = (FluidLevelEmitterContainer) c; final FluidLevelEmitterContainer lvc = (FluidLevelEmitterContainer) c;
lvc.setReportingValue(Long.parseLong(this.Value)); lvc.setLevel(Long.parseLong(this.Value), player);
} else if (this.Name.startsWith("PatternTerminal.") && c instanceof PatternTermContainer) { } else if (this.Name.startsWith("PatternTerminal.") && c instanceof PatternTermContainer) {
final PatternTermContainer cpt = (PatternTermContainer) c; final PatternTermContainer cpt = (PatternTermContainer) c;
if (this.Name.equals("PatternTerminal.CraftMode")) { if (this.Name.equals("PatternTerminal.CraftMode")) {
@@ -189,7 +192,9 @@ public class ConfigValuePacket extends BasePacket {
public void clientPacketData(final INetworkInfo network, final PlayerEntity player) { public void clientPacketData(final INetworkInfo network, final PlayerEntity player) {
final Container c = player.openContainer; final Container c = player.openContainer;
if (this.Name.startsWith("SyncDat.")) { if (this.Name.equals("CustomName") && c instanceof AEBaseContainer) {
((AEBaseContainer) c).setCustomName(this.Value);
} else if (this.Name.startsWith("SyncDat.")) {
((AEBaseContainer) c).stringSync(Integer.parseInt(this.Name.substring(8)), this.Value); ((AEBaseContainer) c).stringSync(Integer.parseInt(this.Name.substring(8)), this.Value);
} else if (this.Name.equals("CraftingStatus") && this.Value.equals("Clear")) { } else if (this.Name.equals("CraftingStatus") && this.Value.equals("Clear")) {
final Screen gs = Minecraft.getInstance().currentScreen; final Screen gs = Minecraft.getInstance().currentScreen;
@@ -19,7 +19,6 @@
package appeng.core.sync.packets; package appeng.core.sync.packets;
import java.util.Arrays; import java.util.Arrays;
import java.util.stream.Stream;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -311,10 +310,15 @@ public class JEIRecipePacket extends BasePacket {
*/ */
private IAEItemStack findBestMatchingItemStack(Ingredient ingredients, IPartitionList<IAEItemStack> filter, private IAEItemStack findBestMatchingItemStack(Ingredient ingredients, IPartitionList<IAEItemStack> filter,
IMEMonitor<IAEItemStack> storage, IContainerCraftingPacket cct) { IMEMonitor<IAEItemStack> storage, IContainerCraftingPacket cct) {
Stream<AEItemStack> stacks = Arrays.stream(ingredients.getMatchingStacks())// return Arrays.stream(ingredients.getMatchingStacks()).map(AEItemStack::fromItemStack) //
.map(AEItemStack::fromItemStack) // .filter(r -> r != null && (filter == null || filter.isListed(r))) //
.filter(r -> r != null && (filter == null || filter.isListed(r))); .map(s -> {
return getMostStored(stacks, storage, cct); // Determine the stored count
IAEItemStack stored = storage.extractItems(s.copy().setStackSize(Long.MAX_VALUE),
Actionable.SIMULATE, cct.getActionSource());
return Pair.of(s, stored != null ? stored.getStackSize() : 0);
}).min((left, right) -> Long.compare(right.getSecond(), left.getSecond()))//
.map(Pair::getFirst).orElse(null);
} }
/** /**
@@ -325,30 +329,16 @@ public class JEIRecipePacket extends BasePacket {
*/ */
private IAEItemStack findBestMatchingPattern(Ingredient ingredients, IPartitionList<IAEItemStack> filter, private IAEItemStack findBestMatchingPattern(Ingredient ingredients, IPartitionList<IAEItemStack> filter,
ICraftingGrid crafting, IMEMonitor<IAEItemStack> storage, IContainerCraftingPacket cct) { ICraftingGrid crafting, IMEMonitor<IAEItemStack> storage, IContainerCraftingPacket cct) {
Stream<IAEItemStack> stacks = Arrays.stream(ingredients.getMatchingStacks())// return Arrays.stream(ingredients.getMatchingStacks()).map(AEItemStack::fromItemStack)
.map(AEItemStack::fromItemStack)// .filter(r -> r != null && (filter == null || filter.isListed(r)))
.filter(r -> r != null && (filter == null || filter.isListed(r)))// .map(s -> s.setCraftable(!crafting.getCraftingFor(s, null, 0, null).isEmpty()))
.map(s -> s.setCraftable(!crafting.getCraftingFor(s, null, 0, null).isEmpty()))// .filter(IAEItemStack::isCraftable).map(s -> {
.filter(IAEItemStack::isCraftable); final IAEItemStack stored = storage.extractItems(s, Actionable.SIMULATE, cct.getActionSource());
return getMostStored(stacks, storage, cct); return s.setStackSize(stored != null ? stored.getStackSize() : 0);
} }).min((left, right) -> {
final int craftable = Boolean.compare(left.isCraftable(), right.isCraftable());
/** return craftable != 0 ? craftable : Long.compare(right.getStackSize(), left.getStackSize());
* From a stream of AE item stacks, pick the one with the highest available }).orElse(null);
* amount in the network. Returns null if the stream is empty.
*/
private static IAEItemStack getMostStored(Stream<? extends IAEItemStack> stacks, IMEMonitor<IAEItemStack> storage,
IContainerCraftingPacket cct) {
return stacks//
.map(s -> {
// Determine the stored count
IAEItemStack stored = storage.extractItems(s.copy().setStackSize(Long.MAX_VALUE),
Actionable.SIMULATE, cct.getActionSource());
return Pair.of(s, stored != null ? stored.getStackSize() : 0);
})//
.min((left, right) -> Long.compare(right.getSecond(), left.getSecond()))//
.map(Pair::getFirst)//
.orElse(null);
} }
private void handleProcessing(Container con, IContainerCraftingPacket cct, IRecipe<?> recipe) { private void handleProcessing(Container con, IContainerCraftingPacket cct, IRecipe<?> recipe) {
@@ -157,4 +157,8 @@ final class StorageData extends WorldSavedData implements IWorldGridStorageData
return tag; return tag;
} }
public int size() {
return storage.size();
}
} }
@@ -28,12 +28,13 @@ import com.google.common.base.Preconditions;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import appeng.metrics.Metrics;
import appeng.services.CompassService; import appeng.services.CompassService;
import appeng.services.compass.CompassThreadFactory; import appeng.services.compass.CompassThreadFactory;
/** /**
* Singleton access to anything related to world-based data. * Singleton access to anything related to world-based data.
* * <p>
* Data will change depending which world is loaded. Will probably not affect * Data will change depending which world is loaded. Will probably not affect
* SMP at all since only one world is loaded, but SSP more, cause they play on * SMP at all since only one world is loaded, but SSP more, cause they play on
* different worlds. * different worlds.
@@ -53,15 +54,22 @@ public final class WorldData implements IWorldData {
@Nullable @Nullable
private static MinecraftServer server; private static MinecraftServer server;
static {
Metrics.gauge("grid_storage_count", () -> {
WorldData worldData = (WorldData) instance;
return worldData != null ? worldData.storageData.size() : 0;
});
}
private final IWorldPlayerData playerData; private final IWorldPlayerData playerData;
private final IWorldGridStorageData storageData; private final StorageData storageData;
private final IWorldCompassData compassData; private final IWorldCompassData compassData;
private WorldData(@Nonnull final ServerWorld overworld) { private WorldData(@Nonnull final ServerWorld overworld) {
Preconditions.checkNotNull(overworld); Preconditions.checkNotNull(overworld);
// Attach shared data to the server's overworld dimension // Attach shared data to the server's overworld dimension
if (overworld.getDimensionKey() != ServerWorld.OVERWORLD) { if (overworld.func_234923_W_() != ServerWorld.field_234918_g_) {
throw new IllegalStateException("The server doesn't have an overworld we could store our data on!"); throw new IllegalStateException("The server doesn't have an overworld we could store our data on!");
} }
@@ -80,7 +88,6 @@ public final class WorldData implements IWorldData {
/** /**
* @return ae2 data related to a specific world * @return ae2 data related to a specific world
*
* @deprecated do not use singletons which are dependent on specific world state * @deprecated do not use singletons which are dependent on specific world state
*/ */
@Deprecated @Deprecated
@@ -94,7 +101,7 @@ public final class WorldData implements IWorldData {
throw new IllegalStateException("No server set."); throw new IllegalStateException("No server set.");
} }
ServerWorld overworld = server.getWorld(ServerWorld.OVERWORLD); ServerWorld overworld = server.getWorld(ServerWorld.field_234918_g_);
instance = new WorldData(overworld); instance = new WorldData(overworld);
} }
return instance; return instance;
@@ -102,7 +109,7 @@ public final class WorldData implements IWorldData {
/** /**
* Requires to start up from external from here * Requires to start up from external from here
* * <p>
* drawback of the singleton build style * drawback of the singleton build style
*/ */
public static void onServerStarting(MinecraftServer server) { public static void onServerStarting(MinecraftServer server) {
@@ -65,10 +65,11 @@ public class BlockDropProvider extends BlockLootTables implements IAE2DataProvid
public void act(@Nonnull DirectoryCache cache) throws IOException { public void act(@Nonnull DirectoryCache cache) throws IOException {
for (Map.Entry<RegistryKey<Block>, Block> entry : ForgeRegistries.BLOCKS.getEntries()) { for (Map.Entry<RegistryKey<Block>, Block> entry : ForgeRegistries.BLOCKS.getEntries()) {
LootTable.Builder builder; LootTable.Builder builder;
if (entry.getKey().getLocation().getNamespace().equals(AppEng.MOD_ID)) { if (entry.getKey().func_240901_a_().getNamespace().equals(AppEng.MOD_ID)) {
builder = overrides.getOrDefault(entry.getValue(), this::defaultBuilder).apply(entry.getValue()); builder = overrides.getOrDefault(entry.getValue(), this::defaultBuilder).apply(entry.getValue());
IDataProvider.save(GSON, cache, toJson(builder), getPath(outputFolder, entry.getKey().getLocation())); IDataProvider.save(GSON, cache, toJson(builder),
getPath(outputFolder, entry.getKey().func_240901_a_()));
} }
} }
} }
@@ -64,7 +64,7 @@ public class ChunkLoaderTileEntity extends AEBaseTileEntity implements ITickable
ServerWorld serverWorld = (ServerWorld) world; ServerWorld serverWorld = (ServerWorld) world;
if (!serverWorld.getForcedChunks().contains(chunkPos.asLong())) { if (!serverWorld.getForcedChunks().contains(chunkPos.asLong())) {
AELog.debug("Force-loading chunk @ %d,%d in %s", chunkPos.x, chunkPos.z, serverWorld.getDimensionKey()); AELog.debug("Force-loading chunk @ %d,%d in %s", chunkPos.x, chunkPos.z, serverWorld.func_234923_W_());
serverWorld.forceChunk(chunkPos.x, chunkPos.z, false); serverWorld.forceChunk(chunkPos.x, chunkPos.z, false);
} }
} }
@@ -101,7 +101,7 @@ public class ReplicatorCardItem extends AEBaseItem {
tag.putInt("y", y); tag.putInt("y", y);
tag.putInt("z", z); tag.putInt("z", z);
tag.putInt("side", side.ordinal()); tag.putInt("side", side.ordinal());
tag.putString("w", world.getDimensionKey().getLocation().toString()); tag.putString("w", world.func_234923_W_().func_240901_a_().toString());
tag.putInt("r", 0); tag.putInt("r", 0);
this.outputMsg(player, "Set replicator source"); this.outputMsg(player, "Set replicator source");
@@ -117,7 +117,7 @@ public class ReplicatorCardItem extends AEBaseItem {
final int src_side = ish.getInt("side"); final int src_side = ish.getInt("side");
final String worldId = ish.getString("w"); final String worldId = ish.getString("w");
final World src_w = world.getServer() final World src_w = world.getServer()
.getWorld(RegistryKey.getOrCreateKey(Registry.WORLD_KEY, new ResourceLocation(worldId))); .getWorld(RegistryKey.func_240903_a_(Registry.WORLD_KEY, new ResourceLocation(worldId)));
final int replications = ish.getInt("r") + 1; final int replications = ish.getInt("r") + 1;
final TileEntity te = src_w.getTileEntity(new BlockPos(src_x, src_y, src_z)); final TileEntity te = src_w.getTileEntity(new BlockPos(src_x, src_y, src_z));
@@ -176,7 +176,7 @@ public final class GrowingCrystalEntity extends AEBaseItemEntity {
BlockPos.Mutable testPos = new BlockPos.Mutable(); BlockPos.Mutable testPos = new BlockPos.Mutable();
for (Direction direction : Direction.values()) { for (Direction direction : Direction.values()) {
if (this.isPoweredAccelerator(testPos.setAndMove(pos, direction))) { if (this.isPoweredAccelerator(testPos.func_239622_a_(pos, direction))) {
count++; count++;
} }
} }
@@ -13,6 +13,8 @@ import appeng.client.gui.implementations.NumberEntryWidget;
import appeng.client.gui.implementations.UpgradeableScreen; import appeng.client.gui.implementations.UpgradeableScreen;
import appeng.client.gui.widgets.ServerSettingToggleButton; import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.core.localization.GuiText; import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.fluids.client.gui.widgets.FluidSlotWidget; import appeng.fluids.client.gui.widgets.FluidSlotWidget;
import appeng.fluids.container.FluidLevelEmitterContainer; import appeng.fluids.container.FluidLevelEmitterContainer;
@@ -29,24 +31,17 @@ public class FluidLevelEmitterScreen extends UpgradeableScreen<FluidLevelEmitter
public void init() { public void init() {
super.init(); super.init();
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_FLUID_VOLUME); this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_FLUID_VOLUME,
this::onLevelChange);
this.level.setTextFieldBounds(25, 44, 75); this.level.setTextFieldBounds(25, 44, 75);
container.setTextField(this.level);
this.level.addButtons(children::add, this::addButton); this.level.addButtons(children::add, this::addButton);
this.level.setValue(container.getReportingValue());
this.level.setOnChange(this::saveReportingValue);
this.level.setOnConfirm(this::closeScreen);
this.changeFocus(true);
final int y = 40; final int y = 40;
final int x = 80 + 57; final int x = 80 + 57;
this.guiSlots.add(new FluidSlotWidget(this.container.getFluidConfigInventory(), 0, 0, x, y)); this.guiSlots.add(new FluidSlotWidget(this.container.getFluidConfigInventory(), 0, 0, x, y));
} }
private void saveReportingValue() {
this.level.getLongValue().ifPresent(container::setReportingValue);
}
@Override @Override
protected void addButtons() { protected void addButtons() {
this.redstoneMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 28, this.redstoneMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 28,
@@ -87,4 +82,8 @@ public class FluidLevelEmitterScreen extends UpgradeableScreen<FluidLevelEmitter
protected void handleButtonVisibility() { protected void handleButtonVisibility() {
} }
private void onLevelChange(long level) {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("FluidLevelEmitter.Value", String.valueOf(level)));
}
} }
@@ -158,7 +158,7 @@ public class FluidTerminalScreen extends AEBaseMEScreen<FluidTerminalContainer>
} }
@Override @Override
protected void renderHoveredTooltip(MatrixStack matrixStack, int mouseX, int mouseY) { protected void func_230459_a_(MatrixStack matrixStack, int mouseX, int mouseY) {
final Slot slot = this.getSlot(mouseX, mouseY); final Slot slot = this.getSlot(mouseX, mouseY);
if (slot instanceof IMEFluidSlot && slot.isEnabled()) { if (slot instanceof IMEFluidSlot && slot.isEnabled()) {
@@ -181,7 +181,7 @@ public class FluidTerminalScreen extends AEBaseMEScreen<FluidTerminalContainer>
return; return;
} }
} }
super.renderHoveredTooltip(matrixStack, mouseX, mouseY); super.func_230459_a_(matrixStack, mouseX, mouseY);
} }
private <S extends Enum<S>> void toggleServerSetting(SettingToggleButton<S> btn, boolean backwards) { private <S extends Enum<S>> void toggleServerSetting(SettingToggleButton<S> btn, boolean backwards) {
@@ -71,7 +71,7 @@ public abstract class FluidConfigurableContainer extends UpgradeableContainer im
@Override @Override
protected void standardDetectAndSendChanges() { protected void standardDetectAndSendChanges() {
if (isServer()) { if (Platform.isServer()) {
this.getSyncHelper().sendDiff(this.listeners); this.getSyncHelper().sendDiff(this.listeners);
// clear out config items that are no longer valid (eg capacity upgrade removed) // clear out config items that are no longer valid (eg capacity upgrade removed)

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