Generalized machine replacement
This commit is contained in:
@@ -1,18 +1,14 @@
|
||||
package com.imbgt.ibg;
|
||||
|
||||
import com.imbgt.ibg.block.MachineSets;
|
||||
import com.imbgt.ibg.block.ModBlocks;
|
||||
import com.imbgt.ibg.block.entity.ModBlockEntities;
|
||||
import com.imbgt.ibg.block.entity.client.AnimatedBlockRenderer;
|
||||
import com.imbgt.ibg.util.FootprintSpec;
|
||||
import com.imbgt.ibg.util.Footprints;
|
||||
|
||||
import com.gregtechceu.gtceu.api.machine.MachineDefinition;
|
||||
import com.gregtechceu.gtceu.api.registry.GTRegistries;
|
||||
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.server.ServerStartingEvent;
|
||||
@@ -52,16 +48,7 @@ public class IBG {
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, Config.SPEC);
|
||||
}
|
||||
|
||||
private void commonSetup(final FMLCommonSetupEvent event) {
|
||||
event.enqueueWork(() -> {
|
||||
Footprints.register(new ResourceLocation("gtceu", "lv_lathe"),
|
||||
FootprintSpec.builder()
|
||||
.addPart(-1, 0, 0)
|
||||
.masterOutline(Shapes.box(0, 0, 0, 1, 14. / 16., 1))
|
||||
.partOutline(Shapes.box(0, 0, 0, 1, 14. / 16., 1))
|
||||
.build());
|
||||
});
|
||||
}
|
||||
private void commonSetup(final FMLCommonSetupEvent event) {}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerStarting(ServerStartingEvent event) {}
|
||||
@@ -72,14 +59,17 @@ public class IBG {
|
||||
@SubscribeEvent
|
||||
public static void onClientSetup(FMLClientSetupEvent event) {
|
||||
event.enqueueWork(() -> {
|
||||
var latheDef = GTRegistries.MACHINES.get(
|
||||
new ResourceLocation("gtceu", "lv_lathe"));
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
BlockEntityRendererProvider<BlockEntity> provider = (BlockEntityRendererProvider) (ctx -> new AnimatedBlockRenderer<>(
|
||||
ctx));
|
||||
for (MachineDefinition def : GTRegistries.MACHINES) {
|
||||
|
||||
if (!MachineSets.matches(def.getId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockEntityRenderers.register(def.getBlockEntityType(),
|
||||
ctx -> new AnimatedBlockRenderer(ctx));
|
||||
}
|
||||
|
||||
BlockEntityRenderers.register(latheDef.getBlockEntityType(), provider);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
51
src/main/java/com/imbgt/ibg/block/MachineSets.java
Normal file
51
src/main/java/com/imbgt/ibg/block/MachineSets.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package com.imbgt.ibg.block;
|
||||
|
||||
import com.imbgt.ibg.util.FootprintSpec;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class MachineSets {
|
||||
|
||||
public static final String NS = "gtceu";
|
||||
|
||||
public record Definition(String suffix, FootprintSpec spec) {
|
||||
|
||||
public boolean matches(ResourceLocation id) {
|
||||
return id.getNamespace().equals(NS) && id.getPath().endsWith("_" + suffix);
|
||||
}
|
||||
}
|
||||
|
||||
public static final List<Definition> DEFINITIONS = List.of(
|
||||
new Definition(
|
||||
"lathe",
|
||||
FootprintSpec.builder()
|
||||
.addPart(-1, 0, 0)
|
||||
.masterOutline(Shapes.box(0, 0, 0, 1, 14.0 / 16.0, 1))
|
||||
.partOutline(Shapes.box(0, 0, 0, 1, 14.0 / 16.0, 1))
|
||||
.build()));
|
||||
|
||||
private MachineSets() {}
|
||||
|
||||
/** Does this machine belong to any configured family? */
|
||||
public static boolean matches(ResourceLocation id) {
|
||||
return DEFINITIONS.stream().anyMatch(f -> f.matches(id));
|
||||
}
|
||||
|
||||
/** The footprint spec for this machine, or null. */
|
||||
public static FootprintSpec getSpec(ResourceLocation id) {
|
||||
return DEFINITIONS.stream().filter(f -> f.matches(id)).map(Definition::spec).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
/** Asset key (filename stem) for this machine, or fallback to last segment. */
|
||||
public static String assetKeyFor(ResourceLocation id) {
|
||||
return DEFINITIONS.stream().filter(f -> f.matches(id)).map(Definition::suffix).findFirst()
|
||||
.orElseGet(() -> {
|
||||
var p = id.getPath();
|
||||
int i = p.indexOf('_');
|
||||
return i >= 0 ? p.substring(i + 1) : p;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.imbgt.ibg.block.custom;
|
||||
|
||||
import com.imbgt.ibg.block.MachineSets;
|
||||
import com.imbgt.ibg.block.entity.PartBE;
|
||||
import com.imbgt.ibg.util.FootprintSpec;
|
||||
import com.imbgt.ibg.util.Footprints;
|
||||
|
||||
import com.gregtechceu.gtceu.api.block.MetaMachineBlock;
|
||||
import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity;
|
||||
@@ -179,7 +182,7 @@ public class PartBlock extends Block implements EntityBlock {
|
||||
Direction facing = masterState.getValue(rot.property);
|
||||
|
||||
// Validate against the full footprint
|
||||
FootprintSpec spec = Footprints.get(mm.getDefinition().getId());
|
||||
FootprintSpec spec = MachineSets.getSpec(mm.getDefinition().getId());
|
||||
if (spec == null) return;
|
||||
|
||||
boolean isExpected = Footprints.partPositions(master, facing, spec).contains(pos);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.imbgt.ibg.block.entity.client;
|
||||
|
||||
import com.imbgt.ibg.IBG;
|
||||
import com.imbgt.ibg.block.MachineSets;
|
||||
|
||||
import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
@@ -9,18 +12,29 @@ import software.bernie.geckolib.model.GeoModel;
|
||||
|
||||
public class AnimatedBlockModel<T extends GeoAnimatable> extends GeoModel<T> {
|
||||
|
||||
@Override
|
||||
public ResourceLocation getModelResource(T animatable) {
|
||||
return new ResourceLocation(IBG.MOD_ID, "geo/animated_block.geo.json");
|
||||
private String keyFrom(T animatable) {
|
||||
if (animatable instanceof MetaMachineBlockEntity mme) {
|
||||
var id = mme.getMetaMachine().getDefinition().getId();
|
||||
return MachineSets.assetKeyFor(id);
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTextureResource(T animatable) {
|
||||
return new ResourceLocation(IBG.MOD_ID, "textures/block/animated_block.png");
|
||||
public ResourceLocation getModelResource(T anim) {
|
||||
String key = keyFrom(anim);
|
||||
return new ResourceLocation(IBG.MOD_ID, "geo/" + key + ".geo.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getAnimationResource(T animatable) {
|
||||
return new ResourceLocation(IBG.MOD_ID, "animations/animated_block.animation.json");
|
||||
public ResourceLocation getTextureResource(T anim) {
|
||||
String key = keyFrom(anim);
|
||||
return new ResourceLocation(IBG.MOD_ID, "textures/block/" + key + ".png");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getAnimationResource(T anim) {
|
||||
String key = keyFrom(anim);
|
||||
return new ResourceLocation(IBG.MOD_ID, "animations/" + key + ".animation.json");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.imbgt.ibg.mixin;
|
||||
|
||||
import com.imbgt.ibg.block.MachineSets;
|
||||
|
||||
import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity;
|
||||
import com.gregtechceu.gtceu.api.capability.IWorkable;
|
||||
import com.gregtechceu.gtceu.api.capability.forge.GTCapability;
|
||||
@@ -41,8 +43,7 @@ public abstract class MetaMachineBlockEntityGeoMixin implements GeoBlockEntity {
|
||||
MetaMachine machine = this.getMetaMachine();
|
||||
|
||||
// Only animate the lathe
|
||||
var defId = machine.getDefinition().getId();
|
||||
if (!"gtceu".equals(defId.getNamespace()) || !"lv_lathe".equals(defId.getPath())) {
|
||||
if (!MachineSets.matches(machine.getDefinition().getId())) {
|
||||
state.getController().forceAnimationReset();
|
||||
return PlayState.STOP;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.imbgt.ibg.mixin;
|
||||
|
||||
import com.imbgt.ibg.block.MachineSets;
|
||||
import com.imbgt.ibg.block.ModBlocks;
|
||||
import com.imbgt.ibg.block.entity.PartBE;
|
||||
import com.imbgt.ibg.util.Footprints;
|
||||
@@ -40,25 +41,24 @@ public abstract class MetaMachineBlockMixin extends AppearanceBlock {
|
||||
|
||||
@Inject(method = "getRenderShape", at = @At("HEAD"), cancellable = true)
|
||||
private void ibg$forceAnimatedRender(BlockState state, CallbackInfoReturnable<RenderShape> cir) {
|
||||
if (getDefinition().getId().toString().equals("gtceu:lv_lathe")) {
|
||||
if (MachineSets.matches(this.getDefinition().getId())) {
|
||||
cir.setReturnValue(RenderShape.ENTITYBLOCK_ANIMATED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOcclusionShape(BlockState state, BlockGetter level, BlockPos pos) {
|
||||
if (getDefinition().getId().toString().equals("gtceu:lv_lathe")) {
|
||||
if (MachineSets.matches(this.getDefinition().getId())) {
|
||||
return Shapes.empty(); // equivalent to Properties.noOcclusion()
|
||||
}
|
||||
return super.getOcclusionShape(state, level, pos);
|
||||
}
|
||||
|
||||
@Inject(method = "getStateForPlacement", at = @At("HEAD"), cancellable = true)
|
||||
private void ibg$latheFootprintCheck(BlockPlaceContext ctx,
|
||||
CallbackInfoReturnable<BlockState> cir) {
|
||||
MetaMachineBlock self = (MetaMachineBlock) (Object) this;
|
||||
var id = self.getDefinition().getId();
|
||||
if (!("gtceu".equals(id.getNamespace()) && "lv_lathe".equals(id.getPath())))
|
||||
private void ibg$footprintCheck(BlockPlaceContext ctx,
|
||||
CallbackInfoReturnable<BlockState> cir) {
|
||||
var spec = MachineSets.getSpec(this.getDefinition().getId());
|
||||
if (spec == null)
|
||||
return;
|
||||
|
||||
Level level = ctx.getLevel();
|
||||
@@ -67,9 +67,6 @@ public abstract class MetaMachineBlockMixin extends AppearanceBlock {
|
||||
// Determine facing like MetaMachineBlock does:
|
||||
Direction facing = ctx.getHorizontalDirection().getOpposite();
|
||||
|
||||
var spec = Footprints.get(self.getDefinition().getId());
|
||||
if (spec == null)
|
||||
return;
|
||||
var partPositions = Footprints.partPositions(base, facing, spec);
|
||||
for (BlockPos p : partPositions) {
|
||||
if (!level.getBlockState(p).canBeReplaced()) {
|
||||
@@ -83,8 +80,7 @@ public abstract class MetaMachineBlockMixin extends AppearanceBlock {
|
||||
private void ibg$placePart(BlockState st, Level lvl, BlockPos pos, BlockState old, boolean moved, CallbackInfo ci) {
|
||||
if (lvl.isClientSide)
|
||||
return;
|
||||
var id = getDefinition().getId();
|
||||
var spec = Footprints.get(id);
|
||||
var spec = MachineSets.getSpec(this.getDefinition().getId());
|
||||
if (spec == null)
|
||||
return;
|
||||
var rot = ((IMachineBlock) (Object) this).getRotationState();
|
||||
@@ -105,8 +101,7 @@ public abstract class MetaMachineBlockMixin extends AppearanceBlock {
|
||||
CallbackInfo ci) {
|
||||
if (lvl.isClientSide || st.getBlock() == newState.getBlock())
|
||||
return;
|
||||
var id = getDefinition().getId();
|
||||
var spec = com.imbgt.ibg.util.Footprints.get(id);
|
||||
var spec = MachineSets.getSpec(this.getDefinition().getId());
|
||||
if (spec == null)
|
||||
return;
|
||||
var rot = ((IMachineBlock) (Object) this).getRotationState();
|
||||
@@ -122,7 +117,7 @@ public abstract class MetaMachineBlockMixin extends AppearanceBlock {
|
||||
@Inject(method = "getShape", at = @At("HEAD"), cancellable = true)
|
||||
private void ibg$combinedOutline(BlockState state, BlockGetter level, BlockPos pos,
|
||||
CollisionContext ctx, CallbackInfoReturnable<VoxelShape> cir) {
|
||||
var spec = com.imbgt.ibg.util.Footprints.get(getDefinition().getId());
|
||||
var spec = MachineSets.getSpec(this.getDefinition().getId());
|
||||
if (spec == null)
|
||||
return;
|
||||
var rot = ((IMachineBlock) (Object) this).getRotationState();
|
||||
@@ -130,7 +125,6 @@ public abstract class MetaMachineBlockMixin extends AppearanceBlock {
|
||||
return;
|
||||
var facing = state.getValue(rot.property);
|
||||
var shape = Footprints.combinedOutline(facing, spec);
|
||||
// var shape = Footprints.rotateOutline(spec.masterOutline(), facing);
|
||||
cir.setReturnValue(shape);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,34 +2,19 @@ package com.imbgt.ibg.util;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Registry + helpers to compute world positions and a continuous outline shape.
|
||||
*/
|
||||
public final class Footprints {
|
||||
|
||||
private static final Map<ResourceLocation, FootprintSpec> REG = new HashMap<>();
|
||||
|
||||
private Footprints() {}
|
||||
|
||||
/** Register or replace a footprint for a machine id. Call during setup. */
|
||||
public static void register(ResourceLocation machineId, FootprintSpec spec) {
|
||||
REG.put(machineId, spec);
|
||||
}
|
||||
|
||||
/** @return null when no footprint registered. */
|
||||
public static FootprintSpec get(ResourceLocation machineId) {
|
||||
return REG.get(machineId);
|
||||
}
|
||||
|
||||
/** All part world positions for a given master and facing. */
|
||||
public static List<BlockPos> partPositions(BlockPos master, Direction facing, FootprintSpec spec) {
|
||||
return spec.parts().stream()
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{
|
||||
"item.ibg.lathe": "Lathe",
|
||||
"block.ibg.animated_block": "Animated Block"
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 499 B After Width: | Height: | Size: 499 B |
Reference in New Issue
Block a user