#Oxidization of a block
18 messages · Page 1 of 1 (latest)
The block class:
package com.nycto.starsandwishes.block.weathering;
import net.minecraft.block.*;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.random.Random;
public class CopperRail extends PoweredRailBlock implements ModOxidizable {
private final Oxidizable.OxidationLevel oxidationLevel;
public CopperRail(Oxidizable.OxidationLevel oxidationLevel, boolean forbidCurves, AbstractBlock.Settings settings) {
super(settings);
this.oxidationLevel = oxidationLevel;
}
@Override
protected void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
this.tickDegradation(state, world, pos, random);
}
@Override
protected boolean hasRandomTicks(BlockState state) {
return Oxidizable.getIncreasedOxidationBlock(state.getBlock()).isPresent();
}
@Override
public OxidationLevel getDegradationLevel() {
return this.oxidationLevel;
}
}
The Init:
public static final Block COPPER_RAIL = registerBlock("copper_rail",
new CopperRail(Oxidizable.OxidationLevel.UNAFFECTED, true, AbstractBlock.Settings.copy(Blocks.POWERED_RAIL)));
The ModOxidizable interface:
package com.nycto.starsandwishes.block.weathering;
import com.google.common.base.Suppliers;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.nycto.starsandwishes.block.ModBlocks;
import net.minecraft.block.Block;
import net.minecraft.block.Oxidizable;
import java.util.function.Supplier;
public interface ModOxidizable extends Oxidizable {
public static final Supplier<BiMap<Block, Block>> OXIDATION_LEVEL_INCREASES = Suppliers.memoize(() -> ImmutableBiMap.<Block, Block>builder()
.put(ModBlocks.COPPER_RAIL, ModBlocks.EXPOSED_COPPER_RAIL)
.put(ModBlocks.EXPOSED_COPPER_RAIL, ModBlocks.WEATHERED_COPPER_RAIL)
.put(ModBlocks.WEATHERED_COPPER_RAIL, ModBlocks.OXIDIZED_COPPER_RAIL)
.build());
public static final Supplier<BiMap<Block, Block>> OXIDATION_LEVEL_DECREASES = Suppliers.memoize(() -> OXIDATION_LEVEL_INCREASES.get().inverse());
}
The vanilla Oxidizable interface:
Pretty sure as long as the block class has the ticking function and implements an interface with the correct supplier (which is extending an interface which is extending an interface) that has the correct ticking functions, it should work
^ The last interface, which Oxidizable extends is Degradable, which is as follows:
The only thing I'm aware im missing and struggling with is the Codec, since its already inheriting a codec from rails which handles the orientation function
I'm thinking the problem may be the lack of MapCodec making it not test for block updates, but I have no experience with them so I'm not sure
For reference, these are OxidizableBlock (the vanilla class which implements Oxidizable, like how my CopperRail implements ModOxidizable) and its Init:
/*
* Decompiled with CFR 0.2.2 (FabricMC 7c48b8c4).
*/
package net.minecraft.block;
import com.mojang.datafixers.kinds.Applicative;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Degradable;
import net.minecraft.block.Oxidizable;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.random.Random;
public class OxidizableBlock
extends Block
implements Oxidizable {
public static final MapCodec<OxidizableBlock> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(((MapCodec)Oxidizable.OxidationLevel.CODEC.fieldOf("weathering_state")).forGetter(Degradable::getDegradationLevel), OxidizableBlock.createSettingsCodec()).apply((Applicative<OxidizableBlock, ?>)instance, OxidizableBlock::new));
private final Oxidizable.OxidationLevel oxidationLevel;
public MapCodec<OxidizableBlock> getCodec() {
return CODEC;
}
public OxidizableBlock(Oxidizable.OxidationLevel oxidationLevel, AbstractBlock.Settings settings) {
super(settings);
this.oxidationLevel = oxidationLevel;
}
@Override
protected void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
this.tickDegradation(state, world, pos, random);
}
@Override
protected boolean hasRandomTicks(BlockState state) {
return Oxidizable.getIncreasedOxidationBlock(state.getBlock()).isPresent();
}
@Override
public Oxidizable.OxidationLevel getDegradationLevel() {
return this.oxidationLevel;
}
@Override
public /* synthetic */ Enum getDegradationLevel() {
return this.getDegradationLevel();
}
}
public static final Block COPPER_BLOCK = Blocks.register("copper_block", (Block)new OxidizableBlock(Oxidizable.OxidationLevel.UNAFFECTED, AbstractBlock.Settings.create().mapColor(MapColor.ORANGE).requiresTool().strength(3.0f, 6.0f).sounds(BlockSoundGroup.COPPER)));
I'm also not sure why the getDegredationLevel() method is overridden twice, one of those implementations being infinitely recursive, but that class is kind of littered with errors which I have chalked up to decompilation issues
Because the OXIDATION_LEVEL_INCREASES map is static, calling Oxidizable.getIncreasedOxidationBlock still refers to the static one in Oxidizable and not your one in ModOxidizable. Instead it is much easier to just use fabrics builtin api to do this. It is called OxidizableBlocksRegistry
public static void registerOxidizableBlockPair(){
OxidizableBlocksRegistry.registerOxidizableBlockPair(ModBlocks.COPPER_RAIL,ModBlocks.EXPOSED_COPPER_RAIL);
}
thank you it worked ^^
@floral flame Hey can you help me out? I am trying to make a custom oxidizable block as well