跳到主要内容

41树干放置器

代码

在tutorialmod.mixins.json中:

"mixins": [
"ExampleMixin",
"TrunkPlacerTypeInvoker"
],

TrunkPlacerTypeInvoker类:

@Mixin(TrunkPlacerType.class)
public interface TrunkPlacerTypeInvoker {
@Invoker("register")
static <P extends TrunkPlacer> TrunkPlacerType<P> callRegister(String id, Codec<P> codec) {
throw new IllegalStateException();
}
}

新增树生成结构:

public class ChestnutTrunkPlacer extends TrunkPlacer {
public static final Codec<ChestnutTrunkPlacer> CODEC = RecordCodecBuilder.create(objectInstance ->
fillTrunkPlacerFields(objectInstance).apply(objectInstance, ChestnutTrunkPlacer::new));

public ChestnutTrunkPlacer(int baseHeight, int firstRandomHeight, int secondRandomHeight) {
super(baseHeight, firstRandomHeight, secondRandomHeight);
}

@Override
protected TrunkPlacerType<?> getType() {
return ModTrunkPlacerTypes.CHESTNUT_TRUNK_PLACER;
}

@Override
public List<FoliagePlacer.TreeNode> generate(TestableWorld world, BiConsumer<BlockPos, BlockState> replacer,
Random random, int height, BlockPos startPos, TreeFeatureConfig config) {
setToDirt(world, replacer, random, startPos.down(), config);
int height_ = height + random.nextBetween(firstRandomHeight, firstRandomHeight + 2) + random.nextBetween(secondRandomHeight - 1, secondRandomHeight + 1);

for(int i = 0; i < height_; i++) {
getAndSetState(world, replacer, random, startPos.up(i), config);

if(i % 2 == 0 && random.nextBoolean()) {
if(random.nextFloat() > 0.25f) {
for(int x = 1; x <= 4; x++) {
replacer.accept(startPos.up(i).offset(Direction.NORTH, x), (BlockState) Function.identity().apply(config.trunkProvider
.get(random, startPos.up(i).offset(Direction.NORTH, x)).with(PillarBlock.AXIS, Direction.Axis.Z)));
}
}

if(random.nextFloat() > 0.25f) {
for(int x = 1; x <= 4; x++) {
replacer.accept(startPos.up(i).offset(Direction.SOUTH, x), (BlockState) Function.identity().apply(config.trunkProvider
.get(random, startPos.up(i).offset(Direction.SOUTH, x)).with(PillarBlock.AXIS, Direction.Axis.Z)));
}
}

if(random.nextFloat() > 0.25f) {
for(int x = 1; x <= 4; x++) {
replacer.accept(startPos.up(i).offset(Direction.EAST, x), (BlockState) Function.identity().apply(config.trunkProvider
.get(random, startPos.up(i).offset(Direction.EAST, x)).with(PillarBlock.AXIS, Direction.Axis.X)));
}
}

if(random.nextFloat() > 0.25f) {
for(int x = 1; x <= 4; x++) {
replacer.accept(startPos.up(i).offset(Direction.WEST, x), (BlockState) Function.identity().apply(config.trunkProvider
.get(random, startPos.up(i).offset(Direction.WEST, x)).with(PillarBlock.AXIS, Direction.Axis.X)));
}
}
}
}

return ImmutableList.of(new FoliagePlacer.TreeNode(startPos.up(height_), 0, false));
}
}

树种类:

public class ModTrunkPlacerTypes {
public static final TrunkPlacerType<?> CHESTNUT_TRUNK_PLACER = TrunkPlacerTypeInvoker.callRegister("chestnut_trunk_placer", ChestnutTrunkPlacer.CODEC);

public static void register() {
TutorialMod.LOGGER.info("Registering Trunk Placers for " + TutorialMod.MOD_ID);
}
}

修改配置ModConfiguredFeatures:

register(context, CHESTNUT_KEY, Feature.TREE, new TreeFeatureConfig.Builder(
BlockStateProvider.of(ModBlocks.CHESTNUT_LOG),
new ChestnutTrunkPlacer(5, 4, 3),

BlockStateProvider.of(ModBlocks.CHESTNUT_LEAVES),
new BlobFoliagePlacer(ConstantIntProvider.create(2), ConstantIntProvider.create(1), 2),

new TwoLayersFeatureSize(1, 0, 2)).build());

在TutorialMod中:

ModTrunkPlacerTypes.register();

效果

image-20240825213450083