Compare commits

...

60 Commits

Author SHA1 Message Date
shartte d07937fa93 Render Performance Improvements (#4721)
* Return a fixed bounding box for frustrum culling of AE tile entity renderers to prevent Forge from re-retrieving the TE from the world and calculating the collision box (very costly for cables).

* Changed dynamic cable bus lighting to be based on block states to improved rendering speed and fix optifine issues. (Potential fix for #4716).
2020-09-10 22:56:50 +02:00
shartte 65f58913a4 Make players assume ownership of networks when they place security stations onto unsecured ones (#4714)
* Fixes #4712: When a security station is placed onto an unsecured network, the placer assumes ownership of the entire network. Otherwise the contiguous network would not necessarily reconnect in the same way when the chunk is reloaded due to differing player-ids throughout the network.
In addition, changes to the node's owner were not being persisted due to the host never being marked as dirty.

* Fix formatting
2020-09-10 22:34:16 +02:00
Sebastian Hartte 81cc0b804d Fixes #4699: AE's glass should only hide it's sides adjacent to other AE glass.
Also disables spawn on AE's glass same as Vanilla glass.
2020-09-09 00:58:14 +02:00
Sebastian Hartte e1fc9908b3 Fixes #4693: Fix color applicator not working on cable-buses. 2020-09-09 00:51:45 +02:00
shartte 9ed1535477 Fixes #4661: Do not update a tile entity when it's in an unloaded chunk (i.e. during chunk unloading) (#4708) 2020-09-08 22:28:30 +02:00
Sebastian Hartte 1ef345d4a4 Formatting fixes. 2020-09-08 22:24:27 +02:00
Sebastian Hartte ff7d1b9719 Fixes #4704: QNB is not finding a registered QNB because it believes the chunk to be unloaded.
Also adds debug logging to the locatable registry to better debug this issues in the future.
2020-09-08 22:20:33 +02:00
shartte 88c9370e4f Crystal Growth Refactor (#4702)
* Refactored crystal in-world purification:
- Removed iterative formula
- Set the default growth factor to 1 rather than 0.5 to simplify settings
- Made the growth-tick-progress-per-tick a configuration setting for 0-6 accelerators
- Unfinished seeds now slowly sink when ejected by an annihilation plane or other system (emulates a player throwing it in)
- Instead of checking for "isLiquid", we now check for a new tag (appliedenergistics2:crystal_purification_medium) to check if the crystal is submerged in an allowed fluid for growth, defaults to #minecraft:water.

* Removed configuration options for changing how accelerators work,
replaced with improved fluid tag option with a clamped multiplier [1,10].
2020-09-08 18:10:45 +02:00
Sebastian Hartte f2aae3ef0f Added a global Voxelshape cache for cable bus voxel shapes, since combining voxel shapes turns out to be an extremely expensive process (i.e. 1.7s for 10000x5 shapes). 2020-09-08 17:56:02 +02:00
Sebastian Hartte 12739f1e66 Remove unneeded cable-bus inventory-model, which caused the part models to be loaded twice leading to unnecessary memory-usage. 2020-09-08 17:53:14 +02:00
shartte 81d2170ada Implemented a cache with maximum quad-count it will cache for the cable bus, (#4670)
which also fixes concurrent access to the hashmap.

(cherry picked from commit b756d68be1)
2020-09-08 14:28:08 +02:00
Sebastian Hartte 0f34f09b32 Remove object-scanning subscriptions and remove unused test-file. 2020-09-06 20:59:37 +02:00
Sebastian Hartte 8e54a8fed9 Fixes a problem where tile entities would become unremovable (well, one more of these at least),
because they would reset their block state upon removal and loss of power.
2020-09-06 20:59:19 +02:00
Sebastian Hartte d9bb81a00f Fixes #4680: Facade advancement is showing an untextured facade. 2020-09-03 17:36:20 +02:00
yueh 39e038d916 Fixes #4683: Hopefully LazyOptional works as advertised (#4684) 2020-09-02 21:36:40 +02:00
yueh f0d0595c8f Fixes #4669: Take NBT into account for comparing. (#4675)
This only covers combining different items together.
Fuzzy filtering is still a bit too fuzzy for corner cases.
2020-09-01 21:59:08 +02:00
shartte 7c99fca789 Fixes removal of facades not invalidating the cached server-side collision boxes. (#4663)
(cherry picked from commit 957bc4c5cc)
2020-09-01 01:07:30 +02:00
yueh ab393b0ed1 Serialize the complete NBT data to avoid mismatches (#4665)
This might increase the network traffic a bit, but the amount of mods actually using the share tag seems to be very limited.
For now it is worth the risk as it solves the problem. In case we run into actual issues, there might still be other solutions, which will be way more complex and can potentially introduce additional problems.

(cherry picked from commit e90dd2f9c6)
2020-09-01 01:07:28 +02:00
yueh 133ed1f09d Remove GZipStreams from packets. (#4664)
This should now be handled by the normal network manager (hopefully).
Also renamed the `CompressedNBTPacket` to `MEInterfaceUpdatePacket` as that is the only use case.
2020-08-31 23:09:28 +02:00
shartte db9ec2b070 Remove the use of SlotItemHandler since we are only faking an inventory-backed slot, (#4654)
we might as well use what we had used pre-2017, which is simply extending a normal Slot.
This should also fix #4652.
2020-08-29 22:03:35 +02:00
Sebastian Hartte 00d4c20d9f Strip pom.xml dependencies. 2020-08-26 11:39:03 +02:00
Sebastian Hartte 5efc085693 Fix tiles that have a "powered" block state from not being able to be broken when
they are connected to a powered grid.
2020-08-24 23:54:37 +02:00
Sebastian Hartte aff94cec8c Fix search box interactions in the interface terminal. 2020-08-24 22:33:04 +02:00
Sebastian Hartte 2184d03d0b Actually save the rotation when a tile is rotated. 2020-08-24 01:06:26 +02:00
Sebastian Hartte 44c0931c02 Fixes #4635: Actually remove requesters when removing requesters. 2020-08-23 20:47:05 +02:00
yueh 423ab81813 Added step to publish to modmaven (#4607)
(cherry picked from commit 7e1bfdb5ac)
2020-08-21 20:40:03 +02:00
shartte 4e42b17e81 Fixes #4590: Crystal seeds (other than certus) don't display their growth stages. (#4618) 2020-08-19 16:43:45 +02:00
shartte fc0f8eab56 Fixes #4611: Use of client-side only method for Tiny TNT explosion. (#4612) 2020-08-18 01:33:47 +02:00
shartte 41b7900706 Fixes #4598: Incorrectly rotated face for determining block lightlevel in ME Chest renderer. (#4599) (#4609)
(cherry picked from commit 954ce1442e)
2020-08-17 21:58:51 +02:00
shartte 7656157b0d Fixes #4602: Prevent encoding invalid patterns and handle corrupted patterns a little more gracefully. (#4608) 2020-08-17 21:49:37 +02:00
Sebastian Hartte 87c2c94bd4 Use minus sign for minus buttons in number widget. 2020-08-11 16:31:20 +02:00
yueh d591a1492c Fixes #4583: Confine fluix crafting into the same block (#4586)
Fluix crystals will now spawn within an area around the center of the block as well as some tuned down motion while still maintaining some randomness.
2020-08-10 11:30:04 +02:00
shartte d1ba26311b One Spatial Dimension (#4570)
* Ported the "one spatial dimension" concept from pre-1.15

* Apply lighting updates after moving chunks.
Mark world data as dirty when changing it.

* Consolidated naming of spatial storage world/dimension.
Use server light manager to update lighting info in chunk.

* Save last transition information,
and add ae2 spatial command to interact with spatial storage.

* Formatting fixes.

* Improved docs for the origin generation.

Inverted condition on when the x/z axis are flipped.
Also added a helper to map a plot to a region file

* Remove TransitionResult since it's only used in lieu of a boolean.
Rework transition to make the checks BEFORE allocating a new cell.

* Removed unused imports.

Co-authored-by: yueh <yueh@users.noreply.github.com>
2020-08-10 11:29:07 +02:00
shartte 8733c2c11f Fix Special Model Registration (#4577)
* Fixes #4575 by updating Forge (ModelRegistryEvent is a modbus event but was misflagged as not being one). And update Forge because their breaking change breaks our mod.

* Update gradle.properties

Co-authored-by: yueh <yueh@users.noreply.github.com>

* Update src/main/resources/META-INF/mods.toml

Co-authored-by: yueh <yueh@users.noreply.github.com>

Co-authored-by: yueh <yueh@users.noreply.github.com>
2020-08-10 11:25:26 +02:00
yueh 4230fc7325 Fixes #4576: Append the amount to each button (#4580) 2020-08-09 13:23:24 +02:00
shartte 484af8baf3 Fixes #4574 by referencing only non-pure fluix crystals in the fluix dust grinder recipe. (#4578) 2020-08-09 12:24:42 +02:00
shartte 9456f639d4 Simplify "unlit" quad loading and move to Mixins (#4569)
* Simplified the UV loader concept: We only need it to make quads "unlit" which means that the lighting system is not applied to them. They always render at their full brightness.

* More documentation and slight cleanups.
2020-08-09 01:27:19 +02:00
shartte fe753c540b Fixes #4571: When not used for displaying localized text, specify Locale.ROOT for toLowerCase/toUpperCase to avoid issues with locale-specific non-ASCII lowercase conversions for ASCII uppercase characters (i.e. turkish lowercase i for uppercase I). (#4573) 2020-08-08 14:56:51 +02:00
Sebastian Hartte 2fabab3a6a Fix AO lighting for faces not fully snapped to block edges. 2020-08-08 02:20:40 +02:00
shartte 6f39bd8fe8 Move the nether quartz dust tag to the forge namespace and use it instead of AE's internal one. (#4568) 2020-08-07 23:13:02 +02:00
yueh c7d3877129 Use the declared power drain for p2p tunnels (#4567) 2020-08-06 20:07:40 +02:00
Sebastian Hartte 822249dda8 Added missing @Override annotations. 2020-08-05 22:11:00 +02:00
yueh 1404806d3d Fixes #4559: Use visual bounding box for overlay (#4561) 2020-08-05 21:52:34 +02:00
yueh 12e3fa9127 Makes formation planes a bit more consistent and less violent. (#4553)
* Makes formation planes a bit more consistent and less violent.

Items will now have a slower speed when spawning as well as a narrower area to avoid having them glitch into a wall and be teleported around

* Removed debug output, added clarifying parenthesis and extracted method.

* Fixes various other issues with the formation plane

Also removed now useless code

Co-authored-by: Sebastian Hartte <sebastian@hartte.de>
2020-08-05 17:56:42 +02:00
shartte 8617dc8340 Plane Connection Refactor (#4556)
* Refactors all plane parts to use a common helper for
calculating connections to adjacent planes.
Also fixes problems with updating these connections on neighbor updates.

* Fix conflicting GuiSync ID.

* Slightly refactor PlaneConnectionHelper, and fix an issue where the bounding box was calculated incorrectly by using the wrong up-direction.
2020-08-05 17:45:33 +02:00
shartte 9bc844738c Fixes #4547: Name clash between ITooltip#getWidth, ITooltip#getHeight and Vanilla Widget methods leads to missing methods at runtime, since the implementing methods will be remapped to SRG names, while referees of the interface will try to call the renamed methods by their name in the interface, leading to an AbstractMethodError. (#4557) 2020-08-05 16:33:44 +02:00
Sebastian Hartte eab6483bd7 Fixes #4551: Bounding box of annihilation planes is too small. 2020-08-05 00:54:26 +02:00
yueh 7ca9405c8b Apply the FE tunnel behaviour to the fluid tunnel (#4550) 2020-08-04 17:57:59 +02:00
yueh 39959145a3 Revert "Apply the FE tunnel behaviour to the fluid tunnel (#4545)" (#4549)
This reverts commit 22f552217f.
2020-08-04 08:45:10 +02:00
yueh 22f552217f Apply the FE tunnel behaviour to the fluid tunnel (#4545)
* Apply the FE tunnel behaviour to the fluid tunnel

* Make a second pass to try and get all the requested fill amount sent out to outputs.

Co-authored-by: Sebastian Hartte <sebastian@hartte.de>
2020-08-03 21:39:34 +02:00
yueh 8f0e408772 Fixes NPE on empty tooltips (#4546) 2020-08-03 20:57:10 +02:00
Sebastian Hartte 62bbc32763 Minor cleanup. 2020-08-03 20:31:30 +02:00
shartte 872d8d33cb Clean up global state for cable render mode (#4539)
* Clean up the global state used to hack part interaction into respecting
the player's facade render mode. Make the name more indicative of
what is actually happening.

* Fun.
2020-08-03 14:46:39 +02:00
shartte 1801302d8f Fix SkyStone chest model issues that I had introduced back in 1.8. (#4542)
This makes the chest 1 pixel higher to restore the look it had in 1.7.
Since the skystone chest's texture is a grungy mess, only the most
obvious texture problems were fixed, while for the skystone block chest,
the look should be close to what it was now.
Also introduces caching for the skystone chest's block shape.
2020-08-03 14:46:23 +02:00
Sebastian Hartte a85ffec9f9 Unified Parameter-Names for Slots 2020-08-02 22:12:08 +02:00
Sebastian Hartte 5fca946ef3 The lambda has to be replaced with an explicit method to annotate it with @OnlyIn. 2020-08-02 15:45:15 +02:00
Sebastian Hartte f8446209ce Move CraftingMonitor rendering customization out to its own class to circumvent issues with a client-side only lambda method being generated in a common-side class. 2020-08-02 15:40:50 +02:00
Sebastian Hartte 088627aedf Remove client-only methods from ChargerBlock which could potentially create synthetic lambda methods that reference client-only classes (and are not stripped). 2020-08-02 15:13:20 +02:00
shartte c8d08f9726 Fixes sidedness issues that cropped up with 1.16 (#4533) 2020-08-01 22:16:57 +02:00
yueh 259d932946 Fixes 4529: Updated IPart to match new ICapabilityProvider (#4534) 2020-08-01 21:01:19 +02:00
239 changed files with 3235 additions and 4320 deletions
+9 -1
View File
@@ -55,7 +55,15 @@ jobs:
KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }}
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew publish --no-daemon --max-workers 1
run: ./gradlew publishMavenPublicationToGitHubPackagesRepository --no-daemon --max-workers 1
- name: Publish to modmaven
env:
KEY_STORE_PASS: ${{ secrets.KEY_STORE_PASS }}
KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }}
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
MODMAVEN_USER: ${{ secrets.MODMAVEN_USER }}
MODMAVEN_PASSWORD: ${{ secrets.MODMAVEN_PASSWORD }}
run: ./gradlew publishMavenPublicationToModmavenRepository --no-daemon --max-workers 1
- name: Prepare artifact metadata
id: prepare_artifact_metadata
run: |
+15
View File
@@ -190,6 +190,13 @@ publishing {
groupId = project.group
artifactId = project.archivesBaseName
version = project.version
// ForgeGradle will generate wild dependency definitions, see https://github.com/MinecraftForge/ForgeGradle/issues/584
// Since we don't actually depend on anything, just remove the entire node.
pom.withXml {
asNode().remove(asNode().dependencies)
}
from components.java
artifact sourcesJar
artifact javadocJar
@@ -205,5 +212,13 @@ publishing {
name = "GitHubPackages"
url = "https://maven.pkg.github.com/AppliedEnergistics/Applied-Energistics-2"
}
maven {
credentials {
username System.getenv("MODMAVEN_USER")
password System.getenv("MODMAVEN_PASSWORD")
}
name = "modmaven"
url = "https://modmaven.k-4u.nl/artifactory/local-releases/"
}
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ artifact_basename=appliedenergistics2
minecraft_release=1.16
minecraft_version=1.16.1
mcp_mappings=20200723-1.16.1
forge_version=32.0.93
forge_version=32.0.108
#########################################################
# Provided APIs #
@@ -23,6 +23,8 @@
package appeng.api.config;
import java.util.Locale;
/**
* Represent the security systems basic permissions, these are not for
* anti-griefing, they are part of the mod as a gameplay feature.
@@ -58,7 +60,7 @@ public enum SecurityPermissions {
*/
SECURITY;
private final String translationKey = "gui.appliedenergistics2.security." + this.name().toLowerCase();
private final String translationKey = "gui.appliedenergistics2.security." + this.name().toLowerCase(Locale.ROOT);
public String getTranslatedName() {
return this.translationKey + ".name";
@@ -53,6 +53,8 @@ public interface ICraftingHelper {
* @param stack If null, a new item will be created to hold the encoded pattern.
* Otherwise the given item must already contains an encoded
* pattern that will be overwritten.
* @throws IllegalArgumentException If either in or out contain only empty
* ItemStacks.
* @return A new encoded pattern, or the given stack with the pattern encoded in
* it.
*/
@@ -73,6 +75,8 @@ public interface ICraftingHelper {
* operation by the ME system.
* @param allowSubstitutes Controls whether the ME system will allow the use of
* equivalent items to craft this recipe.
* @throws IllegalArgumentException If either in or out contain only empty
* ItemStacks.
*/
ItemStack encodeCraftingPattern(@Nullable ItemStack stack, ICraftingRecipe recipe, ItemStack[] in, ItemStack out,
boolean allowSubstitutes);
@@ -1,38 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.implementations;
/**
* Defines the result of performing a transition from the world into a storage
* cell, if its possible, and what the energy usage is.
*/
public class TransitionResult {
public final boolean success;
public final double energyUsage;
public TransitionResult(final boolean success, final double power) {
this.success = success;
this.energyUsage = power;
}
}
@@ -23,13 +23,23 @@
package appeng.api.implementations.items;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import javax.annotation.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface IGrowableCrystal {
ItemStack triggerGrowth(ItemStack is);
float getMultiplier(Block blk, Material mat);
/**
* Gets the crystal growth multiplier based on the material it is submerged in.
*
* @param state The blockstate of the block the crystal is currently in.
* @return The multiplier for the growth tick progress. Zero if the crystal
* cannot grow in the current material.
*/
float getMultiplier(BlockState state, @Nullable World world, @Nullable BlockPos pos);
}
@@ -25,11 +25,8 @@ package appeng.api.implementations.items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.RegistryKey;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import appeng.api.implementations.TransitionResult;
import appeng.api.util.WorldCoord;
/**
@@ -52,13 +49,13 @@ public interface ISpatialStorageCell {
int getMaxStoredDim(ItemStack is);
/**
* get the currently stored Dimension id.
* get the currently stored spatial storage plot id.
*
* @param is spatial storage cell
*
* @return dimension id or -1
* @return plot id or -1
*/
RegistryKey<World> getStoredDimension(ItemStack is);
int getAllocatedPlotId(ItemStack is);
/**
* Perform a spatial swap with the contents of the cell, and the world.
@@ -69,7 +66,7 @@ public interface ISpatialStorageCell {
* @param max max coord
* @param playerId owner of current grid or -1
*
* @return result of transition
* @return success of transition
*/
TransitionResult doSpatialTransition(ItemStack is, ServerWorld w, WorldCoord min, WorldCoord max, int playerId);
boolean doSpatialTransition(ItemStack is, ServerWorld w, WorldCoord min, WorldCoord max, int playerId);
}
@@ -28,4 +28,9 @@ public enum GridNotification {
* the visible connections for this node have changed, useful for cable.
*/
CONNECTIONS_CHANGED,
/**
* the owner of the grid node has changed, and the node needs to be re-saved
*/
OWNER_CHANGED
}
@@ -87,7 +87,8 @@ public interface IGridBlock {
AEColor getGridColor();
/**
* Notifies your IGridBlock that changes were made to your connections
* Called by the {@link IGridNode} to notify its {@link IGridBlock} about
* events.
*/
void onGridNotification(@Nonnull GridNotification notification);
+5 -2
View File
@@ -50,6 +50,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import appeng.api.networking.IGridNode;
@@ -346,10 +347,12 @@ public interface IPart extends ICustomCableConnection {
* capabilities on the cable bus will be forwarded to parts on the appropriate
* side.
*
* @see TileEntity#getCapability(Capability, net.minecraft.util.Direction)
* @see CapabilityProvider#getCapability(Capability,
* net.minecraft.util.Direction)
*
* @return The capability or null.
* @return The capability
*/
@Nonnull
default <T> LazyOptional<T> getCapability(Capability<T> capabilityClass) {
return LazyOptional.empty();
}
@@ -1,51 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2017, 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.api.storage;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.util.RegistryKey;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
public interface ISpatialDimension {
ServerWorld getWorld(RegistryKey<World> cellDim);
@Nullable
RegistryKey<World> createNewCellDimension(BlockPos capacity);
void deleteCellDimension(RegistryKey<World> cellDim);
boolean isCellDimension(RegistryKey<World> cellDim);
BlockPos getCellDimensionOrigin(RegistryKey<World> cellDim);
BlockPos getCellDimensionSize(RegistryKey<World> cellDim);
/**
* Adds a user-facing tooltip that describes this dimension so that a player can
* keep storage cells apart.
*/
void addCellDimensionTooltip(RegistryKey<World> cellDim, List<ITextComponent> lines);
}
@@ -23,10 +23,8 @@ import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
@@ -45,14 +43,6 @@ public class AEBaseBlockItemChargeable extends AEBaseBlockItem implements IAEIte
public AEBaseBlockItemChargeable(Block id, Properties props) {
super(id, props);
ItemModelsProperties.func_239418_a_(this, new ResourceLocation("appliedenergistics2:fill_level"),
(is, world, entity) -> {
double curPower = getAECurrentPower(is);
double maxPower = getAEMaxPower(is);
return (int) Math.round(100 * curPower / maxPower);
});
}
@Override
@@ -0,0 +1,33 @@
package appeng.block.crafting;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
import appeng.client.render.crafting.MonitorBakedModel;
import appeng.client.render.model.AutoRotatingBakedModel;
public class CraftingMonitorBlockRendering extends BlockRenderingCustomizer {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderType.getCutout());
rendering.modelCustomizer(CraftingMonitorBlockRendering::customizeModel);
}
@OnlyIn(Dist.CLIENT)
private static IBakedModel customizeModel(ResourceLocation path, IBakedModel model) {
// The formed model handles rotations itself, the unformed one does not
if (model instanceof MonitorBakedModel) {
return model;
}
return new AutoRotatingBakedModel(model);
}
}
@@ -19,18 +19,12 @@
package appeng.block.misc;
import java.util.Random;
import java.util.function.Function;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResultType;
@@ -42,8 +36,6 @@ import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.math.vector.TransformationMatrix;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
@@ -52,8 +44,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.util.AEAxisAlignedBB;
import appeng.block.AEBaseTileBlock;
import appeng.client.render.effects.ParticleTypes;
import appeng.client.render.renderable.ItemRenderable;
import appeng.client.render.tesr.ModularTESR;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.core.AppEng;
@@ -175,15 +165,4 @@ public class ChargerBlock extends AEBaseTileBlock<ChargerTileEntity> {
return VoxelShapes.create(new AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 1.0, 1.0));
}
@OnlyIn(Dist.CLIENT)
public static Function<TileEntityRendererDispatcher, TileEntityRenderer<ChargerTileEntity>> createTesr() {
return dispatcher -> new ModularTESR<>(dispatcher, new ItemRenderable<>(ChargerBlock::getRenderedItem));
}
@OnlyIn(Dist.CLIENT)
private static Pair<ItemStack, TransformationMatrix> getRenderedItem(ChargerTileEntity tile) {
TransformationMatrix transform = new TransformationMatrix(new Vector3f(0.5f, 0.375f, 0.5f), null, null, null);
return new ImmutablePair<>(tile.getInternalInventory().getStackInSlot(0), transform);
}
}
@@ -39,6 +39,8 @@ import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.DyeColor;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.state.IntegerProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
@@ -82,8 +84,12 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusTileEntity> implement
private static final ICableBusContainer NULL_CABLE_BUS = new NullCableBusContainer();
private static final IntegerProperty LIGHT_LEVEL = IntegerProperty.create("light_level", 0, 15);
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
@@ -126,11 +132,9 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusTileEntity> implement
}
@Override
public int getLightValue(final BlockState state, final IBlockReader world, final BlockPos pos) {
if (state.getBlock() != this) {
return state.getBlock().getLightValue(state, world, pos);
}
return this.cb(world, pos).getLightValue();
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
super.fillStateContainer(builder);
builder.add(LIGHT_LEVEL);
}
@Override
@@ -386,4 +390,13 @@ 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);
}
}
@@ -18,6 +18,8 @@
package appeng.block.networking;
import java.util.Locale;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
@@ -51,7 +53,7 @@ public class WirelessBlock extends AEBaseTileBlock<WirelessTileEntity> {
@Override
public String getString() {
return this.name().toLowerCase();
return this.name().toLowerCase(Locale.ROOT);
}
}
@@ -18,6 +18,9 @@
package appeng.block.storage;
import java.util.EnumMap;
import java.util.Map;
import javax.annotation.Nullable;
import net.minecraft.block.BlockRenderType;
@@ -47,7 +50,18 @@ public class SkyChestBlock extends AEBaseTileBlock<SkyChestTileEntity> {
private static final double AABB_OFFSET_BOTTOM = 0.00;
private static final double AABB_OFFSET_SIDES = 0.06;
private static final double AABB_OFFSET_TOP = 0.125;
private static final double AABB_OFFSET_TOP = 0.0625;
// Precomputed bounding boxes of the chest, sorted into the map by the UP
// direction
private static final Map<Direction, VoxelShape> SHAPES = new EnumMap<>(Direction.class);
static {
for (Direction up : Direction.values()) {
AxisAlignedBB aabb = computeAABB(up);
SHAPES.put(up, VoxelShapes.create(aabb));
}
}
public enum SkyChestType {
STONE, BLOCK
@@ -87,37 +101,30 @@ public class SkyChestBlock extends AEBaseTileBlock<SkyChestTileEntity> {
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
// TODO Cache this! It can't be that hard!
AxisAlignedBB aabb = computeAABB(worldIn, pos);
return VoxelShapes.create(aabb);
final SkyChestTileEntity sk = this.getTileEntity(worldIn, pos);
Direction up = sk != null ? sk.getUp() : Direction.UP;
return SHAPES.get(up);
}
private AxisAlignedBB computeAABB(final IBlockReader w, final BlockPos pos) {
final SkyChestTileEntity sk = this.getTileEntity(w, pos);
Direction o = Direction.UP;
if (sk != null) {
o = sk.getUp();
}
final double offsetX = o.getXOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetY = o.getYOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetZ = o.getZOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
private static AxisAlignedBB computeAABB(Direction up) {
final double offsetX = up.getXOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetY = up.getYOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetZ = up.getZOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
// for x/z top and bottom is swapped
final double minX = Math.max(0.0,
offsetX + (o.getXOffset() < 0 ? AABB_OFFSET_BOTTOM : (o.getXOffset() * AABB_OFFSET_TOP)));
offsetX + (up.getXOffset() < 0 ? AABB_OFFSET_BOTTOM : (up.getXOffset() * AABB_OFFSET_TOP)));
final double minY = Math.max(0.0,
offsetY + (o.getYOffset() < 0 ? AABB_OFFSET_TOP : (o.getYOffset() * AABB_OFFSET_BOTTOM)));
offsetY + (up.getYOffset() < 0 ? AABB_OFFSET_TOP : (up.getYOffset() * AABB_OFFSET_BOTTOM)));
final double minZ = Math.max(0.0,
offsetZ + (o.getZOffset() < 0 ? AABB_OFFSET_BOTTOM : (o.getZOffset() * AABB_OFFSET_TOP)));
offsetZ + (up.getZOffset() < 0 ? AABB_OFFSET_BOTTOM : (up.getZOffset() * AABB_OFFSET_TOP)));
final double maxX = Math.min(1.0,
1.0 - offsetX - (o.getXOffset() < 0 ? AABB_OFFSET_TOP : (o.getXOffset() * AABB_OFFSET_BOTTOM)));
1.0 - offsetX - (up.getXOffset() < 0 ? AABB_OFFSET_TOP : (up.getXOffset() * AABB_OFFSET_BOTTOM)));
final double maxY = Math.min(1.0,
1.0 - offsetY - (o.getYOffset() < 0 ? AABB_OFFSET_BOTTOM : (o.getYOffset() * AABB_OFFSET_TOP)));
1.0 - offsetY - (up.getYOffset() < 0 ? AABB_OFFSET_BOTTOM : (up.getYOffset() * AABB_OFFSET_TOP)));
final double maxZ = Math.min(1.0,
1.0 - offsetZ - (o.getZOffset() < 0 ? AABB_OFFSET_TOP : (o.getZOffset() * AABB_OFFSET_BOTTOM)));
1.0 - offsetZ - (up.getZOffset() < 0 ? AABB_OFFSET_TOP : (up.getZOffset() * AABB_OFFSET_BOTTOM)));
return new AxisAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
}
@@ -31,6 +31,8 @@ import net.minecraft.block.Block;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@@ -38,8 +40,10 @@ import appeng.api.definitions.IBlockDefinition;
import appeng.api.features.AEFeature;
import appeng.block.AEBaseBlock;
import appeng.block.AEBaseBlockItem;
import appeng.block.AEBaseBlockItemChargeable;
import appeng.block.AEBaseTileBlock;
import appeng.bootstrap.components.IBlockRegistrationComponent;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.IItemRegistrationComponent;
import appeng.bootstrap.definitions.TileEntityDefinition;
import appeng.core.AEItemGroup;
@@ -149,6 +153,24 @@ class BlockDefinitionBuilder implements IBlockBuilder {
item.setRegistryName(AppEng.MOD_ID, this.registryName);
}
// Register the client-only item model property for chargeable items
if (item instanceof AEBaseBlockItemChargeable) {
AEBaseBlockItemChargeable chargeable = (AEBaseBlockItemChargeable) item;
this.factory.addBootstrapComponent(new IClientSetupComponent() {
@Override
@OnlyIn(Dist.CLIENT)
public void setup() {
ItemModelsProperties.func_239418_a_(item, new ResourceLocation("appliedenergistics2:fill_level"),
(is, world, entity) -> {
double curPower = chargeable.getAECurrentPower(is);
double maxPower = chargeable.getAEMaxPower(is);
return (int) Math.round(100 * curPower / maxPower);
});
}
});
}
// Register the item and block with the game
this.factory.addBootstrapComponent((IBlockRegistrationComponent) (side, registry) -> registry.register(block));
if (item != null) {
+3 -1
View File
@@ -1,6 +1,8 @@
package appeng.client;
import java.util.Locale;
import org.lwjgl.glfw.GLFW;
public enum ActionKey {
@@ -13,7 +15,7 @@ public enum ActionKey {
}
public String getTranslationKey() {
return "key." + this.name().toLowerCase() + ".desc";
return "key." + this.name().toLowerCase(Locale.ROOT) + ".desc";
}
public int getDefaultKey() {
@@ -138,15 +138,15 @@ public class ClientHelper extends ServerHelper {
}
@Override
public CableRenderMode getRenderMode() {
public CableRenderMode getCableRenderMode() {
if (Platform.isServer()) {
return super.getRenderMode();
return super.getCableRenderMode();
}
final Minecraft mc = Minecraft.getInstance();
final PlayerEntity player = mc.player;
return this.renderModeForPlayer(player);
return this.getCableRenderModeForPlayer(player);
}
@Override
@@ -158,14 +158,14 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
protected void drawGuiSlot(MatrixStack matrixStack, CustomSlotWidget slot, int mouseX, int mouseY,
float partialTicks) {
if (slot.isSlotEnabled()) {
final int left = slot.xPos();
final int top = slot.yPos();
final int right = left + slot.getWidth();
final int bottom = top + slot.getHeight();
final int left = slot.getTooltipAreaX();
final int top = slot.getTooltipAreaY();
final int right = left + slot.getTooltipAreaWidth();
final int bottom = top + slot.getTooltipAreaHeight();
slot.drawContent(matrixStack, getMinecraft(), mouseX, mouseY, partialTicks);
if (this.isPointInRegion(left, top, slot.getWidth(), slot.getHeight(), mouseX, mouseY)
if (this.isPointInRegion(left, top, slot.getTooltipAreaWidth(), slot.getTooltipAreaHeight(), mouseX, mouseY)
&& slot.canClick(getPlayer())) {
RenderSystem.colorMask(true, true, true, false);
this.fillGradient(matrixStack, left, top, right, bottom, -2130706433, -2130706433);
@@ -175,26 +175,30 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
}
private void drawTooltip(MatrixStack matrixStack, ITooltip tooltip, int mouseX, int mouseY) {
final int x = tooltip.xPos(); // ((GuiImgButton) c).x;
int y = tooltip.yPos(); // ((GuiImgButton) c).y;
final int x = tooltip.getTooltipAreaX();
int y = tooltip.getTooltipAreaY();
if (x < mouseX && x + tooltip.getWidth() > mouseX && tooltip.isVisible()) {
if (y < mouseY && y + tooltip.getHeight() > mouseY) {
if (x < mouseX && x + tooltip.getTooltipAreaWidth() > mouseX && tooltip.isTooltipAreaVisible()) {
if (y < mouseY && y + tooltip.getTooltipAreaHeight() > mouseY) {
if (y < 15) {
y = 15;
}
final ITextComponent msg = tooltip.getMessage();
final ITextComponent msg = tooltip.getTooltipMessage();
this.drawTooltip(matrixStack, x + 11, y + 4, msg);
}
}
}
protected void drawTooltip(MatrixStack matrices, int x, int y, ITextComponent message) {
String[] lines = message.getString().split("\n"); // FIXME FABRIC
List<ITextComponent> textLines = Arrays.stream(lines).map(StringTextComponent::new)
.collect(Collectors.toList());
this.drawTooltip(matrices, x, y, textLines);
String tooltipText = message.getString();
if (!tooltipText.isEmpty()) {
String[] lines = tooltipText.split("\n"); // FIXME FABRIC
List<ITextComponent> textLines = Arrays.stream(lines).map(StringTextComponent::new)
.collect(Collectors.toList());
this.drawTooltip(matrices, x, y, textLines);
}
}
// FIXME FABRIC: move out to json (?)
@@ -281,8 +285,8 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
}
for (CustomSlotWidget slot : this.guiSlots) {
if (this.isPointInRegion(slot.xPos(), slot.yPos(), slot.getWidth(), slot.getHeight(), xCoord, yCoord)
&& slot.canClick(getPlayer())) {
if (this.isPointInRegion(slot.getTooltipAreaX(), slot.getTooltipAreaY(), slot.getTooltipAreaWidth(),
slot.getTooltipAreaHeight(), xCoord, yCoord) && slot.canClick(getPlayer())) {
slot.slotClicked(getPlayer().inventory.getItemStack(), btn);
}
}
@@ -8,19 +8,18 @@ import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.SlotItemHandler;
/**
* A proxy for a slot that will always return an itemstack with size 1, if there
* is an item in the slot. Used to prevent the default item count from
* rendering.
*/
class Size1Slot extends SlotItemHandler {
class Size1Slot extends Slot {
private final SlotItemHandler delegate;
private final Slot delegate;
public Size1Slot(SlotItemHandler delegate) {
super(delegate.getItemHandler(), delegate.getSlotIndex(), delegate.xPos, delegate.yPos);
public Size1Slot(Slot delegate) {
super(delegate.inventory, delegate.getSlotIndex(), delegate.xPos, delegate.yPos);
this.delegate = delegate;
}
@@ -90,7 +90,9 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
this.searchField.setMaxStringLength(25);
this.searchField.setTextColor(0xFFFFFF);
this.searchField.setVisible(true);
this.searchField.setFocused2(true);
this.searchField.setResponder(str -> this.refreshList());
this.addListener(this.searchField);
this.changeFocus(true);
}
@Override
@@ -131,11 +133,8 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
@Override
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
if (this.searchField.mouseClicked(xCoord, yCoord, btn)) {
if (btn == 1 && this.searchField.isMouseOver(xCoord, yCoord)) {
this.searchField.setText("");
this.refreshList();
}
if (btn == 1 && this.searchField.isMouseOver(xCoord, yCoord)) {
this.searchField.setText("");
return true;
}
@@ -173,11 +172,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
if (character == ' ' && this.searchField.getText().isEmpty()) {
return true;
}
if (this.searchField.charTyped(character, key)) {
this.refreshList();
return true;
}
return false;
return super.charTyped(character, key);
}
@Override
@@ -245,7 +240,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
/**
* Rebuilds the list of interfaces.
*
* <p>
* Respects a search term if present (ignores case) and adding only matching
* patterns.
*/
@@ -338,12 +333,11 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
/**
* Tries to retrieve a cache for a with search term as keyword.
*
* <p>
* If this cache should be empty, it will populate it with an earlier cache if
* available or at least the cache for the empty string.
*
* @param searchTerm the corresponding search
*
* @return a Set matching a superset of the search term
*/
private Set<Object> getCacheForSearchTerm(final String searchTerm) {
@@ -1,5 +1,7 @@
package appeng.client.gui.implementations;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.LongConsumer;
@@ -24,7 +26,7 @@ import appeng.core.AEConfig;
public class NumberEntryWidget implements ITickingWidget {
private static final ITextComponent PLUS = new StringTextComponent("+");
private static final ITextComponent MINUS = new StringTextComponent("+");
private static final ITextComponent MINUS = new StringTextComponent("-");
private final AEBaseScreen<?> parent;
@@ -33,14 +35,7 @@ public class NumberEntryWidget implements ITickingWidget {
private final NumberBox level;
private final NumberEntryType type;
private Button plus1;
private Button plus10;
private Button plus100;
private Button plus1000;
private Button minus1;
private Button minus10;
private Button minus100;
private Button minus1000;
private List<Button> buttons;
public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type,
LongConsumer changeListener) {
@@ -63,14 +58,7 @@ public class NumberEntryWidget implements ITickingWidget {
public void setActive(boolean active) {
this.level.setEnabled(active);
this.plus1.active = active;
this.plus10.active = active;
this.plus100.active = active;
this.plus1000.active = active;
this.minus1.active = active;
this.minus10.active = active;
this.minus100.active = active;
this.minus1000.active = active;
this.buttons.forEach(b -> b.active = active);
}
public void setTextFieldBounds(int x, int y, int width) {
@@ -93,18 +81,23 @@ public class NumberEntryWidget implements ITickingWidget {
int left = parent.getGuiLeft() + x;
int top = parent.getGuiTop() + y;
addButton.accept(this.plus1 = new Button(left, top, 22, 20, PLUS /* + a */, btn -> addQty(a)));
addButton.accept(this.plus10 = new Button(left + 28, top, 28, 20, PLUS /* + b */, btn -> addQty(b)));
addButton.accept(this.plus100 = new Button(left + 62, top, 32, 20, PLUS /* + c */, btn -> addQty(c)));
addButton.accept(this.plus1000 = new Button(left + 100, top, 38, 20, PLUS/* + d */, btn -> addQty(d)));
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 + 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 + 100, top, 38, 20, makeLabel(PLUS, d), btn -> addQty(d)));
// Placing this here will give a sensible tab order
addChildren.accept(this.level);
addButton.accept(this.minus1 = new Button(left, top + 42, 22, 20, MINUS /* + a */, btn -> addQty(-a)));
addButton.accept(this.minus10 = new Button(left + 28, top + 42, 28, 20, MINUS /* + b */, btn -> addQty(-b)));
addButton.accept(this.minus100 = new Button(left + 62, top + 42, 32, 20, MINUS /* + c */, btn -> addQty(-c)));
addButton.accept(this.minus1000 = new Button(left + 100, top + 42, 38, 20, MINUS /* + d */, btn -> addQty(-d)));
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 + 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)));
this.buttons = buttons;
this.buttons.forEach(addButton);
}
private void addQty(final long i) {
@@ -134,4 +127,8 @@ public class NumberEntryWidget implements ITickingWidget {
this.level.tick();
}
private ITextComponent makeLabel(ITextComponent prefix, int amount) {
return prefix.copyRaw().appendString(String.valueOf(amount));
}
}
@@ -27,7 +27,7 @@ import net.minecraft.util.text.StringTextComponent;
import appeng.api.config.ActionItems;
import appeng.core.localization.ButtonToolTips;
public class ActionButton extends IconButton implements ITooltip {
public class ActionButton extends IconButton {
private static final Pattern PATTERN_NEW_LINE = Pattern.compile("\\n", Pattern.LITERAL);
private final int iconIndex;
@@ -8,6 +8,7 @@ import net.minecraft.client.gui.AbstractGui;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
public abstract class CustomSlotWidget extends AbstractGui implements ITooltip {
private final int x;
@@ -38,32 +39,32 @@ public abstract class CustomSlotWidget extends AbstractGui implements ITooltip {
}
@Override
public ITextComponent getMessage() {
return null;
public ITextComponent getTooltipMessage() {
return StringTextComponent.EMPTY;
}
@Override
public int xPos() {
public int getTooltipAreaX() {
return this.x;
}
@Override
public int yPos() {
public int getTooltipAreaY() {
return this.y;
}
@Override
public int getWidth() {
public int getTooltipAreaWidth() {
return 16;
}
@Override
public int getHeight() {
public int getTooltipAreaHeight() {
return 16;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return false;
}
@@ -18,7 +18,10 @@
package appeng.client.gui.widgets;
import javax.annotation.Nonnull;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
/**
* AEBaseGui controlled Tooltip Interface.
@@ -26,42 +29,45 @@ import net.minecraft.util.text.ITextComponent;
public interface ITooltip {
/**
* returns the tooltip message.
* Returns the tooltip message.
*
* Should use {@link StringTextComponent#EMPTY} for no tooltip
*
* @return tooltip message
*/
ITextComponent getMessage();
@Nonnull
ITextComponent getTooltipMessage();
/**
* x Location for the object that triggers the tooltip.
*
* @return xPosition
*/
int xPos();
int getTooltipAreaX();
/**
* y Location for the object that triggers the tooltip.
*
* @return yPosition
*/
int yPos();
int getTooltipAreaY();
/**
* Width of the object that triggers the tooltip.
*
* @return width
*/
int getWidth();
int getTooltipAreaWidth();
/**
* Height for the object that triggers the tooltip.
*
* @return height
*/
int getHeight();
int getTooltipAreaHeight();
/**
* @return true if button being drawn
*/
boolean isVisible();
boolean isTooltipAreaVisible();
}
@@ -25,6 +25,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.fml.client.gui.GuiUtils;
@@ -97,27 +98,32 @@ public abstract class IconButton extends Button implements ITooltip {
protected abstract int getIconIndex();
@Override
public int xPos() {
public ITextComponent getTooltipMessage() {
return getMessage();
}
@Override
public int getTooltipAreaX() {
return this.x;
}
@Override
public int yPos() {
public int getTooltipAreaY() {
return this.y;
}
@Override
public int getWidth() {
public int getTooltipAreaWidth() {
return this.halfSize ? 8 : 16;
}
@Override
public int getHeight() {
public int getTooltipAreaHeight() {
return this.halfSize ? 8 : 16;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return this.visible;
}
@@ -81,7 +81,7 @@ public class ProgressBar extends Widget implements ITooltip {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
if (this.fullMsg != null) {
return this.fullMsg;
}
@@ -92,27 +92,27 @@ public class ProgressBar extends Widget implements ITooltip {
}
@Override
public int xPos() {
public int getTooltipAreaX() {
return this.x - 2;
}
@Override
public int yPos() {
public int getTooltipAreaY() {
return this.y - 2;
}
@Override
public int getWidth() {
public int getTooltipAreaWidth() {
return this.width + 4;
}
@Override
public int getHeight() {
public int getTooltipAreaHeight() {
return this.height + 4;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return true;
}
@@ -279,7 +279,7 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
ITextComponent displayName = null;
ITextComponent displayValue = null;
@@ -99,27 +99,32 @@ public class TabButton extends Button implements ITooltip {
}
@Override
public int xPos() {
public ITextComponent getTooltipMessage() {
return getMessage();
}
@Override
public int getTooltipAreaX() {
return this.x;
}
@Override
public int yPos() {
public int getTooltipAreaY() {
return this.y;
}
@Override
public int getWidth() {
public int getTooltipAreaWidth() {
return 22;
}
@Override
public int getHeight() {
public int getTooltipAreaHeight() {
return 22;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return this.visible;
}
@@ -77,7 +77,7 @@ public class ToggleButton extends Button implements ITooltip {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
if (this.displayName != null) {
String name = I18n.format(this.displayName);
String value = I18n.format(this.displayHint);
@@ -106,27 +106,27 @@ public class ToggleButton extends Button implements ITooltip {
}
@Override
public int xPos() {
public int getTooltipAreaX() {
return this.x;
}
@Override
public int yPos() {
public int getTooltipAreaY() {
return this.y;
}
@Override
public int getWidth() {
public int getTooltipAreaWidth() {
return 16;
}
@Override
public int getHeight() {
public int getTooltipAreaHeight() {
return 16;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return this.visible;
}
}
@@ -41,11 +41,6 @@ import appeng.fluids.util.FluidSorters;
import appeng.util.Platform;
import appeng.util.prioritylist.IPartitionList;
/**
* @author BrockWS
* @version rv6 - 22/05/2018
* @since rv6 22/05/2018
*/
public class FluidRepo {
private final IItemList<IAEFluidStack> list = Api.instance().storage().getStorageChannel(IFluidStorageChannel.class)
.createList();
@@ -29,13 +29,13 @@ public class SlotDisconnected extends AppEngSlot {
private final ClientDCInternalInv mySlot;
public SlotDisconnected(final ClientDCInternalInv me, final int which, final int x, final int y) {
super(me.getInventory(), which, x, y);
public SlotDisconnected(final ClientDCInternalInv me, final int invSlot, final int x, final int y) {
super(me.getInventory(), invSlot, x, y);
this.mySlot = me;
}
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -45,7 +45,7 @@ public class SlotDisconnected extends AppEngSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
+11 -12
View File
@@ -21,23 +21,22 @@ package appeng.client.me;
import javax.annotation.Nonnull;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.SlotItemHandler;
import appeng.api.storage.data.IAEFluidStack;
import appeng.fluids.container.slots.IMEFluidSlot;
/**
* @author BrockWS
* @version rv6 - 22/05/2018
* @since rv6 22/05/2018
*/
public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
public class SlotFluidME extends Slot implements IMEFluidSlot {
private InternalFluidSlotME slot;
private static final IInventory EMPTY_INVENTORY = new Inventory(0);
private final InternalFluidSlotME slot;
public SlotFluidME(InternalFluidSlotME slot) {
super(null, 0, slot.getxPosition(), slot.getyPosition());
super(EMPTY_INVENTORY, 0, slot.getxPosition(), slot.getyPosition());
this.slot = slot;
}
@@ -50,7 +49,7 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
}
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -69,7 +68,7 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
}
@Override
public void putStack(final ItemStack par1ItemStack) {
public void putStack(final ItemStack stack) {
}
@@ -85,7 +84,7 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
}
+15 -11
View File
@@ -19,23 +19,27 @@
package appeng.client.me;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.SlotItemHandler;
import appeng.api.storage.data.IAEItemStack;
public class SlotME extends SlotItemHandler {
public class SlotME extends Slot {
private final InternalSlotME mySlot;
private static final IInventory EMPTY_INVENTORY = new Inventory(0);
public SlotME(final InternalSlotME me) {
super(null, 0, me.getxPosition(), me.getyPosition());
this.mySlot = me;
private final InternalSlotME slot;
public SlotME(final InternalSlotME slot) {
super(EMPTY_INVENTORY, 0, slot.getxPosition(), slot.getyPosition());
this.slot = slot;
}
public IAEItemStack getAEStack() {
if (this.mySlot.hasPower()) {
return this.mySlot.getAEStack();
if (this.slot.hasPower()) {
return this.slot.getAEStack();
}
return null;
}
@@ -47,15 +51,15 @@ public class SlotME extends SlotItemHandler {
@Override
public ItemStack getStack() {
if (this.mySlot.hasPower()) {
return this.mySlot.getStack();
if (this.slot.hasPower()) {
return this.slot.getStack();
}
return ItemStack.EMPTY;
}
@Override
public boolean getHasStack() {
if (this.mySlot.hasPower()) {
if (this.slot.hasPower()) {
return !this.getStack().isEmpty();
}
return false;
@@ -18,6 +18,8 @@
package appeng.client.render;
import java.util.Locale;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.util.Direction;
@@ -111,6 +113,6 @@ public enum FacingToRotation implements IStringSerializable {
@Override
public String getString() {
return name().toLowerCase();
return name().toLowerCase(Locale.ROOT);
}
}
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
import java.util.function.Function;
import net.minecraft.client.renderer.model.BakedQuad;
@@ -100,7 +101,7 @@ class CableBuilder {
}
return new RenderMaterial(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, textureFolder + color.name().toLowerCase()));
new ResourceLocation(AppEng.MOD_ID, textureFolder + color.name().toLowerCase(Locale.ROOT)));
}
/**
@@ -21,7 +21,6 @@ package appeng.client.render.cablebus;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -30,6 +29,11 @@ import java.util.Random;
import javax.annotation.Nullable;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.Weigher;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.model.BakedQuad;
@@ -50,7 +54,10 @@ import appeng.api.util.AEColor;
public class CableBusBakedModel implements IBakedModel {
private static final Map<CableBusRenderState, List<BakedQuad>> CABLE_MODEL_CACHE = new HashMap<>();
// The number of quads overall that will be cached
private static final int CACHE_QUAD_COUNT = 5000;
private final LoadingCache<CableBusRenderState, List<BakedQuad>> cableModelCache;
private final CableBuilder cableBuilder;
@@ -66,6 +73,17 @@ public class CableBusBakedModel implements IBakedModel {
this.facadeBuilder = facadeBuilder;
this.partModels = partModels;
this.particleTexture = particleTexture;
this.cableModelCache = CacheBuilder.newBuilder()//
.maximumWeight(CACHE_QUAD_COUNT)//
.weigher((Weigher<CableBusRenderState, List<BakedQuad>>) (key, value) -> value.size())//
.build(new CacheLoader<CableBusRenderState, List<BakedQuad>>() {
@Override
public List<BakedQuad> load(CableBusRenderState renderState) {
final List<BakedQuad> model = new ArrayList<>();
addCableQuads(renderState, model);
return model;
}
});
}
@Override
@@ -92,11 +110,7 @@ public class CableBusBakedModel implements IBakedModel {
if (layer == RenderType.getCutout()) {
// First, handle the cable at the center of the cable bus
final List<BakedQuad> cableModel = CABLE_MODEL_CACHE.computeIfAbsent(renderState, k -> {
final List<BakedQuad> model = new ArrayList<>();
this.addCableQuads(renderState, model);
return model;
});
final List<BakedQuad> cableModel = cableModelCache.getUnchecked(renderState);
quads.addAll(cableModel);
// Then handle attachments
@@ -341,8 +355,4 @@ public class CableBusBakedModel implements IBakedModel {
return ItemOverrideList.EMPTY;
}
public static void clearCache() {
CABLE_MODEL_CACHE.clear();
}
}
@@ -18,7 +18,6 @@ public class CableBusModelLoader implements IModelLoader<CableBusModel> {
@Override
public void onResourceManagerReload(IResourceManager resourceManager) {
CableBusBakedModel.clearCache();
}
@Override
@@ -19,6 +19,7 @@
package appeng.client.render.cablebus;
import java.util.EnumMap;
import java.util.Locale;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
@@ -74,7 +75,7 @@ public enum CableCoreType {
public RenderMaterial getTexture(AEColor color) {
return new RenderMaterial(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, this.textureFolder + "/" + color.name().toLowerCase()));
new ResourceLocation(AppEng.MOD_ID, this.textureFolder + "/" + color.name().toLowerCase(Locale.ROOT)));
}
}
@@ -18,6 +18,8 @@
package appeng.client.render.crafting;
import java.util.Locale;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@@ -48,7 +50,7 @@ public class CraftingCubeModelLoader implements IModelLoader<CraftingCubeModel>
if (typeEl != null) {
String typeName = deserializationContext.deserialize(typeEl, String.class);
if (typeName != null) {
unitType = AbstractCraftingUnitBlock.CraftingUnitType.valueOf(typeName.toUpperCase());
unitType = AbstractCraftingUnitBlock.CraftingUnitType.valueOf(typeName.toUpperCase(Locale.ROOT));
}
}
if (unitType == null) {
@@ -49,7 +49,7 @@ public class EnergyParticleData implements IParticleData {
reader.expect(' ');
boolean forItem = reader.readBoolean();
reader.expect(' ');
AEPartLocation direction = AEPartLocation.valueOf(reader.readString().toUpperCase());
AEPartLocation direction = AEPartLocation.valueOf(reader.readString().toUpperCase(Locale.ROOT));
return new EnergyParticleData(forItem, direction);
}
@@ -74,7 +74,8 @@ public class EnergyParticleData implements IParticleData {
@Override
public String getParameters() {
return String.format(Locale.ROOT, "%s %s", forItem ? "true" : "false", direction.name().toLowerCase());
return String.format(Locale.ROOT, "%s %s", forItem ? "true" : "false",
direction.name().toLowerCase(Locale.ROOT));
}
}
@@ -34,8 +34,6 @@ import com.google.common.collect.ImmutableList;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.client.renderer.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
@@ -193,7 +191,7 @@ public class AutoRotatingBakedModel extends DelegateBakedModel {
vec.setX(vec.getX() + 0.5f);
vec.setY(vec.getY() + 0.5f);
vec.setZ(vec.getZ() + 0.5f);
return new float[] { vec.getX(), vec.getY(), vec.getZ() };
return new float[] { snap(vec.getX()), snap(vec.getY()), snap(vec.getZ()) };
case 4:
Vector4f vecc = new Vector4f(fs[0], fs[1], fs[2], fs[3]);
vecc.setX(vecc.getX() - 0.5f);
@@ -203,13 +201,32 @@ public class AutoRotatingBakedModel extends DelegateBakedModel {
vecc.setX(vecc.getX() + 0.5f);
vecc.setY(vecc.getY() + 0.5f);
vecc.setZ(vecc.getZ() + 0.5f);
return new float[] { vecc.getX(), vecc.getY(), vecc.getZ(), vecc.getW() };
return new float[] { snap(vecc.getX()), snap(vecc.getY()), snap(vecc.getZ()), snap(vecc.getW()) };
default:
return fs;
}
}
/**
* This is the same value used by Vanilla's AO lighter.
*/
private static final float EPS = 0.0001f;
/**
* This tries to snap the coordinate to the edges of the block frame, because
* Vanilla uses direct equals comparisons to 0 and 1 for checking if a face
* extends fully towards the edge. This is used primarily for AO calculations.
*/
private static float snap(float x) {
if (Math.abs(x) <= EPS) {
return 0f;
} else if (Math.abs(x - 1) <= EPS) {
return 1f;
}
return x;
}
private float[] transformNormal(float[] fs) {
if (this.face == null) {
switch (fs.length) {
@@ -220,7 +237,7 @@ public class AutoRotatingBakedModel extends DelegateBakedModel {
case 4:
Vector4f vec4 = new Vector4f(fs[0], fs[1], fs[2], fs[3]);
vec4.transform(this.f2r.getMat());
return new float[] { vec4.getX(), vec4.getY(), vec4.getZ(), 0 };
return new float[] { snap(vec4.getX()), snap(vec4.getY()), snap(vec4.getZ()), 0 };
default:
return fs;
@@ -1,210 +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.render.model;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Set;
import java.util.function.Function;
import javax.annotation.Nullable;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.mojang.blaze3d.matrix.MatrixStack;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.BlockFaceUV;
import net.minecraft.client.renderer.model.BlockModel;
import net.minecraft.client.renderer.model.BlockPart;
import net.minecraft.client.renderer.model.BlockPartFace;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.IModelTransform;
import net.minecraft.client.renderer.model.IUnbakedModel;
import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.client.renderer.model.ItemOverride;
import net.minecraft.client.renderer.model.ItemOverrideList;
import net.minecraft.client.renderer.model.ItemTransformVec3f;
import net.minecraft.client.renderer.model.ModelBakery;
import net.minecraft.client.renderer.model.RenderMaterial;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.resources.IResourceManager;
import net.minecraft.util.Direction;
import net.minecraft.util.JSONUtils;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.vector.TransformationMatrix;
import net.minecraftforge.client.model.IModelBuilder;
import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.IModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
import net.minecraftforge.client.model.pipeline.VertexLighterFlat;
import net.minecraftforge.common.model.TransformationHelper;
public class UVLModelLoader implements IModelLoader<UVLModelLoader.UVLModelWrapper> {
public static final UVLModelLoader INSTANCE = new UVLModelLoader();
@Override
public void onResourceManagerReload(IResourceManager resourceManager) {
}
@Override
public UVLModelWrapper read(JsonDeserializationContext deserializationContext, JsonObject modelContents) {
modelContents.remove("loader");
BlockModel blockModel = UVLSERIALIZER.fromJson(modelContents, BlockModel.class);
return new UVLModelWrapper(blockModel);
}
final Gson UVLSERIALIZER = (new GsonBuilder())
.registerTypeAdapter(BlockModel.class, new ModelLoaderRegistry.ExpandedBlockModelDeserializer())
.registerTypeAdapter(BlockPart.class, new BlockPart.Deserializer())
.registerTypeAdapter(BlockPartFace.class, new BlockPartFaceOverrideSerializer())
.registerTypeAdapter(BlockFaceUV.class, new BlockFaceUV.Deserializer())
.registerTypeAdapter(ItemTransformVec3f.class, new ItemTransformVec3f.Deserializer())
.registerTypeAdapter(ItemCameraTransforms.class, new ItemCameraTransforms.Deserializer())
.registerTypeAdapter(ItemOverride.class, new ItemOverride.Deserializer())
.registerTypeAdapter(TransformationMatrix.class, new TransformationHelper.Deserializer()).create();
private static class BlockPartFaceOverrideSerializer extends BlockPartFace.Deserializer {
@Override
public BlockPartFace deserialize(JsonElement p_deserialize_1_, Type p_deserialize_2_,
JsonDeserializationContext p_deserialize_3_) throws JsonParseException {
BlockPartFace blockFace = super.deserialize(p_deserialize_1_, p_deserialize_2_, p_deserialize_3_);
Pair<Float, Float> uvl = this.parseUVL(p_deserialize_1_.getAsJsonObject());
if (uvl != null) {
return new BlockPartFaceWithUVL(blockFace.cullFace, blockFace.tintIndex, blockFace.texture,
blockFace.blockFaceUV, uvl.getLeft(), uvl.getRight());
}
return blockFace;
}
protected Pair<Float, Float> parseUVL(JsonObject object) {
if (!object.has("uvlightmap")) {
return null;
}
object = object.get("uvlightmap").getAsJsonObject();
return new ImmutablePair<>(JSONUtils.getFloat(object, "sky", 0), JSONUtils.getFloat(object, "block", 0));
}
}
private static class BlockPartFaceWithUVL extends BlockPartFace {
private final float sky;
private final float block;
public BlockPartFaceWithUVL(@Nullable Direction cullFaceIn, int tintIndexIn, String textureIn,
BlockFaceUV blockFaceUVIn, float sky, float block) {
super(cullFaceIn, tintIndexIn, textureIn, blockFaceUVIn);
this.sky = sky;
this.block = block;
}
public float getSky() {
return sky;
}
public float getBlock() {
return block;
}
}
public static class UVLModelWrapper implements IModelGeometry<UVLModelWrapper> {
private final BlockModel parent;
public UVLModelWrapper(BlockModel parent) {
this.parent = parent;
}
@Override
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery,
Function<RenderMaterial, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform,
ItemOverrideList overrides, ResourceLocation modelLocation) {
TextureAtlasSprite particle = spriteGetter.apply(owner.resolveTexture("particle"));
IModelBuilder<?> builder = IModelBuilder.of(owner, overrides, particle);
for (BlockPart blockpart : parent.getElements()) {
for (Direction direction : blockpart.mapFaces.keySet()) {
BlockPartFace blockpartface = blockpart.mapFaces.get(direction);
TextureAtlasSprite textureatlassprite1 = spriteGetter
.apply(owner.resolveTexture(blockpartface.texture));
BakedQuad quad = BlockModel.makeBakedQuad(blockpart, blockpartface, textureatlassprite1, direction,
modelTransform, modelLocation);
if (blockpartface instanceof BlockPartFaceWithUVL) {
BlockPartFaceWithUVL uvlFace = (BlockPartFaceWithUVL) blockpartface;
quad = applyPreBakedLighting(quad, textureatlassprite1, uvlFace.sky, uvlFace.block);
}
if (blockpartface.cullFace == null) {
builder.addGeneralQuad(quad);
} else {
builder.addFaceQuad(modelTransform.getRotation().rotateTransform(blockpartface.cullFace), quad);
}
}
}
return builder.build();
}
private BakedQuad applyPreBakedLighting(BakedQuad quad, TextureAtlasSprite sprite, float sky, float block) {
// FIXME: just piping through the quads and manipulating uv index 2 directly
// seems way easier than this
BakedQuadBuilder builder = new BakedQuadBuilder(sprite);
VertexLighterFlat trans = new VertexLighterFlat(Minecraft.getInstance().getBlockColors()) {
@Override
protected void updateLightmap(float[] normal, float[] lightmap, float x, float y, float z) {
lightmap[0] = block;
lightmap[1] = sky;
}
@Override
public void setQuadTint(int tint) {
// Tint requires a block state which we don't have at this point
}
};
MatrixStack identity = new MatrixStack();
trans.setTransform(identity.getLast());
trans.setParent(builder);
quad.pipe(trans);
builder.setQuadTint(quad.getTintIndex());
builder.setQuadOrientation(quad.getFace());
builder.setApplyDiffuseLighting(false);
return builder.build();
}
@Override
public Collection<RenderMaterial> getTextures(IModelConfiguration owner,
Function<ResourceLocation, IUnbakedModel> modelGetter,
Set<com.mojang.datafixers.util.Pair<String, String>> missingTextureErrors) {
return parent.getTextures(modelGetter, missingTextureErrors);
}
}
}
@@ -20,6 +20,7 @@ package appeng.client.render.spatial;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.Locale;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
@@ -59,7 +60,7 @@ public class SpatialPylonModel implements BasicUnbakedModel<SpatialPylonModel> {
private static RenderMaterial getTexturePath(SpatialPylonTextureType type) {
return new RenderMaterial(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, "block/spatial_pylon/" + type.name().toLowerCase()));
new ResourceLocation(AppEng.MOD_ID, "block/spatial_pylon/" + type.name().toLowerCase(Locale.ROOT)));
}
}
@@ -0,0 +1,30 @@
package appeng.client.render.tesr;
import java.util.function.Function;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.vector.TransformationMatrix;
import net.minecraft.util.math.vector.Vector3f;
import appeng.client.render.renderable.ItemRenderable;
import appeng.tile.misc.ChargerTileEntity;
public final class ChargerTESR {
private ChargerTESR() {
}
public static Function<TileEntityRendererDispatcher, TileEntityRenderer<ChargerTileEntity>> FACTORY = dispatcher -> new ModularTESR<>(
dispatcher, new ItemRenderable<>(ChargerTESR::getRenderedItem));
private static Pair<ItemStack, TransformationMatrix> getRenderedItem(ChargerTileEntity tile) {
TransformationMatrix transform = new TransformationMatrix(new Vector3f(0.5f, 0.375f, 0.5f), null, null, null);
return new ImmutablePair<>(tile.getInternalInventory().getStackInSlot(0), transform);
}
}
@@ -142,7 +142,7 @@ public class ChestTileEntityRenderer extends TileEntityRenderer<ChestTileEntity>
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand,
@Nonnull IModelData extraData) {
if (side != null) {
side = r.rotate(side); // This fixes the incorrect lightmap position
side = r.resultingRotate(side); // This fixes the incorrect lightmap position
}
List<BakedQuad> quads = new ArrayList<>(super.getQuads(state, side, rand, extraData));
@@ -60,11 +60,11 @@ public class SkyChestTESR extends TileEntityRenderer<SkyChestTileEntity> {
this.singleBottom.addBox(1.0F, 0.0F, 1.0F, 14.0F, 10.0F, 14.0F, 0.0F);
this.singleLid = new ModelRenderer(64, 64, 0, 0);
this.singleLid.addBox(1.0F, 0.0F, 0.0F, 14.0F, 5.0F, 14.0F, 0.0F);
this.singleLid.rotationPointY = 9.0F;
this.singleLid.rotationPointY = 10.0F;
this.singleLid.rotationPointZ = 1.0F;
this.singleLatch = new ModelRenderer(64, 64, 0, 0);
this.singleLatch.addBox(7.0F, -1.0F, 15.0F, 2.0F, 4.0F, 1.0F, 0.0F);
this.singleLatch.rotationPointY = 8.0F;
this.singleLatch.rotationPointY = 9.0F;
}
@Override
@@ -93,8 +93,6 @@ public abstract class AEBaseContainer extends Container {
private boolean sentCustomName;
private int ticksSinceCheck = 900;
private IAEItemStack clientRequestedTargetItem = null;
// Slots that were created to represent the player inventory
private List<Slot> playerInventorySlots = null;
public AEBaseContainer(ContainerType<?> containerType, int id, final PlayerInventory ip, final TileEntity myTile,
final IPart myPart) {
@@ -52,7 +52,7 @@ public class FormationPlaneContainer extends UpgradeableContainer {
return helper.open(player, locator);
}
@GuiSync(6)
@GuiSync(7)
public YesNo placeMode;
public FormationPlaneContainer(int id, final PlayerInventory ip, final FormationPlanePart te) {
@@ -42,7 +42,7 @@ import appeng.api.networking.security.IActionHost;
import appeng.container.AEBaseContainer;
import appeng.container.ContainerLocator;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.CompressedNBTPacket;
import appeng.core.sync.packets.MEInterfaceUpdatePacket;
import appeng.helpers.DualityInterface;
import appeng.helpers.IInterfaceHost;
import appeng.helpers.InventoryAction;
@@ -177,7 +177,7 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
if (!this.data.isEmpty()) {
try {
NetworkHandler.instance().sendTo(new CompressedNBTPacket(this.data),
NetworkHandler.instance().sendTo(new MEInterfaceUpdatePacket(this.data),
(ServerPlayerEntity) this.getPlayerInv().player);
} catch (final IOException e) {
// :P
@@ -261,13 +261,19 @@ public class PatternTermContainer extends MEMonitorableContainer
return new ItemStack[] { out };
}
} else {
boolean hasValue = false;
final ItemStack[] list = new ItemStack[3];
for (int i = 0; i < this.outputSlots.length; i++) {
final ItemStack out = this.outputSlots[i].getStack();
list[i] = out;
if (!out.isEmpty()) {
hasValue = true;
}
}
if (hasValue) {
return list;
}
return list;
}
return null;
@@ -105,8 +105,8 @@ public class QuartzKnifeContainer extends AEBaseContainer {
}
private class QuartzKniveSlot extends OutputSlot {
QuartzKniveSlot(IItemHandler a, int b, int c, int d, int i) {
super(a, b, c, d, i);
QuartzKniveSlot(IItemHandler inv, int invSlot, int x, int y, int iconIdx) {
super(inv, invSlot, x, y, iconIdx);
}
@Override
@@ -49,8 +49,8 @@ public class AppEngCraftingSlot extends AppEngSlot {
private int amountCrafted;
public AppEngCraftingSlot(final PlayerEntity par1PlayerEntity, final IItemHandler par2IInventory,
final IItemHandler par3IInventory, final int par4, final int par5, final int par6) {
super(par3IInventory, par4, par5, par6);
final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
this.thePlayer = par1PlayerEntity;
this.craftMatrix = par2IInventory;
}
@@ -60,7 +60,7 @@ public class AppEngCraftingSlot extends AppEngSlot {
* armor slots.
*/
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -33,9 +33,9 @@ import appeng.container.AEBaseContainer;
import appeng.util.helpers.ItemHandlerUtil;
public class AppEngSlot extends Slot {
private static IInventory emptyInventory = new Inventory(0);
private static final IInventory EMPTY_INVENTORY = new Inventory(0);
private final IItemHandler itemHandler;
private final int index;
private final int invSlot;
private final int defX;
private final int defY;
@@ -46,10 +46,10 @@ public class AppEngSlot extends Slot {
private CalculatedValidity isValid;
private boolean isDisplay = false;
public AppEngSlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(emptyInventory, idx, x, y);
public AppEngSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(EMPTY_INVENTORY, invSlot, x, y);
this.itemHandler = inv;
this.index = idx;
this.invSlot = invSlot;
this.defX = x;
this.defY = y;
@@ -71,13 +71,13 @@ public class AppEngSlot extends Slot {
}
public void clearStack() {
ItemHandlerUtil.setStackInSlot(this.itemHandler, this.index, ItemStack.EMPTY);
ItemHandlerUtil.setStackInSlot(this.itemHandler, this.invSlot, ItemStack.EMPTY);
}
@Override
public boolean isItemValid(@Nonnull final ItemStack par1ItemStack) {
public boolean isItemValid(@Nonnull final ItemStack stack) {
if (this.isSlotEnabled()) {
return this.itemHandler.isItemValid(this.index, par1ItemStack);
return this.itemHandler.isItemValid(this.invSlot, stack);
}
return false;
}
@@ -98,13 +98,13 @@ public class AppEngSlot extends Slot {
return this.getDisplayStack();
}
return this.itemHandler.getStackInSlot(this.index);
return this.itemHandler.getStackInSlot(this.invSlot);
}
@Override
public void putStack(final ItemStack stack) {
if (this.isSlotEnabled()) {
ItemHandlerUtil.setStackInSlot(this.itemHandler, this.index, stack);
ItemHandlerUtil.setStackInSlot(this.itemHandler, this.invSlot, stack);
this.onSlotChanged();
}
}
@@ -128,7 +128,7 @@ public class AppEngSlot extends Slot {
@Override
public int getSlotStackLimit() {
return this.itemHandler.getSlotLimit(this.index);
return this.itemHandler.getSlotLimit(this.invSlot);
}
@Override
@@ -137,9 +137,9 @@ public class AppEngSlot extends Slot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
if (this.isSlotEnabled()) {
return !this.itemHandler.extractItem(this.index, 1, true).isEmpty();
return !this.itemHandler.extractItem(this.invSlot, 1, true).isEmpty();
}
return false;
}
@@ -147,7 +147,7 @@ public class AppEngSlot extends Slot {
@Override
@Nonnull
public ItemStack decrStackSize(int amount) {
return this.itemHandler.extractItem(this.index, amount, false);
return this.itemHandler.extractItem(this.invSlot, amount, false);
}
@Override
@@ -166,7 +166,7 @@ public class AppEngSlot extends Slot {
}
public ItemStack getDisplayStack() {
return this.itemHandler.getStackInSlot(this.index);
return this.itemHandler.getStackInSlot(this.invSlot);
}
public float getOpacityOfIcon() {
@@ -29,11 +29,11 @@ public class CraftingMatrixSlot extends AppEngSlot {
private final AEBaseContainer c;
private final IInventory wrappedInventory;
public CraftingMatrixSlot(final AEBaseContainer c, final IItemHandler par1iInventory, final int par2,
final int par3, final int par4) {
super(par1iInventory, par2, par3, par4);
public CraftingMatrixSlot(final AEBaseContainer c, final IItemHandler inv, final int invSlot, final int x,
final int y) {
super(inv, invSlot, x, y);
this.c = c;
this.wrappedInventory = new WrapperInvItemHandler(par1iInventory);
this.wrappedInventory = new WrapperInvItemHandler(inv);
}
@Override
@@ -82,7 +82,7 @@ public class CraftingTermSlot extends AppEngCraftingSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
@@ -24,17 +24,17 @@ import net.minecraftforge.items.IItemHandler;
public class DisabledSlot extends AppEngSlot {
public DisabledSlot(final IItemHandler par1iInventory, final int slotIndex, final int x, final int y) {
super(par1iInventory, slotIndex, x, y);
public DisabledSlot(final IItemHandler par1iInventory, final int invSlot, final int x, final int y) {
super(par1iInventory, invSlot, x, y);
}
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
}
@@ -22,8 +22,8 @@ import net.minecraftforge.items.IItemHandler;
public class FakeBlacklistSlot extends FakeTypeOnlySlot {
public FakeBlacklistSlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(inv, idx, x, y);
public FakeBlacklistSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
}
@Override
@@ -22,7 +22,7 @@ import net.minecraftforge.items.IItemHandler;
public class FakeCraftingMatrixSlot extends FakeSlot {
public FakeCraftingMatrixSlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(inv, idx, x, y);
public FakeCraftingMatrixSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
}
}
@@ -24,8 +24,8 @@ import net.minecraftforge.items.IItemHandler;
public class FakeSlot extends AppEngSlot {
public FakeSlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(inv, idx, x, y);
public FakeSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
}
@Override
@@ -39,7 +39,7 @@ public class FakeSlot extends AppEngSlot {
}
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -53,7 +53,7 @@ public class FakeSlot extends AppEngSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
}
@@ -23,8 +23,8 @@ import net.minecraftforge.items.IItemHandler;
public class FakeTypeOnlySlot extends FakeSlot {
public FakeTypeOnlySlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(inv, idx, x, y);
public FakeTypeOnlySlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
}
@Override
@@ -26,12 +26,12 @@ public class InaccessibleSlot extends AppEngSlot {
private ItemStack dspStack = ItemStack.EMPTY;
public InaccessibleSlot(final IItemHandler i, final int slotIdx, final int x, final int y) {
super(i, slotIdx, x, y);
public InaccessibleSlot(final IItemHandler i, final int invSlot, final int x, final int y) {
super(i, invSlot, x, y);
}
@Override
public boolean isItemValid(final ItemStack i) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -42,7 +42,7 @@ public class InaccessibleSlot extends AppEngSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
@@ -27,14 +27,14 @@ public class MolecularAssemblerPatternSlot extends AppEngSlot {
private final MolecularAssemblerContainer mac;
public MolecularAssemblerPatternSlot(final MolecularAssemblerContainer mac, final IItemHandler i, final int slotIdx,
final int x, final int y) {
super(i, slotIdx, x, y);
public MolecularAssemblerPatternSlot(final MolecularAssemblerContainer mac, final IItemHandler inv,
final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
this.mac = mac;
}
@Override
public boolean isItemValid(final ItemStack i) {
return this.mac.isValidItemForSlot(this.getSlotIndex(), i);
public boolean isItemValid(final ItemStack stack) {
return this.mac.isValidItemForSlot(this.getSlotIndex(), stack);
}
}
@@ -22,7 +22,7 @@ import net.minecraftforge.items.IItemHandler;
public class NormalSlot extends AppEngSlot {
public NormalSlot(final IItemHandler inv, final int slot, final int xPos, final int yPos) {
super(inv, slot, xPos, yPos);
public NormalSlot(final IItemHandler inv, final int invSlot, final int xPos, final int yPos) {
super(inv, invSlot, xPos, yPos);
}
}
@@ -31,9 +31,9 @@ public class OptionalFakeSlot extends FakeSlot implements IOptionalSlot {
private final IOptionalSlotHost host;
private boolean renderDisabled = true;
public OptionalFakeSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int idx, final int x,
final int y, final int offX, final int offY, final int groupNum) {
super(inv, idx, x + offX * 18, y + offY * 18);
public OptionalFakeSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int invSlot,
final int x, final int y, final int offX, final int offY, final int groupNum) {
super(inv, invSlot, x + offX * 18, y + offY * 18);
this.srcX = x;
this.srcY = y;
this.groupNum = groupNum;
@@ -25,9 +25,9 @@ public class OptionalNormalSlot extends AppEngSlot implements IOptionalSlot {
private final int groupNum;
private final IOptionalSlotHost host;
public OptionalNormalSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int slot,
public OptionalNormalSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int invSlot,
final int xPos, final int yPos, final int groupNum) {
super(inv, slot, xPos, yPos);
super(inv, invSlot, xPos, yPos);
this.groupNum = groupNum;
this.host = containerBus;
}
@@ -26,9 +26,10 @@ public class OptionalRestrictedInputSlot extends RestrictedInputSlot {
private final int groupNum;
private final IOptionalSlotHost host;
public OptionalRestrictedInputSlot(final PlacableItemType valid, final IItemHandler i, final IOptionalSlotHost host,
final int slotIndex, final int x, final int y, final int grpNum, final PlayerInventory invPlayer) {
super(valid, i, slotIndex, x, y, invPlayer);
public OptionalRestrictedInputSlot(final PlacableItemType valid, final IItemHandler inv,
final IOptionalSlotHost host, final int invSlot, final int x, final int y, final int grpNum,
final PlayerInventory invPlayer) {
super(valid, inv, invSlot, x, y, invPlayer);
this.groupNum = grpNum;
this.host = host;
}
@@ -23,9 +23,9 @@ import net.minecraftforge.items.IItemHandler;
public class OptionalTypeOnlyFakeSlot extends OptionalFakeSlot {
public OptionalTypeOnlyFakeSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int idx,
public OptionalTypeOnlyFakeSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int invSlot,
final int x, final int y, final int offX, final int offY, final int groupNum) {
super(inv, containerBus, idx, x, y, offX, offY, groupNum);
super(inv, containerBus, invSlot, x, y, offX, offY, groupNum);
}
@Override
@@ -23,13 +23,13 @@ import net.minecraftforge.items.IItemHandler;
public class OutputSlot extends AppEngSlot {
public OutputSlot(final IItemHandler a, final int b, final int c, final int d, final int i) {
super(a, b, c, d);
this.setIIcon(i);
public OutputSlot(final IItemHandler inv, final int invSlot, final int x, final int y, final int iconIndex) {
super(inv, invSlot, x, y);
this.setIIcon(iconIndex);
}
@Override
public boolean isItemValid(final ItemStack i) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
}
@@ -22,9 +22,9 @@ import net.minecraftforge.items.IItemHandler;
public class PatternOutputsSlot extends OptionalFakeSlot {
public PatternOutputsSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int idx, final int x,
final int y, final int offX, final int offY, final int groupNum) {
super(inv, containerBus, idx, x, y, offX, offY, groupNum);
public PatternOutputsSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int invSlot,
final int x, final int y, final int offX, final int offY, final int groupNum) {
super(inv, containerBus, invSlot, x, y, offX, offY, groupNum);
}
@Override
@@ -22,8 +22,8 @@ import net.minecraftforge.items.IItemHandler;
public class PlayerHotBarSlot extends AppEngSlot {
public PlayerHotBarSlot(final IItemHandler par1iInventory, final int par2, final int par3, final int par4) {
super(par1iInventory, par2, par3, par4);
public PlayerHotBarSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
this.setPlayerSide(true);
}
}
@@ -24,8 +24,8 @@ import net.minecraftforge.items.IItemHandler;
public class PlayerInvSlot extends AppEngSlot {
public PlayerInvSlot(final IItemHandler par1iInventory, final int idx, final int x, final int y) {
super(par1iInventory, idx, x, y);
public PlayerInvSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
this.setPlayerSide(true);
}
@@ -70,9 +70,9 @@ public class RestrictedInputSlot extends AppEngSlot {
private boolean allowEdit = true;
private int stackLimit = -1;
public RestrictedInputSlot(final PlacableItemType valid, final IItemHandler i, final int slotIndex, final int x,
public RestrictedInputSlot(final PlacableItemType valid, final IItemHandler inv, final int invSlot, final int x,
final int y, final PlayerInventory p) {
super(i, slotIndex, x, y);
super(inv, invSlot, x, y);
this.which = valid;
this.setIIcon(valid.IIcon);
this.p = p;
@@ -99,20 +99,20 @@ public class RestrictedInputSlot extends AppEngSlot {
}
@Override
public boolean isItemValid(final ItemStack i) {
if (!this.getContainer().isValidForSlot(this, i)) {
public boolean isItemValid(final ItemStack stack) {
if (!this.getContainer().isValidForSlot(this, stack)) {
return false;
}
if (i.isEmpty()) {
if (stack.isEmpty()) {
return false;
}
if (i.getItem() == Items.AIR) {
if (stack.getItem() == Items.AIR) {
return false;
}
if (!super.isItemValid(i)) {
if (!super.isItemValid(stack)) {
return false;
}
@@ -127,7 +127,7 @@ public class RestrictedInputSlot extends AppEngSlot {
switch (this.which) {
case ENCODED_CRAFTING_PATTERN:
final ICraftingPatternDetails de = crafting.decodePattern(i, this.p.player.world);
final ICraftingPatternDetails de = crafting.decodePattern(stack, this.p.player.world);
if (de != null) {
return de.isCraftable();
}
@@ -135,19 +135,19 @@ public class RestrictedInputSlot extends AppEngSlot {
case VALID_ENCODED_PATTERN_W_OUTPUT:
case ENCODED_PATTERN_W_OUTPUT:
case ENCODED_PATTERN:
return crafting.isEncodedPattern(i);
return crafting.isEncodedPattern(stack);
case BLANK_PATTERN:
return materials.blankPattern().isSameAs(i);
return materials.blankPattern().isSameAs(stack);
case PATTERN:
return materials.blankPattern().isSameAs(i) || crafting.isEncodedPattern(i);
return materials.blankPattern().isSameAs(stack) || crafting.isEncodedPattern(stack);
case INSCRIBER_PLATE:
if (materials.namePress().isSameAs(i)) {
if (materials.namePress().isSameAs(stack)) {
return true;
}
return InscriberRecipes.isValidOptionalIngredient(p.player.world, i);
return InscriberRecipes.isValidOptionalIngredient(p.player.world, stack);
case INSCRIBER_INPUT:
return true;/*
@@ -157,46 +157,48 @@ public class RestrictedInputSlot extends AppEngSlot {
case METAL_INGOTS:
return isMetalIngot(i);
return isMetalIngot(stack);
case VIEW_CELL:
return items.viewCell().isSameAs(i);
return items.viewCell().isSameAs(stack);
case ORE:
return GrinderRecipes.isValidIngredient(p.player.world, i);
return GrinderRecipes.isValidIngredient(p.player.world, stack);
case FUEL:
return ForgeHooks.getBurnTime(i) > 0;
return ForgeHooks.getBurnTime(stack) > 0;
case POWERED_TOOL:
return Platform.isChargeable(i);
return Platform.isChargeable(stack);
case QE_SINGULARITY:
return materials.qESingularity().isSameAs(i);
return materials.qESingularity().isSameAs(stack);
case RANGE_BOOSTER:
return materials.wirelessBooster().isSameAs(i);
return materials.wirelessBooster().isSameAs(stack);
case SPATIAL_STORAGE_CELLS:
return i.getItem() instanceof ISpatialStorageCell
&& ((ISpatialStorageCell) i.getItem()).isSpatialStorage(i);
return stack.getItem() instanceof ISpatialStorageCell
&& ((ISpatialStorageCell) stack.getItem()).isSpatialStorage(stack);
case STORAGE_CELLS:
return Api.instance().registries().cell().isCellHandled(i);
return Api.instance().registries().cell().isCellHandled(stack);
case WORKBENCH_CELL:
return i.getItem() instanceof ICellWorkbenchItem && ((ICellWorkbenchItem) i.getItem()).isEditable(i);
return stack.getItem() instanceof ICellWorkbenchItem
&& ((ICellWorkbenchItem) stack.getItem()).isEditable(stack);
case STORAGE_COMPONENT:
return i.getItem() instanceof IStorageComponent
&& ((IStorageComponent) i.getItem()).isStorageComponent(i);
return stack.getItem() instanceof IStorageComponent
&& ((IStorageComponent) stack.getItem()).isStorageComponent(stack);
case TRASH:
if (Api.instance().registries().cell().isCellHandled(i)) {
if (Api.instance().registries().cell().isCellHandled(stack)) {
return false;
}
return !(i.getItem() instanceof IStorageComponent
&& ((IStorageComponent) i.getItem()).isStorageComponent(i));
return !(stack.getItem() instanceof IStorageComponent
&& ((IStorageComponent) stack.getItem()).isStorageComponent(stack));
case ENCODABLE_ITEM:
return i.getItem() instanceof INetworkEncodable
|| Api.instance().registries().wireless().isWirelessTerminal(i);
return stack.getItem() instanceof INetworkEncodable
|| Api.instance().registries().wireless().isWirelessTerminal(stack);
case BIOMETRIC_CARD:
return i.getItem() instanceof IBiometricCard;
return stack.getItem() instanceof IBiometricCard;
case UPGRADES:
return i.getItem() instanceof IUpgradeModule && ((IUpgradeModule) i.getItem()).getType(i) != null;
return stack.getItem() instanceof IUpgradeModule
&& ((IUpgradeModule) stack.getItem()).getType(stack) != null;
default:
break;
}
@@ -205,7 +207,7 @@ public class RestrictedInputSlot extends AppEngSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return this.isAllowEdit();
}
+27
View File
@@ -31,6 +31,8 @@ import java.util.Set;
import java.util.function.DoubleSupplier;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import com.google.common.base.Strings;
import org.apache.commons.lang3.tuple.Pair;
@@ -393,6 +395,15 @@ public final class AEConfig {
return this.meteoriteDimensionWhitelist;
}
@Nullable
public String getImprovedFluidTag() {
return Strings.emptyToNull(COMMON.improvedFluidTag.get());
}
public float getImprovedFluidMultiplier() {
return COMMON.improvedFluidMultiplier.get().floatValue();
}
// Setters keep visibility as low as possible.
private static class ClientConfig {
@@ -507,6 +518,11 @@ public final class AEConfig {
public final ConfigValue<Integer> condenserMatterBallsPower;
public final ConfigValue<Integer> condenserSingularityPower;
// In-World Purification
// Settings for improved speed depending on fluid the crystal is in
public final ConfigValue<String> improvedFluidTag;
public final ConfigValue<Double> improvedFluidMultiplier;
public final Map<TickRates, ConfigValue<Integer>> tickRateMin = new HashMap<>();
public final Map<TickRates, ConfigValue<Integer>> tickRateMax = new HashMap<>();
@@ -617,6 +633,17 @@ public final class AEConfig {
tickRateMax.put(tickRate, builder.define(tickRate.name() + "Max", tickRate.getDefaultMax()));
}
builder.pop();
builder.comment("Settings for in-world purification of crystals.").push("inWorldPurification");
improvedFluidTag = builder.comment(
"A fluid tag that identifies fluids that improve crystal purification speed. Does not affect purification with water/lava.")
.define("improvedFluidTag", "");
improvedFluidMultiplier = builder
.comment("The speed multiplier to use when the crystals are submerged in the improved fluid.")
.defineInRange("improvedFluidMultiplier", 2.0, 1.0, 10.0);
builder.pop();
}
}
+1 -57
View File
@@ -19,7 +19,6 @@
package appeng.core;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import javax.annotation.Nonnull;
@@ -40,8 +39,6 @@ import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.structure.Structure;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
@@ -56,29 +53,10 @@ import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import appeng.block.paint.PaintSplotchesModel;
import appeng.block.qnb.QnbFormedModel;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.IInitComponent;
import appeng.bootstrap.components.IPostInitComponent;
import appeng.capabilities.Capabilities;
import appeng.client.ClientHelper;
import appeng.client.render.DummyFluidItemModel;
import appeng.client.render.FacadeItemModel;
import appeng.client.render.SimpleModelLoader;
import appeng.client.render.cablebus.CableBusModelLoader;
import appeng.client.render.cablebus.P2PTunnelFrequencyModel;
import appeng.client.render.crafting.CraftingCubeModelLoader;
import appeng.client.render.crafting.EncodedPatternModelLoader;
import appeng.client.render.model.BiometricCardModel;
import appeng.client.render.model.ColorApplicatorModel;
import appeng.client.render.model.DriveModel;
import appeng.client.render.model.GlassModel;
import appeng.client.render.model.MemoryCardModel;
import appeng.client.render.model.SkyCompassModel;
import appeng.client.render.model.UVLModelLoader;
import appeng.client.render.spatial.SpatialPylonModel;
import appeng.core.features.registries.PartModels;
import appeng.core.stats.AdvancementTriggers;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.worlddata.WorldData;
@@ -90,7 +68,6 @@ import appeng.entity.TinyTNTPrimedRenderer;
import appeng.hooks.TickHandler;
import appeng.integration.Integrations;
import appeng.parts.PartPlacement;
import appeng.parts.automation.PlaneModelLoader;
import appeng.server.ServerHelper;
@Mod(AppEng.MOD_ID)
@@ -117,7 +94,7 @@ public final class AppEng {
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, AEConfig.CLIENT_SPEC);
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AEConfig.COMMON_SPEC);
proxy = DistExecutor.safeRunForDist(() -> ClientHelper::new, () -> ServerHelper::new);
proxy = DistExecutor.unsafeRunForDist(() -> ClientHelper::new, () -> ServerHelper::new);
CreativeTab.init();
new FacadeItemGroup(); // This call has a side-effect (adding it to the creative screen)
@@ -181,39 +158,6 @@ public final class AppEng {
RenderingRegistry.registerEntityRenderingHandler(ChargedQuartzEntity.TYPE,
m -> new ItemRenderer(m, Minecraft.getInstance().getItemRenderer()));
// TODO: Do not use the internal API
final ApiDefinitions definitions = Api.INSTANCE.definitions();
definitions.getRegistry().getBootstrapComponents(IClientSetupComponent.class)
.forEachRemaining(IClientSetupComponent::setup);
addBuiltInModel("glass", GlassModel::new);
addBuiltInModel("sky_compass", SkyCompassModel::new);
addBuiltInModel("dummy_fluid_item", DummyFluidItemModel::new);
addBuiltInModel("memory_card", MemoryCardModel::new);
addBuiltInModel("biometric_card", BiometricCardModel::new);
addBuiltInModel("drive", DriveModel::new);
addBuiltInModel("color_applicator", ColorApplicatorModel::new);
addBuiltInModel("spatial_pylon", SpatialPylonModel::new);
addBuiltInModel("paint_splotches", PaintSplotchesModel::new);
addBuiltInModel("quantum_bridge_formed", QnbFormedModel::new);
addBuiltInModel("p2p_tunnel_frequency", P2PTunnelFrequencyModel::new);
addBuiltInModel("facade", FacadeItemModel::new);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "encoded_pattern"),
EncodedPatternModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "part_plane"),
PlaneModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "crafting_cube"),
CraftingCubeModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "uvlightmap"), UVLModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "cable_bus"),
new CableBusModelLoader((PartModels) Api.INSTANCE.registries().partModels()));
}
@OnlyIn(Dist.CLIENT)
private static <T extends IModelGeometry<T>> void addBuiltInModel(String id, Supplier<T> modelFactory) {
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, id),
new SimpleModelLoader<>(modelFactory));
}
@Nonnull
+10 -2
View File
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerEntity;
@@ -55,11 +56,18 @@ public abstract class CommonHelper {
public abstract void postInit();
public abstract CableRenderMode getRenderMode();
public abstract CableRenderMode getCableRenderMode();
public abstract void triggerUpdates();
public abstract void updateRenderMode(PlayerEntity player);
/**
* Sets the player that is currently interacting with a cable or part attached
* to a cable. This will return that player's cable render mode from calls to
* {@link #getCableRenderMode()}, until another player or null is set.
*
* @param player Null to revert to the default cable render mode.
*/
public abstract void setPartInteractionPlayer(@Nullable PlayerEntity player);
public abstract boolean isActionKey(@Nonnull final ActionKey key, InputMappings.Input input);
+65 -8
View File
@@ -18,6 +18,8 @@
package appeng.core;
import java.util.function.Supplier;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@@ -50,7 +52,8 @@ import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.ParticleFactoryRegisterEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.IEventBus;
@@ -79,7 +82,10 @@ import appeng.api.networking.security.ISecurityGrid;
import appeng.api.networking.spatial.ISpatialCache;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.ITickManager;
import appeng.block.paint.PaintSplotchesModel;
import appeng.block.qnb.QnbFormedModel;
import appeng.bootstrap.components.IBlockRegistrationComponent;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.IEntityRegistrationComponent;
import appeng.bootstrap.components.IItemColorRegistrationComponent;
import appeng.bootstrap.components.IItemRegistrationComponent;
@@ -118,6 +124,13 @@ import appeng.client.gui.implementations.UpgradeableScreen;
import appeng.client.gui.implementations.VibrationChamberScreen;
import appeng.client.gui.implementations.WirelessScreen;
import appeng.client.gui.implementations.WirelessTermScreen;
import appeng.client.render.DummyFluidItemModel;
import appeng.client.render.FacadeItemModel;
import appeng.client.render.SimpleModelLoader;
import appeng.client.render.cablebus.CableBusModelLoader;
import appeng.client.render.cablebus.P2PTunnelFrequencyModel;
import appeng.client.render.crafting.CraftingCubeModelLoader;
import appeng.client.render.crafting.EncodedPatternModelLoader;
import appeng.client.render.effects.ChargedOreFX;
import appeng.client.render.effects.CraftingFx;
import appeng.client.render.effects.EnergyFx;
@@ -126,6 +139,13 @@ import appeng.client.render.effects.LightningFX;
import appeng.client.render.effects.MatterCannonFX;
import appeng.client.render.effects.ParticleTypes;
import appeng.client.render.effects.VibrantFX;
import appeng.client.render.model.BiometricCardModel;
import appeng.client.render.model.ColorApplicatorModel;
import appeng.client.render.model.DriveModel;
import appeng.client.render.model.GlassModel;
import appeng.client.render.model.MemoryCardModel;
import appeng.client.render.model.SkyCompassModel;
import appeng.client.render.spatial.SpatialPylonModel;
import appeng.client.render.tesr.InscriberTESR;
import appeng.client.render.tesr.SkyChestTESR;
import appeng.container.AEBaseContainer;
@@ -194,20 +214,21 @@ import appeng.me.cache.SecurityCache;
import appeng.me.cache.SpatialPylonCache;
import appeng.me.cache.TickManagerCache;
import appeng.mixins.StructureAccessor;
import appeng.parts.automation.PlaneModelLoader;
import appeng.recipes.game.DisassembleRecipe;
import appeng.recipes.game.FacadeRecipe;
import appeng.recipes.handlers.GrinderRecipe;
import appeng.recipes.handlers.GrinderRecipeSerializer;
import appeng.recipes.handlers.InscriberRecipe;
import appeng.recipes.handlers.InscriberRecipeSerializer;
import appeng.server.AECommand;
import appeng.spatial.StorageCellBiome;
import appeng.spatial.StorageChunkGenerator;
import appeng.spatial.SpatialStorageBiome;
import appeng.spatial.SpatialStorageChunkGenerator;
import appeng.spatial.SpatialStorageDimensionIds;
import appeng.tile.AEBaseTileEntity;
import appeng.tile.crafting.MolecularAssemblerRenderer;
import appeng.worldgen.ChargedQuartzOreConfig;
import appeng.worldgen.ChargedQuartzOreFeature;
import appeng.worldgen.meteorite.MeteoriteStructure;
import appeng.worldgen.meteorite.MeteoriteStructurePiece;
final class Registration {
@@ -239,6 +260,39 @@ final class Registration {
@OnlyIn(Dist.CLIENT)
public void modelRegistryEvent(ModelRegistryEvent event) {
registerSpecialModels();
// TODO: Do not use the internal API
final ApiDefinitions definitions = Api.INSTANCE.definitions();
definitions.getRegistry().getBootstrapComponents(IClientSetupComponent.class)
.forEachRemaining(IClientSetupComponent::setup);
addBuiltInModel("glass", GlassModel::new);
addBuiltInModel("sky_compass", SkyCompassModel::new);
addBuiltInModel("dummy_fluid_item", DummyFluidItemModel::new);
addBuiltInModel("memory_card", MemoryCardModel::new);
addBuiltInModel("biometric_card", BiometricCardModel::new);
addBuiltInModel("drive", DriveModel::new);
addBuiltInModel("color_applicator", ColorApplicatorModel::new);
addBuiltInModel("spatial_pylon", SpatialPylonModel::new);
addBuiltInModel("paint_splotches", PaintSplotchesModel::new);
addBuiltInModel("quantum_bridge_formed", QnbFormedModel::new);
addBuiltInModel("p2p_tunnel_frequency", P2PTunnelFrequencyModel::new);
addBuiltInModel("facade", FacadeItemModel::new);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "encoded_pattern"),
EncodedPatternModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "part_plane"),
PlaneModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "crafting_cube"),
CraftingCubeModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "cable_bus"),
new CableBusModelLoader((PartModels) Api.INSTANCE.registries().partModels()));
}
@OnlyIn(Dist.CLIENT)
private static <T extends IModelGeometry<T>> void addBuiltInModel(String id, Supplier<T> modelFactory) {
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, id),
new SimpleModelLoader<>(modelFactory));
}
/**
@@ -628,6 +682,8 @@ final class Registration {
new ResourceLocation(dimension));
}
MeteoriteStructurePiece.register();
ForgeRegistries.BIOMES.forEach(b -> {
addMeteoriteWorldGen(b);
addQuartzWorldGen(b);
@@ -687,11 +743,12 @@ final class Registration {
MeteoriteStructure.INSTANCE.setRegistryName(MeteoriteStructure.ID),
GenerationStage.Decoration.TOP_LAYER_MODIFICATION);
Registry.register(Registry.CHUNK_GENERATOR_CODEC, AppEng.makeId("storage"), StorageChunkGenerator.CODEC);
Registry.register(Registry.CHUNK_GENERATOR_CODEC, SpatialStorageDimensionIds.CHUNK_GENERATOR_ID,
SpatialStorageChunkGenerator.CODEC);
}
public void registerBiomes(RegistryEvent.Register<Biome> evt) {
evt.getRegistry().register(StorageCellBiome.INSTANCE.setRegistryName(AppEng.makeId("storage")));
evt.getRegistry().register(SpatialStorageBiome.INSTANCE.setRegistryName(SpatialStorageDimensionIds.BIOME_ID));
}
@OnlyIn(Dist.CLIENT)
@@ -726,7 +783,7 @@ final class Registration {
modEventBus.addListener(this::registerParticleFactories);
modEventBus.addListener(this::registerTextures);
MinecraftForge.EVENT_BUS.addListener(this::modelRegistryEvent);
modEventBus.addListener(this::modelRegistryEvent);
modEventBus.addListener(this::registerItemColors);
modEventBus.addListener(this::handleModelBake);
}
@@ -115,7 +115,12 @@ public class ApiCrafting implements ICraftingHelper {
// We use the shared itemstack for an identity lookup.
IAEItemStack ais = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(is);
return new CraftingPatternDetails(ais, world);
try {
return new CraftingPatternDetails(ais, world);
} catch (IllegalStateException e) {
AELog.warn("Could not decode an invalid pattern %s: %s", is, e);
return null;
}
}
private boolean attemptRecovery(EncodedPatternItem patternItem, ItemStack itemStack, World world) {
+1 -1
View File
@@ -41,6 +41,6 @@ public class ApiPart implements IPartHelper {
@Override
public CableRenderMode getCableRenderMode() {
return AppEng.proxy.getRenderMode();
return AppEng.proxy.getCableRenderMode();
}
}
@@ -20,7 +20,9 @@ package appeng.core.api.definitions;
import static appeng.block.AEBaseBlock.defaultProps;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.block.DispenserBlock;
import net.minecraft.block.SlabBlock;
import net.minecraft.block.SoundType;
@@ -28,6 +30,7 @@ import net.minecraft.block.StairsBlock;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.entity.EntityClassification;
import net.minecraft.entity.EntityType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.ToolType;
@@ -39,6 +42,7 @@ import appeng.api.features.AEFeature;
import appeng.block.AEBaseBlockItemChargeable;
import appeng.block.crafting.AbstractCraftingUnitBlock.CraftingUnitType;
import appeng.block.crafting.CraftingMonitorBlock;
import appeng.block.crafting.CraftingMonitorBlockRendering;
import appeng.block.crafting.CraftingStorageBlock;
import appeng.block.crafting.CraftingStorageItem;
import appeng.block.crafting.CraftingUnitBlock;
@@ -94,9 +98,8 @@ import appeng.bootstrap.components.IInitComponent;
import appeng.bootstrap.definitions.TileEntityDefinition;
import appeng.client.render.crafting.CraftingCubeRendering;
import appeng.client.render.crafting.CraftingMonitorTESR;
import appeng.client.render.crafting.MonitorBakedModel;
import appeng.client.render.model.AutoRotatingBakedModel;
import appeng.client.render.spatial.SpatialPylonRendering;
import appeng.client.render.tesr.ChargerTESR;
import appeng.client.render.tesr.ChestTileEntityRenderer;
import appeng.client.render.tesr.CrankTESR;
import appeng.client.render.tesr.DriveLedTileEntityRenderer;
@@ -262,18 +265,20 @@ public final class ApiBlocks implements IBlocks {
this.chiseledQuartzBlock = deco.block("chiseled_quartz_block", () -> new AEDecorativeBlock(QUARTZ_PROPERTIES))
.build();
this.quartzGlass = registry.features(AEFeature.QUARTZ_GLASS)
.block("quartz_glass", () -> new QuartzGlassBlock(defaultProps(Material.GLASS).notSolid()))
.rendering(new BlockRenderingCustomizer() {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderType.getCutout());
}
}).build();
AbstractBlock.IExtendedPositionPredicate<EntityType<?>> neverAllowSpawn = (p1, p2, p3, p4) -> false;
this.quartzGlass = registry.features(AEFeature.QUARTZ_GLASS).block("quartz_glass", () -> {
return new QuartzGlassBlock(defaultProps(Material.GLASS).notSolid().setAllowsSpawn(neverAllowSpawn));
}).rendering(new BlockRenderingCustomizer() {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderType.getCutout());
}
}).build();
this.quartzVibrantGlass = deco
.block("quartz_vibrant_glass",
() -> new QuartzLampBlock(defaultProps(Material.GLASS).setLightLevel(b -> 15).notSolid()))
() -> new QuartzLampBlock(defaultProps(Material.GLASS).setLightLevel(b -> 15).notSolid()
.setAllowsSpawn(neverAllowSpawn)))
.addFeatures(AEFeature.DECORATIVE_LIGHTS, AEFeature.QUARTZ_GLASS)
.rendering(new BlockRenderingCustomizer() {
@Override
@@ -371,7 +376,7 @@ public final class ApiBlocks implements IBlocks {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(TileEntityRendering<ChargerTileEntity> rendering) {
rendering.tileEntityRenderer(ChargerBlock.createTesr());
rendering.tileEntityRenderer(ChargerTESR.FACTORY);
}
}).build())
.build();
@@ -532,20 +537,7 @@ public final class ApiBlocks implements IBlocks {
rendering.tileEntityRenderer(CraftingMonitorTESR::new);
}
}).build())
.rendering(new BlockRenderingCustomizer() {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderType.getCutout());
rendering.modelCustomizer((path, model) -> {
// The formed model handles rotations itself, the unformed one does not
if (model instanceof MonitorBakedModel) {
return model;
}
return new AutoRotatingBakedModel(model);
});
}
}).build();
.rendering(new CraftingMonitorBlockRendering()).build();
this.molecularAssembler = registry
.block("molecular_assembler", () -> new MolecularAssemblerBlock(defaultProps(Material.IRON).notSolid()))
@@ -23,6 +23,9 @@ import java.util.function.Consumer;
import net.minecraft.entity.EntityClassification;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.item.Rarity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.ToolType;
@@ -35,6 +38,8 @@ import appeng.api.util.AEColoredItemDefinition;
import appeng.bootstrap.FeatureFactory;
import appeng.bootstrap.IItemRendering;
import appeng.bootstrap.ItemRenderingCustomizer;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.core.AppEng;
import appeng.core.features.ActivityState;
import appeng.core.features.ColoredItemDefinition;
import appeng.core.features.ItemStackSrc;
@@ -51,6 +56,7 @@ import appeng.hooks.BlockToolDispenseItemBehavior;
import appeng.hooks.MatterCannonDispenseItemBehavior;
import appeng.items.materials.MaterialType;
import appeng.items.misc.CrystalSeedItem;
import appeng.items.misc.CrystalSeedRendering;
import appeng.items.misc.EncodedPatternItem;
import appeng.items.misc.PaintBallItem;
import appeng.items.misc.PaintBallItemRendering;
@@ -210,7 +216,22 @@ public final class ApiItems implements IItems {
.addFeatures(AEFeature.PORTABLE_CELL, AEFeature.STORAGE_CELLS).build();
this.colorApplicator = powerTools.item("color_applicator", ColorApplicatorItem::new).props(chargedDefaults)
.addFeatures(AEFeature.COLOR_APPLICATOR).dispenserBehavior(BlockToolDispenseItemBehavior::new)
.rendering(new ColorApplicatorItemRendering()).build();
.bootstrap(item -> new IClientSetupComponent() {
@Override
@OnlyIn(Dist.CLIENT)
public void setup() {
ColorApplicatorItem colorApplicatorItem = (ColorApplicatorItem) item;
ItemModelsProperties.func_239418_a_(item, new ResourceLocation(AppEng.MOD_ID, "colored"),
(itemStack, world, entity) -> {
// 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
// re-search its
// inventory for a new paintball everytime
AEColor col = colorApplicatorItem.getActiveColor(itemStack);
return (col != null) ? 1 : 0;
});
}
}).rendering(new ColorApplicatorItemRendering()).build();
this.biometricCard = registry.item("biometric_card", BiometricCardItem::new)
.props(props -> props.maxStackSize(1)).features(AEFeature.SECURITY).build();
@@ -221,7 +242,8 @@ public final class ApiItems implements IItems {
.features(AEFeature.NETWORK_TOOL).build();
this.cellCreative = registry.item("creative_storage_cell", CreativeStorageCellItem::new)
.props(props -> props.maxStackSize(1)).features(AEFeature.STORAGE_CELLS, AEFeature.CREATIVE).build();
.props(props -> props.maxStackSize(1).rarity(Rarity.EPIC))
.features(AEFeature.STORAGE_CELLS, AEFeature.CREATIVE).build();
this.viewCell = registry.item("view_cell", ViewCellItem::new).props(props -> props.maxStackSize(1))
.features(AEFeature.VIEW_CELL).build();
@@ -278,15 +300,15 @@ public final class ApiItems implements IItems {
this.certusCrystalSeed = registry
.item("certus_crystal_seed",
props -> new CrystalSeedItem(props, materials.purifiedCertusQuartzCrystal().item()))
.features(AEFeature.CRYSTAL_SEEDS).build();
.bootstrap(CrystalSeedRendering::new).features(AEFeature.CRYSTAL_SEEDS).build();
this.fluixCrystalSeed = registry
.item("fluix_crystal_seed",
props -> new CrystalSeedItem(props, materials.purifiedFluixCrystal().item()))
.features(AEFeature.CRYSTAL_SEEDS).build();
.bootstrap(CrystalSeedRendering::new).features(AEFeature.CRYSTAL_SEEDS).build();
this.netherQuartzSeed = registry
.item("nether_quartz_seed",
props -> new CrystalSeedItem(props, materials.purifiedNetherQuartzCrystal().item()))
.features(AEFeature.CRYSTAL_SEEDS).build();
.bootstrap(CrystalSeedRendering::new).features(AEFeature.CRYSTAL_SEEDS).build();
GrowingCrystalEntity.TYPE = registry
.<GrowingCrystalEntity>entity("growing_crystal", GrowingCrystalEntity::new, EntityClassification.MISC)
@@ -22,12 +22,12 @@ import java.util.HashMap;
import java.util.Map;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import appeng.api.events.LocatableEventAnnounce;
import appeng.api.events.LocatableEventAnnounce.LocatableEvent;
import appeng.api.features.ILocatable;
import appeng.api.features.ILocatableRegistry;
import appeng.core.AELog;
import appeng.util.Platform;
public final class LocatableRegistry implements ILocatableRegistry {
@@ -35,18 +35,19 @@ public final class LocatableRegistry implements ILocatableRegistry {
public LocatableRegistry() {
this.set = new HashMap<>();
MinecraftForge.EVENT_BUS.register(this);
MinecraftForge.EVENT_BUS.addListener(this::updateLocatable);
}
@SubscribeEvent
public void updateLocatable(final LocatableEventAnnounce e) {
private void updateLocatable(final LocatableEventAnnounce e) {
if (Platform.isClient()) {
return; // IGNORE!
}
if (e.change == LocatableEvent.REGISTER) {
AELog.debug("Registering locatable %s: %s", e.target.getLocatableSerial(), e.target);
this.set.put(e.target.getLocatableSerial(), e.target);
} else if (e.change == LocatableEvent.UNREGISTER) {
AELog.debug("Unregistering locatable %s: %s", e.target.getLocatableSerial(), e.target);
this.set.remove(e.target.getLocatableSerial());
}
}
@@ -29,7 +29,6 @@ import appeng.core.sync.packets.BlockTransitionEffectPacket;
import appeng.core.sync.packets.ClickPacket;
import appeng.core.sync.packets.CompassRequestPacket;
import appeng.core.sync.packets.CompassResponsePacket;
import appeng.core.sync.packets.CompressedNBTPacket;
import appeng.core.sync.packets.ConfigButtonPacket;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.core.sync.packets.CraftRequestPacket;
@@ -39,6 +38,7 @@ import appeng.core.sync.packets.ItemTransitionEffectPacket;
import appeng.core.sync.packets.JEIRecipePacket;
import appeng.core.sync.packets.LightningPacket;
import appeng.core.sync.packets.MEFluidInventoryUpdatePacket;
import appeng.core.sync.packets.MEInterfaceUpdatePacket;
import appeng.core.sync.packets.MEInventoryUpdatePacket;
import appeng.core.sync.packets.MatterCannonPacket;
import appeng.core.sync.packets.MockExplosionPacket;
@@ -101,7 +101,7 @@ public class BasePacketHandler {
PACKET_ASSEMBLER_ANIMATION(AssemblerAnimationPacket.class, AssemblerAnimationPacket::new),
PACKET_COMPRESSED_NBT(CompressedNBTPacket.class, CompressedNBTPacket::new),
PACKET_ME_INTERFACE_UPDATE(MEInterfaceUpdatePacket.class, MEInterfaceUpdatePacket::new),
PACKET_PAINTED_ENTITY(PaintedEntityPacket.class, PaintedEntityPacket::new),
@@ -19,13 +19,9 @@
package appeng.core.sync.packets;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.BufferOverflowException;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.annotation.Nullable;
@@ -41,7 +37,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.network.NetworkDirection;
import appeng.api.storage.data.IAEFluidStack;
import appeng.core.AELog;
import appeng.core.sync.BasePacket;
import appeng.core.sync.network.INetworkInfo;
import appeng.fluids.client.gui.FluidTerminalScreen;
@@ -55,8 +50,6 @@ import appeng.fluids.util.AEFluidStack;
public class MEFluidInventoryUpdatePacket extends BasePacket {
private static final int UNCOMPRESSED_PACKET_BYTE_LIMIT = 16 * 1024 * 1024;
private static final int OPERATION_BYTE_LIMIT = 2 * 1024;
private static final int TEMP_BUFFER_SIZE = 1024;
private static final int STREAM_MASK = 0xff;
// input.
@Nullable
@@ -66,47 +59,18 @@ public class MEFluidInventoryUpdatePacket extends BasePacket {
@Nullable
private final PacketBuffer data;
@Nullable
private final GZIPOutputStream compressFrame;
private int writtenBytes = 0;
private boolean empty = true;
public MEFluidInventoryUpdatePacket(final PacketBuffer stream) {
this.data = null;
this.compressFrame = null;
this.list = new LinkedList<>();
this.ref = stream.readByte();
try (final GZIPInputStream gzReader = new GZIPInputStream(new InputStream() {
@Override
public int read() {
if (stream.readableBytes() <= 0) {
return -1;
}
return stream.readByte() & STREAM_MASK;
}
})) {
final PacketBuffer uncompressed = new PacketBuffer(Unpooled.buffer(stream.readableBytes()));
final byte[] tmp = new byte[TEMP_BUFFER_SIZE];
while (gzReader.available() != 0) {
final int bytes = gzReader.read(tmp);
if (bytes > 0) {
uncompressed.writeBytes(tmp, 0, bytes);
}
}
while (uncompressed.readableBytes() > 0) {
this.list.add(AEFluidStack.fromPacket(uncompressed));
}
} catch (IOException e) {
throw new RuntimeException("Failed to decompress packet.", e);
while (stream.readableBytes() > 0) {
this.list.add(AEFluidStack.fromPacket(stream));
}
this.empty = this.list.isEmpty();
}
@@ -121,14 +85,6 @@ public class MEFluidInventoryUpdatePacket extends BasePacket {
this.data = new PacketBuffer(Unpooled.buffer(OPERATION_BYTE_LIMIT));
this.data.writeInt(this.getPacketID());
this.data.writeByte(this.ref);
this.compressFrame = new GZIPOutputStream(new OutputStream() {
@Override
public void write(final int value) {
MEFluidInventoryUpdatePacket.this.data.writeByte(value);
}
});
this.list = null;
}
@@ -145,28 +101,19 @@ public class MEFluidInventoryUpdatePacket extends BasePacket {
@Nullable
@Override
public IPacket<?> toPacket(NetworkDirection direction) {
try {
this.compressFrame.close();
this.configureWrite(this.data);
return super.toPacket(direction);
} catch (final IOException e) {
AELog.debug(e);
}
return null;
this.configureWrite(this.data);
return super.toPacket(direction);
}
public void appendFluid(final IAEFluidStack fs) throws IOException, BufferOverflowException {
final PacketBuffer tmp = new PacketBuffer(Unpooled.buffer(OPERATION_BYTE_LIMIT));
fs.writeToPacket(tmp);
this.compressFrame.flush();
if (this.writtenBytes + tmp.readableBytes() > UNCOMPRESSED_PACKET_BYTE_LIMIT) {
throw new BufferOverflowException();
} else {
this.writtenBytes += tmp.readableBytes();
this.compressFrame.write(tmp.array(), 0, tmp.readableBytes());
this.data.writeBytes(tmp.array(), 0, tmp.readableBytes());
this.empty = false;
}
}
@@ -18,13 +18,7 @@
package appeng.core.sync.packets;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import io.netty.buffer.Unpooled;
@@ -32,7 +26,6 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@@ -41,55 +34,24 @@ import appeng.client.gui.implementations.InterfaceTerminalScreen;
import appeng.core.sync.BasePacket;
import appeng.core.sync.network.INetworkInfo;
//TODO, this is pointless, NBT is already compressed when written to a PacketBuffer.
public class CompressedNBTPacket extends BasePacket {
public class MEInterfaceUpdatePacket extends BasePacket {
// input.
private final CompoundNBT in;
// output...
private final PacketBuffer data;
private final GZIPOutputStream compressFrame;
public CompressedNBTPacket(final PacketBuffer stream) {
public MEInterfaceUpdatePacket(final PacketBuffer stream) {
this.data = null;
this.compressFrame = null;
try (DataInputStream inStream = new DataInputStream(new GZIPInputStream(new InputStream() {
@Override
public int read() {
if (stream.readableBytes() <= 0) {
return -1;
}
return stream.readByte() & 0xff;
}
}))) {
this.in = CompressedStreamTools.read(inStream);
} catch (IOException e) {
throw new RuntimeException("Failed to decompress packet.", e);
}
this.in = stream.readCompoundTag();
}
// api
public CompressedNBTPacket(final CompoundNBT din) throws IOException {
public MEInterfaceUpdatePacket(final CompoundNBT din) throws IOException {
this.in = null;
this.data = new PacketBuffer(Unpooled.buffer(2048));
this.data.writeInt(this.getPacketID());
this.in = din;
this.compressFrame = new GZIPOutputStream(new OutputStream() {
@Override
public void write(final int value) {
CompressedNBTPacket.this.data.writeByte(value);
}
});
CompressedStreamTools.write(din, new DataOutputStream(this.compressFrame));
this.compressFrame.close();
this.data.writeCompoundTag(din);
this.configureWrite(this.data);
}
@@ -19,12 +19,10 @@
package appeng.core.sync.packets;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.BufferOverflowException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.annotation.Nullable;
@@ -45,7 +43,6 @@ import appeng.client.gui.implementations.CraftConfirmScreen;
import appeng.client.gui.implementations.CraftingCPUScreen;
import appeng.client.gui.implementations.MEMonitorableScreen;
import appeng.client.gui.implementations.NetworkStatusScreen;
import appeng.core.AELog;
import appeng.core.sync.BasePacket;
import appeng.core.sync.network.INetworkInfo;
import appeng.util.item.AEItemStack;
@@ -53,8 +50,6 @@ import appeng.util.item.AEItemStack;
public class MEInventoryUpdatePacket extends BasePacket {
private static final int UNCOMPRESSED_PACKET_BYTE_LIMIT = 16 * 1024 * 1024;
private static final int OPERATION_BYTE_LIMIT = 2 * 1024;
private static final int TEMP_BUFFER_SIZE = 1024;
private static final int STREAM_MASK = 0xff;
// input.
@Nullable
@@ -64,48 +59,18 @@ public class MEInventoryUpdatePacket extends BasePacket {
@Nullable
private final PacketBuffer data;
@Nullable
private final GZIPOutputStream compressFrame;
private int writtenBytes = 0;
private boolean empty = true;
public MEInventoryUpdatePacket(final PacketBuffer stream) {
this.data = null;
this.compressFrame = null;
this.list = new ArrayList<>();
this.ref = stream.readByte();
// int originalBytes = stream.readableBytes();
try (GZIPInputStream gzReader = new GZIPInputStream(new InputStream() {
@Override
public int read() {
if (stream.readableBytes() <= 0) {
return -1;
}
return stream.readByte() & STREAM_MASK;
}
})) {
final PacketBuffer uncompressed = new PacketBuffer(Unpooled.buffer(stream.readableBytes()));
final byte[] tmp = new byte[TEMP_BUFFER_SIZE];
while (gzReader.available() != 0) {
final int bytes = gzReader.read(tmp);
if (bytes > 0) {
uncompressed.writeBytes(tmp, 0, bytes);
}
}
while (uncompressed.readableBytes() > 0) {
this.list.add(AEItemStack.fromPacket(uncompressed));
}
} catch (IOException e) {
throw new RuntimeException("Failed to decompress packet.", e);
while (stream.readableBytes() > 0) {
this.list.add(AEItemStack.fromPacket(stream));
}
this.empty = this.list.isEmpty();
}
@@ -120,14 +85,6 @@ public class MEInventoryUpdatePacket extends BasePacket {
this.data = new PacketBuffer(Unpooled.buffer(OPERATION_BYTE_LIMIT));
this.data.writeInt(this.getPacketID());
this.data.writeByte(this.ref);
this.compressFrame = new GZIPOutputStream(new OutputStream() {
@Override
public void write(final int value) {
MEInventoryUpdatePacket.this.data.writeByte(value);
}
});
this.list = null;
}
@@ -156,28 +113,19 @@ public class MEInventoryUpdatePacket extends BasePacket {
@Nullable
@Override
public IPacket<?> toPacket(NetworkDirection direction) {
try {
this.compressFrame.close();
this.configureWrite(this.data);
return super.toPacket(direction);
} catch (final IOException e) {
AELog.debug(e);
}
return null;
this.configureWrite(this.data);
return super.toPacket(direction);
}
public void appendItem(final IAEItemStack is) throws IOException, BufferOverflowException {
final PacketBuffer tmp = new PacketBuffer(Unpooled.buffer(OPERATION_BYTE_LIMIT));
is.writeToPacket(tmp);
this.compressFrame.flush();
if (this.writtenBytes + tmp.readableBytes() > UNCOMPRESSED_PACKET_BYTE_LIMIT) {
throw new BufferOverflowException();
} else {
this.writtenBytes += tmp.readableBytes();
this.compressFrame.write(tmp.array(), 0, tmp.readableBytes());
this.data.writeBytes(tmp.array(), 0, tmp.readableBytes());
this.empty = false;
}
}
@@ -68,11 +68,14 @@ public class PartPlacementPacket extends BasePacket {
@Override
public void serverPacketData(final INetworkInfo manager, final PlayerEntity player) {
final ServerPlayerEntity sender = (ServerPlayerEntity) player;
AppEng.proxy.updateRenderMode(sender);
PartPlacement.setEyeHeight(this.eyeHeight);
PartPlacement.place(sender.getHeldItem(this.hand), new BlockPos(this.x, this.y, this.z),
Direction.values()[this.face], sender, this.hand, sender.world,
PartPlacement.PlaceType.INTERACT_FIRST_PASS, 0);
AppEng.proxy.updateRenderMode(null);
AppEng.proxy.setPartInteractionPlayer(sender);
try {
PartPlacement.setEyeHeight(this.eyeHeight);
PartPlacement.place(sender.getHeldItem(this.hand), new BlockPos(this.x, this.y, this.z),
Direction.values()[this.face], sender, this.hand, sender.world,
PartPlacement.PlaceType.INTERACT_FIRST_PASS, 0);
} finally {
AppEng.proxy.setPartInteractionPlayer(null);
}
}
}
@@ -20,11 +20,8 @@ package appeng.decorative.solid;
import net.minecraft.block.AbstractGlassBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.util.Direction;
import appeng.helpers.AEMaterials;
public class QuartzGlassBlock extends AbstractGlassBlock {
public QuartzGlassBlock(Properties props) {
@@ -33,8 +30,7 @@ public class QuartzGlassBlock extends AbstractGlassBlock {
@Override
public boolean isSideInvisible(BlockState state, BlockState adjacentBlockState, Direction side) {
final Material mat = adjacentBlockState.getMaterial();
if (mat == Material.GLASS || mat == AEMaterials.GLASS) {
if (adjacentBlockState.getBlock() instanceof QuartzGlassBlock) {
if (adjacentBlockState.getRenderType() == state.getRenderType()) {
return true;
}
@@ -29,7 +29,6 @@ import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.ToolType;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import appeng.block.AEBaseBlock;
import appeng.core.worlddata.WorldData;
@@ -43,11 +42,10 @@ public class SkyStoneBlock extends AEBaseBlock {
super(props);
this.type = type;
MinecraftForge.EVENT_BUS.register(this);
MinecraftForge.EVENT_BUS.addListener(this::breakFaster);
}
@SubscribeEvent
public void breakFaster(final PlayerEvent.BreakSpeed event) {
private void breakFaster(final PlayerEvent.BreakSpeed event) {
if (event.getState().getBlock() == this && event.getPlayer() != null) {
final ItemStack is = event.getPlayer().getItemStackFromSlot(EquipmentSlotType.MAINHAND);
int level = -1;
@@ -19,6 +19,7 @@
package appeng.entity;
import java.util.List;
import java.util.Random;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
@@ -42,6 +43,8 @@ import appeng.util.Platform;
public final class ChargedQuartzEntity extends AEBaseItemEntity {
private static final Random RANDOM = new Random();
public static EntityType<ChargedQuartzEntity> TYPE;
private int delay = 0;
@@ -135,9 +138,15 @@ public final class ChargedQuartzEntity extends AEBaseItemEntity {
}
materials.fluixCrystal().maybeStack(2).ifPresent(is -> {
final ItemEntity entity = new ItemEntity(this.world, this.getPosX(), this.getPosY(), this.getPosZ(),
is);
final double x = Math.floor(this.getPosX()) + .25d + RANDOM.nextDouble() * .5;
final double y = Math.floor(this.getPosY()) + .25d + RANDOM.nextDouble() * .5;
final double z = Math.floor(this.getPosZ()) + .25d + RANDOM.nextDouble() * .5;
final double xSpeed = RANDOM.nextDouble() * .25 - 0.125;
final double ySpeed = RANDOM.nextDouble() * .25 - 0.125;
final double zSpeed = RANDOM.nextDouble() * .25 - 0.125;
final ItemEntity entity = new ItemEntity(this.world, x, y, z, is);
entity.setMotion(xSpeed, ySpeed, zSpeed);
this.world.addEntity(entity);
});
@@ -19,13 +19,14 @@
package appeng.entity;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.entity.EntityType;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;
import appeng.api.features.AEFeature;
@@ -35,12 +36,27 @@ import appeng.client.EffectType;
import appeng.core.AEConfig;
import appeng.core.AppEng;
import appeng.items.misc.CrystalSeedItem;
import appeng.util.Platform;
public final class GrowingCrystalEntity extends AEBaseItemEntity {
public static EntityType<GrowingCrystalEntity> TYPE;
// Growth tick progress per tick by number of adjacent accelerators
// Expressed as 1/1000th of a growth tick, applied to progress_1000
// each time this entity ticks.
private static final int[] GROWTH_TICK_PROGRESS = { 1, // no accelerators
40, // 1 accelerator
92, // 2 accelerators
159, // 3 accelerators
247, // 4 accelerators
361, // 5 accelerators
509 // 6 accelerators
};
/**
* The accumulated progress towards a single growth tick of the crystal in
* 1/1000th of a growth tick.
*/
private int progress_1000 = 0;
public GrowingCrystalEntity(EntityType<? extends GrowingCrystalEntity> type, World world) {
@@ -56,126 +72,140 @@ public final class GrowingCrystalEntity extends AEBaseItemEntity {
public void tick() {
super.tick();
final ItemStack is = this.getItem();
final Item gc = is.getItem();
if (!(gc instanceof IGrowableCrystal)) {
return;
}
applyGrowthTick((IGrowableCrystal) gc, is);
}
private void applyGrowthTick(IGrowableCrystal cry, ItemStack is) {
if (!AEConfig.instance().isFeatureEnabled(AEFeature.IN_WORLD_PURIFICATION)) {
return;
}
final ItemStack is = this.getItem();
final Item gc = is.getItem();
final int x = MathHelper.floor(this.getPosX());
final int y = MathHelper.floor((this.getBoundingBox().minY + this.getBoundingBox().maxY) / 2.0D);
final int z = MathHelper.floor(this.getPosZ());
if (gc instanceof IGrowableCrystal) // if it changes this just stops being an issue...
{
final int j = MathHelper.floor(this.getPosX());
final int i = MathHelper.floor((this.getBoundingBox().minY + this.getBoundingBox().maxY) / 2.0D);
final int k = MathHelper.floor(this.getPosZ());
BlockPos pos = new BlockPos(x, y, z);
final BlockState state = this.world.getBlockState(pos);
final BlockState state = this.world.getBlockState(new BlockPos(j, i, k));
final Material mat = state.getMaterial();
final IGrowableCrystal cry = (IGrowableCrystal) is.getItem();
final float multiplier = cry.getMultiplier(state, world, pos);
final float multiplier = cry.getMultiplier(state.getBlock(), mat);
final int speed = (int) Math.max(1, this.getSpeed(j, i, k) * multiplier);
if (multiplier <= 0) {
// Crystal is in unsuitable material, reset progress and quit
this.progress_1000 = 0;
return;
}
final boolean isClient = Platform.isClient();
final int progressPerTick = (int) Math.max(1, this.getSpeed(pos) * multiplier);
if (mat.isLiquid()) {
if (isClient) {
this.progress_1000++;
} else {
this.progress_1000 += speed;
}
} else {
if (world.isRemote()) {
// On the client, we reuse the growth-tick-progress
// as a tick-counter for particle effects
int len = getTicksBetweenParticleEffects(progressPerTick);
if (++this.progress_1000 >= len) {
this.progress_1000 = 0;
AppEng.proxy.spawnEffect(EffectType.Vibrant, this.world, this.getPosX(), this.getPosY() + 0.2,
this.getPosZ(), null);
}
} else {
this.progress_1000 += progressPerTick;
if (isClient) {
int len = 40;
if (this.progress_1000 >= 1000) {
// We need to copy the stack or the change detection will not work and not sync
// this new stack to the client
ItemStack newItem = is.copy();
if (speed > 2) {
len = 20;
}
if (speed > 90) {
len = 15;
}
if (speed > 150) {
len = 10;
}
if (speed > 240) {
len = 7;
}
if (speed > 360) {
len = 3;
}
if (speed > 500) {
len = 1;
}
if (this.progress_1000 >= len) {
this.progress_1000 = 0;
AppEng.proxy.spawnEffect(EffectType.Vibrant, this.world, this.getPosX(), this.getPosY() + 0.2,
this.getPosZ(), null);
}
} else {
if (this.progress_1000 > 1000) {
// If we did not use a while loop here, the fastest growth for a crystal
// would be limited to a minimum of 30 seconds (based on 600 required growth
// ticks).
// Should a crystal decide to use a high multiplier for a certain material,
// it should be possible to go faster.
do {
newItem = cry.triggerGrowth(newItem);
this.progress_1000 -= 1000;
// We need to copy the stack or the change detection will not work and not sync
// this new stack to the client
ItemStack newItem = cry.triggerGrowth(is.copy());
this.setItem(newItem);
}
// We assume that if the item changes, the process is complete and we can break
} while (this.progress_1000 >= 1000 && newItem.getItem() == is.getItem());
this.setItem(newItem);
}
}
}
private int getSpeed(final int x, final int y, final int z) {
final int per = 80;
final float mul = 0.3f;
int qty = 0;
if (this.isAccelerated(x + 1, y, z)) {
qty += per + qty * mul;
private static int getTicksBetweenParticleEffects(int progressPerTick) {
if (progressPerTick > 500) {
return 1; // 20 times per second
} else if (progressPerTick > 360) {
return 3;
} else if (progressPerTick > 240) {
return 7;
} else if (progressPerTick > 150) {
return 10;
} else if (progressPerTick > 90) {
return 15;
} else if (progressPerTick > 2) {
return 20;
} else {
return 40; // Every 2 seconds
}
if (this.isAccelerated(x, y + 1, z)) {
qty += per + qty * mul;
}
if (this.isAccelerated(x, y, z + 1)) {
qty += per + qty * mul;
}
if (this.isAccelerated(x - 1, y, z)) {
qty += per + qty * mul;
}
if (this.isAccelerated(x, y - 1, z)) {
qty += per + qty * mul;
}
if (this.isAccelerated(x, y, z - 1)) {
qty += per + qty * mul;
}
return qty;
}
private boolean isAccelerated(final int x, final int y, final int z) {
final TileEntity te = this.world.getTileEntity(new BlockPos(x, y, z));
/**
* Gets the extra progress per tick in 1/1000th of a growth tick based on the
* surrounding accelerators.
*/
private int getSpeed(BlockPos pos) {
int acceleratorCount = getAcceleratorCount(pos);
if (acceleratorCount < 0) {
return GROWTH_TICK_PROGRESS[0];
} else if (acceleratorCount >= GROWTH_TICK_PROGRESS.length) {
return GROWTH_TICK_PROGRESS[GROWTH_TICK_PROGRESS.length - 1];
} else {
return GROWTH_TICK_PROGRESS[acceleratorCount];
}
}
private int getAcceleratorCount(BlockPos pos) {
int count = 0;
BlockPos.Mutable testPos = new BlockPos.Mutable();
for (Direction direction : Direction.values()) {
if (this.isPoweredAccelerator(testPos.func_239622_a_(pos, direction))) {
count++;
}
}
return count;
}
private boolean isPoweredAccelerator(BlockPos pos) {
final TileEntity te = this.world.getTileEntity(pos);
return te instanceof ICrystalGrowthAccelerator && ((ICrystalGrowthAccelerator) te).isPowered();
}
// Don't let seeds "float" on water surface
@Override
protected void applyFloatMotion() {
ItemStack item = getItem();
// Make ungrown seeds sink, and fully grown seeds bouyant allowing for
// automation based around dropping seeds between 5 CGAs, then catchiung
// them on their way up.
if (item.getItem() instanceof CrystalSeedItem) {
Vector3d v = this.getMotion();
// Apply a much smaller acceleration to make them slowly sink
double yAccel = this.hasNoGravity() ? 0 : -0.002;
// Apply the x/z slow-down, and the y acceleration
this.setMotion(v.x * 0.99, v.y + yAccel, v.z * 0.99);
return;
}
super.applyFloatMotion();
@@ -140,8 +140,8 @@ public final class TinyTNTPrimedEntity extends TNTEntity implements IEntityAddit
return;
}
final Explosion ex = new Explosion(this.world, this, this.getPosX(), this.getPosY(), this.getPosZ(), 0.2f,
false, Mode.BREAK);
final Explosion ex = new Explosion(this.world, this, null, null, this.getPosX(), this.getPosY(), this.getPosZ(),
0.2f, false, Explosion.Mode.BREAK);
final AxisAlignedBB area = new AxisAlignedBB(this.getPosX() - 1.5, this.getPosY() - 1.5f, this.getPosZ() - 1.5,
this.getPosX() + 1.5, this.getPosY() + 1.5, this.getPosZ() + 1.5);
final List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this, area);
@@ -37,15 +37,18 @@ public class FacadeContainer implements IFacadeContainer {
private final int facades = 6;
private final CableBusStorage storage;
private final Runnable changeCallback;
public FacadeContainer(final CableBusStorage cbs) {
public FacadeContainer(final CableBusStorage cbs, Runnable changeCallback) {
this.storage = cbs;
this.changeCallback = changeCallback;
}
@Override
public boolean addFacade(final IFacadePart a) {
if (this.getFacade(a.getSide()) == null) {
this.storage.setFacade(a.getSide().ordinal(), a);
this.notifyChange();
return true;
}
return false;
@@ -56,6 +59,7 @@ public class FacadeContainer implements IFacadeContainer {
if (side != null && side != AEPartLocation.INTERNAL) {
if (this.storage.getFacade(side.ordinal()) != null) {
this.storage.setFacade(side.ordinal(), null);
this.notifyChange();
if (host != null) {
host.markForUpdate();
}
@@ -84,6 +88,7 @@ public class FacadeContainer implements IFacadeContainer {
for (int x = 0; x < this.facades; x++) {
this.storage.setFacade(x, newFacades[x]);
}
this.notifyChange();
}
@Override
@@ -175,4 +180,9 @@ public class FacadeContainer implements IFacadeContainer {
}
return true;
}
private void notifyChange() {
this.changeCallback.run();
}
}
+1 -1
View File
@@ -49,7 +49,7 @@ public class FacadePart implements IFacadePart {
@Override
public void getBoxes(final IPartCollisionHelper ch, boolean livingEntity) {
if (livingEntity) {
if (livingEntity || !ch.isBBCollision()) {
// prevent weird snag behavior
ch.addBox(0.0, 0.0, 14, 16.0, 16.0, 16.0);
} else {
@@ -12,6 +12,7 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidAttributes;
@@ -55,7 +56,8 @@ public class FluidSlotWidget extends CustomSlotWidget {
final float blue = (attributes.getColor() & 255) / 255.0F;
RenderSystem.color3f(red, green, blue);
blit(matrixStack, xPos(), yPos(), this.getBlitOffset(), getWidth(), getHeight(), sprite);
blit(matrixStack, getTooltipAreaX(), getTooltipAreaY(), this.getBlitOffset(), getTooltipAreaWidth(),
getTooltipAreaHeight(), sprite);
}
}
@@ -79,16 +81,16 @@ public class FluidSlotWidget extends CustomSlotWidget {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
final IAEFluidStack fluid = this.getFluidStack();
if (fluid != null) {
return new TranslationTextComponent(fluid.getFluidStack().getTranslationKey());
}
return null;
return StringTextComponent.EMPTY;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return true;
}
@@ -89,7 +89,7 @@ public class FluidTankWidget extends Widget implements ITooltip {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
final IAEFluidStack fluid = this.tank.getFluidInSlot(this.slot);
if (fluid != null && fluid.getStackSize() > 0) {
return fluid.getFluid().getAttributes().getDisplayName(fluid.getFluidStack()).deepCopy()
@@ -99,27 +99,27 @@ public class FluidTankWidget extends Widget implements ITooltip {
}
@Override
public int xPos() {
public int getTooltipAreaX() {
return this.x - 2;
}
@Override
public int yPos() {
public int getTooltipAreaY() {
return this.y - 2;
}
@Override
public int getWidth() {
public int getTooltipAreaWidth() {
return this.width + 4;
}
@Override
public int getHeight() {
public int getTooltipAreaHeight() {
return this.height + 4;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return true;
}
@@ -48,7 +48,8 @@ public class OptionalFluidSlotWidget extends FluidSlotWidget {
} else {
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 0.4F);
}
GuiUtils.drawTexturedModalRect(guileft + this.xPos() - 1, guitop + this.yPos() - 1, this.srcX - 1,
this.srcY - 1, this.getWidth() + 2, this.getHeight() + 2, currentZIndex);
GuiUtils.drawTexturedModalRect(guileft + this.getTooltipAreaX() - 1, guitop + this.getTooltipAreaY() - 1,
this.srcX - 1, this.srcY - 1, this.getTooltipAreaWidth() + 2, this.getTooltipAreaHeight() + 2,
currentZIndex);
}
}

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