#Oxidization of a block

18 messages · Page 1 of 1 (latest)

floral flame
#

The block is a rail, so it already extends PoweredRailBlock and cant extend OxidizableBlock, and implements my interface ModOxidizable which extends Oxidizable, the only difference being the supplier has my values in it. I want it to be weathering but even implementing Oxidizable or ModOxidizable I cant figure it out.

#

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());
}
#

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

fallow flint
#

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

floral flame
#
    public static void registerOxidizableBlockPair(){
        OxidizableBlocksRegistry.registerOxidizableBlockPair(ModBlocks.COPPER_RAIL,ModBlocks.EXPOSED_COPPER_RAIL);
    }
floral flame
#

thank you it worked ^^

sacred vault
#

@floral flame Hey can you help me out? I am trying to make a custom oxidizable block as well