feat: implement BORG Kindberg
This commit is contained in:
parent
4acbedbfca
commit
ed1e725810
64 changed files with 313 additions and 1172 deletions
build.gradlentx4core.mixins.json
src/main
java/net/anvilcraft/ntx4core
Ntx4Core.javaNtx4CoreBlocks.javaNtx4CoreItemGroup.javaNtx4CoreItems.javaUtil.java
blocks
cosmetics
ClientEventHandler.javaCosmeticArmorRenderer.javaCosmeticFeatureRenderer.javaCosmeticItem.javaCosmeticModel.javaCosmeticsManager.javaICosmetic.javaICosmeticProvider.java
mixin
recipe
AbstractIngredientCondition.javaIRecipeMapper.javaIngredientsContainPredicate.javaInputReplaceRecipeMapper.javaRecipeContainsPredicate.javaRecipesEvent.javaShapedRecipeBuilder.javaStackIngredientCondition.javaTagIngredientCondition.java
recipes
worldgen
resources
META-INF
assets/ntx4core
data
minecraft/tags/blocks/mineable
ntx4core
loot_tables/blocks
recipes
structures
borg_1.nbtborg_2.nbtborg_3.nbtborg_4.nbtborg_5.nbtborg_6.nbtborg_7.nbtborg_8.nbtborg_9.nbtborg_start.nbt
tags/worldgen/biome/has_structure
worldgen
structure_set
template_pool/borg
|
@ -18,6 +18,10 @@ loom {
|
|||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven {
|
||||
url "https://maven.tilera.xyz/"
|
||||
}
|
||||
maven {
|
||||
url "https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/"
|
||||
}
|
||||
|
@ -31,6 +35,7 @@ dependencies {
|
|||
forge "net.minecraftforge:forge:${project.forge_version}"
|
||||
|
||||
modImplementation "software.bernie.geckolib:geckolib-forge-1.18:3.0.57"
|
||||
modImplementation "net.anvilcraft:anvillib-18:0.1.1"
|
||||
}
|
||||
|
||||
processResources {
|
||||
|
|
|
@ -3,12 +3,13 @@ package net.anvilcraft.ntx4core;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
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.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import software.bernie.geckolib3.GeckoLib;
|
||||
|
||||
@Mod("ntx4core")
|
||||
public class Ntx4Core {
|
||||
|
@ -20,8 +21,8 @@ public class Ntx4Core {
|
|||
|
||||
Ntx4CoreBlocks.BLOCKS.register(bus);
|
||||
Ntx4CoreItems.ITEMS.register(bus);
|
||||
|
||||
GeckoLib.initialize();
|
||||
Ntx4CoreFeatures.STRUCTURE_FEATURES.register(bus);
|
||||
Ntx4CoreStructures.CONFIGURED_STRUCTURE_FEATURES.register(bus);
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(Ntx4CoreShaders.class);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package net.anvilcraft.ntx4core;
|
||||
|
||||
import net.anvilcraft.ntx4core.blocks.BlockAlec;
|
||||
import net.anvilcraft.ntx4core.blocks.BlockAlecubus;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
@ -10,6 +10,6 @@ public class Ntx4CoreBlocks {
|
|||
public static final DeferredRegister<Block> BLOCKS
|
||||
= DeferredRegister.create(ForgeRegistries.BLOCKS, Ntx4Core.MODID);
|
||||
|
||||
public static final RegistryObject<Block> ALEC
|
||||
= BLOCKS.register("alec", BlockAlec::new);
|
||||
public static final RegistryObject<Block> ALECUBUS
|
||||
= BLOCKS.register("alecubus", BlockAlecubus::new);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,6 @@ public class Ntx4CoreItemGroup extends ItemGroup {
|
|||
|
||||
@Override
|
||||
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);
|
||||
|
||||
public static final RegistryObject<Item> ALEC = ITEMS.register(
|
||||
"alec",
|
||||
"alecubus",
|
||||
()
|
||||
-> new BlockItem(
|
||||
Ntx4CoreBlocks.ALEC.get(),
|
||||
Ntx4CoreBlocks.ALECUBUS.get(),
|
||||
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.explosion.Explosion;
|
||||
|
||||
public class BlockAlec extends Block {
|
||||
public BlockAlec() {
|
||||
public class BlockAlecubus extends Block {
|
||||
public BlockAlecubus() {
|
||||
super(Settings.of(Material.STONE, MapColor.BRIGHT_RED)
|
||||
.requiresTool()
|
||||
.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;
|
||||
|
||||
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.Util;
|
||||
import net.anvilcraft.ntx4core.recipe.InputReplaceRecipeMapper;
|
||||
import net.anvilcraft.ntx4core.recipe.RecipesEvent;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
|
||||
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD)
|
||||
public class InputReplacements {
|
||||
@SubscribeEvent
|
||||
public static void onRecipeRegister(RecipesEvent ev) {
|
||||
if (!FMLEnvironment.production)
|
||||
return;
|
||||
|
||||
var darkMatter = Util.ingredientFromString("projecte:dark_matter");
|
||||
|
||||
ev.mapRecipeID(
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
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.Util;
|
||||
import net.anvilcraft.ntx4core.recipe.RecipeContainsPredicate;
|
||||
import net.anvilcraft.ntx4core.recipe.RecipesEvent;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
|
||||
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD)
|
||||
public class RecipeRemovals {
|
||||
@SubscribeEvent
|
||||
public static void onRecipeRegister(RecipesEvent ev) {
|
||||
if (!FMLEnvironment.production)
|
||||
return;
|
||||
|
||||
ev.removeRecipesMatching(new RecipeContainsPredicate(
|
||||
Util.stackFromRegistry(new Identifier("projecte", "condenser_mk1"))
|
||||
));
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
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.recipe.RecipesEvent;
|
||||
import net.anvilcraft.ntx4core.recipe.ShapedRecipeBuilder;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
|
||||
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD)
|
||||
public class RecipeReplacements {
|
||||
@SubscribeEvent
|
||||
public static void onRecipeRegister(RecipesEvent ev) {
|
||||
if (!FMLEnvironment.production)
|
||||
return;
|
||||
|
||||
ev.mapRecipeID(
|
||||
new Identifier("shrink", "shrinking_device"),
|
||||
r
|
||||
-> new ShapedRecipeBuilder("shrinking_device", r.getOutput())
|
||||
-> new ShapedRecipeBuilder(Ntx4Core.id("shrinking_device"), r.getOutput())
|
||||
.pattern("IDI", "TFE", "IDI")
|
||||
.ingredient('I', "#forge:ingots/osmium")
|
||||
.ingredient('D', "projecte:dark_matter")
|
||||
|
@ -28,7 +32,7 @@ public class RecipeReplacements {
|
|||
ev.mapRecipeID(
|
||||
new Identifier("compactmachines", "personal_shrinking_device"),
|
||||
r
|
||||
-> new ShapedRecipeBuilder("shrinking_device", r.getOutput())
|
||||
-> new ShapedRecipeBuilder(Ntx4Core.id("shrinking_device"), r.getOutput())
|
||||
.pattern("IDI", "TFE", "IDI")
|
||||
.ingredient('I', "#forge:ingots/iron")
|
||||
.ingredient('D', "projecte:dark_matter")
|
||||
|
@ -41,7 +45,7 @@ public class RecipeReplacements {
|
|||
ev.mapRecipeID(
|
||||
new Identifier("tempad", "tempad"),
|
||||
r
|
||||
-> new ShapedRecipeBuilder("tempad", r.getOutput())
|
||||
-> new ShapedRecipeBuilder(Ntx4Core.id("tempad"), r.getOutput())
|
||||
.pattern("MGM", "TCE", "MGM")
|
||||
.ingredient('M', "#forge:ingots/copper")
|
||||
.ingredient('G', "#forge:ingots/refined_glowstone")
|
||||
|
@ -54,7 +58,7 @@ public class RecipeReplacements {
|
|||
ev.mapRecipeID(
|
||||
new Identifier("dmlreforged", "deep_learner"),
|
||||
r
|
||||
-> new ShapedRecipeBuilder("deep_learner", r.getOutput())
|
||||
-> new ShapedRecipeBuilder(Ntx4Core.id("deep_learner"), r.getOutput())
|
||||
.pattern("MGM", "TCE", "MGM")
|
||||
.ingredient('M', "#forge:ingots/manyullyn")
|
||||
.ingredient('G', "mekanism:elite_control_circuit")
|
||||
|
@ -67,7 +71,7 @@ public class RecipeReplacements {
|
|||
ev.mapRecipeID(
|
||||
new Identifier("scannable", "scanner"),
|
||||
r
|
||||
-> new ShapedRecipeBuilder("scanner", r.getOutput())
|
||||
-> new ShapedRecipeBuilder(Ntx4Core.id("scanner"), r.getOutput())
|
||||
.pattern("MGM", "TCE", "MGM")
|
||||
.ingredient('M', "#forge:ingots/iron")
|
||||
.ingredient('G', "mekanism:advanced_control_circuit")
|
||||
|
@ -80,7 +84,7 @@ public class RecipeReplacements {
|
|||
ev.mapRecipeID(
|
||||
new Identifier("enderrift", "rift"),
|
||||
r
|
||||
-> new ShapedRecipeBuilder("enderrift", r.getOutput())
|
||||
-> new ShapedRecipeBuilder(Ntx4Core.id("enderrift"), r.getOutput())
|
||||
.pattern("PDP", "DCD", "PDP")
|
||||
.ingredient('P', "ae2:fluix_pearl")
|
||||
.ingredient('C', "mekanism:qio_drive_array")
|
||||
|
@ -91,7 +95,7 @@ public class RecipeReplacements {
|
|||
ev.mapRecipeID(
|
||||
new Identifier("enderrift", "rift_orb"),
|
||||
r
|
||||
-> new ShapedRecipeBuilder("rift_orb", r.getOutput())
|
||||
-> new ShapedRecipeBuilder(Ntx4Core.id("rift_orb"), r.getOutput())
|
||||
.pattern("DPD", "PCP", "DPD")
|
||||
.ingredient('D', "projecte:dark_matter")
|
||||
.ingredient('P', "minecraft:ender_eye")
|
||||
|
@ -102,7 +106,7 @@ public class RecipeReplacements {
|
|||
ev.mapRecipeID(
|
||||
new Identifier("projecte", "dark_matter"),
|
||||
r
|
||||
-> new ShapedRecipeBuilder("dark_matter", r.getOutput())
|
||||
-> new ShapedRecipeBuilder(Ntx4Core.id("dark_matter"), r.getOutput())
|
||||
.pattern("DFD", "FSF", "DFD")
|
||||
.ingredient('F', "projecte:aeternalis_fuel")
|
||||
.ingredient('S', "ae2:singularity")
|
||||
|
@ -113,7 +117,7 @@ public class RecipeReplacements {
|
|||
ev.mapRecipeID(
|
||||
new Identifier("quantumquarryplus", "qqprcp"),
|
||||
r
|
||||
-> new ShapedRecipeBuilder("quantum_quarry", r.getOutput())
|
||||
-> new ShapedRecipeBuilder(Ntx4Core.id("quantum_quarry"), r.getOutput())
|
||||
.pattern("ECE", "BFD", "ECE")
|
||||
.ingredient('E', "#forge:ingots/enderium")
|
||||
.ingredient('C', "quantumquarryplus:endercell")
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
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.recipe.RecipesEvent;
|
||||
import net.anvilcraft.ntx4core.recipe.ShapedRecipeBuilder;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
@EventBusSubscriber(modid = Ntx4Core.MODID, bus = Bus.MOD)
|
||||
public class ShapedRecipes {
|
||||
@SubscribeEvent
|
||||
public static void onRecipeRegister(RecipesEvent ev) {
|
||||
if (!FMLEnvironment.production)
|
||||
return;
|
||||
|
||||
ev.registerRecipe(new ShapedRecipeBuilder(
|
||||
"he_who_remains_tempad",
|
||||
Ntx4Core.id("he_who_remains_tempad"),
|
||||
new ItemStack(ForgeRegistries.ITEMS.getValue(
|
||||
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 net.minecraft.world.item.crafting.Ingredient f_43902_ # Ingredient.entries
|
||||
public net.minecraft.world.item.crafting.Ingredient$TagValue f_43959_ # Ingredient$TagEntry.tag
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "ntx4core:block/alec"
|
||||
"model": "ntx4core:block/alecubus"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"itemGroup.ntx4core": "Notex 4",
|
||||
|
||||
"block.ntx4core.alec": "Alec",
|
||||
"block.ntx4core.alecubus": "Alecubus",
|
||||
|
||||
"item.ntx4core.computational_core": "Computational 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": [
|
||||
"ntx4core:alec"
|
||||
"ntx4core:alecubus"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "ntx4core:alec"
|
||||
"name": "ntx4core:alecubus"
|
||||
}
|
||||
],
|
||||
"rolls": 1.0
|
|
@ -10,7 +10,7 @@
|
|||
"gas": "mekanism:antimatter"
|
||||
},
|
||||
"output": {
|
||||
"item": "ntx4core:alec"
|
||||
"item": "ntx4core:alecubus"
|
||||
},
|
||||
"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",
|
||||
"minVersion": "0.8",
|
||||
"mixins": [
|
||||
"common.RecipeManagerMixin"
|
||||
"accessor.StructureFeatureAccessor"
|
||||
],
|
||||
"client": [
|
||||
"client.SplashOverlayMixin",
|
||||
|
|
Loading…
Add table
Reference in a new issue