feat: implement BORG Kindberg
This commit is contained in:
parent
4acbedbfca
commit
ed1e725810
|
@ -18,6 +18,10 @@ loom {
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
maven {
|
||||||
|
url "https://maven.tilera.xyz/"
|
||||||
|
}
|
||||||
maven {
|
maven {
|
||||||
url "https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/"
|
url "https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/"
|
||||||
}
|
}
|
||||||
|
@ -31,6 +35,7 @@ dependencies {
|
||||||
forge "net.minecraftforge:forge:${project.forge_version}"
|
forge "net.minecraftforge:forge:${project.forge_version}"
|
||||||
|
|
||||||
modImplementation "software.bernie.geckolib:geckolib-forge-1.18:3.0.57"
|
modImplementation "software.bernie.geckolib:geckolib-forge-1.18:3.0.57"
|
||||||
|
modImplementation "net.anvilcraft:anvillib-18:0.1.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
|
|
@ -3,12 +3,13 @@ package net.anvilcraft.ntx4core;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import net.anvilcraft.ntx4core.worldgen.Ntx4CoreFeatures;
|
||||||
|
import net.anvilcraft.ntx4core.worldgen.Ntx4CoreStructures;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.eventbus.api.IEventBus;
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import software.bernie.geckolib3.GeckoLib;
|
|
||||||
|
|
||||||
@Mod("ntx4core")
|
@Mod("ntx4core")
|
||||||
public class Ntx4Core {
|
public class Ntx4Core {
|
||||||
|
@ -20,8 +21,8 @@ public class Ntx4Core {
|
||||||
|
|
||||||
Ntx4CoreBlocks.BLOCKS.register(bus);
|
Ntx4CoreBlocks.BLOCKS.register(bus);
|
||||||
Ntx4CoreItems.ITEMS.register(bus);
|
Ntx4CoreItems.ITEMS.register(bus);
|
||||||
|
Ntx4CoreFeatures.STRUCTURE_FEATURES.register(bus);
|
||||||
GeckoLib.initialize();
|
Ntx4CoreStructures.CONFIGURED_STRUCTURE_FEATURES.register(bus);
|
||||||
|
|
||||||
MinecraftForge.EVENT_BUS.register(Ntx4CoreShaders.class);
|
MinecraftForge.EVENT_BUS.register(Ntx4CoreShaders.class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package net.anvilcraft.ntx4core;
|
package net.anvilcraft.ntx4core;
|
||||||
|
|
||||||
import net.anvilcraft.ntx4core.blocks.BlockAlec;
|
import net.anvilcraft.ntx4core.blocks.BlockAlecubus;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraftforge.registries.DeferredRegister;
|
import net.minecraftforge.registries.DeferredRegister;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
@ -10,6 +10,6 @@ public class Ntx4CoreBlocks {
|
||||||
public static final DeferredRegister<Block> BLOCKS
|
public static final DeferredRegister<Block> BLOCKS
|
||||||
= DeferredRegister.create(ForgeRegistries.BLOCKS, Ntx4Core.MODID);
|
= DeferredRegister.create(ForgeRegistries.BLOCKS, Ntx4Core.MODID);
|
||||||
|
|
||||||
public static final RegistryObject<Block> ALEC
|
public static final RegistryObject<Block> ALECUBUS
|
||||||
= BLOCKS.register("alec", BlockAlec::new);
|
= BLOCKS.register("alecubus", BlockAlecubus::new);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,6 @@ public class Ntx4CoreItemGroup extends ItemGroup {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack createIcon() {
|
public ItemStack createIcon() {
|
||||||
return new ItemStack(Ntx4CoreBlocks.ALEC.get());
|
return new ItemStack(Ntx4CoreBlocks.ALECUBUS.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,10 @@ public class Ntx4CoreItems {
|
||||||
= DeferredRegister.create(ForgeRegistries.ITEMS, Ntx4Core.MODID);
|
= DeferredRegister.create(ForgeRegistries.ITEMS, Ntx4Core.MODID);
|
||||||
|
|
||||||
public static final RegistryObject<Item> ALEC = ITEMS.register(
|
public static final RegistryObject<Item> ALEC = ITEMS.register(
|
||||||
"alec",
|
"alecubus",
|
||||||
()
|
()
|
||||||
-> new BlockItem(
|
-> new BlockItem(
|
||||||
Ntx4CoreBlocks.ALEC.get(),
|
Ntx4CoreBlocks.ALECUBUS.get(),
|
||||||
new Item.Settings().group(Ntx4CoreItemGroup.INSTANCE)
|
new Item.Settings().group(Ntx4CoreItemGroup.INSTANCE)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core;
|
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.recipe.Ingredient;
|
|
||||||
import net.minecraft.tag.TagKey;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
|
|
||||||
public class Util {
|
|
||||||
public static ItemStack stackFromRegistry(Identifier id) {
|
|
||||||
if (ForgeRegistries.ITEMS.containsKey(id)) {
|
|
||||||
return new ItemStack(ForgeRegistries.ITEMS.getValue(id));
|
|
||||||
} else if (ForgeRegistries.BLOCKS.containsKey(id)) {
|
|
||||||
return new ItemStack(ForgeRegistries.BLOCKS.getValue(id));
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("No block or item with ID " + id + "!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Ingredient ingredientFromString(String s) {
|
|
||||||
if (s.charAt(0) == '#')
|
|
||||||
return Ingredient.fromTag(
|
|
||||||
TagKey.of(Registry.ITEM_KEY, new Identifier(s.substring(1)))
|
|
||||||
);
|
|
||||||
|
|
||||||
return Ingredient.ofStacks(stackFromRegistry(new Identifier(s)));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,8 +11,8 @@ import net.minecraft.world.BlockView;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.explosion.Explosion;
|
import net.minecraft.world.explosion.Explosion;
|
||||||
|
|
||||||
public class BlockAlec extends Block {
|
public class BlockAlecubus extends Block {
|
||||||
public BlockAlec() {
|
public BlockAlecubus() {
|
||||||
super(Settings.of(Material.STONE, MapColor.BRIGHT_RED)
|
super(Settings.of(Material.STONE, MapColor.BRIGHT_RED)
|
||||||
.requiresTool()
|
.requiresTool()
|
||||||
.strength(2.f, 6.f)
|
.strength(2.f, 6.f)
|
|
@ -1,24 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.cosmetics;
|
|
||||||
|
|
||||||
import net.anvilcraft.ntx4core.Ntx4Core;
|
|
||||||
import net.minecraft.client.render.entity.PlayerEntityRenderer;
|
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.client.event.EntityRenderersEvent;
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
|
||||||
|
|
||||||
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD, value = { Dist.CLIENT })
|
|
||||||
public class ClientEventHandler {
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void clientSetup(EntityRenderersEvent.AddLayers event) {
|
|
||||||
Ntx4Core.LOGGER.info("Client Setup: adding CosmeticLayer");
|
|
||||||
for (String skin : event.getSkins()) {
|
|
||||||
Ntx4Core.LOGGER.info("Client Setup: player check");
|
|
||||||
if (event.getSkin(skin) instanceof PlayerEntityRenderer render) {
|
|
||||||
Ntx4Core.LOGGER.info("Client Setup: added CosmeticLayer");
|
|
||||||
render.addFeature(new CosmeticFeatureRenderer(render, skin));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,415 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.cosmetics;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import net.minecraft.client.render.OverlayTexture;
|
|
||||||
import net.minecraft.client.render.RenderLayer;
|
|
||||||
import net.minecraft.client.render.VertexConsumer;
|
|
||||||
import net.minecraft.client.render.VertexConsumerProvider;
|
|
||||||
import net.minecraft.client.render.entity.model.BipedEntityModel;
|
|
||||||
import net.minecraft.client.render.entity.model.EntityModelLayers;
|
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.math.Matrix4f;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.util.math.Vec3f;
|
|
||||||
import net.minecraftforge.fml.ModList;
|
|
||||||
import org.jetbrains.annotations.ApiStatus.AvailableSince;
|
|
||||||
import software.bernie.geckolib3.compat.PatchouliCompat;
|
|
||||||
import software.bernie.geckolib3.core.IAnimatable;
|
|
||||||
import software.bernie.geckolib3.core.IAnimatableModel;
|
|
||||||
import software.bernie.geckolib3.core.controller.AnimationController;
|
|
||||||
import software.bernie.geckolib3.core.controller.AnimationController.ModelFetcher;
|
|
||||||
import software.bernie.geckolib3.core.event.predicate.AnimationEvent;
|
|
||||||
import software.bernie.geckolib3.core.processor.IBone;
|
|
||||||
import software.bernie.geckolib3.core.util.Color;
|
|
||||||
import software.bernie.geckolib3.geo.render.built.GeoBone;
|
|
||||||
import software.bernie.geckolib3.geo.render.built.GeoModel;
|
|
||||||
import software.bernie.geckolib3.model.AnimatedGeoModel;
|
|
||||||
import software.bernie.geckolib3.renderers.geo.IGeoRenderer;
|
|
||||||
import software.bernie.geckolib3.util.EModelRenderCycle;
|
|
||||||
import software.bernie.geckolib3.util.GeoUtils;
|
|
||||||
import software.bernie.geckolib3.util.IRenderCycle;
|
|
||||||
import software.bernie.geckolib3.util.RenderUtils;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class CosmeticArmorRenderer extends BipedEntityModel
|
|
||||||
implements IGeoRenderer<CosmeticItem>, ModelFetcher<CosmeticItem> {
|
|
||||||
protected CosmeticItem currentArmorItem;
|
|
||||||
protected LivingEntity entityLiving;
|
|
||||||
protected float widthScale = 1;
|
|
||||||
protected float heightScale = 1;
|
|
||||||
protected Matrix4f dispatchedMat = new Matrix4f();
|
|
||||||
protected Matrix4f renderEarlyMat = new Matrix4f();
|
|
||||||
|
|
||||||
public String headBone = null;
|
|
||||||
public String bodyBone = null;
|
|
||||||
public String rightArmBone = null;
|
|
||||||
public String leftArmBone = null;
|
|
||||||
public String rightLegBone = null;
|
|
||||||
public String leftLegBone = null;
|
|
||||||
|
|
||||||
private final AnimatedGeoModel<CosmeticItem> modelProvider;
|
|
||||||
|
|
||||||
protected VertexConsumerProvider rtb = null;
|
|
||||||
|
|
||||||
private IRenderCycle currentModelRenderCycle = EModelRenderCycle.INITIAL;
|
|
||||||
|
|
||||||
{ AnimationController.addModelFetcher(this); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public IAnimatableModel<CosmeticItem> apply(IAnimatable t) {
|
|
||||||
if (t instanceof CosmeticItem)
|
|
||||||
return this.getGeoModelProvider();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CosmeticArmorRenderer() {
|
|
||||||
super(MinecraftClient.getInstance().getEntityModelLoader().getModelPart(
|
|
||||||
EntityModelLayers.PLAYER_INNER_ARMOR
|
|
||||||
));
|
|
||||||
|
|
||||||
this.modelProvider = new CosmeticModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
MatrixStack poseStack,
|
|
||||||
VertexConsumer buffer,
|
|
||||||
int packedLight,
|
|
||||||
int packedOverlay,
|
|
||||||
float red,
|
|
||||||
float green,
|
|
||||||
float blue,
|
|
||||||
float alpha
|
|
||||||
) {
|
|
||||||
this.render(0, poseStack, buffer, packedLight);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void render(
|
|
||||||
float partialTick, MatrixStack poseStack, VertexConsumer buffer, int packedLight
|
|
||||||
) {
|
|
||||||
GeoModel model = this.modelProvider.getModel(
|
|
||||||
this.modelProvider.getModelLocation(this.currentArmorItem)
|
|
||||||
);
|
|
||||||
AnimationEvent animationEvent = new AnimationEvent(
|
|
||||||
this.currentArmorItem,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
MinecraftClient.getInstance().getTickDelta(),
|
|
||||||
false, // can also be getLastFrameDuration()
|
|
||||||
Arrays.asList(this.entityLiving)
|
|
||||||
);
|
|
||||||
|
|
||||||
poseStack.push();
|
|
||||||
poseStack.translate(0, 24 / 16F, 0);
|
|
||||||
poseStack.scale(-1, -1, 1);
|
|
||||||
|
|
||||||
//this.dispatchedMat = poseStack.last().pose().copy();
|
|
||||||
this.dispatchedMat = poseStack.peek().getPositionMatrix().copy();
|
|
||||||
|
|
||||||
this.modelProvider.setLivingAnimations(
|
|
||||||
this.currentArmorItem, getInstanceId(this.currentArmorItem), animationEvent
|
|
||||||
);
|
|
||||||
setCurrentModelRenderCycle(EModelRenderCycle.INITIAL);
|
|
||||||
fitToBiped();
|
|
||||||
RenderSystem.setShaderTexture(0, getTextureLocation(this.currentArmorItem));
|
|
||||||
|
|
||||||
Color renderColor = getRenderColor(
|
|
||||||
this.currentArmorItem, partialTick, poseStack, null, buffer, packedLight
|
|
||||||
);
|
|
||||||
RenderLayer renderType = getRenderType(
|
|
||||||
this.currentArmorItem,
|
|
||||||
partialTick,
|
|
||||||
poseStack,
|
|
||||||
null,
|
|
||||||
buffer,
|
|
||||||
packedLight,
|
|
||||||
getTextureLocation(this.currentArmorItem)
|
|
||||||
);
|
|
||||||
|
|
||||||
render(
|
|
||||||
model,
|
|
||||||
this.currentArmorItem,
|
|
||||||
partialTick,
|
|
||||||
renderType,
|
|
||||||
poseStack,
|
|
||||||
null,
|
|
||||||
buffer,
|
|
||||||
packedLight,
|
|
||||||
OverlayTexture.DEFAULT_UV,
|
|
||||||
renderColor.getRed() / 255f,
|
|
||||||
renderColor.getGreen() / 255f,
|
|
||||||
renderColor.getBlue() / 255f,
|
|
||||||
renderColor.getAlpha() / 255f
|
|
||||||
);
|
|
||||||
|
|
||||||
if (ModList.get().isLoaded("patchouli"))
|
|
||||||
PatchouliCompat.patchouliLoaded(poseStack);
|
|
||||||
|
|
||||||
poseStack.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderEarly(
|
|
||||||
CosmeticItem animatable,
|
|
||||||
MatrixStack poseStack,
|
|
||||||
float partialTick,
|
|
||||||
VertexConsumerProvider bufferSource,
|
|
||||||
VertexConsumer buffer,
|
|
||||||
int packedLight,
|
|
||||||
int packedOverlay,
|
|
||||||
float red,
|
|
||||||
float green,
|
|
||||||
float blue,
|
|
||||||
float alpha
|
|
||||||
) {
|
|
||||||
//this.renderEarlyMat = poseStack.last().pose().copy();
|
|
||||||
this.renderEarlyMat = poseStack.peek().getPositionMatrix().copy();
|
|
||||||
this.currentArmorItem = animatable;
|
|
||||||
|
|
||||||
IGeoRenderer.super.renderEarly(
|
|
||||||
animatable,
|
|
||||||
poseStack,
|
|
||||||
partialTick,
|
|
||||||
bufferSource,
|
|
||||||
buffer,
|
|
||||||
packedLight,
|
|
||||||
packedOverlay,
|
|
||||||
red,
|
|
||||||
green,
|
|
||||||
blue,
|
|
||||||
alpha
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderRecursively(
|
|
||||||
GeoBone bone,
|
|
||||||
MatrixStack poseStack,
|
|
||||||
VertexConsumer buffer,
|
|
||||||
int packedLight,
|
|
||||||
int packedOverlay,
|
|
||||||
float red,
|
|
||||||
float green,
|
|
||||||
float blue,
|
|
||||||
float alpha
|
|
||||||
) {
|
|
||||||
if (bone.isTrackingXform()) {
|
|
||||||
//Matrix4f poseState = poseStack.last().pose();
|
|
||||||
Matrix4f poseState = poseStack.peek().getPositionMatrix();
|
|
||||||
Vec3d renderOffset = getRenderOffset(this.currentArmorItem, 1);
|
|
||||||
Matrix4f localMatrix
|
|
||||||
= RenderUtils.invertAndMultiplyMatrices(poseState, this.dispatchedMat);
|
|
||||||
|
|
||||||
bone.setModelSpaceXform(
|
|
||||||
RenderUtils.invertAndMultiplyMatrices(poseState, this.renderEarlyMat)
|
|
||||||
);
|
|
||||||
//localMatrix.translate(new Vec3f(renderOffset));
|
|
||||||
localMatrix.addToLastColumn(new Vec3f(renderOffset));
|
|
||||||
bone.setLocalSpaceXform(localMatrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
IGeoRenderer.super.renderRecursively(
|
|
||||||
bone, poseStack, buffer, packedLight, packedOverlay, red, green, blue, alpha
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vec3d getRenderOffset(CosmeticItem entity, float partialTick) {
|
|
||||||
return Vec3d.ZERO;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void fitToBiped() {
|
|
||||||
if (this.headBone != null) {
|
|
||||||
IBone headBone = this.modelProvider.getBone(this.headBone);
|
|
||||||
|
|
||||||
GeoUtils.copyRotations(this.head, headBone);
|
|
||||||
headBone.setPositionX(this.head.pivotX);
|
|
||||||
headBone.setPositionY(-this.head.pivotY);
|
|
||||||
headBone.setPositionZ(this.head.pivotZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.bodyBone != null) {
|
|
||||||
IBone bodyBone = this.modelProvider.getBone(this.bodyBone);
|
|
||||||
|
|
||||||
GeoUtils.copyRotations(this.body, bodyBone);
|
|
||||||
bodyBone.setPositionX(this.body.pivotX);
|
|
||||||
bodyBone.setPositionY(-this.body.pivotY);
|
|
||||||
bodyBone.setPositionZ(this.body.pivotZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.rightArmBone != null) {
|
|
||||||
IBone rightArmBone = this.modelProvider.getBone(this.rightArmBone);
|
|
||||||
|
|
||||||
GeoUtils.copyRotations(this.rightArm, rightArmBone);
|
|
||||||
rightArmBone.setPositionX(this.rightArm.pivotX + 5);
|
|
||||||
rightArmBone.setPositionY(2 - this.rightArm.pivotY);
|
|
||||||
rightArmBone.setPositionZ(this.rightArm.pivotZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.leftArmBone != null) {
|
|
||||||
IBone leftArmBone = this.modelProvider.getBone(this.leftArmBone);
|
|
||||||
|
|
||||||
GeoUtils.copyRotations(this.leftArm, leftArmBone);
|
|
||||||
leftArmBone.setPositionX(this.leftArm.pivotX - 5);
|
|
||||||
leftArmBone.setPositionY(2 - this.leftArm.pivotY);
|
|
||||||
leftArmBone.setPositionZ(this.leftArm.pivotZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.rightLegBone != null) {
|
|
||||||
IBone rightLegBone = this.modelProvider.getBone(this.rightLegBone);
|
|
||||||
|
|
||||||
GeoUtils.copyRotations(this.rightLeg, rightLegBone);
|
|
||||||
rightLegBone.setPositionX(this.rightLeg.pivotX + 2);
|
|
||||||
rightLegBone.setPositionY(12 - this.rightLeg.pivotY);
|
|
||||||
rightLegBone.setPositionZ(this.rightLeg.pivotZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.leftLegBone != null) {
|
|
||||||
IBone leftLegBone = this.modelProvider.getBone(this.leftLegBone);
|
|
||||||
|
|
||||||
GeoUtils.copyRotations(this.leftLeg, leftLegBone);
|
|
||||||
leftLegBone.setPositionX(this.leftLeg.pivotX - 2);
|
|
||||||
leftLegBone.setPositionY(12 - this.leftLeg.pivotY);
|
|
||||||
leftLegBone.setPositionZ(this.leftLeg.pivotZ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AnimatedGeoModel<CosmeticItem> getGeoModelProvider() {
|
|
||||||
return this.modelProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@AvailableSince(value = "3.1.24")
|
|
||||||
@Override
|
|
||||||
@Nonnull
|
|
||||||
public IRenderCycle getCurrentModelRenderCycle() {
|
|
||||||
return this.currentModelRenderCycle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@AvailableSince(value = "3.1.24")
|
|
||||||
@Override
|
|
||||||
public void setCurrentModelRenderCycle(IRenderCycle currentModelRenderCycle) {
|
|
||||||
this.currentModelRenderCycle = currentModelRenderCycle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@AvailableSince(value = "3.1.24")
|
|
||||||
@Override
|
|
||||||
public float getWidthScale(CosmeticItem animatable) {
|
|
||||||
return this.widthScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
@AvailableSince(value = "3.1.24")
|
|
||||||
@Override
|
|
||||||
public float getHeightScale(CosmeticItem entity) {
|
|
||||||
return this.heightScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Identifier getTextureLocation(CosmeticItem animatable) {
|
|
||||||
return this.modelProvider.getTextureLocation(animatable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Everything after this point needs to be called every frame before rendering
|
|
||||||
*/
|
|
||||||
public CosmeticArmorRenderer setCurrentItem(LivingEntity entity, CosmeticItem item) {
|
|
||||||
this.entityLiving = entity;
|
|
||||||
this.currentArmorItem = item;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final CosmeticArmorRenderer applyEntityStats(BipedEntityModel defaultArmor) {
|
|
||||||
this.child = defaultArmor.child;
|
|
||||||
this.sneaking = defaultArmor.sneaking;
|
|
||||||
this.riding = defaultArmor.riding;
|
|
||||||
this.rightArmPose = defaultArmor.rightArmPose;
|
|
||||||
this.leftArmPose = defaultArmor.leftArmPose;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void filterBones() {
|
|
||||||
this.headBone = getCurrentCosmetic().getHead();
|
|
||||||
this.bodyBone = getCurrentCosmetic().getBody();
|
|
||||||
this.leftArmBone = getCurrentCosmetic().getLeftArm();
|
|
||||||
this.rightArmBone = getCurrentCosmetic().getRightArm();
|
|
||||||
this.leftLegBone = getCurrentCosmetic().getLeftLeg();
|
|
||||||
this.rightLegBone = getCurrentCosmetic().getRightLeg();
|
|
||||||
|
|
||||||
getGeoModelProvider().getModel(getCurrentCosmetic().getModelLocation());
|
|
||||||
|
|
||||||
this.setBoneVisibility(this.headBone, getCurrentCosmetic().getHead() != null);
|
|
||||||
this.setBoneVisibility(this.bodyBone, getCurrentCosmetic().getBody() != null);
|
|
||||||
this.setBoneVisibility(
|
|
||||||
this.leftArmBone, getCurrentCosmetic().getLeftArm() != null
|
|
||||||
);
|
|
||||||
this.setBoneVisibility(
|
|
||||||
this.rightArmBone, getCurrentCosmetic().getRightArm() != null
|
|
||||||
);
|
|
||||||
this.setBoneVisibility(
|
|
||||||
this.leftLegBone, getCurrentCosmetic().getLeftLeg() != null
|
|
||||||
);
|
|
||||||
this.setBoneVisibility(
|
|
||||||
this.rightLegBone, getCurrentCosmetic().getRightLeg() != null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a specific bone (and its child-bones) to visible or not
|
|
||||||
* @param boneName The name of the bone
|
|
||||||
* @param isVisible Whether the bone should be visible
|
|
||||||
*/
|
|
||||||
protected void setBoneVisibility(String boneName, boolean isVisible) {
|
|
||||||
if (boneName == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.modelProvider.getBone(boneName).setHidden(!isVisible);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use {@link CosmeticArmorRenderer#setBoneVisibility(String, boolean)}
|
|
||||||
*/
|
|
||||||
@Deprecated(forRemoval = true)
|
|
||||||
protected IBone getAndHideBone(String boneName) {
|
|
||||||
setBoneVisibility(boneName, false);
|
|
||||||
|
|
||||||
return this.modelProvider.getBone(boneName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use {@link IGeoRenderer#getInstanceId(Object)}<br>
|
|
||||||
* Remove in 1.20+
|
|
||||||
*/
|
|
||||||
@Deprecated(forRemoval = true)
|
|
||||||
public Integer getUniqueID(CosmeticItem animatable) {
|
|
||||||
return getInstanceId(animatable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInstanceId(CosmeticItem animatable) {
|
|
||||||
return Objects.hash(
|
|
||||||
this.currentArmorItem.getCosmetic().getID(), this.entityLiving.getUuid()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCurrentRTB(VertexConsumerProvider bufferSource) {
|
|
||||||
this.rtb = bufferSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VertexConsumerProvider getCurrentRTB() {
|
|
||||||
return this.rtb;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ICosmetic getCurrentCosmetic() {
|
|
||||||
return this.currentArmorItem.getCosmetic();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.cosmetics;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import net.minecraft.client.model.ModelPart;
|
|
||||||
import net.minecraft.client.network.AbstractClientPlayerEntity;
|
|
||||||
import net.minecraft.client.render.RenderLayer;
|
|
||||||
import net.minecraft.client.render.VertexConsumer;
|
|
||||||
import net.minecraft.client.render.VertexConsumerProvider;
|
|
||||||
import net.minecraft.client.render.entity.PlayerEntityRenderer;
|
|
||||||
import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer;
|
|
||||||
import net.minecraft.client.render.entity.model.BipedEntityModel;
|
|
||||||
import net.minecraft.client.render.entity.model.PlayerEntityModel;
|
|
||||||
import net.minecraft.client.render.item.ItemRenderer;
|
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
|
||||||
|
|
||||||
public class CosmeticFeatureRenderer extends ArmorFeatureRenderer<
|
|
||||||
AbstractClientPlayerEntity,
|
|
||||||
PlayerEntityModel<AbstractClientPlayerEntity>,
|
|
||||||
BipedEntityModel<AbstractClientPlayerEntity>> {
|
|
||||||
private static final Map<ICosmetic, CosmeticItem> modelCache = new HashMap<>();
|
|
||||||
private static CosmeticArmorRenderer cosmeticRenderer = null;
|
|
||||||
PlayerEntityRenderer renderer;
|
|
||||||
String skin;
|
|
||||||
|
|
||||||
public CosmeticFeatureRenderer(PlayerEntityRenderer renderer, String skin) {
|
|
||||||
super(renderer, null, null);
|
|
||||||
this.renderer = renderer;
|
|
||||||
this.skin = skin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
MatrixStack matrix,
|
|
||||||
VertexConsumerProvider buffer,
|
|
||||||
int light,
|
|
||||||
AbstractClientPlayerEntity player,
|
|
||||||
float limbSwing,
|
|
||||||
float limbSwingAmount,
|
|
||||||
float partialTicks,
|
|
||||||
float ageInTicks,
|
|
||||||
float netHeadYaw,
|
|
||||||
float headPitch
|
|
||||||
) {
|
|
||||||
for (ICosmetic c : CosmeticsManager.getCosmeticsForPlayer(player.getUuid())) {
|
|
||||||
if (c.readyToRender())
|
|
||||||
this.renderCosmetic(matrix, buffer, player, light, c, partialTicks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderCosmetic(
|
|
||||||
MatrixStack matrix,
|
|
||||||
VertexConsumerProvider buffer,
|
|
||||||
AbstractClientPlayerEntity player,
|
|
||||||
int light,
|
|
||||||
ICosmetic cosmetic,
|
|
||||||
float partialTicks
|
|
||||||
) {
|
|
||||||
if (cosmeticRenderer == null)
|
|
||||||
cosmeticRenderer = new CosmeticArmorRenderer();
|
|
||||||
if (!modelCache.containsKey(cosmetic))
|
|
||||||
modelCache.put(cosmetic, new CosmeticItem(cosmetic));
|
|
||||||
CosmeticItem item = modelCache.get(cosmetic);
|
|
||||||
copyRotations(this.renderer.getModel(), cosmeticRenderer);
|
|
||||||
cosmeticRenderer.applyEntityStats(this.renderer.getModel());
|
|
||||||
cosmeticRenderer.setCurrentItem(player, item);
|
|
||||||
cosmeticRenderer.filterBones();
|
|
||||||
|
|
||||||
VertexConsumer vertex = ItemRenderer.getArmorGlintConsumer(
|
|
||||||
buffer,
|
|
||||||
RenderLayer.getArmorCutoutNoCull(cosmetic.getTextureLocation()),
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
cosmeticRenderer.render(partialTicks, matrix, vertex, light);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void copyRotations(BipedEntityModel<?> from, BipedEntityModel<?> to) {
|
|
||||||
copyRotations(from.head, to.head);
|
|
||||||
copyRotations(from.hat, to.hat);
|
|
||||||
copyRotations(from.body, to.body);
|
|
||||||
copyRotations(from.leftArm, to.leftArm);
|
|
||||||
copyRotations(from.rightArm, to.rightArm);
|
|
||||||
copyRotations(from.rightLeg, to.rightLeg);
|
|
||||||
copyRotations(from.leftLeg, to.leftLeg);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void copyRotations(ModelPart from, ModelPart to) {
|
|
||||||
to.copyTransform(from);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.cosmetics;
|
|
||||||
|
|
||||||
import software.bernie.geckolib3.core.IAnimatable;
|
|
||||||
import software.bernie.geckolib3.core.PlayState;
|
|
||||||
import software.bernie.geckolib3.core.builder.AnimationBuilder;
|
|
||||||
import software.bernie.geckolib3.core.controller.AnimationController;
|
|
||||||
import software.bernie.geckolib3.core.event.predicate.AnimationEvent;
|
|
||||||
import software.bernie.geckolib3.core.manager.AnimationData;
|
|
||||||
import software.bernie.geckolib3.core.manager.AnimationFactory;
|
|
||||||
import software.bernie.geckolib3.util.GeckoLibUtil;
|
|
||||||
|
|
||||||
public class CosmeticItem implements IAnimatable {
|
|
||||||
private ICosmetic cosmetic = null;
|
|
||||||
private AnimationBuilder animationBuilder = new AnimationBuilder();
|
|
||||||
|
|
||||||
public CosmeticItem(ICosmetic cosmetic) {
|
|
||||||
this.cosmetic = cosmetic;
|
|
||||||
this.cosmetic.addAnimations(animationBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
private <P extends IAnimatable> PlayState predicate(AnimationEvent<P> event) {
|
|
||||||
event.getController().transitionLengthTicks = 0;
|
|
||||||
event.getController().setAnimation(animationBuilder);
|
|
||||||
return PlayState.CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void registerControllers(AnimationData data) {
|
|
||||||
data.addAnimationController(
|
|
||||||
new AnimationController<>(this, "controller", 20, this::predicate)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final AnimationFactory factory = GeckoLibUtil.createFactory(this);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AnimationFactory getFactory() {
|
|
||||||
return this.factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ICosmetic getCosmetic() {
|
|
||||||
return this.cosmetic;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.cosmetics;
|
|
||||||
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import software.bernie.geckolib3.model.AnimatedGeoModel;
|
|
||||||
|
|
||||||
public class CosmeticModel extends AnimatedGeoModel<CosmeticItem> {
|
|
||||||
@Override
|
|
||||||
public Identifier getAnimationFileLocation(CosmeticItem animatable) {
|
|
||||||
return animatable.getCosmetic().getAnimationFileLocation();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Identifier getModelLocation(CosmeticItem animatable) {
|
|
||||||
return animatable.getCosmetic().getModelLocation();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Identifier getTextureLocation(CosmeticItem animatable) {
|
|
||||||
return animatable.getCosmetic().getTextureLocation();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.cosmetics;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class CosmeticsManager {
|
|
||||||
private static List<ICosmeticProvider> providers = new ArrayList<>();
|
|
||||||
private static Map<UUID, List<ICosmetic>> cosmeticCache = new HashMap<>();
|
|
||||||
private static Set<UUID> activePlayers = new HashSet<>();
|
|
||||||
|
|
||||||
private static void refresh() {
|
|
||||||
boolean doRefresh = false;
|
|
||||||
for (ICosmeticProvider provider : providers) {
|
|
||||||
doRefresh = doRefresh || provider.requestsRefresh();
|
|
||||||
}
|
|
||||||
if (!doRefresh)
|
|
||||||
return;
|
|
||||||
cosmeticCache.clear();
|
|
||||||
for (UUID uuid : activePlayers) {
|
|
||||||
loadPlayer(uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void loadPlayer(UUID player) {
|
|
||||||
if (cosmeticCache.containsKey(player))
|
|
||||||
return;
|
|
||||||
cosmeticCache.put(player, new ArrayList<>());
|
|
||||||
List<ICosmetic> cosmetics = cosmeticCache.get(player);
|
|
||||||
for (ICosmeticProvider provider : providers) {
|
|
||||||
provider.addCosmetics(player, (cosmetic) -> cosmetics.add(cosmetic));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void registerProvider(ICosmeticProvider provider) {
|
|
||||||
providers.add(provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static List<ICosmetic> getCosmeticsForPlayer(UUID uuid) {
|
|
||||||
if (!activePlayers.contains(uuid)) {
|
|
||||||
activePlayers.add(uuid);
|
|
||||||
loadPlayer(uuid);
|
|
||||||
}
|
|
||||||
refresh();
|
|
||||||
return cosmeticCache.get(uuid);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.cosmetics;
|
|
||||||
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import software.bernie.geckolib3.core.builder.AnimationBuilder;
|
|
||||||
|
|
||||||
public interface ICosmetic {
|
|
||||||
Identifier getAnimationFileLocation();
|
|
||||||
|
|
||||||
Identifier getModelLocation();
|
|
||||||
|
|
||||||
Identifier getTextureLocation();
|
|
||||||
|
|
||||||
default String getHead() {
|
|
||||||
return null; //head
|
|
||||||
}
|
|
||||||
|
|
||||||
default String getBody() {
|
|
||||||
return null; //body
|
|
||||||
}
|
|
||||||
|
|
||||||
default String getLeftArm() {
|
|
||||||
return null; //arm_left
|
|
||||||
}
|
|
||||||
|
|
||||||
default String getRightArm() {
|
|
||||||
return null; //arm_right
|
|
||||||
}
|
|
||||||
|
|
||||||
default String getLeftLeg() {
|
|
||||||
return null; //leg_left
|
|
||||||
}
|
|
||||||
|
|
||||||
default String getRightLeg() {
|
|
||||||
return null; //leg_right
|
|
||||||
}
|
|
||||||
|
|
||||||
void addAnimations(AnimationBuilder builder);
|
|
||||||
|
|
||||||
default boolean readyToRender() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Identifier getID();
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.cosmetics;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public interface ICosmeticProvider {
|
|
||||||
boolean requestsRefresh();
|
|
||||||
|
|
||||||
void addCosmetics(UUID player, Consumer<ICosmetic> cosmeticAdder);
|
|
||||||
}
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package net.anvilcraft.ntx4core.mixin.accessor;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
import net.minecraft.world.gen.GenerationStep;
|
||||||
|
import net.minecraft.world.gen.feature.StructureFeature;
|
||||||
|
|
||||||
|
@Mixin(StructureFeature.class)
|
||||||
|
public interface StructureFeatureAccessor {
|
||||||
|
@Accessor("STRUCTURE_TO_GENERATION_STEP")
|
||||||
|
public static Map<StructureFeature<?>, GenerationStep.Feature>
|
||||||
|
getStructureToGenerationStepMap() {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,54 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.mixin.common;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
|
|
||||||
import net.anvilcraft.ntx4core.Ntx4Core;
|
|
||||||
import net.anvilcraft.ntx4core.recipe.RecipesEvent;
|
|
||||||
import net.minecraft.recipe.Recipe;
|
|
||||||
import net.minecraft.recipe.RecipeManager;
|
|
||||||
import net.minecraft.recipe.RecipeType;
|
|
||||||
import net.minecraft.resource.ResourceManager;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.profiler.Profiler;
|
|
||||||
import net.minecraftforge.fml.ModLoader;
|
|
||||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
|
||||||
|
|
||||||
@Mixin(RecipeManager.class)
|
|
||||||
public class RecipeManagerMixin {
|
|
||||||
@Shadow
|
|
||||||
private Map<RecipeType<?>, Map<Identifier, Recipe<?>>> recipes;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
private Map<Identifier, Recipe<?>> recipesById;
|
|
||||||
|
|
||||||
@Inject(method = "apply", at = @At("RETURN"))
|
|
||||||
private void afterLoad(
|
|
||||||
Map<Identifier, JsonElement> alec1,
|
|
||||||
ResourceManager alec2,
|
|
||||||
Profiler alec3,
|
|
||||||
CallbackInfo ci
|
|
||||||
) {
|
|
||||||
if (!FMLEnvironment.production) {
|
|
||||||
Ntx4Core.LOGGER.warn("Running in dev env, skipping Recipe Event!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ntx4Core.LOGGER.info("Firing Recipe Event");
|
|
||||||
Map<RecipeType<?>, Map<Identifier, Recipe<?>>> recipes = new HashMap<>();
|
|
||||||
this.recipes.forEach((k, v) -> recipes.put(k, new HashMap<>(v)));
|
|
||||||
|
|
||||||
var ev = new RecipesEvent(recipes, new HashMap<>(this.recipesById));
|
|
||||||
ModLoader.get().postEvent(ev);
|
|
||||||
this.recipes = ev.recipes;
|
|
||||||
this.recipesById = ev.recipesById;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.recipe;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import net.anvilcraft.ntx4core.Util;
|
|
||||||
import net.minecraft.recipe.Ingredient;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
|
|
||||||
public abstract class AbstractIngredientCondition implements Predicate<Ingredient> {
|
|
||||||
public static AbstractIngredientCondition of(String s) {
|
|
||||||
return s.charAt(0) == '#'
|
|
||||||
? new TagIngredientCondition(new Identifier(s.substring(1)))
|
|
||||||
: new StackIngredientCondition(Util.stackFromRegistry(new Identifier(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean test(Ingredient i) {
|
|
||||||
return Arrays.stream(i.entries).anyMatch(this::entryMatches);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract boolean entryMatches(Ingredient.Entry e);
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.recipe;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import net.minecraft.recipe.Recipe;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IRecipeMapper describes a class that knows how to conditionally replace recipes.
|
|
||||||
*/
|
|
||||||
public interface IRecipeMapper extends Function<Recipe<?>, Recipe<?>> {
|
|
||||||
public boolean shouldMap(Recipe<?> recipe);
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.recipe;
|
|
||||||
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import net.minecraft.recipe.Ingredient;
|
|
||||||
import net.minecraft.recipe.Recipe;
|
|
||||||
|
|
||||||
public class IngredientsContainPredicate implements Predicate<Recipe<?>> {
|
|
||||||
public Predicate<Ingredient> pred;
|
|
||||||
|
|
||||||
public IngredientsContainPredicate(Predicate<Ingredient> pred) {
|
|
||||||
this.pred = pred;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean test(Recipe<?> r) {
|
|
||||||
return r.getIngredients().stream().anyMatch(this.pred);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.recipe;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import net.anvilcraft.ntx4core.Util;
|
|
||||||
import net.minecraft.recipe.Ingredient;
|
|
||||||
import net.minecraft.recipe.Recipe;
|
|
||||||
|
|
||||||
public class InputReplaceRecipeMapper implements IRecipeMapper {
|
|
||||||
public Map<Predicate<Ingredient>, Ingredient> replacements = new HashMap<>();
|
|
||||||
|
|
||||||
public InputReplaceRecipeMapper replace(Predicate<Ingredient> p, Ingredient i) {
|
|
||||||
this.replacements.put(p, i);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputReplaceRecipeMapper replace(String p, Ingredient i) {
|
|
||||||
return this.replace(AbstractIngredientCondition.of(p), i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputReplaceRecipeMapper replace(String p, String i) {
|
|
||||||
return this.replace(p, Util.ingredientFromString(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputReplaceRecipeMapper replace(Predicate<Ingredient> p, String i) {
|
|
||||||
return this.replace(p, Util.ingredientFromString(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldMap(Recipe<?> recipe) {
|
|
||||||
var ingredients = recipe.getIngredients();
|
|
||||||
if (ingredients == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (var k : this.replacements.keySet())
|
|
||||||
if (ingredients.stream().anyMatch(k))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Recipe<?> apply(Recipe<?> recipe) {
|
|
||||||
var ingredients = recipe.getIngredients();
|
|
||||||
for (int i = 0; i < ingredients.size(); i++) {
|
|
||||||
var ing = ingredients.get(i);
|
|
||||||
for (var entry : this.replacements.entrySet())
|
|
||||||
if (entry.getKey().test(ing))
|
|
||||||
ingredients.set(i, entry.getValue());
|
|
||||||
}
|
|
||||||
return recipe;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.recipe;
|
|
||||||
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.recipe.Recipe;
|
|
||||||
|
|
||||||
public class RecipeContainsPredicate implements Predicate<Recipe<?>> {
|
|
||||||
public ItemStack item;
|
|
||||||
|
|
||||||
public RecipeContainsPredicate(ItemStack item) {
|
|
||||||
this.item = item;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean test(Recipe<?> r) {
|
|
||||||
return r.getIngredients() == null
|
|
||||||
? false
|
|
||||||
: r.getIngredients().stream().anyMatch(new StackIngredientCondition(this.item)
|
|
||||||
) || r.getOutput().isItemEqual(this.item);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.recipe;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import net.minecraft.recipe.Recipe;
|
|
||||||
import net.minecraft.recipe.RecipeType;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraftforge.eventbus.api.Event;
|
|
||||||
import net.minecraftforge.fml.event.IModBusEvent;
|
|
||||||
|
|
||||||
public class RecipesEvent extends Event implements IModBusEvent {
|
|
||||||
public Map<RecipeType<?>, Map<Identifier, Recipe<?>>> recipes;
|
|
||||||
public Map<Identifier, Recipe<?>> recipesById;
|
|
||||||
|
|
||||||
public RecipesEvent(
|
|
||||||
Map<RecipeType<?>, Map<Identifier, Recipe<?>>> recipes,
|
|
||||||
Map<Identifier, Recipe<?>> recipesById
|
|
||||||
) {
|
|
||||||
this.recipes = recipes;
|
|
||||||
this.recipesById = recipesById;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerRecipe(Recipe<?> recipe) {
|
|
||||||
if (!this.recipes.containsKey(recipe.getType()))
|
|
||||||
this.recipes.put(recipe.getType(), new HashMap<>());
|
|
||||||
|
|
||||||
this.recipes.get(recipe.getType()).put(recipe.getId(), recipe);
|
|
||||||
this.recipesById.put(recipe.getId(), recipe);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<Recipe<?>> removeRecipeID(Identifier id) {
|
|
||||||
if (this.recipesById.containsKey(id)) {
|
|
||||||
return Optional.of(
|
|
||||||
this.recipes.get(this.recipesById.remove(id).getType()).remove(id)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeRecipesMatching(Predicate<Recipe<?>> p) {
|
|
||||||
var iter = this.recipesById.entrySet().iterator();
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
var entry = iter.next();
|
|
||||||
if (p.test(entry.getValue())) {
|
|
||||||
iter.remove();
|
|
||||||
this.recipes.get(entry.getValue().getType()).remove(entry.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mapRecipes(IRecipeMapper mapper) {
|
|
||||||
var iter = this.recipesById.entrySet().iterator();
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
var entry = iter.next();
|
|
||||||
if (mapper.shouldMap(entry.getValue())) {
|
|
||||||
var mapped = mapper.apply(entry.getValue());
|
|
||||||
if (mapped != entry.getValue()) {
|
|
||||||
iter.remove();
|
|
||||||
this.recipes.get(entry.getValue().getType()).remove(entry.getKey());
|
|
||||||
this.registerRecipe(mapped);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mapRecipeID(Identifier id, Function<Recipe<?>, Recipe<?>> func) {
|
|
||||||
var recipe = this.recipesById.get(id);
|
|
||||||
if (recipe != null) {
|
|
||||||
var mapped = func.apply(recipe);
|
|
||||||
if (recipe != mapped) {
|
|
||||||
this.removeRecipeID(id);
|
|
||||||
this.registerRecipe(mapped);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.recipe;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import net.anvilcraft.ntx4core.Ntx4Core;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.recipe.Ingredient;
|
|
||||||
import net.minecraft.recipe.ShapedRecipe;
|
|
||||||
import net.minecraft.tag.TagKey;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.collection.DefaultedList;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
|
|
||||||
public class ShapedRecipeBuilder {
|
|
||||||
public Identifier ident;
|
|
||||||
public String[] pattern;
|
|
||||||
public Map<Character, Ingredient> ingredients = new HashMap<>();
|
|
||||||
public ItemStack output;
|
|
||||||
|
|
||||||
public ShapedRecipeBuilder(Identifier ident, ItemStack output) {
|
|
||||||
this.ident = ident;
|
|
||||||
this.output = output;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShapedRecipeBuilder(String ident, ItemStack output) {
|
|
||||||
this(Ntx4Core.id(ident), output);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShapedRecipeBuilder pattern(String... pat) {
|
|
||||||
this.pattern = pat;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShapedRecipeBuilder ingredient(char c, Ingredient i) {
|
|
||||||
this.ingredients.put(c, i);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShapedRecipeBuilder ingredient(char c, ItemStack... is) {
|
|
||||||
return this.ingredient(c, Ingredient.ofStacks(is));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShapedRecipeBuilder ingredient(char c, Item i) {
|
|
||||||
return this.ingredient(c, new ItemStack(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShapedRecipeBuilder ingredient(char c, Block b) {
|
|
||||||
return this.ingredient(c, new ItemStack(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShapedRecipeBuilder ingredient(char c, String s) {
|
|
||||||
if (s.charAt(0) == '#') {
|
|
||||||
return this.tagIngredient(c, new Identifier(s.substring(1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
var ident = new Identifier(s);
|
|
||||||
var maybeItem = ForgeRegistries.ITEMS.getValue(ident);
|
|
||||||
if (maybeItem == null) {
|
|
||||||
var maybeBlock = ForgeRegistries.BLOCKS.getValue(ident);
|
|
||||||
if (maybeBlock == null)
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"ID " + s + " not found in item or block registry!"
|
|
||||||
);
|
|
||||||
|
|
||||||
return this.ingredient(c, maybeBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.ingredient(c, maybeItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShapedRecipeBuilder tagIngredient(char c, Identifier t) {
|
|
||||||
return this.ingredient(c, Ingredient.fromTag(TagKey.of(Registry.ITEM_KEY, t)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShapedRecipe build() {
|
|
||||||
int width = -1;
|
|
||||||
for (String line : this.pattern) {
|
|
||||||
if (width != -1 && width != line.length())
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Lines in crafting pattern must be same width!"
|
|
||||||
);
|
|
||||||
width = line.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
DefaultedList<Ingredient> ingredients = DefaultedList.of();
|
|
||||||
Arrays.stream(this.pattern)
|
|
||||||
.flatMap(s -> s.chars().mapToObj(c -> (char) c))
|
|
||||||
.map(this.ingredients::get)
|
|
||||||
.forEach(ingredients::add);
|
|
||||||
|
|
||||||
return new ShapedRecipe(
|
|
||||||
this.ident, "", width, this.pattern.length, ingredients, this.output
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.recipe;
|
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.recipe.Ingredient.Entry;
|
|
||||||
import net.minecraft.recipe.Ingredient.StackEntry;
|
|
||||||
|
|
||||||
public class StackIngredientCondition extends AbstractIngredientCondition {
|
|
||||||
public ItemStack stack;
|
|
||||||
|
|
||||||
public StackIngredientCondition(ItemStack stack) {
|
|
||||||
this.stack = stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean entryMatches(Entry e) {
|
|
||||||
return e instanceof StackEntry se && se.stack.isItemEqual(this.stack);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package net.anvilcraft.ntx4core.recipe;
|
|
||||||
|
|
||||||
import net.minecraft.recipe.Ingredient.Entry;
|
|
||||||
import net.minecraft.recipe.Ingredient.TagEntry;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
|
|
||||||
public class TagIngredientCondition extends AbstractIngredientCondition {
|
|
||||||
public Identifier id;
|
|
||||||
|
|
||||||
public TagIngredientCondition(Identifier id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean entryMatches(Entry e) {
|
|
||||||
return e instanceof TagEntry te && te.tag.id().equals(this.id);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +1,22 @@
|
||||||
package net.anvilcraft.ntx4core.recipes;
|
package net.anvilcraft.ntx4core.recipes;
|
||||||
|
|
||||||
|
import net.anvilcraft.anvillib.Util;
|
||||||
|
import net.anvilcraft.anvillib.recipe.InputReplaceRecipeMapper;
|
||||||
|
import net.anvilcraft.anvillib.recipe.RecipesEvent;
|
||||||
import net.anvilcraft.ntx4core.Ntx4Core;
|
import net.anvilcraft.ntx4core.Ntx4Core;
|
||||||
import net.anvilcraft.ntx4core.Util;
|
|
||||||
import net.anvilcraft.ntx4core.recipe.InputReplaceRecipeMapper;
|
|
||||||
import net.anvilcraft.ntx4core.recipe.RecipesEvent;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
||||||
|
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||||
|
|
||||||
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD)
|
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD)
|
||||||
public class InputReplacements {
|
public class InputReplacements {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onRecipeRegister(RecipesEvent ev) {
|
public static void onRecipeRegister(RecipesEvent ev) {
|
||||||
|
if (!FMLEnvironment.production)
|
||||||
|
return;
|
||||||
|
|
||||||
var darkMatter = Util.ingredientFromString("projecte:dark_matter");
|
var darkMatter = Util.ingredientFromString("projecte:dark_matter");
|
||||||
|
|
||||||
ev.mapRecipeID(
|
ev.mapRecipeID(
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
package net.anvilcraft.ntx4core.recipes;
|
package net.anvilcraft.ntx4core.recipes;
|
||||||
|
|
||||||
|
import net.anvilcraft.anvillib.Util;
|
||||||
|
import net.anvilcraft.anvillib.recipe.RecipeContainsPredicate;
|
||||||
|
import net.anvilcraft.anvillib.recipe.RecipesEvent;
|
||||||
import net.anvilcraft.ntx4core.Ntx4Core;
|
import net.anvilcraft.ntx4core.Ntx4Core;
|
||||||
import net.anvilcraft.ntx4core.Util;
|
|
||||||
import net.anvilcraft.ntx4core.recipe.RecipeContainsPredicate;
|
|
||||||
import net.anvilcraft.ntx4core.recipe.RecipesEvent;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
||||||
|
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||||
|
|
||||||
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD)
|
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD)
|
||||||
public class RecipeRemovals {
|
public class RecipeRemovals {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onRecipeRegister(RecipesEvent ev) {
|
public static void onRecipeRegister(RecipesEvent ev) {
|
||||||
|
if (!FMLEnvironment.production)
|
||||||
|
return;
|
||||||
|
|
||||||
ev.removeRecipesMatching(new RecipeContainsPredicate(
|
ev.removeRecipesMatching(new RecipeContainsPredicate(
|
||||||
Util.stackFromRegistry(new Identifier("projecte", "condenser_mk1"))
|
Util.stackFromRegistry(new Identifier("projecte", "condenser_mk1"))
|
||||||
));
|
));
|
||||||
|
|
|
@ -1,21 +1,25 @@
|
||||||
package net.anvilcraft.ntx4core.recipes;
|
package net.anvilcraft.ntx4core.recipes;
|
||||||
|
|
||||||
|
import net.anvilcraft.anvillib.recipe.RecipesEvent;
|
||||||
|
import net.anvilcraft.anvillib.recipe.ShapedRecipeBuilder;
|
||||||
import net.anvilcraft.ntx4core.Ntx4Core;
|
import net.anvilcraft.ntx4core.Ntx4Core;
|
||||||
import net.anvilcraft.ntx4core.recipe.RecipesEvent;
|
|
||||||
import net.anvilcraft.ntx4core.recipe.ShapedRecipeBuilder;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
||||||
|
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||||
|
|
||||||
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD)
|
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD)
|
||||||
public class RecipeReplacements {
|
public class RecipeReplacements {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onRecipeRegister(RecipesEvent ev) {
|
public static void onRecipeRegister(RecipesEvent ev) {
|
||||||
|
if (!FMLEnvironment.production)
|
||||||
|
return;
|
||||||
|
|
||||||
ev.mapRecipeID(
|
ev.mapRecipeID(
|
||||||
new Identifier("shrink", "shrinking_device"),
|
new Identifier("shrink", "shrinking_device"),
|
||||||
r
|
r
|
||||||
-> new ShapedRecipeBuilder("shrinking_device", r.getOutput())
|
-> new ShapedRecipeBuilder(Ntx4Core.id("shrinking_device"), r.getOutput())
|
||||||
.pattern("IDI", "TFE", "IDI")
|
.pattern("IDI", "TFE", "IDI")
|
||||||
.ingredient('I', "#forge:ingots/osmium")
|
.ingredient('I', "#forge:ingots/osmium")
|
||||||
.ingredient('D', "projecte:dark_matter")
|
.ingredient('D', "projecte:dark_matter")
|
||||||
|
@ -28,7 +32,7 @@ public class RecipeReplacements {
|
||||||
ev.mapRecipeID(
|
ev.mapRecipeID(
|
||||||
new Identifier("compactmachines", "personal_shrinking_device"),
|
new Identifier("compactmachines", "personal_shrinking_device"),
|
||||||
r
|
r
|
||||||
-> new ShapedRecipeBuilder("shrinking_device", r.getOutput())
|
-> new ShapedRecipeBuilder(Ntx4Core.id("shrinking_device"), r.getOutput())
|
||||||
.pattern("IDI", "TFE", "IDI")
|
.pattern("IDI", "TFE", "IDI")
|
||||||
.ingredient('I', "#forge:ingots/iron")
|
.ingredient('I', "#forge:ingots/iron")
|
||||||
.ingredient('D', "projecte:dark_matter")
|
.ingredient('D', "projecte:dark_matter")
|
||||||
|
@ -41,7 +45,7 @@ public class RecipeReplacements {
|
||||||
ev.mapRecipeID(
|
ev.mapRecipeID(
|
||||||
new Identifier("tempad", "tempad"),
|
new Identifier("tempad", "tempad"),
|
||||||
r
|
r
|
||||||
-> new ShapedRecipeBuilder("tempad", r.getOutput())
|
-> new ShapedRecipeBuilder(Ntx4Core.id("tempad"), r.getOutput())
|
||||||
.pattern("MGM", "TCE", "MGM")
|
.pattern("MGM", "TCE", "MGM")
|
||||||
.ingredient('M', "#forge:ingots/copper")
|
.ingredient('M', "#forge:ingots/copper")
|
||||||
.ingredient('G', "#forge:ingots/refined_glowstone")
|
.ingredient('G', "#forge:ingots/refined_glowstone")
|
||||||
|
@ -54,7 +58,7 @@ public class RecipeReplacements {
|
||||||
ev.mapRecipeID(
|
ev.mapRecipeID(
|
||||||
new Identifier("dmlreforged", "deep_learner"),
|
new Identifier("dmlreforged", "deep_learner"),
|
||||||
r
|
r
|
||||||
-> new ShapedRecipeBuilder("deep_learner", r.getOutput())
|
-> new ShapedRecipeBuilder(Ntx4Core.id("deep_learner"), r.getOutput())
|
||||||
.pattern("MGM", "TCE", "MGM")
|
.pattern("MGM", "TCE", "MGM")
|
||||||
.ingredient('M', "#forge:ingots/manyullyn")
|
.ingredient('M', "#forge:ingots/manyullyn")
|
||||||
.ingredient('G', "mekanism:elite_control_circuit")
|
.ingredient('G', "mekanism:elite_control_circuit")
|
||||||
|
@ -67,7 +71,7 @@ public class RecipeReplacements {
|
||||||
ev.mapRecipeID(
|
ev.mapRecipeID(
|
||||||
new Identifier("scannable", "scanner"),
|
new Identifier("scannable", "scanner"),
|
||||||
r
|
r
|
||||||
-> new ShapedRecipeBuilder("scanner", r.getOutput())
|
-> new ShapedRecipeBuilder(Ntx4Core.id("scanner"), r.getOutput())
|
||||||
.pattern("MGM", "TCE", "MGM")
|
.pattern("MGM", "TCE", "MGM")
|
||||||
.ingredient('M', "#forge:ingots/iron")
|
.ingredient('M', "#forge:ingots/iron")
|
||||||
.ingredient('G', "mekanism:advanced_control_circuit")
|
.ingredient('G', "mekanism:advanced_control_circuit")
|
||||||
|
@ -80,7 +84,7 @@ public class RecipeReplacements {
|
||||||
ev.mapRecipeID(
|
ev.mapRecipeID(
|
||||||
new Identifier("enderrift", "rift"),
|
new Identifier("enderrift", "rift"),
|
||||||
r
|
r
|
||||||
-> new ShapedRecipeBuilder("enderrift", r.getOutput())
|
-> new ShapedRecipeBuilder(Ntx4Core.id("enderrift"), r.getOutput())
|
||||||
.pattern("PDP", "DCD", "PDP")
|
.pattern("PDP", "DCD", "PDP")
|
||||||
.ingredient('P', "ae2:fluix_pearl")
|
.ingredient('P', "ae2:fluix_pearl")
|
||||||
.ingredient('C', "mekanism:qio_drive_array")
|
.ingredient('C', "mekanism:qio_drive_array")
|
||||||
|
@ -91,7 +95,7 @@ public class RecipeReplacements {
|
||||||
ev.mapRecipeID(
|
ev.mapRecipeID(
|
||||||
new Identifier("enderrift", "rift_orb"),
|
new Identifier("enderrift", "rift_orb"),
|
||||||
r
|
r
|
||||||
-> new ShapedRecipeBuilder("rift_orb", r.getOutput())
|
-> new ShapedRecipeBuilder(Ntx4Core.id("rift_orb"), r.getOutput())
|
||||||
.pattern("DPD", "PCP", "DPD")
|
.pattern("DPD", "PCP", "DPD")
|
||||||
.ingredient('D', "projecte:dark_matter")
|
.ingredient('D', "projecte:dark_matter")
|
||||||
.ingredient('P', "minecraft:ender_eye")
|
.ingredient('P', "minecraft:ender_eye")
|
||||||
|
@ -102,7 +106,7 @@ public class RecipeReplacements {
|
||||||
ev.mapRecipeID(
|
ev.mapRecipeID(
|
||||||
new Identifier("projecte", "dark_matter"),
|
new Identifier("projecte", "dark_matter"),
|
||||||
r
|
r
|
||||||
-> new ShapedRecipeBuilder("dark_matter", r.getOutput())
|
-> new ShapedRecipeBuilder(Ntx4Core.id("dark_matter"), r.getOutput())
|
||||||
.pattern("DFD", "FSF", "DFD")
|
.pattern("DFD", "FSF", "DFD")
|
||||||
.ingredient('F', "projecte:aeternalis_fuel")
|
.ingredient('F', "projecte:aeternalis_fuel")
|
||||||
.ingredient('S', "ae2:singularity")
|
.ingredient('S', "ae2:singularity")
|
||||||
|
@ -113,7 +117,7 @@ public class RecipeReplacements {
|
||||||
ev.mapRecipeID(
|
ev.mapRecipeID(
|
||||||
new Identifier("quantumquarryplus", "qqprcp"),
|
new Identifier("quantumquarryplus", "qqprcp"),
|
||||||
r
|
r
|
||||||
-> new ShapedRecipeBuilder("quantum_quarry", r.getOutput())
|
-> new ShapedRecipeBuilder(Ntx4Core.id("quantum_quarry"), r.getOutput())
|
||||||
.pattern("ECE", "BFD", "ECE")
|
.pattern("ECE", "BFD", "ECE")
|
||||||
.ingredient('E', "#forge:ingots/enderium")
|
.ingredient('E', "#forge:ingots/enderium")
|
||||||
.ingredient('C', "quantumquarryplus:endercell")
|
.ingredient('C', "quantumquarryplus:endercell")
|
||||||
|
|
|
@ -1,21 +1,25 @@
|
||||||
package net.anvilcraft.ntx4core.recipes;
|
package net.anvilcraft.ntx4core.recipes;
|
||||||
|
|
||||||
|
import net.anvilcraft.anvillib.recipe.RecipesEvent;
|
||||||
|
import net.anvilcraft.anvillib.recipe.ShapedRecipeBuilder;
|
||||||
import net.anvilcraft.ntx4core.Ntx4Core;
|
import net.anvilcraft.ntx4core.Ntx4Core;
|
||||||
import net.anvilcraft.ntx4core.recipe.RecipesEvent;
|
|
||||||
import net.anvilcraft.ntx4core.recipe.ShapedRecipeBuilder;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
||||||
|
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
|
||||||
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD)
|
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD)
|
||||||
public class ShapedRecipes {
|
public class ShapedRecipes {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onRecipeRegister(RecipesEvent ev) {
|
public static void onRecipeRegister(RecipesEvent ev) {
|
||||||
|
if (!FMLEnvironment.production)
|
||||||
|
return;
|
||||||
|
|
||||||
ev.registerRecipe(new ShapedRecipeBuilder(
|
ev.registerRecipe(new ShapedRecipeBuilder(
|
||||||
"he_who_remains_tempad",
|
Ntx4Core.id("he_who_remains_tempad"),
|
||||||
new ItemStack(ForgeRegistries.ITEMS.getValue(
|
new ItemStack(ForgeRegistries.ITEMS.getValue(
|
||||||
new Identifier("tempad", "he_who_remains_tempad")
|
new Identifier("tempad", "he_who_remains_tempad")
|
||||||
))
|
))
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package net.anvilcraft.ntx4core.worldgen;
|
||||||
|
|
||||||
|
import net.anvilcraft.anvillib.worldgen.AdvancedStructurePoolFeatureConfig;
|
||||||
|
import net.anvilcraft.ntx4core.Ntx4Core;
|
||||||
|
import net.anvilcraft.ntx4core.mixin.accessor.StructureFeatureAccessor;
|
||||||
|
import net.minecraft.world.gen.GenerationStep;
|
||||||
|
import net.minecraft.world.gen.feature.StructureFeature;
|
||||||
|
import net.minecraft.world.gen.feature.VillageFeature;
|
||||||
|
import net.minecraftforge.registries.DeferredRegister;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
|
||||||
|
public class Ntx4CoreFeatures {
|
||||||
|
public static final DeferredRegister<StructureFeature<?>> STRUCTURE_FEATURES
|
||||||
|
= DeferredRegister.create(ForgeRegistries.STRUCTURE_FEATURES, Ntx4Core.MODID);
|
||||||
|
|
||||||
|
public static final VillageFeature BORG_KINDBERG
|
||||||
|
= new VillageFeature(AdvancedStructurePoolFeatureConfig.CODEC);
|
||||||
|
|
||||||
|
static {
|
||||||
|
StructureFeatureAccessor.getStructureToGenerationStepMap().put(
|
||||||
|
BORG_KINDBERG, GenerationStep.Feature.SURFACE_STRUCTURES
|
||||||
|
);
|
||||||
|
STRUCTURE_FEATURES.register("borg", () -> BORG_KINDBERG);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package net.anvilcraft.ntx4core.worldgen;
|
||||||
|
|
||||||
|
import net.anvilcraft.anvillib.worldgen.AdvancedStructurePoolFeatureConfig;
|
||||||
|
import net.anvilcraft.ntx4core.Ntx4Core;
|
||||||
|
import net.anvilcraft.ntx4core.worldgen.borg.BorgKindbergStructurePieces;
|
||||||
|
import net.minecraft.tag.TagKey;
|
||||||
|
import net.minecraft.util.registry.BuiltinRegistries;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||||
|
import net.minecraftforge.registries.DeferredRegister;
|
||||||
|
import net.minecraftforge.registries.RegistryObject;
|
||||||
|
|
||||||
|
public class Ntx4CoreStructures {
|
||||||
|
public static final DeferredRegister<ConfiguredStructureFeature<?, ?>>
|
||||||
|
CONFIGURED_STRUCTURE_FEATURES = DeferredRegister.create(
|
||||||
|
BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.getKey(), Ntx4Core.MODID
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final RegistryObject<ConfiguredStructureFeature<?, ?>> BORG_KINDBERG
|
||||||
|
= CONFIGURED_STRUCTURE_FEATURES.register(
|
||||||
|
"borg",
|
||||||
|
()
|
||||||
|
-> Ntx4CoreFeatures.BORG_KINDBERG.configure(
|
||||||
|
new AdvancedStructurePoolFeatureConfig(
|
||||||
|
BorgKindbergStructurePieces.START, 7, 256
|
||||||
|
),
|
||||||
|
TagKey.of(Registry.BIOME_KEY, Ntx4Core.id("has_structure/borg")),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package net.anvilcraft.ntx4core.worldgen.borg;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
|
||||||
|
import net.anvilcraft.ntx4core.Ntx4Core;
|
||||||
|
import net.minecraft.structure.pool.StructurePool;
|
||||||
|
import net.minecraft.structure.pool.StructurePoolElement;
|
||||||
|
import net.minecraft.structure.pool.StructurePools;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.registry.RegistryEntry;
|
||||||
|
|
||||||
|
public class BorgKindbergStructurePieces {
|
||||||
|
public static final RegistryEntry<StructurePool> START
|
||||||
|
= StructurePools.register(new StructurePool(
|
||||||
|
Ntx4Core.id("borg/start_pool"),
|
||||||
|
new Identifier("empty"),
|
||||||
|
ImmutableList.of(
|
||||||
|
Pair.of(StructurePoolElement.ofSingle("ntx4core:borg_start"), 1)
|
||||||
|
),
|
||||||
|
StructurePool.Projection.RIGID
|
||||||
|
));
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
# Make stuff for custom title screen public
|
|
||||||
public-f net.minecraft.client.gui.screens.LoadingOverlay f_96161_ # SplashOverlay.BRAND_ARGB
|
public-f net.minecraft.client.gui.screens.LoadingOverlay f_96161_ # SplashOverlay.BRAND_ARGB
|
||||||
public net.minecraft.world.item.crafting.Ingredient f_43902_ # Ingredient.entries
|
public net.minecraft.world.item.crafting.Ingredient f_43902_ # Ingredient.entries
|
||||||
public net.minecraft.world.item.crafting.Ingredient$TagValue f_43959_ # Ingredient$TagEntry.tag
|
public net.minecraft.world.item.crafting.Ingredient$TagValue f_43959_ # Ingredient$TagEntry.tag
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"variants": {
|
"variants": {
|
||||||
"": {
|
"": {
|
||||||
"model": "ntx4core:block/alec"
|
"model": "ntx4core:block/alecubus"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"itemGroup.ntx4core": "Notex 4",
|
"itemGroup.ntx4core": "Notex 4",
|
||||||
|
|
||||||
"block.ntx4core.alec": "Alec",
|
"block.ntx4core.alecubus": "Alecubus",
|
||||||
|
|
||||||
"item.ntx4core.computational_core": "Computational Core",
|
"item.ntx4core.computational_core": "Computational Core",
|
||||||
"item.ntx4core.energy_infused_core": "Energy-Infused Core",
|
"item.ntx4core.energy_infused_core": "Energy-Infused Core",
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"parent": "ntx4core:block/alec"
|
|
||||||
}
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"parent": "ntx4core:block/alecubus"
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"values": [
|
"values": [
|
||||||
"ntx4core:alec"
|
"ntx4core:alecubus"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
{
|
||||||
"type": "minecraft:item",
|
"type": "minecraft:item",
|
||||||
"name": "ntx4core:alec"
|
"name": "ntx4core:alecubus"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rolls": 1.0
|
"rolls": 1.0
|
|
@ -10,7 +10,7 @@
|
||||||
"gas": "mekanism:antimatter"
|
"gas": "mekanism:antimatter"
|
||||||
},
|
},
|
||||||
"output": {
|
"output": {
|
||||||
"item": "ntx4core:alec"
|
"item": "ntx4core:alecubus"
|
||||||
},
|
},
|
||||||
"duration": 1250
|
"duration": 1250
|
||||||
}
|
}
|
BIN
src/main/resources/data/ntx4core/structures/borg_1.nbt
Normal file
BIN
src/main/resources/data/ntx4core/structures/borg_1.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/data/ntx4core/structures/borg_2.nbt
Normal file
BIN
src/main/resources/data/ntx4core/structures/borg_2.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/data/ntx4core/structures/borg_3.nbt
Normal file
BIN
src/main/resources/data/ntx4core/structures/borg_3.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/data/ntx4core/structures/borg_4.nbt
Normal file
BIN
src/main/resources/data/ntx4core/structures/borg_4.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/data/ntx4core/structures/borg_5.nbt
Normal file
BIN
src/main/resources/data/ntx4core/structures/borg_5.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/data/ntx4core/structures/borg_6.nbt
Normal file
BIN
src/main/resources/data/ntx4core/structures/borg_6.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/data/ntx4core/structures/borg_7.nbt
Normal file
BIN
src/main/resources/data/ntx4core/structures/borg_7.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/data/ntx4core/structures/borg_8.nbt
Normal file
BIN
src/main/resources/data/ntx4core/structures/borg_8.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/data/ntx4core/structures/borg_9.nbt
Normal file
BIN
src/main/resources/data/ntx4core/structures/borg_9.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/data/ntx4core/structures/borg_start.nbt
Normal file
BIN
src/main/resources/data/ntx4core/structures/borg_start.nbt
Normal file
Binary file not shown.
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"values": [
|
||||||
|
"#minecraft:has_structure/village_plains"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"structures": [
|
||||||
|
{
|
||||||
|
"weight": 1,
|
||||||
|
"structure": "ntx4core:borg"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"placement": {
|
||||||
|
"salt": 28948,
|
||||||
|
"type": "minecraft:random_spread",
|
||||||
|
"spacing": 256,
|
||||||
|
"separation": 128
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "ntx4core:borg/1_pool",
|
||||||
|
"fallback": "minecraft:empty",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"weight": 1,
|
||||||
|
"element": {
|
||||||
|
"location": "ntx4core:borg_1",
|
||||||
|
"processors": "minecraft:empty",
|
||||||
|
"projection": "rigid",
|
||||||
|
"element_type": "minecraft:single_pool_element"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "ntx4core:borg/2_pool",
|
||||||
|
"fallback": "minecraft:empty",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"weight": 1,
|
||||||
|
"element": {
|
||||||
|
"location": "ntx4core:borg_2",
|
||||||
|
"processors": "minecraft:empty",
|
||||||
|
"projection": "rigid",
|
||||||
|
"element_type": "minecraft:single_pool_element"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "ntx4core:borg/3_pool",
|
||||||
|
"fallback": "minecraft:empty",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"weight": 1,
|
||||||
|
"element": {
|
||||||
|
"location": "ntx4core:borg_3",
|
||||||
|
"processors": "minecraft:empty",
|
||||||
|
"projection": "rigid",
|
||||||
|
"element_type": "minecraft:single_pool_element"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "ntx4core:borg/4_pool",
|
||||||
|
"fallback": "minecraft:empty",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"weight": 1,
|
||||||
|
"element": {
|
||||||
|
"location": "ntx4core:borg_4",
|
||||||
|
"processors": "minecraft:empty",
|
||||||
|
"projection": "rigid",
|
||||||
|
"element_type": "minecraft:single_pool_element"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "ntx4core:borg/5_pool",
|
||||||
|
"fallback": "minecraft:empty",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"weight": 1,
|
||||||
|
"element": {
|
||||||
|
"location": "ntx4core:borg_5",
|
||||||
|
"processors": "minecraft:empty",
|
||||||
|
"projection": "rigid",
|
||||||
|
"element_type": "minecraft:single_pool_element"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "ntx4core:borg/6_pool",
|
||||||
|
"fallback": "minecraft:empty",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"weight": 1,
|
||||||
|
"element": {
|
||||||
|
"location": "ntx4core:borg_6",
|
||||||
|
"processors": "minecraft:empty",
|
||||||
|
"projection": "rigid",
|
||||||
|
"element_type": "minecraft:single_pool_element"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "ntx4core:borg/7_pool",
|
||||||
|
"fallback": "minecraft:empty",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"weight": 1,
|
||||||
|
"element": {
|
||||||
|
"location": "ntx4core:borg_7",
|
||||||
|
"processors": "minecraft:empty",
|
||||||
|
"projection": "rigid",
|
||||||
|
"element_type": "minecraft:single_pool_element"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "ntx4core:borg/8_pool",
|
||||||
|
"fallback": "minecraft:empty",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"weight": 1,
|
||||||
|
"element": {
|
||||||
|
"location": "ntx4core:borg_8",
|
||||||
|
"processors": "minecraft:empty",
|
||||||
|
"projection": "rigid",
|
||||||
|
"element_type": "minecraft:single_pool_element"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "ntx4core:borg/9_pool",
|
||||||
|
"fallback": "minecraft:empty",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"weight": 1,
|
||||||
|
"element": {
|
||||||
|
"location": "ntx4core:borg_9",
|
||||||
|
"processors": "minecraft:empty",
|
||||||
|
"projection": "rigid",
|
||||||
|
"element_type": "minecraft:single_pool_element"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"common.RecipeManagerMixin"
|
"accessor.StructureFeatureAccessor"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"client.SplashOverlayMixin",
|
"client.SplashOverlayMixin",
|
||||||
|
|
Loading…
Reference in a new issue