Worldgen, Compass (temp)

This commit is contained in:
Sebastian Hartte
2020-07-07 01:55:15 +02:00
parent 9220ca0048
commit 5eece068ba
42 changed files with 359 additions and 1665 deletions
@@ -50,11 +50,13 @@ import net.minecraft.client.texture.Sprite;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.DyeColor;
import net.minecraft.util.Hand;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.hit.HitResult.Type;
@@ -360,6 +362,11 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusBlockEntity> implemen
return false;
}
@Override
public void addStacksForDisplay(ItemGroup group, DefaultedList<ItemStack> list) {
// do nothing
}
@Override
public BlockState getFacadeState(BlockView world, BlockPos pos, Direction side) {
if (side != null) {
+12 -1
View File
@@ -6,8 +6,10 @@ import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.IItemColorRegistrationComponent;
import appeng.bootstrap.components.IModelBakeComponent;
import appeng.client.gui.implementations.*;
import appeng.client.render.SimpleModelLoader;
import appeng.client.render.cablebus.CableBusModelLoader;
import appeng.client.render.effects.*;
import appeng.client.render.model.SkyCompassModel;
import appeng.client.render.tesr.InscriberTESR;
import appeng.client.render.tesr.SkyChestTESR;
import appeng.container.implementations.*;
@@ -36,6 +38,7 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.options.KeyBinding;
import net.minecraft.client.render.entity.ItemEntityRenderer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.MinecraftServer;
@@ -46,6 +49,7 @@ import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -234,7 +238,8 @@ public final class AppEngClient extends AppEngBase {
ModelLoadingRegistry.INSTANCE.registerResourceProvider(rm -> new CableBusModelLoader((PartModels) Api.INSTANCE.registries().partModels()));
// FIXME FABRIC addBuiltInModel("glass", GlassModel::new);
// FIXME FABRIC addBuiltInModel("sky_compass", SkyCompassModel::new);
addBuiltInModel("block/sky_compass", SkyCompassModel::new);
addBuiltInModel("item/sky_compass", SkyCompassModel::new);
// FIXME FABRIC addBuiltInModel("dummy_fluid_item", DummyFluidItemModel::new);
// FIXME FABRIC addBuiltInModel("memory_card", MemoryCardModel::new);
// FIXME FABRIC addBuiltInModel("biometric_card", BiometricCardModel::new);
@@ -256,6 +261,12 @@ public final class AppEngClient extends AppEngBase {
// FIXME FABRIC new CableBusModelLoader());
}
private static <T extends UnbakedModel> void addBuiltInModel(String id, Supplier<T> modelFactory) {
ModelLoadingRegistry.INSTANCE.registerResourceProvider(
resourceManager -> new SimpleModelLoader<T>(AppEng.makeId(id), modelFactory)
);
}
private void registerScreens() {
ScreenRegistry.register(GrinderContainer.TYPE, GrinderScreen::new);
ScreenRegistry.register(QNBContainer.TYPE, QNBScreen::new);
@@ -0,0 +1,26 @@
package appeng.client.render;
import appeng.client.render.model.AutoRotatingBakedModel;
import net.minecraft.client.render.model.BakedModel;
public final class BakedModelUnwrapper {
private BakedModelUnwrapper() {
}
public static <T> T unwrap(BakedModel model, Class<T> targetClass) {
if (targetClass.isInstance(model)) {
return targetClass.cast(model);
}
if (model instanceof AutoRotatingBakedModel) {
model = ((AutoRotatingBakedModel) model).getWrapped();
if (targetClass.isInstance(model)) {
return targetClass.cast(model);
}
}
return null;
}
}
@@ -0,0 +1,34 @@
package appeng.client.render;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.util.Identifier;
import java.util.Collection;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* An unbaked model that has standard models as a dependency and produces a custom baked model
* as a result.
*/
public interface BasicUnbakedModel extends UnbakedModel {
default Stream<SpriteIdentifier> getAdditionalTextures() {
return Stream.empty();
}
@Override
default Collection<SpriteIdentifier> getTextureDependencies(Function<Identifier, UnbakedModel> unbakedModelGetter, Set<Pair<String, String>> unresolvedTextureReferences) {
return Stream.concat(
getModelDependencies().stream()
.map(unbakedModelGetter)
.flatMap(ubm -> ubm.getTextureDependencies(unbakedModelGetter, unresolvedTextureReferences).stream()),
getAdditionalTextures()
).collect(Collectors.toList());
}
}
@@ -0,0 +1,33 @@
package appeng.client.render;
import net.fabricmc.fabric.api.client.model.ModelProviderContext;
import net.fabricmc.fabric.api.client.model.ModelResourceProvider;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.util.Identifier;
import java.util.function.Supplier;
/**
* A quaint model provider that provides a single model with a single given resource identifier.
*/
public class SimpleModelLoader<T extends UnbakedModel> implements ModelResourceProvider {
private final Identifier identifier;
private final Supplier<T> factory;
public SimpleModelLoader(Identifier identifier, Supplier<T> factory) {
this.factory = factory;
this.identifier = identifier;
}
@Override
public UnbakedModel loadModelResource(Identifier identifier, ModelProviderContext modelProviderContext) {
if (identifier.equals(this.identifier)) {
return factory.get();
} else {
return null;
}
}
}
@@ -19,16 +19,15 @@
package appeng.client.render.cablebus;
import appeng.api.util.AEColor;
import appeng.client.render.BasicUnbakedModel;
import appeng.core.AELog;
import appeng.core.features.registries.PartModels;
import com.google.common.collect.ImmutableMap;
import com.mojang.datafixers.util.Pair;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.util.Identifier;
@@ -36,16 +35,14 @@ import net.minecraft.util.Identifier;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* The built-in model for the cable bus block.
*/
@Environment(EnvType.CLIENT)
public class CableBusModel implements UnbakedModel {
public class CableBusModel implements BasicUnbakedModel {
private final PartModels partModels;
@@ -59,6 +56,11 @@ public class CableBusModel implements UnbakedModel {
return partModels.getModels();
}
@Override
public Stream<SpriteIdentifier> getAdditionalTextures() {
return CableBuilder.getTextures().stream();
}
@Nullable
@Override
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter, ModelBakeSettings rotationContainer, Identifier modelId) {
@@ -75,15 +77,6 @@ public class CableBusModel implements UnbakedModel {
return new CableBusBakedModel(cableBuilder, facadeBuilder, partModels, particleTexture);
}
@Override
public Collection<SpriteIdentifier> getTextureDependencies(Function<Identifier, UnbakedModel> unbakedModelGetter, Set<Pair<String, String>> unresolvedTextureReferences) {
return Stream.concat(
getModelDependencies().stream()
.map(unbakedModelGetter)
.flatMap(ubm -> ubm.getTextureDependencies(unbakedModelGetter, unresolvedTextureReferences).stream()),
CableBuilder.getTextures().stream()
).collect(Collectors.toList());
}
private Map<Identifier, BakedModel> loadPartModels(ModelLoader loader,
ModelBakeSettings rotationContainer) {
@@ -28,6 +28,10 @@ public class AutoRotatingBakedModel extends ForwardingBakedModel implements Fabr
return false;
}
public BakedModel getWrapped() {
return wrapped;
}
@Override
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
RenderContext.QuadTransform transform = getTransform(blockView, pos);
@@ -18,43 +18,46 @@
package appeng.client.render.model;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import appeng.hooks.CompassManager;
import appeng.hooks.CompassResult;
import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.minecraft.block.BlockState;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.util.math.Matrix4f;
import net.minecraft.util.math.Quaternion;
import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.math.Vector3f;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.client.model.data.IDynamicBakedModel;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Quaternion;
import net.minecraft.world.BlockRenderView;
import net.minecraftforge.client.model.data.ModelProperty;
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
import appeng.hooks.CompassManager;
import appeng.hooks.CompassResult;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* This baked model combines the quads of a compass base and the quads of a
* compass pointer, which will be rotated around the Y-axis to get the compass
* to point in the right direction.
*/
public class SkyCompassBakedModel implements IDynamicBakedModel {
public class SkyCompassBakedModel implements BakedModel, FabricBakedModel {
// Rotation is expressed as radians
public static final ModelProperty<Float> ROTATION = new ModelProperty<>();
private final BakedModel base;
@@ -67,48 +70,63 @@ public class SkyCompassBakedModel implements IDynamicBakedModel {
this.pointer = pointer;
}
public BakedModel getBase() {
return base;
}
public BakedModel getPointer() {
return pointer;
}
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand,
IModelData extraData) {
float rotation = 0;
// Get rotation from the special block state
Float rotationFromData = extraData.getData(ROTATION);
if (rotationFromData != null) {
rotation = rotationFromData;
} else {
// This is used to render a compass pointing in a specific direction when being
// held in hand
rotation = this.fallbackRotation;
}
public boolean isVanillaAdapter() {
return false;
}
@Override
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
MeshBuilder mb = RendererAccess.INSTANCE.getRenderer().meshBuilder();
mb.getEmitter().square(Direction.UP, 0, 0, 1, 1, 0).emit();
Mesh build = mb.build();
context.meshConsumer().accept(build);
float rotation = getAnimatedRotation(pos, false);
emitQuads(context, rotation);
}
@Override
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
// This is used to render a compass pointing in a specific direction when being
// held in hand
emitQuads(context, this.fallbackRotation);
}
private void emitQuads(RenderContext context, float rotation) {
// Pre-compute the quad count to avoid list resizes
List<BakedQuad> quads = new ArrayList<>();
quads.addAll(this.base.getQuads(state, side, rand, extraData));
context.fallbackConsumer().accept(this.base);
// We'll add the pointer as "sideless"
if (side == null) {
// Set up the rotation around the Y-axis for the pointer
Matrix4f matrix = new Matrix4f();
matrix.loadIdentity();
matrix.multiply(new Quaternion(0, rotation, 0, false));
MatrixVertexTransformer transformer = new MatrixVertexTransformer(matrix);
for (BakedQuad bakedQuad : this.pointer.getQuads(state, side, rand, extraData)) {
BakedQuadBuilder builder = new BakedQuadBuilder();
transformer.setParent(builder);
transformer.setVertexFormat(builder.getVertexFormat());
bakedQuad.pipe(transformer);
// FIXME: This entire code is no longer truly valid...
// FIXME builder.setQuadOrientation( null ); // After rotation, facing a
// specific side cannot be guaranteed
// anymore
BakedQuad q = builder.build();
quads.add(q);
// Set up the rotation around the Y-axis for the pointer
context.pushTransform(quad -> {
Quaternion quaternion = new Quaternion(0, rotation, 0, false);
Vector3f pos = new Vector3f();
for (int i = 0; i < 4; i++) {
quad.copyPos(i, pos);
pos.add(-0.5f, -0.5f, -0.5f);
pos.rotate(quaternion);
pos.add(0.5f, 0.5f, 0.5f);
quad.pos(i, pos);
}
}
return true;
});
context.fallbackConsumer().accept(this.pointer);
context.popTransform();
}
return quads;
// this is used in the block entity renderer
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction face, Random random) {
return base.getQuads(state, face, random);
}
@Override
@@ -147,9 +165,9 @@ public class SkyCompassBakedModel implements IDynamicBakedModel {
* This handles setting the rotation of the compass when being held in hand. If
* it's not held in hand, it'll animate using the spinning animation.
*/
return new ModelOverrideList() {
return new ModelOverrideList(null, null, null, Collections.emptyList()) {
@Override
public BakedModel getModelWithOverrides(BakedModel originalModel, ItemStack stack, @Nullable World world,
public BakedModel apply(BakedModel originalModel, ItemStack stack, @Nullable ClientWorld world,
@Nullable LivingEntity entity) {
// FIXME: This check prevents compasses being held by OTHERS from getting the
// rotation, BUT do we actually still need this???
@@ -159,7 +177,7 @@ public class SkyCompassBakedModel implements IDynamicBakedModel {
float offRads = (float) (player.yaw / 180.0f * (float) Math.PI + Math.PI);
SkyCompassBakedModel.this.fallbackRotation = offRads
+ getAnimatedRotation(player.getPosition(), true);
+ getAnimatedRotation(player.getBlockPos(), true);
} else {
SkyCompassBakedModel.this.fallbackRotation = getAnimatedRotation(null, false);
}
@@ -18,31 +18,30 @@
package appeng.client.render.model;
import appeng.client.render.BasicUnbakedModel;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.util.Identifier;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import com.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.IModelTransform;
import net.minecraft.client.render.model.IUnbakedModel;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.Identifier;
import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.geometry.IModelGeometry;
/**
* The parent model for the compass baked model. Declares the dependencies for
* the base and pointer submodels mostly.
*/
public class SkyCompassModel implements IModelGeometry<SkyCompassModel> {
public class SkyCompassModel implements BasicUnbakedModel {
private static final Identifier MODEL_BASE = new Identifier(
"appliedenergistics2:block/sky_compass_base");
@@ -52,19 +51,17 @@ public class SkyCompassModel implements IModelGeometry<SkyCompassModel> {
public static final List<Identifier> DEPENDENCIES = ImmutableList.of(MODEL_BASE, MODEL_POINTER);
@Nullable
@Override
public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
Function<SpriteIdentifier, Sprite> spriteGetter, IModelTransform modelTransform,
ModelOverrideList overrides, Identifier modelLocation) {
BakedModel baseModel = bakery.getBakedModel(MODEL_BASE, modelTransform, spriteGetter);
BakedModel pointerModel = bakery.getBakedModel(MODEL_POINTER, modelTransform, spriteGetter);
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter, ModelBakeSettings rotationContainer, Identifier modelId) {
BakedModel baseModel = loader.bake(MODEL_BASE, rotationContainer);
BakedModel pointerModel = loader.bake(MODEL_POINTER, rotationContainer);
return new SkyCompassBakedModel(baseModel, pointerModel);
}
@Override
public Collection<SpriteIdentifier> getTextures(IModelConfiguration owner,
Function<Identifier, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors) {
return Collections.emptyList();
public Collection<Identifier> getModelDependencies() {
return ImmutableSet.of(MODEL_BASE, MODEL_POINTER);
}
}
@@ -18,23 +18,29 @@
package appeng.client.render.tesr;
import appeng.client.render.BakedModelUnwrapper;
import appeng.client.render.FacingToRotation;
import appeng.client.render.model.SkyCompassBakedModel;
import appeng.tile.misc.SkyCompassBlockEntity;
import net.fabricmc.api.EnvType;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.util.math.MatrixStack;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.TexturedRenderLayers;
import net.minecraft.client.render.block.BlockRenderManager;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.BlockModelRenderer;
import net.minecraft.client.render.block.BlockRenderManager;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Direction;
import net.fabricmc.api.Environment;
import net.minecraft.util.math.Quaternion;
import appeng.client.render.FacingToRotation;
import appeng.tile.misc.SkyCompassBlockEntity;
import java.util.Random;
@Environment(EnvType.CLIENT)
public class SkyCompassTESR extends BlockEntityRenderer<SkyCompassBlockEntity> {
@@ -48,18 +54,22 @@ public class SkyCompassTESR extends BlockEntityRenderer<SkyCompassBlockEntity> {
@Override
public void render(SkyCompassBlockEntity te, float partialTicks, MatrixStack ms, VertexConsumerProvider buffers,
int combinedLightIn, int combinedOverlayIn) {
if (blockRenderer == null) {
blockRenderer = MinecraftClient.getInstance().getBlockRenderManager();
}
VertexConsumer buffer = buffers.getBuffer(TexturedRenderLayers.getEntityTranslucentCull());
BlockModelRenderer modelRenderer = blockRenderer.getModelRenderer();
BlockState blockState = te.getCachedState();
BakedModel model = blockRenderer.getModels().getModel(blockState);
SkyCompassBakedModel skyCompassModel = BakedModelUnwrapper.unwrap(model, SkyCompassBakedModel.class);
if (skyCompassModel == null) {
return;
}
BakedModel baseModel = skyCompassModel.getBase();
BakedModel pointerModel = skyCompassModel.getPointer();
// FIXME: Rotation was previously handled by an auto rotating model I think, but
// FIXME: Should be handled using matrices instead
Direction forward = te.getForward();
Direction up = te.getUp();
// This ensures the needle isn't flipped by the model rotator. Since the model
@@ -71,14 +81,19 @@ public class SkyCompassTESR extends BlockEntityRenderer<SkyCompassBlockEntity> {
// Flip forward/up for rendering, the base model is facing up without any
// rotation
ms.push();
VertexConsumer buffer = buffers.getBuffer(RenderLayer.getSolid());
modelRenderer.render(te.getWorld(), model, blockState, te.getPos(), ms, buffer, false, new Random(), 42L, combinedOverlayIn);
// modelRenderer.render(ms.peek(), buffer, null, baseModel, 1, 1, 1, combinedLightIn, combinedOverlayIn);
float rotation = getRotation(te);
ms.translate(0.5D, 0.5D, 0.5D);
FacingToRotation.get(up, forward).push(ms);
ms.multiply(new Quaternion(0, rotation, 0, false));
ms.translate(-0.5D, -0.5D, -0.5D);
// FIXME FABRIC ModelDataMap modelData = new ModelDataMap.Builder().withInitial(SkyCompassBakedModel.ROTATION, getRotation(te)).build();
blockRenderer.getModelRenderer().render(ms.peek(), buffer, null, model, 1, 1, 1, combinedLightIn,
combinedOverlayIn);
modelRenderer.render(ms.peek(), buffer, null, pointerModel, 1, 1, 1, combinedLightIn, combinedOverlayIn);
ms.pop();
}
@@ -88,13 +103,13 @@ public class SkyCompassTESR extends BlockEntityRenderer<SkyCompassBlockEntity> {
float rotation = 0;
if (skyCompass.getForward() == Direction.UP || skyCompass.getForward() == Direction.DOWN) {
// FIXME FABRIC rotation = SkyCompassBakedModel.getAnimatedRotation(skyCompass.getPos(), false);
rotation = SkyCompassBakedModel.getAnimatedRotation(skyCompass.getPos(), false);
} else {
// FIXME FABRIC rotation = SkyCompassBakedModel.getAnimatedRotation(null, false);
rotation = SkyCompassBakedModel.getAnimatedRotation(null, false);
}
if (skyCompass.getForward() == Direction.DOWN) {
// FIXME FABRIC rotation = flipidiy(rotation);
rotation = flipidiy(rotation);
}
return rotation;
+49 -1
View File
@@ -1,5 +1,7 @@
package appeng.core;
import appeng.api.AEApi;
import appeng.api.features.AEFeature;
import appeng.api.features.IRegistryContainer;
import appeng.api.networking.IGridCacheRegistry;
import appeng.api.networking.crafting.ICraftingGrid;
@@ -27,13 +29,15 @@ import appeng.core.sync.network.TargetPoint;
import appeng.fluids.container.*;
import appeng.fluids.registries.BasicFluidCellGuiHandler;
import appeng.hooks.ToolItemHook;
import appeng.items.parts.FacadeItem;
import appeng.items.tools.NetworkToolItem;
import appeng.me.cache.*;
import appeng.mixins.CriteriaRegisterMixin;
import appeng.recipes.handlers.*;
import appeng.worldgen.ChargedQuartzOreConfig;
import appeng.worldgen.ChargedQuartzOreFeature;
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
@@ -44,6 +48,13 @@ import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.decorator.Decorator;
import net.minecraft.world.gen.decorator.NopeDecoratorConfig;
import net.minecraft.world.gen.decorator.RangeDecoratorConfig;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.OreFeatureConfig;
import java.util.function.Consumer;
@@ -76,9 +87,11 @@ public abstract class AppEngBase implements AppEng {
registerParticleTypes();
registerRecipeTypes();
registerRecipeSerializers();
registerWorldGen();
setupInternalRegistries();
}
public static void setupInternalRegistries() {
@@ -281,4 +294,39 @@ public abstract class AppEngBase implements AppEng {
return type;
}
private void registerWorldGen() {
Registry.register(Registry.FEATURE, AppEng.makeId("charged_quartz_ore"), new ChargedQuartzOreFeature(ChargedQuartzOreConfig.CODEC));
Biome.BIOMES.forEach(b -> {
// FIXME FABRIC addMeteoriteWorldGen(b);
addQuartzWorldGen(b);
});
}
private static void addQuartzWorldGen(Biome b) {
if (!AEConfig.instance().isFeatureEnabled(AEFeature.CERTUS_QUARTZ_WORLD_GEN)) {
return;
}
BlockState quartzOre = AEApi.instance().definitions().blocks().quartzOre().block().getDefaultState();
b.addFeature(GenerationStep.Feature.UNDERGROUND_ORES,
Feature.ORE
.configure(new OreFeatureConfig(OreFeatureConfig.Target.NATURAL_STONE,
quartzOre, AEConfig.instance().getQuartzOresPerCluster()))
.createDecoratedFeature(Decorator.COUNT_RANGE.configure(
new RangeDecoratorConfig(AEConfig.instance().getQuartzOresClusterAmount(), 12, 12, 72))));
if (AEConfig.instance().isFeatureEnabled(AEFeature.CHARGED_CERTUS_ORE)) {
BlockState chargedQuartzOre = AEApi.instance().definitions().blocks().quartzOreCharged().block()
.getDefaultState();
b.addFeature(GenerationStep.Feature.UNDERGROUND_DECORATION,
ChargedQuartzOreFeature.INSTANCE
.configure(new ChargedQuartzOreConfig(quartzOre, chargedQuartzOre,
AEConfig.instance().getSpawnChargedChance()))
.createDecoratedFeature(Decorator.NOPE.configure(NopeDecoratorConfig.field_24892)));
}
}
}
@@ -0,0 +1,30 @@
package appeng.worldgen;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.block.BlockState;
import net.minecraft.world.gen.feature.FeatureConfig;
import net.minecraft.world.gen.feature.OreFeatureConfig;
/**
* Extends a {@link OreFeatureConfig} with a chance.
*/
public class ChargedQuartzOreConfig implements FeatureConfig {
public static final Codec<ChargedQuartzOreConfig> CODEC = RecordCodecBuilder.create((instance) -> instance.group(
BlockState.CODEC.fieldOf("target").forGetter((config) -> config.target),
BlockState.CODEC.fieldOf("state").forGetter((config) -> config.state),
Codec.FLOAT.fieldOf("chance").withDefault(0f).forGetter((config) -> config.chance))
.apply(instance, ChargedQuartzOreConfig::new));
public final BlockState target;
public final BlockState state;
public final float chance;
public ChargedQuartzOreConfig(BlockState target, BlockState state, float chance) {
this.target = target;
this.state = state;
this.chance = chance;
}
}
@@ -1,52 +1,47 @@
package appeng.worldgen;
import java.util.Random;
import java.util.function.Function;
import com.mojang.datafixers.Dynamic;
import com.mojang.serialization.Codec;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.Heightmap;
import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.GenerationSettings;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.ReplaceBlockFeature;
import appeng.core.AppEng;
import java.util.Random;
import java.util.function.Predicate;
/**
* Extends {@link ReplaceBlockFeature} by also allowing for a replacement
* Extends {@link net.minecraft.world.gen.feature.OreFeature} by also allowing for a replacement
* chance. In addition, the feature will check every block in the chunk.
*/
public class ChargedQuartzOreFeature extends Feature<ChargedQuartzOreConfig> {
public static final ChargedQuartzOreFeature INSTANCE = new ChargedQuartzOreFeature(
ChargedQuartzOreConfig::deserialize);
public static final ChargedQuartzOreFeature INSTANCE = new ChargedQuartzOreFeature(ChargedQuartzOreConfig.CODEC);
static {
INSTANCE.setRegistryName(AppEng.MOD_ID, "charged_quartz_ore");
}
public ChargedQuartzOreFeature(Function<Dynamic<?>, ? extends ChargedQuartzOreConfig> p_i51444_1_) {
super(p_i51444_1_);
public ChargedQuartzOreFeature(Codec<ChargedQuartzOreConfig> codec) {
super(codec);
}
@Override
public boolean place(WorldAccess worldIn, ChunkGenerator<? extends GenerationSettings> generator, Random rand,
BlockPos pos, ChargedQuartzOreConfig config) {
public boolean generate(ServerWorldAccess worldIn,
net.minecraft.world.gen.StructureAccessor structureAccessor,
ChunkGenerator generator,
Random rand,
BlockPos pos,
ChargedQuartzOreConfig config) {
ChunkPos chunkPos = new ChunkPos(pos);
BlockPos.Mutable bpos = new BlockPos.Mutable();
int height = worldIn.getHeight(Heightmap.Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ());
int height = worldIn.getTopY(Heightmap.Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ());
Chunk chunk = worldIn.getChunk(pos);
for (int y = 0; y < height; y++) {
bpos.setY(y);
for (int x = chunkPos.getXStart(); x <= chunkPos.getXEnd(); x++) {
for (int x = chunkPos.getStartX(); x <= chunkPos.getEndX(); x++) {
bpos.setX(x);
for (int z = chunkPos.getZStart(); z <= chunkPos.getZEnd(); z++) {
for (int z = chunkPos.getStartZ(); z <= chunkPos.getEndZ(); z++) {
bpos.setZ(z);
if (chunk.getBlockState(bpos).getBlock() == config.target.getBlock()
&& rand.nextFloat() < config.chance) {
@@ -1,3 +0,0 @@
{
"loader": "appliedenergistics2:sky_compass"
}
@@ -1,3 +0,0 @@
{
"parent": "appliedenergistics2:block/sky_compass"
}
@@ -1,33 +0,0 @@
package appeng.client.render;
import java.util.function.Supplier;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import net.minecraft.resources.IResourceManager;
import net.minecraftforge.client.model.IModelLoader;
import net.minecraftforge.client.model.geometry.IModelGeometry;
/**
* A quaint model loader that does not accept any additional parameters in JSON.
*/
public class SimpleModelLoader<T extends IModelGeometry<T>> implements IModelLoader<T> {
private final Supplier<T> factory;
public SimpleModelLoader(Supplier<T> factory) {
this.factory = factory;
}
@Override
public void onResourceManagerReload(IResourceManager resourceManager) {
}
@Override
public T read(JsonDeserializationContext deserializationContext, JsonObject modelContents) {
return factory.get();
}
}
@@ -1,298 +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.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormatElement;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.util.math.Vector4f;
import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.BlockRenderView;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
import net.minecraftforge.client.model.pipeline.QuadGatheringTransformer;
import appeng.client.render.FacingToRotation;
public class AutoRotatingBakedModel implements BakedModel {
private final BakedModel parent;
private final LoadingCache<AutoRotatingCacheKey, List<BakedQuad>> quadCache;
public AutoRotatingBakedModel(BakedModel parent) {
this.parent = parent;
// 6 (DUNSWE) * 6 (DUNSWE) * 7 (DUNSWE + null) = 252
this.quadCache = CacheBuilder.newBuilder().maximumSize(252)
.build(new CacheLoader<AutoRotatingCacheKey, List<BakedQuad>>() {
@Override
public List<BakedQuad> load(AutoRotatingCacheKey key) {
return AutoRotatingBakedModel.this.getRotatedModel(key.getBlockState(), key.getSide(),
new Random(0), key.getModelData());
}
});
}
private List<BakedQuad> getRotatedModel(BlockState state, Direction side, Random rand, AEModelData modelData) {
FacingToRotation f2r = FacingToRotation.get(modelData.getForward(), modelData.getUp());
if (f2r.isRedundant()) {
return AutoRotatingBakedModel.this.parent.getQuads(state, side, rand, modelData);
}
List<BakedQuad> original = AutoRotatingBakedModel.this.parent.getQuads(state, f2r.resultingRotate(side), rand,
modelData);
List<BakedQuad> rotated = new ArrayList<>(original.size());
for (BakedQuad quad : original) {
BakedQuadBuilder builder = new BakedQuadBuilder();
VertexRotator rot = new VertexRotator(f2r, quad.getFace());
rot.setParent(builder);
quad.pipe(rot);
if (quad.getFace() != null) {
builder.setQuadOrientation(f2r.rotate(quad.getFace()));
} else {
builder.setQuadOrientation(null);
}
BakedQuad unpackedQuad = builder.build();
// Make a copy of it to resolve the vertex data and throw away the unpacked
// stuff
// This also fixes a bug in Forge's UnpackedBakedQuad, which unpacks a
// byte-based normal like 0,0,-1
// to 0,0,-0.99607843. We replace these normals with the proper 0,0,-1 when
// rotation, which
// causes a bug in the AO lighter, if an unpacked quad pipes this value back to
// it.
// Packing it back to the vanilla vertex format will fix this inconsistency
// because it converts
// the normal back to a byte-based format, which then re-applies Forge's own bug
// when piping it
// to the AO lighter, thus fixing our problem.
BakedQuad packedQuad = new BakedQuad(unpackedQuad.getVertexData(), quad.getColorIndex(),
unpackedQuad.getFace(), quad.func_187508_a(), quad.shouldApplyDiffuseLighting());
rotated.add(packedQuad);
}
return rotated;
}
@Override
public boolean useAmbientOcclusion() {
return this.parent.useAmbientOcclusion();
}
@Override
public boolean hasDepth() {
return this.parent.hasDepth();
}
@Override
public boolean isSideLit() {
return parent.isSideLit();
}
@Override
public boolean isBuiltin() {
return this.parent.isBuiltin();
}
@Override
public Sprite getSprite() {
return this.parent.getSprite();
}
@Override
@Deprecated
public ModelTransformation getTransformation() {
return parent.getTransformation();
}
@Override
public ModelOverrideList getOverrides() {
return parent.getOverrides();
}
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand) {
return getQuads(state, side, rand, EmptyModelData.INSTANCE);
}
@Nonnull
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand,
@Nonnull IModelData extraData) {
if (!(extraData instanceof AEModelData)) {
return this.parent.getQuads(state, side, rand, extraData);
}
AEModelData aeModelData = (AEModelData) extraData;
if (aeModelData.isCacheable()) {
return quadCache.getUnchecked(new AutoRotatingCacheKey(state, aeModelData, side));
} else {
return this.getRotatedModel(state, side, rand, aeModelData);
}
}
@Nonnull
@Override
public IModelData getModelData(@Nonnull BlockRenderView world, @Nonnull BlockPos pos, @Nonnull BlockState state,
@Nonnull IModelData tileData) {
return this.parent.getModelData(world, pos, state, tileData);
}
public static class VertexRotator extends QuadGatheringTransformer {
private final FacingToRotation f2r;
private final Direction face;
public VertexRotator(FacingToRotation f2r, Direction face) {
this.f2r = f2r;
this.face = face;
}
@Override
public void setParent(IVertexConsumer parent) {
super.setParent(parent);
if (Objects.equal(this.getVertexFormat(), parent.getVertexFormat())) {
return;
}
this.setVertexFormat(parent.getVertexFormat());
}
@Override
protected void processQuad() {
VertexFormat format = this.parent.getVertexFormat();
ImmutableList<VertexFormatElement> elements = format.getElements();
for (int v = 0; v < 4; v++) {
for (int e = 0; e < elements.size(); e++) {
VertexFormatElement element = elements.get(e);
if (element.getType() == VertexFormatElement.Usage.POSITION) {
this.parent.put(e, this.transform(this.quadData[e][v]));
} else if (element.getType() == VertexFormatElement.Usage.NORMAL) {
this.parent.put(e, this.transformNormal(this.quadData[e][v]));
} else {
this.parent.put(e, this.quadData[e][v]);
}
}
}
}
private float[] transform(float[] fs) {
switch (fs.length) {
case 3:
Vector4f vec = new Vector4f(fs[0], fs[1], fs[2], 1);
vec.setX(vec.getX() - 0.5f);
vec.setY(vec.getY() - 0.5f);
vec.setZ(vec.getZ() - 0.5f);
vec.transform(this.f2r.getMat());
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() };
case 4:
Vector4f vecc = new Vector4f(fs[0], fs[1], fs[2], fs[3]);
vecc.setX(vecc.getX() - 0.5f);
vecc.setY(vecc.getY() - 0.5f);
vecc.setZ(vecc.getZ() - 0.5f);
vecc.transform(this.f2r.getMat());
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() };
default:
return fs;
}
}
private float[] transformNormal(float[] fs) {
if (this.face == null) {
switch (fs.length) {
case 3:
Vector4f vec = new Vector4f(fs[0], fs[1], fs[2], 0);
vec.transform(this.f2r.getMat());
return new float[] { vec.getX(), vec.getY(), vec.getZ() };
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 };
default:
return fs;
}
} else {
switch (fs.length) {
case 3:
Vec3i vec = this.f2r.rotate(this.face).getVector();
return new float[] { vec.getX(), vec.getY(), vec.getZ() };
case 4:
Vector4f veccc = new Vector4f(fs[0], fs[1], fs[2], fs[3]);
Vec3i vecc = this.f2r.rotate(this.face).getVector();
return new float[] { vecc.getX(), vecc.getY(), vecc.getZ(), veccc.getW() };
default:
return fs;
}
}
}
@Override
public void setQuadTint(int tint) {
this.parent.setQuadTint(tint);
}
@Override
public void setQuadOrientation(Direction orientation) {
this.parent.setQuadOrientation(f2r.rotate(orientation));
}
@Override
public void setApplyDiffuseLighting(boolean diffuse) {
this.parent.setApplyDiffuseLighting(diffuse);
}
@Override
public void setTexture(Sprite texture) {
this.parent.setTexture(texture);
}
}
}
@@ -1,71 +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 net.minecraft.block.BlockState;
import net.minecraft.util.math.Direction;
/**
* Used as the cache key for caching automatically rotated baked models.
*/
final class AutoRotatingCacheKey {
private final BlockState blockState;
private final AEModelData modelData;
private final Direction side;
AutoRotatingCacheKey(BlockState blockState, AEModelData modelData, Direction side) {
this.blockState = blockState;
this.modelData = modelData;
this.side = side;
}
public BlockState getBlockState() {
return this.blockState;
}
public AEModelData getModelData() {
return modelData;
}
public Direction getSide() {
return this.side;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || this.getClass() != o.getClass()) {
return false;
}
AutoRotatingCacheKey cacheKey = (AutoRotatingCacheKey) o;
return this.blockState.equals(cacheKey.blockState) && this.modelData.equals(cacheKey.modelData)
&& this.side == cacheKey.side;
}
@Override
public int hashCode() {
int result = this.blockState.hashCode();
result = 31 * result + this.modelData.hashCode();
result = 31 * result + (this.side != null ? this.side.hashCode() : 0);
return result;
}
}
@@ -33,7 +33,6 @@ import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.decorator.Decorator;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.FeatureConfig;
import net.minecraft.world.gen.feature.IFeatureConfig;
import net.minecraft.world.gen.feature.OreFeatureConfig;
import net.minecraft.world.gen.placement.CountRangeConfig;
import net.minecraft.world.gen.placement.IPlacementConfig;
@@ -282,32 +281,6 @@ final class Registration {
MeteoriteStructure.INSTANCE.configure(FeatureConfig.DEFAULT));
}
private static void addQuartzWorldGen(Biome b) {
if (!AEConfig.instance().isFeatureEnabled(AEFeature.CERTUS_QUARTZ_WORLD_GEN)) {
return;
}
BlockState quartzOre = AEApi.instance().definitions().blocks().quartzOre().block().getDefaultState();
b.addFeature(GenerationStep.Feature.UNDERGROUND_ORES,
Feature.ORE
.configure(new OreFeatureConfig(OreFeatureConfig.Target.NATURAL_STONE,
quartzOre, AEConfig.instance().getQuartzOresPerCluster()))
.createDecoratedFeature(Decorator.COUNT_RANGE.configure(
new CountRangeConfig(AEConfig.instance().getQuartzOresClusterAmount(), 12, 12, 72))));
if (AEConfig.instance().isFeatureEnabled(AEFeature.CHARGED_CERTUS_ORE)) {
BlockState chargedQuartzOre = AEApi.instance().definitions().blocks().quartzOreCharged().block()
.getDefaultState();
b.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION,
ChargedQuartzOreFeature.INSTANCE
.configure(new ChargedQuartzOreConfig(quartzOre, chargedQuartzOre,
AEConfig.instance().getSpawnChargedChance()))
.createDecoratedFeature(Decorator.NOPE.configure(IPlacementConfig.NO_PLACEMENT_CONFIG)));
}
}
public void registerWorldGen(RegistryEvent.Register<Feature<?>> evt) {
IForgeRegistry<Feature<?>> r = evt.getRegistry();
@@ -1,79 +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.integration.modules.theoneprobe;
import java.util.List;
import java.util.Optional;
import com.google.common.collect.Lists;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.IProbeInfoProvider;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.parts.IPart;
import appeng.core.AppEng;
import appeng.integration.modules.theoneprobe.part.ChannelInfoProvider;
import appeng.integration.modules.theoneprobe.part.IPartProbInfoProvider;
import appeng.integration.modules.theoneprobe.part.P2PStateInfoProvider;
import appeng.integration.modules.theoneprobe.part.PartAccessor;
import appeng.integration.modules.theoneprobe.part.PowerStateInfoProvider;
import appeng.integration.modules.theoneprobe.part.StorageMonitorInfoProvider;
public final class PartInfoProvider implements IProbeInfoProvider {
private final List<IPartProbInfoProvider> providers;
private final PartAccessor accessor = new PartAccessor();
public PartInfoProvider() {
final IPartProbInfoProvider channel = new ChannelInfoProvider();
final IPartProbInfoProvider power = new PowerStateInfoProvider();
final IPartProbInfoProvider storageMonitor = new StorageMonitorInfoProvider();
final IPartProbInfoProvider p2p = new P2PStateInfoProvider();
this.providers = Lists.newArrayList(channel, power, p2p, storageMonitor);
}
@Override
public String getID() {
return AppEng.MOD_ID + ":PartInfoProvider";
}
@Override
public void addProbeInfo(ProbeMode mode, IProbeInfo probeInfo, PlayerEntity player, World world,
BlockState blockState, IProbeHitData data) {
final BlockEntity te = world.getBlockEntity(data.getPos());
final Optional<IPart> maybePart = this.accessor.getMaybePart(te, data);
if (maybePart.isPresent()) {
final IPart part = maybePart.get();
for (final IPartProbInfoProvider provider : this.providers) {
provider.addProbeInfo(part, mode, probeInfo, player, world, blockState, data);
}
}
}
}
@@ -1,31 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2020, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* 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.integration.modules.theoneprobe;
import net.minecraftforge.fml.InterModComms;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
public class TOP {
public static void enqueueIMC(final InterModEnqueueEvent event) {
if (ModList.get().isLoaded("theoneprobe")) {
InterModComms.sendTo("theoneprobe", "getTheOneProbe", TheOneProbeModule::new);
}
}
}
@@ -1,38 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2020, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* 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.integration.modules.theoneprobe;
import java.util.function.Function;
import mcjty.theoneprobe.api.ITheOneProbe;
import appeng.integration.IIntegrationModule;
import appeng.integration.modules.theoneprobe.config.AEConfigProvider;
public class TheOneProbeModule implements IIntegrationModule, Function<ITheOneProbe, Void> {
@Override
public Void apply(ITheOneProbe input) {
input.registerProbeConfigProvider(new AEConfigProvider());
input.registerProvider(new TileInfoProvider());
input.registerProvider(new PartInfoProvider());
return null;
}
}
@@ -1,47 +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.integration.modules.theoneprobe;
import java.util.Locale;
import net.minecraft.text.TranslatableText;
public enum TheOneProbeText {
CRAFTING, DEVICE_ONLINE, DEVICE_OFFLINE, DEVICE_MISSING_CHANNEL, P2P_UNLINKED, P2P_INPUT_ONE_OUTPUT,
P2P_INPUT_MANY_OUTPUTS, P2P_OUTPUT, P2P_FREQUENCY, LOCKED, UNLOCKED, SHOWING, CONTAINS, CHANNELS, STORED_ENERGY;
private final String root;
TheOneProbeText() {
this.root = "theoneprobe.appliedenergistics2";
}
public String getTranslationString(Object... args) {
return getTranslationComponent(args).getFormattedText();
}
public TranslatableText getTranslationComponent(Object... args) {
return new TranslatableText(this.getUnlocalized(), args);
}
public String getUnlocalized() {
return this.root + '.' + this.name().toLowerCase(Locale.ENGLISH);
}
}
@@ -1,73 +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.integration.modules.theoneprobe;
import java.util.List;
import com.google.common.collect.Lists;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.IProbeInfoProvider;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.core.AppEng;
import appeng.integration.modules.theoneprobe.tile.ChargerInfoProvider;
import appeng.integration.modules.theoneprobe.tile.CraftingMonitorInfoProvider;
import appeng.integration.modules.theoneprobe.tile.ITileProbInfoProvider;
import appeng.integration.modules.theoneprobe.tile.PowerStateInfoProvider;
import appeng.integration.modules.theoneprobe.tile.PowerStorageInfoProvider;
import appeng.tile.AEBaseBlockEntity;
public final class TileInfoProvider implements IProbeInfoProvider {
private final List<ITileProbInfoProvider> providers;
public TileInfoProvider() {
final ITileProbInfoProvider charger = new ChargerInfoProvider();
final ITileProbInfoProvider energyCell = new CraftingMonitorInfoProvider();
final ITileProbInfoProvider craftingBlock = new PowerStateInfoProvider();
final ITileProbInfoProvider craftingMonitor = new PowerStorageInfoProvider();
this.providers = Lists.newArrayList(charger, energyCell, craftingBlock, craftingMonitor);
}
@Override
public String getID() {
return AppEng.MOD_ID + ":TileInfoProvider";
}
@Override
public void addProbeInfo(ProbeMode mode, IProbeInfo probeInfo, PlayerEntity player, World world,
BlockState blockState, IProbeHitData data) {
final BlockEntity tile = world.getBlockEntity(data.getPos());
if (tile instanceof AEBaseBlockEntity) {
final AEBaseBlockEntity aeBaseTile = (AEBaseBlockEntity) tile;
for (final ITileProbInfoProvider provider : this.providers) {
provider.addProbeInfo(aeBaseTile, mode, probeInfo, player, world, blockState, data);
}
}
}
}
@@ -1,49 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.config;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeConfig;
import mcjty.theoneprobe.api.IProbeConfigProvider;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeHitEntityData;
import appeng.tile.AEBaseBlockEntity;
public class AEConfigProvider implements IProbeConfigProvider {
@Override
public void getProbeConfig(IProbeConfig config, PlayerEntity player, World world, Entity entity,
IProbeHitEntityData data) {
// Still no AE entities.
}
@Override
public void getProbeConfig(IProbeConfig config, PlayerEntity player, World world, BlockState blockState,
IProbeHitData data) {
if (world.getBlockEntity(data.getPos()) instanceof AEBaseBlockEntity) {
config.setRFMode(0);
}
}
}
@@ -1,60 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.part;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.parts.IPart;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import appeng.parts.networking.SmartCablePart;
import appeng.parts.networking.SmartDenseCablePart;
public class ChannelInfoProvider implements IPartProbInfoProvider {
@Override
public void addProbeInfo(IPart part, ProbeMode mode, IProbeInfo probeInfo, PlayerEntity player, World world,
BlockState blockState, IProbeHitData data) {
if (part instanceof SmartDenseCablePart || part instanceof SmartCablePart) {
final int usedChannels;
final int maxChannels = (part instanceof SmartDenseCablePart) ? 32 : 8;
if (part.getGridNode().isActive()) {
final CompoundTag tmp = new CompoundTag();
part.writeToNBT(tmp);
usedChannels = tmp.getByte("usedChannels");
} else {
usedChannels = 0;
}
final String formattedChannelString = TheOneProbeText.CHANNELS.getTranslationString(usedChannels,
maxChannels);
probeInfo.text(formattedChannelString);
}
}
}
@@ -1,45 +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.integration.modules.theoneprobe.part;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.IProbeInfoProvider;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.parts.IPart;
/**
* Similar to {@link IProbeInfoProvider}, but already providing the
* {@link IPart} being looked at.
*
*/
public interface IPartProbInfoProvider {
/**
* @see IProbeInfoProvider#addProbeInfo(ProbeMode, IProbeInfo, EntityPlayer,
* World, IBlockState, IProbeHitData)
*/
void addProbeInfo(IPart part, ProbeMode mode, IProbeInfo probeInfo, PlayerEntity player, World world,
BlockState blockState, IProbeHitData data);
}
@@ -1,106 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.part;
import com.google.common.collect.Iterators;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.parts.IPart;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import appeng.me.GridAccessException;
import appeng.parts.p2p.P2PTunnelPart;
import appeng.util.Platform;
public class P2PStateInfoProvider implements IPartProbInfoProvider {
private static final int STATE_UNLINKED = 0;
private static final int STATE_OUTPUT = 1;
private static final int STATE_INPUT = 2;
@Override
public void addProbeInfo(IPart part, ProbeMode mode, IProbeInfo probeInfo, PlayerEntity player, World world,
BlockState blockState, IProbeHitData data) {
if (part instanceof P2PTunnelPart) {
final P2PTunnelPart tunnel = (P2PTunnelPart) part;
if (!tunnel.isPowered()) {
return;
}
// The default state
int state = STATE_UNLINKED;
int outputCount = 0;
if (!tunnel.isOutput()) {
outputCount = getOutputCount(tunnel);
if (outputCount > 0) {
// Only set it to INPUT if we know there are any outputs
state = STATE_INPUT;
}
} else {
final P2PTunnelPart input = tunnel.getInput();
if (input != null) {
state = STATE_OUTPUT;
}
}
switch (state) {
case STATE_UNLINKED:
probeInfo.text(TheOneProbeText.P2P_UNLINKED.getTranslationString());
break;
case STATE_OUTPUT:
probeInfo.text(TheOneProbeText.P2P_OUTPUT.getTranslationString());
break;
case STATE_INPUT:
probeInfo.text(getOutputText(outputCount));
break;
}
final short freq = tunnel.getFrequency();
final String freqTooltip = Platform.p2p().toHexString(freq);
probeInfo.text(freqTooltip);
}
}
private static int getOutputCount(P2PTunnelPart tunnel) {
try {
return Iterators.size(tunnel.getOutputs().iterator());
} catch (GridAccessException e) {
// Well... unknown size it is!
return 0;
}
}
private static String getOutputText(int outputs) {
if (outputs <= 1) {
return TheOneProbeText.P2P_INPUT_ONE_OUTPUT.getTranslationString();
} else {
return TheOneProbeText.P2P_INPUT_MANY_OUTPUTS.getTranslationString(outputs);
}
}
}
@@ -1,49 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.part;
import java.util.Optional;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import mcjty.theoneprobe.api.IProbeHitData;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartHost;
import appeng.api.parts.SelectedPart;
public final class PartAccessor {
public Optional<IPart> getMaybePart(final BlockEntity te, final IProbeHitData data) {
if (te instanceof IPartHost) {
BlockPos pos = data.getPos();
final Vec3d position = data.getHitPos().add(-pos.getX(), -pos.getY(), -pos.getZ());
final IPartHost host = (IPartHost) te;
final SelectedPart sp = host.selectPart(position);
if (sp.part != null) {
return Optional.of(sp.part);
}
}
return Optional.empty();
}
}
@@ -1,61 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.part;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.implementations.IPowerChannelState;
import appeng.api.parts.IPart;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
public class PowerStateInfoProvider implements IPartProbInfoProvider {
@Override
public void addProbeInfo(IPart part, ProbeMode mode, IProbeInfo probeInfo, PlayerEntity player, World world,
BlockState blockState, IProbeHitData data) {
if (part instanceof IPowerChannelState) {
final IPowerChannelState state = (IPowerChannelState) part;
final String tooltip = this.getToolTip(state.isActive(), state.isPowered());
probeInfo.text(tooltip);
}
}
private String getToolTip(final boolean isActive, final boolean isPowered) {
final String result;
if (isActive && isPowered) {
result = TheOneProbeText.DEVICE_ONLINE.getTranslationString();
} else if (isPowered) {
result = TheOneProbeText.DEVICE_MISSING_CHANNEL.getTranslationString();
} else {
result = TheOneProbeText.DEVICE_OFFLINE.getTranslationString();
}
return result;
}
}
@@ -1,66 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.part;
import net.minecraft.block.BlockState;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.implementations.parts.IStorageMonitorPart;
import appeng.api.parts.IPart;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
public class StorageMonitorInfoProvider implements IPartProbInfoProvider {
@Override
public void addProbeInfo(IPart part, ProbeMode mode, IProbeInfo probeInfo, PlayerEntity player, World world,
BlockState blockState, IProbeHitData data) {
if (part instanceof IStorageMonitorPart) {
final IStorageMonitorPart monitor = (IStorageMonitorPart) part;
final IAEStack<?> displayed = monitor.getDisplayed();
final boolean isLocked = monitor.isLocked();
// TODO: generalize
if (displayed instanceof IAEItemStack) {
final IAEItemStack ais = (IAEItemStack) displayed;
probeInfo.text(TheOneProbeText.SHOWING.getTranslationComponent() + ": "
+ ais.asItemStackRepresentation().getName());
} else if (displayed instanceof IAEFluidStack) {
final IAEFluidStack ais = (IAEFluidStack) displayed;
final String fluidName = I18n.format(ais.getFluidStack().getTranslationKey());
final String text = TheOneProbeText.SHOWING.getTranslationComponent() + ": " + fluidName;
probeInfo.text(text);
}
probeInfo.text(isLocked ? TheOneProbeText.LOCKED.getTranslationString()
: TheOneProbeText.UNLOCKED.getTranslationString());
}
}
}
@@ -1,56 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.tile;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import mcjty.theoneprobe.api.ElementAlignment;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.tile.AEBaseBlockEntity;
import appeng.tile.misc.ChargerBlockEntity;
public class ChargerInfoProvider implements ITileProbInfoProvider {
@Override
public void addProbeInfo(AEBaseBlockEntity tile, ProbeMode mode, IProbeInfo probeInfo, PlayerEntity player,
World world, BlockState blockState, IProbeHitData data) {
if (tile instanceof ChargerBlockEntity) {
final ChargerBlockEntity charger = (ChargerBlockEntity) tile;
final FixedItemInv chargerInventory = charger.getInternalInventory();
final ItemStack chargingItem = chargerInventory.getInvStack(0);
if (!chargingItem.isEmpty()) {
final String currentInventory = chargingItem.getName().getString();
final IProbeInfo centerAlignedHorizontalLayout = probeInfo
.horizontal(probeInfo.defaultLayoutStyle().alignment(ElementAlignment.ALIGN_CENTER));
centerAlignedHorizontalLayout.item(chargingItem);
centerAlignedHorizontalLayout.text(currentInventory);
}
}
}
}
@@ -1,61 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.tile;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.ElementAlignment;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.storage.data.IAEItemStack;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import appeng.tile.AEBaseBlockEntity;
import appeng.tile.crafting.CraftingMonitorBlockEntity;
public class CraftingMonitorInfoProvider implements ITileProbInfoProvider {
@Override
public void addProbeInfo(AEBaseBlockEntity tile, ProbeMode mode, IProbeInfo probeInfo, PlayerEntity player,
World world, BlockState blockState, IProbeHitData data) {
if (tile instanceof CraftingMonitorBlockEntity) {
final CraftingMonitorBlockEntity monitor = (CraftingMonitorBlockEntity) tile;
final IAEItemStack displayStack = monitor.getJobProgress();
if (displayStack != null) {
// TODO: check if OK
final ItemStack itemStack = displayStack.asItemStackRepresentation();
final String itemName = itemStack.getName().getString();
final String formattedCrafting = TheOneProbeText.CRAFTING.getTranslationComponent(itemName)
.getFormattedText();
final IProbeInfo centerAlignedHorizontalLayout = probeInfo
.horizontal(probeInfo.defaultLayoutStyle().alignment(ElementAlignment.ALIGN_CENTER));
centerAlignedHorizontalLayout.item(itemStack);
centerAlignedHorizontalLayout.text(formattedCrafting);
}
}
}
}
@@ -1,45 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.tile;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.IProbeInfoProvider;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.tile.AEBaseBlockEntity;
/**
* Similar to {@link IProbeInfoProvider}, but already providing the
* {@link AEBaseBlockEntity} being looked at.
*
*/
public interface ITileProbInfoProvider {
/**
* @see IProbeInfoProvider#addProbeInfo(ProbeMode, IProbeInfo, EntityPlayer,
* World, IBlockState, IProbeHitData)
*/
void addProbeInfo(AEBaseBlockEntity tile, ProbeMode mode, IProbeInfo probeInfo, PlayerEntity player, World world,
BlockState blockState, IProbeHitData data);
}
@@ -1,55 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.tile;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.implementations.IPowerChannelState;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import appeng.tile.AEBaseBlockEntity;
public class PowerStateInfoProvider implements ITileProbInfoProvider {
@Override
public void addProbeInfo(AEBaseBlockEntity tile, ProbeMode mode, IProbeInfo probeInfo, PlayerEntity player,
World world, BlockState blockState, IProbeHitData data) {
if (tile instanceof IPowerChannelState) {
final IPowerChannelState state = (IPowerChannelState) tile;
final boolean isActive = state.isActive();
final boolean isPowered = state.isPowered();
if (isActive && isPowered) {
probeInfo.text(TheOneProbeText.DEVICE_ONLINE.getTranslationString());
} else if (isPowered) {
probeInfo.text(TheOneProbeText.DEVICE_MISSING_CHANNEL.getTranslationString());
} else {
probeInfo.text(TheOneProbeText.DEVICE_OFFLINE.getTranslationString());
}
}
}
}
@@ -1,61 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.tile;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.networking.energy.IAEPowerStorage;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import appeng.tile.AEBaseBlockEntity;
import appeng.util.Platform;
public class PowerStorageInfoProvider implements ITileProbInfoProvider {
@Override
public void addProbeInfo(AEBaseBlockEntity tile, ProbeMode mode, IProbeInfo probeInfo, PlayerEntity player,
World world, BlockState blockState, IProbeHitData data) {
if (tile instanceof IAEPowerStorage) {
final IAEPowerStorage storage = (IAEPowerStorage) tile;
final double maxPower = storage.getAEMaxPower();
if (maxPower > 0) {
final long internalCurrentPower = (long) (storage.getAECurrentPower() * 100);
if (internalCurrentPower >= 0) {
final long internalMaxPower = (long) (100 * maxPower);
final String formatCurrentPower = Platform.formatPowerLong(internalCurrentPower, false);
final String formatMaxPower = Platform.formatPowerLong(internalMaxPower, false);
final String formattedString = TheOneProbeText.STORED_ENERGY
.getTranslationComponent(formatCurrentPower, formatMaxPower).getFormattedText();
probeInfo.text(formattedString);
}
}
}
}
}
@@ -44,7 +44,7 @@ import net.minecraft.util.text.event.HoverEvent;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkStatus;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.Heightmap;
import net.minecraft.world.gen.feature.structure.StructureStart;
import net.minecraft.server.world.ServerWorld;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
@@ -28,7 +28,7 @@ import net.minecraft.world.biome.provider.SingleBiomeProviderSettings;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.GenerationSettings;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.Heightmap;
import net.minecraft.world.gen.WorldGenRegion;
import appeng.api.AEApi;
@@ -1,54 +0,0 @@
package appeng.tile.powersink;
import net.minecraftforge.energy.IEnergyStorage;
import appeng.api.config.Actionable;
import appeng.api.config.PowerUnits;
/**
* Adapts an {@link IExternalPowerSink} to Forges {@link IEnergyStorage}.
*/
class ForgeEnergyAdapter implements IEnergyStorage {
private final IExternalPowerSink sink;
ForgeEnergyAdapter(IExternalPowerSink sink) {
this.sink = sink;
}
@Override
public final int receiveEnergy(int maxReceive, boolean simulate) {
final double offered = maxReceive;
final double overflow = this.sink.injectExternalPower(PowerUnits.RF, offered,
simulate ? Actionable.SIMULATE : Actionable.MODULATE);
return (int) (maxReceive - overflow);
}
@Override
public final int getEnergyStored() {
return (int) Math.floor(PowerUnits.AE.convertTo(PowerUnits.RF, this.sink.getAECurrentPower()));
}
@Override
public final int getMaxEnergyStored() {
return (int) Math.floor(PowerUnits.AE.convertTo(PowerUnits.RF, this.sink.getAEMaxPower()));
}
@Override
public int extractEnergy(int maxExtract, boolean simulate) {
return 0;
}
@Override
public boolean canExtract() {
return false;
}
@Override
public boolean canReceive() {
return true;
}
}
@@ -1,45 +0,0 @@
package appeng.worldgen;
import com.google.common.collect.ImmutableMap;
import com.mojang.datafixers.Dynamic;
import com.mojang.datafixers.types.DynamicOps;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.world.gen.feature.IFeatureConfig;
import net.minecraft.world.gen.feature.ReplaceBlockConfig;
import appeng.core.AEConfig;
/**
* Extends a {@link ReplaceBlockConfig} with a chance.
*/
public class ChargedQuartzOreConfig implements IFeatureConfig {
public final BlockState target;
public final BlockState state;
public final float chance;
public ChargedQuartzOreConfig(BlockState target, BlockState state, float chance) {
this.target = target;
this.state = state;
this.chance = chance;
}
@Override
public <T> Dynamic<T> serialize(DynamicOps<T> ops) {
return new Dynamic<>(ops,
ops.createMap(
ImmutableMap.of(ops.createString("target"), BlockState.serialize(ops, this.target).getValue(),
ops.createString("state"), BlockState.serialize(ops, this.state).getValue(),
ops.createString("chance"), ops.createFloat(this.chance))));
}
public static <T> ChargedQuartzOreConfig deserialize(Dynamic<T> p_214657_0_) {
BlockState target = p_214657_0_.get("target").map(BlockState::deserialize).orElse(Blocks.AIR.getDefaultState());
BlockState state = p_214657_0_.get("state").map(BlockState::deserialize).orElse(Blocks.AIR.getDefaultState());
float chance = p_214657_0_.get("chance").asFloat(AEConfig.instance().getSpawnChargedChance());
return new ChargedQuartzOreConfig(target, state, chance);
}
}
@@ -3,7 +3,7 @@ package appeng.worldgen.meteorite;
import java.util.Random;
import java.util.function.Function;
import com.mojang.datafixers.Dynamic;
import com.mojang.serialization.Dynamic;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeManager;
@@ -11,7 +11,6 @@ import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.EndChunkGenerator;
import net.minecraft.world.gen.NetherChunkGenerator;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.feature.StructureFeature;
import net.minecraft.world.gen.feature.structure.ScatteredStructure;
import net.minecraft.world.gen.feature.structure.Structure;
@@ -13,12 +13,12 @@ import net.minecraft.tag.Tag;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MutableBoundingBox;
import net.minecraft.world.Heightmap;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.Biome.Category;
import net.minecraft.world.biome.Biome.TempCategory;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.gen.Heightmap.Type;
import net.minecraft.world.Heightmap.Type;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.feature.structure.Structure;
import net.minecraft.world.gen.feature.structure.StructureStart;