Worldgen, Compass (temp)
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* 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 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.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
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.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Quaternion;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
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 BakedModel, FabricBakedModel {
|
||||
|
||||
// Rotation is expressed as radians
|
||||
|
||||
private final BakedModel base;
|
||||
|
||||
private final BakedModel pointer;
|
||||
|
||||
private float fallbackRotation = 0;
|
||||
|
||||
public SkyCompassBakedModel(BakedModel base, BakedModel pointer) {
|
||||
this.base = base;
|
||||
this.pointer = pointer;
|
||||
}
|
||||
|
||||
public BakedModel getBase() {
|
||||
return base;
|
||||
}
|
||||
|
||||
public BakedModel getPointer() {
|
||||
return pointer;
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
context.fallbackConsumer().accept(this.base);
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// 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
|
||||
public boolean useAmbientOcclusion() {
|
||||
return this.base.useAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDepth() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSideLit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sprite getSprite() {
|
||||
return this.base.getSprite();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelTransformation getTransformation() {
|
||||
return this.base.getTransformation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelOverrideList getOverrides() {
|
||||
/*
|
||||
* 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(null, null, null, Collections.emptyList()) {
|
||||
@Override
|
||||
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???
|
||||
if (world != null && entity instanceof ClientPlayerEntity) {
|
||||
PlayerEntity player = (PlayerEntity) entity;
|
||||
|
||||
float offRads = (float) (player.yaw / 180.0f * (float) Math.PI + Math.PI);
|
||||
|
||||
SkyCompassBakedModel.this.fallbackRotation = offRads
|
||||
+ getAnimatedRotation(player.getBlockPos(), true);
|
||||
} else {
|
||||
SkyCompassBakedModel.this.fallbackRotation = getAnimatedRotation(null, false);
|
||||
}
|
||||
|
||||
return originalModel;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the effective, animated rotation for the compass given the current
|
||||
* position of the compass.
|
||||
*/
|
||||
public static float getAnimatedRotation(@Nullable BlockPos pos, boolean prefetch) {
|
||||
|
||||
// Only query for a meteor position if we know our own position
|
||||
if (pos != null) {
|
||||
CompassResult cr = CompassManager.INSTANCE.getCompassDirection(0, pos.getX(), pos.getY(), pos.getZ());
|
||||
|
||||
// Prefetch meteor positions from the server for adjacent blocks so they are
|
||||
// available more quickly when
|
||||
// we're moving
|
||||
if (prefetch) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
CompassManager.INSTANCE.getCompassDirection(0, pos.getX() + i - 1, pos.getY(),
|
||||
pos.getZ() + j - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cr.isValidResult()) {
|
||||
if (cr.isSpin()) {
|
||||
long timeMillis = System.currentTimeMillis();
|
||||
// .5 seconds per full rotation
|
||||
timeMillis %= 500;
|
||||
return timeMillis / 500.f * (float) Math.PI * 2;
|
||||
} else {
|
||||
return (float) cr.getRad();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long timeMillis = System.currentTimeMillis();
|
||||
// 3 seconds per full rotation
|
||||
timeMillis %= 3000;
|
||||
return timeMillis / 3000.f * (float) Math.PI * 2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 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;
|
||||
|
||||
/**
|
||||
* The parent model for the compass baked model. Declares the dependencies for
|
||||
* the base and pointer submodels mostly.
|
||||
*/
|
||||
public class SkyCompassModel implements BasicUnbakedModel {
|
||||
|
||||
private static final Identifier MODEL_BASE = new Identifier(
|
||||
"appliedenergistics2:block/sky_compass_base");
|
||||
|
||||
private static final Identifier MODEL_POINTER = new Identifier(
|
||||
"appliedenergistics2:block/sky_compass_pointer");
|
||||
|
||||
public static final List<Identifier> DEPENDENCIES = ImmutableList.of(MODEL_BASE, MODEL_POINTER);
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
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<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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package appeng.worldgen;
|
||||
|
||||
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.Heightmap;
|
||||
import net.minecraft.world.ServerWorldAccess;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* 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.CODEC);
|
||||
|
||||
public ChargedQuartzOreFeature(Codec<ChargedQuartzOreConfig> codec) {
|
||||
super(codec);
|
||||
}
|
||||
|
||||
@Override
|
||||
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.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.getStartX(); x <= chunkPos.getEndX(); x++) {
|
||||
bpos.setX(x);
|
||||
for (int z = chunkPos.getStartZ(); z <= chunkPos.getEndZ(); z++) {
|
||||
bpos.setZ(z);
|
||||
if (chunk.getBlockState(bpos).getBlock() == config.target.getBlock()
|
||||
&& rand.nextFloat() < config.chance) {
|
||||
chunk.setBlockState(bpos, config.state, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user