mirror of
https://github.com/FabricMC/fabric.git
synced 2025-04-03 10:39:57 -04:00
Add flattening, stripping and tilling registries (#1632)
* Add flattening, stripping and tilling registries * Where'd the spaces come from? * Clarify docs * Better overloads for TillableBlockRegistry.register * Mutablise AxeItem.STRIPPED_BLOCKS if needed * Remove simplest TillableBlockRegistry.register overload because the default predicate is for farmland * Add test mod * Update fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/TillableBlockRegistry.java Co-authored-by: haykam821 <24855774+haykam821@users.noreply.github.com> Co-authored-by: haykam821 <24855774+haykam821@users.noreply.github.com>
This commit is contained in:
parent
96bf6a7e71
commit
211ddf95aa
10 changed files with 393 additions and 2 deletions
fabric-content-registries-v0
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-content-registries-v0"
|
||||
version = getSubprojectVersion(project, "0.2.4")
|
||||
version = getSubprojectVersion(project, "0.3.0")
|
||||
|
||||
loom {
|
||||
accessWidener = file("src/main/resources/fabric-content-registries-v0.accesswidener")
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.registry;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
|
||||
import net.fabricmc.fabric.mixin.content.registry.ShovelItemAccessor;
|
||||
|
||||
/**
|
||||
* A registry for shovel flattening interactions. A vanilla example is turning dirt to dirt paths.
|
||||
*/
|
||||
public final class FlattenableBlockRegistry {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
private FlattenableBlockRegistry() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a flattening interaction.
|
||||
*
|
||||
* @param input the input block that can be flattened
|
||||
* @param flattened the flattened result block state
|
||||
*/
|
||||
public static void register(Block input, BlockState flattened) {
|
||||
Objects.requireNonNull(input, "input block cannot be null");
|
||||
Objects.requireNonNull(flattened, "flattened block state cannot be null");
|
||||
BlockState old = ShovelItemAccessor.getPathStates().put(input, flattened);
|
||||
|
||||
if (old != null) {
|
||||
LOGGER.debug("Replaced old flattening mapping from {} to {} with {}", input, old, flattened);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.registry;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.state.property.Properties;
|
||||
|
||||
import net.fabricmc.fabric.mixin.content.registry.AxeItemAccessor;
|
||||
|
||||
/**
|
||||
* A registry for axe stripping interactions. A vanilla example is turning logs to stripped logs.
|
||||
*/
|
||||
public final class StrippableBlockRegistry {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
private StrippableBlockRegistry() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a stripping interaction.
|
||||
*
|
||||
* <p>Both blocks must have the {@link Properties#AXIS axis} property.
|
||||
*
|
||||
* @param input the input block that can be stripped
|
||||
* @param stripped the stripped result block
|
||||
* @throws IllegalArgumentException if the input or the output doesn't have the {@link Properties#AXIS axis} property
|
||||
*/
|
||||
public static void register(Block input, Block stripped) {
|
||||
requireNonNullAndAxisProperty(input, "input block");
|
||||
requireNonNullAndAxisProperty(stripped, "stripped block");
|
||||
Map<Block, Block> strippedBlocks = AxeItemAccessor.getStrippedBlocks();
|
||||
|
||||
if (!(strippedBlocks instanceof HashMap<?, ?>)) {
|
||||
strippedBlocks = new HashMap<>(strippedBlocks);
|
||||
AxeItemAccessor.setStrippedBlocks(strippedBlocks);
|
||||
}
|
||||
|
||||
Block old = strippedBlocks.put(input, stripped);
|
||||
|
||||
if (old != null) {
|
||||
LOGGER.debug("Replaced old stripping mapping from {} to {} with {}", input, old, stripped);
|
||||
}
|
||||
}
|
||||
|
||||
private static void requireNonNullAndAxisProperty(Block block, String name) {
|
||||
Objects.requireNonNull(block, name + " cannot be null");
|
||||
|
||||
if (!block.getStateManager().getProperties().contains(Properties.AXIS)) {
|
||||
throw new IllegalArgumentException(name + " must have the 'axis' property");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.registry;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.HoeItem;
|
||||
import net.minecraft.item.ItemConvertible;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
|
||||
import net.fabricmc.fabric.mixin.content.registry.HoeItemAccessor;
|
||||
|
||||
/**
|
||||
* A registry for hoe tilling interactions. A vanilla example is turning dirt to dirt paths.
|
||||
*/
|
||||
public final class TillableBlockRegistry {
|
||||
private TillableBlockRegistry() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a tilling interaction.
|
||||
*
|
||||
* <p>Tilling interactions are a two-step process. First, a usage predicate is run that decides whether to till
|
||||
* a block. If the predicate returns {@code true}, an action is executed. Default instances of these can be created
|
||||
* with these {@link HoeItem} methods:
|
||||
* <ul>
|
||||
* <li>usage predicate for farmland-like behavior: {@link HoeItem#usagePredicate(ItemUsageContext)}</li>
|
||||
* <li>simple action: {@link HoeItem#getTillingConsumer(BlockState)}</li>
|
||||
* <li>simple action that also drops an item: {@link HoeItem#getTillingConsumer(BlockState, ItemConvertible)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param input the input block that can be tilled
|
||||
* @param usagePredicate a predicate that filters if the block can be tilled
|
||||
* @param tillingAction an action that is executed if the predicate returns {@code true}
|
||||
*/
|
||||
public static void register(Block input, Predicate<ItemUsageContext> usagePredicate, Consumer<ItemUsageContext> tillingAction) {
|
||||
Objects.requireNonNull(input, "input block cannot be null");
|
||||
HoeItemAccessor.getTilledBlocks().put(input, Pair.of(usagePredicate, tillingAction));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a simple tilling interaction.
|
||||
*
|
||||
* @param input the input block that can be tilled
|
||||
* @param usagePredicate a predicate that filters if the block can be tilled
|
||||
* @param tilled the tilled result block state
|
||||
*/
|
||||
public static void register(Block input, Predicate<ItemUsageContext> usagePredicate, BlockState tilled) {
|
||||
Objects.requireNonNull(tilled, "tilled block state cannot be null");
|
||||
register(input, usagePredicate, HoeItem.getTillingConsumer(tilled));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a simple tilling interaction that also drops an item.
|
||||
*
|
||||
* @param input the input block that can be tilled
|
||||
* @param usagePredicate a predicate that filters if the block can be tilled
|
||||
* @param tilled the tilled result block state
|
||||
* @param droppedItem an item that is dropped when the input block is tilled
|
||||
*/
|
||||
public static void register(Block input, Predicate<ItemUsageContext> usagePredicate, BlockState tilled, ItemConvertible droppedItem) {
|
||||
Objects.requireNonNull(tilled, "tilled block state cannot be null");
|
||||
Objects.requireNonNull(droppedItem, "dropped item cannot be null");
|
||||
register(input, usagePredicate, HoeItem.getTillingConsumer(tilled, droppedItem));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.content.registry;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.AxeItem;
|
||||
|
||||
@Mixin(AxeItem.class)
|
||||
public interface AxeItemAccessor {
|
||||
@Accessor("STRIPPED_BLOCKS")
|
||||
static Map<Block, Block> getStrippedBlocks() {
|
||||
throw new AssertionError("Untransformed @Accessor");
|
||||
}
|
||||
|
||||
@Accessor("STRIPPED_BLOCKS")
|
||||
@Mutable
|
||||
static void setStrippedBlocks(Map<Block, Block> strippedBlocks) {
|
||||
throw new AssertionError("Untransformed @Accessor");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.content.registry;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.HoeItem;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
|
||||
@Mixin(HoeItem.class)
|
||||
public interface HoeItemAccessor {
|
||||
@Accessor("TILLED_BLOCKS")
|
||||
static Map<Block, Pair<Predicate<ItemUsageContext>, Consumer<ItemUsageContext>>> getTilledBlocks() {
|
||||
throw new AssertionError("Untransformed @Accessor");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.content.registry;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ShovelItem;
|
||||
|
||||
@Mixin(ShovelItem.class)
|
||||
public interface ShovelItemAccessor {
|
||||
@Accessor("PATH_STATES")
|
||||
static Map<Block, BlockState> getPathStates() {
|
||||
throw new AssertionError("Untransformed @Accessor");
|
||||
}
|
||||
}
|
|
@ -3,8 +3,11 @@
|
|||
"package": "net.fabricmc.fabric.mixin.content.registry",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
"AxeItemAccessor",
|
||||
"HoeItemAccessor",
|
||||
"MixinAbstractFurnaceBlockEntity",
|
||||
"MixinFireBlock"
|
||||
"MixinFireBlock",
|
||||
"ShovelItemAccessor"
|
||||
],
|
||||
"client": [
|
||||
"client.MixinClientPlayNetworkHandler"
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.content.registry;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.item.HoeItem;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.registry.FlattenableBlockRegistry;
|
||||
import net.fabricmc.fabric.api.registry.StrippableBlockRegistry;
|
||||
import net.fabricmc.fabric.api.registry.TillableBlockRegistry;
|
||||
|
||||
public final class ContentRegistryTest implements ModInitializer {
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
// Expected behavior:
|
||||
// - red wool is flattenable to yellow wool
|
||||
// - quartz pillars are strippable to hay blocks
|
||||
// - green wool is tillable to lime wool
|
||||
|
||||
FlattenableBlockRegistry.register(Blocks.RED_WOOL, Blocks.YELLOW_WOOL.getDefaultState());
|
||||
StrippableBlockRegistry.register(Blocks.QUARTZ_PILLAR, Blocks.HAY_BLOCK);
|
||||
|
||||
// assert that StrippableBlockRegistry throws when the blocks don't have 'axis'
|
||||
try {
|
||||
StrippableBlockRegistry.register(Blocks.BLUE_WOOL, Blocks.OAK_LOG);
|
||||
StrippableBlockRegistry.register(Blocks.HAY_BLOCK, Blocks.BLUE_WOOL);
|
||||
throw new AssertionError("StrippableBlockRegistry didn't throw when blocks where missing the 'axis' property!");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected behavior
|
||||
}
|
||||
|
||||
TillableBlockRegistry.register(Blocks.GREEN_WOOL, context -> true, HoeItem.getTillingConsumer(Blocks.LIME_WOOL.getDefaultState()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "fabric-content-registries-v0-testmod",
|
||||
"name": "Fabric Content Registries (v0) Test Mod",
|
||||
"version": "1.0.0",
|
||||
"environment": "*",
|
||||
"license": "Apache-2.0",
|
||||
"depends": {
|
||||
"fabric-content-registries-v0": "*"
|
||||
},
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"net.fabricmc.fabric.test.content.registry.ContentRegistryTest"
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue