Behavior registration cleanup

- Add global providers to movement and interaction behavior registries
- All blocks tagged #wooden_doors or #wooden_trapdoors will now have the
correct interaction behavior
- Use IRegistryDelegate instead of ResourceLocation
This commit is contained in:
PepperCode1 2022-07-08 16:15:19 -07:00
parent a92855254c
commit c194f320ba
16 changed files with 210 additions and 198 deletions

View file

@ -1,7 +1,7 @@
package com.simibubi.create;
import static com.simibubi.create.AllInteractionBehaviours.addInteractionBehaviour;
import static com.simibubi.create.AllMovementBehaviours.addMovementBehaviour;
import static com.simibubi.create.AllInteractionBehaviours.interactionBehaviour;
import static com.simibubi.create.AllMovementBehaviours.movementBehaviour;
import static com.simibubi.create.AllTags.axeOnly;
import static com.simibubi.create.AllTags.axeOrPickaxe;
import static com.simibubi.create.AllTags.pickaxeOnly;
@ -640,7 +640,7 @@ public class AllBlocks {
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
.transform(pickaxeOnly())
.blockstate(new BasinGenerator()::generate)
.onRegister(addMovementBehaviour(new BasinMovementBehaviour()))
.onRegister(movementBehaviour(new BasinMovementBehaviour()))
.item()
.transform(customItemModel("_", "block"))
.register();
@ -655,8 +655,8 @@ public class AllBlocks {
.tag(AllBlockTags.FAN_TRANSPARENT.tag, AllBlockTags.FAN_HEATERS.tag)
.loot((lt, block) -> lt.add(block, BlazeBurnerBlock.buildLootTable()))
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
.onRegister(addMovementBehaviour(new BlazeBurnerMovementBehaviour()))
.onRegister(addInteractionBehaviour(new BlazeBurnerInteractionBehaviour()))
.onRegister(movementBehaviour(new BlazeBurnerMovementBehaviour()))
.onRegister(interactionBehaviour(new BlazeBurnerInteractionBehaviour()))
.item(BlazeBurnerBlockItem::withBlaze)
.model(AssetLookup.<BlazeBurnerBlockItem>customBlockItemModel("blaze_burner", "block_with_blaze"))
.build()
@ -974,7 +974,7 @@ public class AllBlocks {
.properties(p -> p.color(MaterialColor.TERRACOTTA_LIGHT_GRAY))
.transform(axeOrPickaxe())
.blockstate((c, p) -> p.directionalBlock(c.get(), AssetLookup.partialBaseModel(c, p)))
.onRegister(addMovementBehaviour(new PortableStorageInterfaceMovement()))
.onRegister(movementBehaviour(new PortableStorageInterfaceMovement()))
.item()
.transform(customItemModel())
.register();
@ -1109,7 +1109,7 @@ public class AllBlocks {
.transform(BuilderTransformers.bearing("mechanical", "gearbox", false))
.transform(BlockStressDefaults.setImpact(4.0))
.tag(AllBlockTags.SAFE_NBT.tag)
.onRegister(addMovementBehaviour(new StabilizedBearingMovementBehaviour()))
.onRegister(movementBehaviour(new StabilizedBearingMovementBehaviour()))
.register();
public static final BlockEntry<ClockworkBearingBlock> CLOCKWORK_BEARING =
@ -1235,7 +1235,7 @@ public class AllBlocks {
.transform(axeOrPickaxe())
.blockstate(BlockStateGen.directionalBlockProvider(true))
.transform(BlockStressDefaults.setImpact(4.0))
.onRegister(addMovementBehaviour(new DrillMovementBehaviour()))
.onRegister(movementBehaviour(new DrillMovementBehaviour()))
.item()
.transform(customItemModel())
.register();
@ -1246,7 +1246,7 @@ public class AllBlocks {
.transform(axeOrPickaxe())
.blockstate(new SawGenerator()::generate)
.transform(BlockStressDefaults.setImpact(4.0))
.onRegister(addMovementBehaviour(new SawMovementBehaviour()))
.onRegister(movementBehaviour(new SawMovementBehaviour()))
.addLayer(() -> RenderType::cutoutMipped)
.item()
.transform(customItemModel())
@ -1258,8 +1258,8 @@ public class AllBlocks {
.transform(axeOrPickaxe())
.blockstate(BlockStateGen.directionalAxisBlockProvider())
.transform(BlockStressDefaults.setImpact(4.0))
.onRegister(addMovementBehaviour(new DeployerMovementBehaviour()))
.onRegister(addInteractionBehaviour(new DeployerMovingInteraction()))
.onRegister(movementBehaviour(new DeployerMovementBehaviour()))
.onRegister(interactionBehaviour(new DeployerMovingInteraction()))
.item(AssemblyOperatorBlockItem::new)
.transform(customItemModel())
.register();
@ -1270,7 +1270,7 @@ public class AllBlocks {
.properties(p -> p.color(MaterialColor.PODZOL))
.transform(axeOrPickaxe())
.blockstate((c, p) -> p.directionalBlock(c.get(), AssetLookup.partialBaseModel(c, p)))
.onRegister(addMovementBehaviour(new PortableStorageInterfaceMovement()))
.onRegister(movementBehaviour(new PortableStorageInterfaceMovement()))
.item()
.transform(customItemModel())
.register();
@ -1280,7 +1280,7 @@ public class AllBlocks {
.initialProperties(SharedProperties::stone)
.properties(p -> p.color(MaterialColor.COLOR_GRAY))
.transform(axeOrPickaxe())
.onRegister(addMovementBehaviour(new ContactMovementBehaviour()))
.onRegister(movementBehaviour(new ContactMovementBehaviour()))
.blockstate((c, p) -> p.directionalBlock(c.get(), AssetLookup.forPowered(c, p)))
.item()
.transform(customItemModel("_", "block"))
@ -1291,7 +1291,7 @@ public class AllBlocks {
.initialProperties(SharedProperties::stone)
.properties(p -> p.color(MaterialColor.METAL))
.transform(axeOrPickaxe())
.onRegister(addMovementBehaviour(new HarvesterMovementBehaviour()))
.onRegister(movementBehaviour(new HarvesterMovementBehaviour()))
.blockstate(BlockStateGen.horizontalBlockProvider(true))
.addLayer(() -> RenderType::cutoutMipped)
.item()
@ -1303,7 +1303,7 @@ public class AllBlocks {
.initialProperties(SharedProperties::stone)
.properties(p -> p.color(MaterialColor.COLOR_GRAY))
.transform(axeOrPickaxe())
.onRegister(addMovementBehaviour(new PloughMovementBehaviour()))
.onRegister(movementBehaviour(new PloughMovementBehaviour()))
.blockstate(BlockStateGen.horizontalBlockProvider(false))
.simpleItem()
.register();
@ -1316,8 +1316,8 @@ public class AllBlocks {
.initialProperties(SharedProperties::wooden)
.properties(p -> p.color(colour.getMaterialColor()))
.transform(axeOnly())
.onRegister(addMovementBehaviour(movementBehaviour))
.onRegister(addInteractionBehaviour(interactionBehaviour))
.onRegister(movementBehaviour(movementBehaviour))
.onRegister(interactionBehaviour(interactionBehaviour))
.onRegister(assignDataBehaviour(new EntityNameDisplaySource(), "entity_name"))
.blockstate((c, p) -> {
p.simpleBlock(c.get(), p.models()
@ -1588,8 +1588,8 @@ public class AllBlocks {
.blockstate((c, p) -> p.horizontalBlock(c.get(),
s -> AssetLookup.partialBaseModel(c, p,
s.getValue(ControlsBlock.VIRTUAL) ? "virtual" : s.getValue(ControlsBlock.OPEN) ? "open" : "closed")))
.onRegister(addMovementBehaviour(new ControlsMovementBehaviour()))
.onRegister(addInteractionBehaviour(new ControlsInteractionBehaviour()))
.onRegister(movementBehaviour(new ControlsMovementBehaviour()))
.onRegister(interactionBehaviour(new ControlsInteractionBehaviour()))
.lang("Train Controls")
.item()
.transform(customItemModel())
@ -1651,7 +1651,7 @@ public class AllBlocks {
.properties(p -> p.color(MaterialColor.STONE))
.transform(pickaxeOnly())
.tag(AllBlockTags.SAFE_NBT.tag)
.onRegister(addMovementBehaviour(FunnelMovementBehaviour.andesite()))
.onRegister(movementBehaviour(FunnelMovementBehaviour.andesite()))
.blockstate(new FunnelGenerator("andesite", false)::generate)
.item(FunnelItem::new)
.model(FunnelGenerator.itemModel("andesite"))
@ -1674,7 +1674,7 @@ public class AllBlocks {
.properties(p -> p.color(MaterialColor.TERRACOTTA_YELLOW))
.transform(pickaxeOnly())
.tag(AllBlockTags.SAFE_NBT.tag)
.onRegister(addMovementBehaviour(FunnelMovementBehaviour.brass()))
.onRegister(movementBehaviour(FunnelMovementBehaviour.brass()))
.blockstate(new FunnelGenerator("brass", true)::generate)
.item(FunnelItem::new)
.model(FunnelGenerator.itemModel("brass"))
@ -1918,14 +1918,14 @@ public class AllBlocks {
REGISTRATE.block("peculiar_bell", PeculiarBellBlock::new)
.properties(p -> p.color(MaterialColor.GOLD))
.transform(BuilderTransformers.bell())
.onRegister(addMovementBehaviour(new BellMovementBehaviour()))
.onRegister(movementBehaviour(new BellMovementBehaviour()))
.register();
public static final BlockEntry<HauntedBellBlock> HAUNTED_BELL =
REGISTRATE.block("haunted_bell", HauntedBellBlock::new)
.properties(p -> p.color(MaterialColor.SAND))
.transform(BuilderTransformers.bell())
.onRegister(addMovementBehaviour(new HauntedBellMovementBehaviour()))
.onRegister(movementBehaviour(new HauntedBellMovementBehaviour()))
.register();
public static final DyedBlockList<ToolboxBlock> TOOLBOXES = new DyedBlockList<>(colour -> {

View file

@ -1,70 +1,80 @@
package com.simibubi.create;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.function.Supplier;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
import com.simibubi.create.content.contraptions.components.structureMovement.MovingInteractionBehaviour;
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.DoorMovingInteraction;
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.LeverMovingInteraction;
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.TrapdoorMovingInteraction;
import com.tterrag.registrate.util.nullness.NonNullConsumer;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.registries.IRegistryDelegate;
public class AllInteractionBehaviours {
private static final HashMap<ResourceLocation, Supplier<MovingInteractionBehaviour>> INTERACT_BEHAVIOURS =
new HashMap<>();
private static final Map<IRegistryDelegate<Block>, MovingInteractionBehaviour> BLOCK_BEHAVIOURS = new HashMap<>();
private static final List<BehaviourProvider> GLOBAL_BEHAVIOURS = new ArrayList<>();
public static void addInteractionBehaviour(ResourceLocation loc, Supplier<MovingInteractionBehaviour> behaviour) {
if (INTERACT_BEHAVIOURS.containsKey(loc))
Create.LOGGER.warn("Interaction behaviour for " + loc.toString() + " was overridden");
INTERACT_BEHAVIOURS.put(loc, behaviour);
public static void registerBehaviour(IRegistryDelegate<Block> block, MovingInteractionBehaviour provider) {
BLOCK_BEHAVIOURS.put(block, provider);
}
public static void addInteractionBehaviour(Block block, Supplier<MovingInteractionBehaviour> behaviour) {
addInteractionBehaviour(block.getRegistryName(), behaviour);
}
public static <B extends Block> NonNullConsumer<? super B> addInteractionBehaviour(
MovingInteractionBehaviour movementBehaviour) {
return b -> addInteractionBehaviour(b.getRegistryName(), () -> movementBehaviour);
public static void registerBehaviourProvider(BehaviourProvider provider) {
GLOBAL_BEHAVIOURS.add(provider);
}
@Nullable
public static MovingInteractionBehaviour of(ResourceLocation loc) {
return (INTERACT_BEHAVIOURS.get(loc) == null) ? null
: INTERACT_BEHAVIOURS.get(loc)
.get();
}
@Nullable
public static MovingInteractionBehaviour of(Block block) {
return of(block.getRegistryName());
}
public static boolean contains(Block block) {
return INTERACT_BEHAVIOURS.containsKey(block.getRegistryName());
}
static void register() {
addInteractionBehaviour(Blocks.LEVER.getRegistryName(), LeverMovingInteraction::new);
// TODO: Scan registry for instanceof (-> modded door support)
for (Block trapdoor : ImmutableList.of(Blocks.ACACIA_TRAPDOOR, Blocks.OAK_TRAPDOOR, Blocks.DARK_OAK_TRAPDOOR,
Blocks.SPRUCE_TRAPDOOR, Blocks.JUNGLE_TRAPDOOR, Blocks.BIRCH_TRAPDOOR, Blocks.WARPED_TRAPDOOR,
Blocks.CRIMSON_TRAPDOOR)) {
addInteractionBehaviour(trapdoor.getRegistryName(), TrapdoorMovingInteraction::new);
public static MovingInteractionBehaviour getBehaviour(BlockState state) {
MovingInteractionBehaviour behaviour = BLOCK_BEHAVIOURS.get(state.getBlock().delegate);
if (behaviour != null) {
return behaviour;
}
for (Block door : ImmutableList.of(Blocks.ACACIA_DOOR, Blocks.OAK_DOOR, Blocks.DARK_OAK_DOOR,
Blocks.SPRUCE_DOOR, Blocks.JUNGLE_DOOR, Blocks.BIRCH_DOOR, Blocks.WARPED_DOOR, Blocks.CRIMSON_DOOR)) {
addInteractionBehaviour(door.getRegistryName(), DoorMovingInteraction::new);
for (BehaviourProvider provider : GLOBAL_BEHAVIOURS) {
behaviour = provider.getBehaviour(state);
if (behaviour != null) {
return behaviour;
}
}
return null;
}
public static <B extends Block> NonNullConsumer<? super B> interactionBehaviour(
MovingInteractionBehaviour behaviour) {
return b -> registerBehaviour(b.delegate, behaviour);
}
static void registerDefaults() {
registerBehaviour(Blocks.LEVER.delegate, new LeverMovingInteraction());
DoorMovingInteraction doorBehaviour = new DoorMovingInteraction();
registerBehaviourProvider(state -> {
if (state.is(BlockTags.WOODEN_DOORS)) {
return doorBehaviour;
}
return null;
});
TrapdoorMovingInteraction trapdoorBehaviour = new TrapdoorMovingInteraction();
registerBehaviourProvider(state -> {
if (state.is(BlockTags.WOODEN_TRAPDOORS)) {
return trapdoorBehaviour;
}
return null;
});
}
public interface BehaviourProvider {
@Nullable
MovingInteractionBehaviour getBehaviour(BlockState state);
}
}

View file

@ -1,8 +1,11 @@
package com.simibubi.create;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.jetbrains.annotations.Nullable;
import com.simibubi.create.content.contraptions.components.actors.BellMovementBehaviour;
import com.simibubi.create.content.contraptions.components.actors.CampfireMovementBehaviour;
@ -11,54 +14,56 @@ import com.simibubi.create.content.contraptions.components.actors.dispenser.Drop
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
import com.tterrag.registrate.util.nullness.NonNullConsumer;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.registries.IRegistryDelegate;
public class AllMovementBehaviours {
private static final HashMap<ResourceLocation, MovementBehaviour> MOVEMENT_BEHAVIOURS = new HashMap<>();
private static final Map<IRegistryDelegate<Block>, MovementBehaviour> BLOCK_BEHAVIOURS = new HashMap<>();
private static final List<BehaviourProvider> GLOBAL_BEHAVIOURS = new ArrayList<>();
public static void addMovementBehaviour(ResourceLocation resourceLocation, MovementBehaviour movementBehaviour) {
if (MOVEMENT_BEHAVIOURS.containsKey(resourceLocation))
Create.LOGGER.warn("Movement behaviour for " + resourceLocation.toString() + " was overridden");
MOVEMENT_BEHAVIOURS.put(resourceLocation, movementBehaviour);
public static void registerBehaviour(IRegistryDelegate<Block> block, MovementBehaviour behaviour) {
BLOCK_BEHAVIOURS.put(block, behaviour);
}
public static void addMovementBehaviour(Block block, MovementBehaviour movementBehaviour) {
addMovementBehaviour(block.getRegistryName(), movementBehaviour);
public static void registerBehaviourProvider(BehaviourProvider provider) {
GLOBAL_BEHAVIOURS.add(provider);
}
@Nullable
public static MovementBehaviour of(ResourceLocation resourceLocation) {
return MOVEMENT_BEHAVIOURS.getOrDefault(resourceLocation, null);
public static MovementBehaviour getBehaviour(BlockState state) {
MovementBehaviour behaviour = BLOCK_BEHAVIOURS.get(state.getBlock().delegate);
if (behaviour != null) {
return behaviour;
}
for (BehaviourProvider provider : GLOBAL_BEHAVIOURS) {
behaviour = provider.getBehaviour(state);
if (behaviour != null) {
return behaviour;
}
}
return null;
}
@Nullable
public static MovementBehaviour of(Block block) {
return of(block.getRegistryName());
public static <B extends Block> NonNullConsumer<? super B> movementBehaviour(
MovementBehaviour behaviour) {
return b -> registerBehaviour(b.delegate, behaviour);
}
@Nullable
public static MovementBehaviour of(BlockState state) {
return of(state.getBlock());
}
public static boolean contains(Block block) {
return MOVEMENT_BEHAVIOURS.containsKey(block.getRegistryName());
}
public static <B extends Block> NonNullConsumer<? super B> addMovementBehaviour(
MovementBehaviour movementBehaviour) {
return b -> addMovementBehaviour(b.getRegistryName(), movementBehaviour);
}
static void register() {
addMovementBehaviour(Blocks.BELL, new BellMovementBehaviour());
addMovementBehaviour(Blocks.CAMPFIRE, new CampfireMovementBehaviour());
static void registerDefaults() {
registerBehaviour(Blocks.BELL.delegate, new BellMovementBehaviour());
registerBehaviour(Blocks.CAMPFIRE.delegate, new CampfireMovementBehaviour());
DispenserMovementBehaviour.gatherMovedDispenseItemBehaviours();
addMovementBehaviour(Blocks.DISPENSER, new DispenserMovementBehaviour());
addMovementBehaviour(Blocks.DROPPER, new DropperMovementBehaviour());
registerBehaviour(Blocks.DISPENSER.delegate, new DispenserMovementBehaviour());
registerBehaviour(Blocks.DROPPER.delegate, new DropperMovementBehaviour());
}
public interface BehaviourProvider {
@Nullable
MovementBehaviour getBehaviour(BlockState state);
}
}

View file

@ -99,9 +99,9 @@ public class Create {
AllContainerTypes.register();
AllEntityTypes.register();
AllTileEntities.register();
AllMovementBehaviours.register();
AllDisplayBehaviours.register();
AllInteractionBehaviours.register();
AllMovementBehaviours.registerDefaults();
AllInteractionBehaviours.registerDefaults();
AllDisplayBehaviours.registerDefaults();
AllArmInteractionPointTypes.register();
AllWorldFeatures.register();
AllEnchantments.register();

View file

@ -52,7 +52,7 @@ public class ContraptionBlockSource implements BlockSource {
@Override
public BlockState getBlockState() {
if(context.state.hasProperty(BlockStateProperties.FACING) && overrideFacing != null)
if (context.state.hasProperty(BlockStateProperties.FACING) && overrideFacing != null)
return context.state.setValue(BlockStateProperties.FACING, overrideFacing);
return context.state;
}

View file

@ -395,7 +395,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
for (MutablePair<StructureBlockInfo, MovementContext> pair : contraption.getActors()) {
MovementContext context = pair.right;
StructureBlockInfo blockInfo = pair.left;
MovementBehaviour actor = AllMovementBehaviours.of(blockInfo.state);
MovementBehaviour actor = AllMovementBehaviours.getBehaviour(blockInfo.state);
if (actor == null)
continue;
@ -459,7 +459,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
for (MutablePair<StructureBlockInfo, MovementContext> pair : contraption.getActors()) {
MovementContext context = pair.right;
StructureBlockInfo blockInfo = pair.left;
MovementBehaviour actor = AllMovementBehaviours.of(blockInfo.state);
MovementBehaviour actor = AllMovementBehaviours.getBehaviour(blockInfo.state);
if (actor instanceof PortableStorageInterfaceMovement && isActorActive(context, actor))
if (context.position != null)
actor.visitNewPosition(context, new BlockPos(context.position));

View file

@ -620,18 +620,22 @@ public abstract class Contraption {
protected void addBlock(BlockPos pos, Pair<StructureBlockInfo, BlockEntity> pair) {
StructureBlockInfo captured = pair.getKey();
BlockPos localPos = pos.subtract(anchor);
StructureBlockInfo StructureBlockInfo = new StructureBlockInfo(localPos, captured.state, captured.nbt);
StructureBlockInfo structureBlockInfo = new StructureBlockInfo(localPos, captured.state, captured.nbt);
if (blocks.put(localPos, StructureBlockInfo) != null)
if (blocks.put(localPos, structureBlockInfo) != null)
return;
bounds = bounds.minmax(new AABB(localPos));
BlockEntity te = pair.getValue();
storage.addBlock(localPos, te);
if (AllMovementBehaviours.contains(captured.state.getBlock()))
actors.add(MutablePair.of(StructureBlockInfo, null));
if (AllInteractionBehaviours.contains(captured.state.getBlock()))
interactors.put(localPos, AllInteractionBehaviours.of(captured.state.getBlock()));
if (AllMovementBehaviours.getBehaviour(captured.state) != null)
actors.add(MutablePair.of(structureBlockInfo, null));
MovingInteractionBehaviour interactionBehaviour = AllInteractionBehaviours.getBehaviour(captured.state);
if (interactionBehaviour != null)
interactors.put(localPos, interactionBehaviour);
if (te instanceof CreativeCrateTileEntity
&& ((CreativeCrateTileEntity) te).getBehaviour(FilteringBehaviour.TYPE)
.getFilter()
@ -712,7 +716,7 @@ public abstract class Contraption {
StructureBlockInfo structureBlockInfo = getBlocks().get(pos);
if (structureBlockInfo == null)
return;
MovingInteractionBehaviour behaviour = AllInteractionBehaviours.of(structureBlockInfo.state.getBlock());
MovingInteractionBehaviour behaviour = AllInteractionBehaviours.getBehaviour(structureBlockInfo.state);
if (behaviour != null)
interactors.put(pos, behaviour);
});
@ -737,7 +741,7 @@ public abstract class Contraption {
for (MutablePair<StructureBlockInfo, MovementContext> actor : getActors()) {
CompoundTag compound = new CompoundTag();
compound.put("Pos", NbtUtils.writeBlockPos(actor.left.pos));
AllMovementBehaviours.of(actor.left.state)
AllMovementBehaviours.getBehaviour(actor.left.state)
.writeExtraData(actor.right);
actor.right.writeToNBT(compound);
actorsNBT.add(compound);
@ -855,9 +859,7 @@ public abstract class Contraption {
if (!world.isClientSide)
return;
Block block = info.state.getBlock();
CompoundTag tag = info.nbt;
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(block);
if (tag == null)
return;
@ -873,6 +875,7 @@ public abstract class Contraption {
((KineticTileEntity) te).setSpeed(0);
te.getBlockState();
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(info.state);
if (movementBehaviour == null || !movementBehaviour.hasSpecialInstancedRendering())
maybeInstancedTileEntities.add(te);
@ -1107,14 +1110,14 @@ public abstract class Contraption {
public void startMoving(Level world) {
for (MutablePair<StructureBlockInfo, MovementContext> pair : actors) {
MovementContext context = new MovementContext(world, pair.left, this);
AllMovementBehaviours.of(pair.left.state)
AllMovementBehaviours.getBehaviour(pair.left.state)
.startMoving(context);
pair.setRight(context);
}
}
public void stop(Level world) {
foreachActor(world, (behaviour, ctx) -> {
forEachActor(world, (behaviour, ctx) -> {
behaviour.stopMoving(ctx);
ctx.position = null;
ctx.motion = Vec3.ZERO;
@ -1123,9 +1126,9 @@ public abstract class Contraption {
});
}
public void foreachActor(Level world, BiConsumer<MovementBehaviour, MovementContext> callBack) {
public void forEachActor(Level world, BiConsumer<MovementBehaviour, MovementContext> callBack) {
for (MutablePair<StructureBlockInfo, MovementContext> pair : actors)
callBack.accept(AllMovementBehaviours.of(pair.getLeft().state), pair.getRight());
callBack.accept(AllMovementBehaviours.getBehaviour(pair.getLeft().state), pair.getRight());
}
protected boolean shouldUpdateAfterMovement(StructureBlockInfo info) {
@ -1322,7 +1325,7 @@ public abstract class Contraption {
public boolean containsBlockBreakers() {
for (MutablePair<StructureBlockInfo, MovementContext> pair : actors) {
MovementBehaviour behaviour = AllMovementBehaviours.of(pair.getLeft().state);
MovementBehaviour behaviour = AllMovementBehaviours.getBehaviour(pair.getLeft().state);
if (behaviour instanceof BlockBreakingMovementBehaviour || behaviour instanceof HarvesterMovementBehaviour)
return true;
}

View file

@ -617,8 +617,9 @@ public class ContraptionCollider {
if (collidedState.getBlock() instanceof CocoaBlock)
continue;
if (AllMovementBehaviours.contains(blockInfo.state.getBlock())) {
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state.getBlock());
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state);
if (movementBehaviour != null) {
if (movementBehaviour instanceof BlockBreakingMovementBehaviour) {
BlockBreakingMovementBehaviour behaviour = (BlockBreakingMovementBehaviour) movementBehaviour;
if (!behaviour.canBreak(world, colliderPos, collidedState) && !emptyCollider)

View file

@ -10,8 +10,6 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
public abstract class MovingInteractionBehaviour {
public MovingInteractionBehaviour() {}
protected void setContraptionActorData(AbstractContraptionEntity contraptionEntity, int index,
StructureBlockInfo info, MovementContext ctx) {
contraptionEntity.contraption.actors.remove(index);

View file

@ -21,7 +21,7 @@ public class DoorMovingInteraction extends SimpleBlockMovingInteraction {
protected BlockState handle(Player player, Contraption contraption, BlockPos pos, BlockState currentState) {
if (!(currentState.getBlock() instanceof DoorBlock))
return currentState;
boolean trainDoor = currentState.getBlock() instanceof SlidingDoorBlock;
SoundEvent sound = currentState.getValue(DoorBlock.OPEN) ? trainDoor ? null : SoundEvents.WOODEN_DOOR_CLOSE
: trainDoor ? SoundEvents.IRON_DOOR_OPEN : SoundEvents.WOODEN_DOOR_OPEN;

View file

@ -65,7 +65,7 @@ public class ContraptionInstanceManager extends BlockEntityInstanceManager {
if (contraption.isHiddenInPortal(context.localPos))
return null;
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state);
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state);
if (movementBehaviour != null && movementBehaviour.hasSpecialInstancedRendering()) {
ActorInstance instance = movementBehaviour.createInstance(materialManager, renderWorld, context);

View file

@ -155,7 +155,7 @@ public class ContraptionRenderDispatcher {
context.world = world;
StructureTemplate.StructureBlockInfo blockInfo = actor.getLeft();
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state);
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state);
if (movementBehaviour != null) {
if (c.isHiddenInPortal(blockInfo.pos))
continue;

View file

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
@ -26,51 +27,38 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.registries.IRegistryDelegate;
public class AllDisplayBehaviours {
public static final HashMap<ResourceLocation, DisplayBehaviour>
public static final Map<ResourceLocation, DisplayBehaviour> GATHERER_BEHAVIOURS = new HashMap<>();
GATHERER_BEHAVIOURS = new HashMap<>();
public static final Map<IRegistryDelegate<Block>, List<DisplaySource>> SOURCES_BY_BLOCK = new HashMap<>();
public static final Map<IRegistryDelegate<BlockEntityType<?>>, List<DisplaySource>> SOURCES_BY_TILE = new HashMap<>();
public static final HashMap<ResourceLocation, List<DisplaySource>>
SOURCES_BY_BLOCK = new HashMap<>(), SOURCES_BY_TILE = new HashMap<>();
public static final HashMap<ResourceLocation, DisplayTarget>
TARGETS_BY_BLOCK = new HashMap<>(), TARGETS_BY_TILE = new HashMap<>();
public static final Map<IRegistryDelegate<Block>, DisplayTarget> TARGETS_BY_BLOCK = new HashMap<>();
public static final Map<IRegistryDelegate<BlockEntityType<?>>, DisplayTarget> TARGETS_BY_TILE = new HashMap<>();
public static DisplayBehaviour register(ResourceLocation id, DisplayBehaviour behaviour) {
if (GATHERER_BEHAVIOURS.containsKey(id))
Create.LOGGER.warn("Data Gatherer Behaviour for " + id.toString() + " was overridden");
behaviour.id = id;
GATHERER_BEHAVIOURS.put(id, behaviour);
return behaviour;
}
public static void assign(DisplayBehaviour behaviour, Block block) {
assignBlock(behaviour, block.getRegistryName());
}
public static void assign(DisplayBehaviour behaviour, BlockEntityType<?> teType) {
assignTileEntity(behaviour, teType.getRegistryName());
}
public static void assignBlock(DisplayBehaviour behaviour, ResourceLocation blockId) {
public static void assignBlock(DisplayBehaviour behaviour, IRegistryDelegate<Block> block) {
if (behaviour instanceof DisplaySource source)
SOURCES_BY_BLOCK.computeIfAbsent(blockId, r -> new ArrayList<>())
SOURCES_BY_BLOCK.computeIfAbsent(block, r -> new ArrayList<>())
.add(source);
if (behaviour instanceof DisplayTarget target)
TARGETS_BY_BLOCK.put(blockId, target);
TARGETS_BY_BLOCK.put(block, target);
}
public static void assignTileEntity(DisplayBehaviour behaviour, ResourceLocation tileId) {
public static void assignTile(DisplayBehaviour behaviour, IRegistryDelegate<BlockEntityType<?>> teType) {
if (behaviour instanceof DisplaySource source)
SOURCES_BY_TILE.computeIfAbsent(tileId, r -> new ArrayList<>())
SOURCES_BY_TILE.computeIfAbsent(teType, r -> new ArrayList<>())
.add(source);
if (behaviour instanceof DisplayTarget target)
TARGETS_BY_TILE.put(tileId, target);
TARGETS_BY_TILE.put(teType, target);
}
public static <B extends Block> NonNullConsumer<? super B> assignDataBehaviour(DisplayBehaviour behaviour,
@ -81,7 +69,7 @@ public class AllDisplayBehaviours {
if (suffix.length > 0)
idSuffix += "_" + suffix[0];
assignBlock(register(new ResourceLocation(registryName.getNamespace(), registryName.getPath() + idSuffix),
behaviour), registryName);
behaviour), b.delegate);
};
}
@ -92,10 +80,10 @@ public class AllDisplayBehaviours {
String idSuffix = behaviour instanceof DisplaySource ? "_source" : "_target";
if (suffix.length > 0)
idSuffix += "_" + suffix[0];
assignTileEntity(
assignTile(
register(new ResourceLocation(registryName.getNamespace(), registryName.getPath() + idSuffix),
behaviour),
registryName);
b.delegate);
};
}
@ -119,7 +107,42 @@ public class AllDisplayBehaviours {
//
public static List<DisplaySource> sourcesOf(Block block) {
return SOURCES_BY_BLOCK.getOrDefault(block.getRegistryName(), Collections.emptyList());
}
public static List<DisplaySource> sourcesOf(BlockState state) {
return sourcesOf(state.getBlock());
}
public static List<DisplaySource> sourcesOf(BlockEntityType<?> tileEntityType) {
return SOURCES_BY_TILE.getOrDefault(tileEntityType, Collections.emptyList());
}
public static List<DisplaySource> sourcesOf(BlockEntity tileEntity) {
return sourcesOf(tileEntity.getType());
}
@Nullable
public static DisplayTarget targetOf(Block block) {
return TARGETS_BY_BLOCK.get(block.delegate);
}
@Nullable
public static DisplayTarget targetOf(BlockState state) {
return targetOf(state.getBlock());
}
@Nullable
public static DisplayTarget targetOf(BlockEntityType<?> tileEntityType) {
return TARGETS_BY_TILE.get(tileEntityType.delegate);
}
@Nullable
public static DisplayTarget targetOf(BlockEntity tileEntity) {
return targetOf(tileEntity.getType());
}
public static List<DisplaySource> sourcesOf(LevelAccessor level, BlockPos pos) {
BlockState blockState = level.getBlockState(pos);
BlockEntity blockEntity = level.getBlockEntity(pos);
@ -145,43 +168,14 @@ public class AllDisplayBehaviours {
return targetOfTE;
}
public static List<DisplaySource> sourcesOf(BlockState state) {
return sourcesOf(state.getBlock());
}
public static List<DisplaySource> sourcesOf(BlockEntity tileEntity) {
return SOURCES_BY_TILE.getOrDefault(tileEntity.getType()
.getRegistryName(), Collections.emptyList());
}
public static List<DisplaySource> sourcesOf(Block block) {
return SOURCES_BY_BLOCK.getOrDefault(block.getRegistryName(), Collections.emptyList());
}
@Nullable
public static DisplayTarget targetOf(BlockState state) {
return targetOf(state.getBlock());
}
@Nullable
public static DisplayTarget targetOf(BlockEntity tileEntity) {
return TARGETS_BY_TILE.get(tileEntity.getType()
.getRegistryName());
}
@Nullable
public static DisplayTarget targetOf(Block block) {
return TARGETS_BY_BLOCK.get(block.getRegistryName());
}
//
public static void register() {
assign(register(Create.asResource("sign_display_target"), new SignDisplayTarget()), BlockEntityType.SIGN);
assign(register(Create.asResource("lectern_display_target"), new LecternDisplayTarget()), BlockEntityType.LECTERN);
assign(register(Create.asResource("death_count_display_source"), new DeathCounterDisplaySource()), Blocks.RESPAWN_ANCHOR);
assign(register(Create.asResource("scoreboard_display_source"), new ScoreboardDisplaySource()), BlockEntityType.COMMAND_BLOCK);
assign(register(Create.asResource("enchant_power_display_source"), new EnchantPowerDisplaySource()), BlockEntityType.ENCHANTING_TABLE);
assign(register(Create.asResource("redstone_power_display_source"), new RedstonePowerDisplaySource()), Blocks.TARGET);
public static void registerDefaults() {
assignTile(register(Create.asResource("sign_display_target"), new SignDisplayTarget()), BlockEntityType.SIGN.delegate);
assignTile(register(Create.asResource("lectern_display_target"), new LecternDisplayTarget()), BlockEntityType.LECTERN.delegate);
assignBlock(register(Create.asResource("death_count_display_source"), new DeathCounterDisplaySource()), Blocks.RESPAWN_ANCHOR.delegate);
assignTile(register(Create.asResource("scoreboard_display_source"), new ScoreboardDisplaySource()), BlockEntityType.COMMAND_BLOCK.delegate);
assignTile(register(Create.asResource("enchant_power_display_source"), new EnchantPowerDisplaySource()), BlockEntityType.ENCHANTING_TABLE.delegate);
assignBlock(register(Create.asResource("redstone_power_display_source"), new RedstonePowerDisplaySource()), Blocks.TARGET.delegate);
}
}

View file

@ -463,7 +463,7 @@ public class Train {
c.forEachPresentEntity(cce -> cce.getContraption()
.getActors()
.forEach(pair -> {
MovementBehaviour behaviour = AllMovementBehaviours.of(pair.getKey().state);
MovementBehaviour behaviour = AllMovementBehaviours.getBehaviour(pair.getKey().state);
if (behaviour != null)
behaviour.cancelStall(pair.getValue());
}));

View file

@ -1,7 +1,7 @@
package com.simibubi.create.foundation.data;
import static com.simibubi.create.AllInteractionBehaviours.addInteractionBehaviour;
import static com.simibubi.create.AllMovementBehaviours.addMovementBehaviour;
import static com.simibubi.create.AllInteractionBehaviours.interactionBehaviour;
import static com.simibubi.create.AllMovementBehaviours.movementBehaviour;
import static com.simibubi.create.AllTags.axeOrPickaxe;
import static com.simibubi.create.AllTags.pickaxeOnly;
import static com.simibubi.create.foundation.data.BlockStateGen.axisBlock;
@ -103,7 +103,7 @@ public class BuilderTransformers {
})
.transform(pickaxeOnly())
.tag(BlockTags.TRAPDOORS)
.onRegister(addInteractionBehaviour(new TrapdoorMovingInteraction()))
.onRegister(interactionBehaviour(new TrapdoorMovingInteraction()))
.item()
.tag(ItemTags.TRAPDOORS)
.build();
@ -120,8 +120,8 @@ public class BuilderTransformers {
})
.addLayer(() -> RenderType::cutoutMipped)
.transform(pickaxeOnly())
.onRegister(addInteractionBehaviour(new DoorMovingInteraction()))
.onRegister(addMovementBehaviour(new SlidingDoorMovementBehaviour()))
.onRegister(interactionBehaviour(new DoorMovingInteraction()))
.onRegister(movementBehaviour(new SlidingDoorMovementBehaviour()))
.tag(BlockTags.DOORS)
.tag(BlockTags.WOODEN_DOORS) // for villager AI
.loot((lr, block) -> lr.add(block, BlockLoot.createDoorTable(block)))

View file

@ -127,6 +127,7 @@ public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
return this.entity(self(), name, factory, classification);
}
@Override
public <T extends Entity, P> CreateEntityBuilder<T, P> entity(P parent, String name,
EntityType.EntityFactory<T> factory, MobCategory classification) {
return (CreateEntityBuilder<T, P>) this.entry(name, (callback) -> {