Sculk Sensor Frequency Registry ()

* Sculk Sensor Frequency Registry

- Mixin'd to `SculkSensorBlock` to make its `FREQUENCIES` map modifiable.
- Created `SculkSensorFrequencyRegistry` with a dedicated method for registering these frequencies, with all necessary checks to avoid issues, and javadoc to assist in understanding.
- Added tests to the test mod, as well as a block that emits a test event, to ensure it all works.

Unfortunately, the mixin currently uses a Redirect. If this is undesired, feel free to suggest other ways of achieving the end result of being able to modify the frequencies map.

* Update SculkSensorFrequencyRegistry.java

* cleaner javadoc

* Update fabric-content-registries-v0/src/main/resources/fabric-content-registries-v0.mixins.json

Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com>

* Final touches

...get it?

(oh and removed that Dynamic because tech didn't like it)

* Whoops

Forgot to remove the Dynamic import
Also restored the actual contents of the dynamic, as javadoc.

Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com>
This commit is contained in:
Shnupbups 2022-06-29 04:21:04 +10:00 committed by GitHub
parent 03a4e5689e
commit 07df213ec3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 146 additions and 1 deletions
fabric-content-registries-v0/src
main
java/net/fabricmc/fabric
resources
testmod
java/net/fabricmc/fabric/test/content/registry
resources/data/minecraft/tags/game_events

View file

@ -0,0 +1,59 @@
/*
* 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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.minecraft.block.SculkSensorBlock;
import net.minecraft.tag.GameEventTags;
import net.minecraft.world.event.GameEvent;
/**
* Provides a method for registering sculk sensor frequencies.
*/
public final class SculkSensorFrequencyRegistry {
private static final Logger LOGGER = LoggerFactory.getLogger(SculkSensorFrequencyRegistry.class);
private SculkSensorFrequencyRegistry() {
}
/**
* Registers a sculk sensor frequency for the given game event.
*
* <p>A frequency is defined as the redstone signal strength a sculk sensor will emit to a comparator when it detects a specific vibration.
*
* <p>As redstone signal strengths are limited to a maximum of 15, a frequency must also be between 1 and 15. As such, many game events will share a single frequency.
*
* <p>Note that the game event must also be in the {@linkplain GameEventTags#VIBRATIONS} tag to be detected by sculk sensors in the first place.
*
* @param event The event to register the frequency for.
* @param frequency The frequency to register.
* @throws IllegalArgumentException if the given frequency is not within the allowed range.
*/
public static void register(GameEvent event, int frequency) {
if (frequency <= 0 || frequency >= 16) {
throw new IllegalArgumentException("Attempted to register Sculk Sensor frequency for event "+event.getId()+" with frequency "+frequency+". Sculk Sensor frequencies must be between 1 and 15 inclusive.");
}
int replaced = SculkSensorBlock.FREQUENCIES.put(event, frequency);
if (replaced != 0) {
LOGGER.debug("Replaced old frequency mapping for {} - was {}, now {}", event.getId(), replaced, frequency);
}
}
}

View file

@ -0,0 +1,36 @@
/*
* 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 it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import net.minecraft.block.SculkSensorBlock;
@Mixin(SculkSensorBlock.class)
public class SculkSensorBlockMixin {
/**
* Redirects the call to {@linkplain Object2IntMaps#unmodifiable(Object2IntMap)} in initialization of {@linkplain SculkSensorBlock#FREQUENCIES}.
*/
@Redirect(method = "<clinit>", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/Object2IntMaps;unmodifiable(Lit/unimi/dsi/fastutil/objects/Object2IntMap;)Lit/unimi/dsi/fastutil/objects/Object2IntMap;"))
private static <K> Object2IntMap<K> makeFrequenciesMapModifiable(Object2IntMap<? extends K> m) {
return (Object2IntMap<K>) m;
}
}

View file

@ -12,6 +12,7 @@
"MixinAbstractFurnaceBlockEntity",
"MixinFireBlock",
"OxidizableMixin",
"SculkSensorBlockMixin",
"ShovelItemAccessor",
"VillagerEntityAccessor",
"VillagerEntityMixin"

View file

@ -19,17 +19,29 @@ package net.fabricmc.fabric.test.content.registry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.HoeItem;
import net.minecraft.item.Items;
import net.minecraft.tag.BlockTags;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.Registry;
import net.minecraft.village.VillagerProfession;
import net.minecraft.world.World;
import net.minecraft.world.event.GameEvent;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry;
import net.fabricmc.fabric.api.registry.FlattenableBlockRegistry;
import net.fabricmc.fabric.api.registry.OxidizableBlocksRegistry;
import net.fabricmc.fabric.api.registry.SculkSensorFrequencyRegistry;
import net.fabricmc.fabric.api.registry.StrippableBlockRegistry;
import net.fabricmc.fabric.api.registry.TillableBlockRegistry;
import net.fabricmc.fabric.api.registry.VillagerInteractionRegistries;
@ -38,9 +50,13 @@ import net.fabricmc.fabric.api.registry.VillagerPlantableRegistry;
public final class ContentRegistryTest implements ModInitializer {
public static final Logger LOGGER = LoggerFactory.getLogger(ContentRegistryTest.class);
public static final Identifier TEST_EVENT_ID = new Identifier("fabric-content-registries-v0-testmod", "test_event");
public static final GameEvent TEST_EVENT = new GameEvent(TEST_EVENT_ID.toString(), GameEvent.DEFAULT_RANGE);
@Override
public void onInitialize() {
// Expected behavior:
// - sand is now flammable
// - red wool is flattenable to yellow wool
// - quartz pillars are strippable to hay blocks
// - green wool is tillable to lime wool
@ -49,7 +65,7 @@ public final class ContentRegistryTest implements ModInitializer {
// - villagers can now collect, consume (at the same level of bread) and compost apples
// - villagers can now collect and plant oak saplings
// - assign a loot table to the nitwit villager type
// - sand is now flammable
// - right-clicking a 'test_event' block will emit a 'test_event' game event, which will have a sculk sensor frequency of 2
FlammableBlockRegistry.getDefaultInstance().add(BlockTags.SAND, 4, 4);
FlattenableBlockRegistry.register(Blocks.RED_WOOL, Blocks.YELLOW_WOOL.getDefaultState());
@ -108,5 +124,32 @@ public final class ContentRegistryTest implements ModInitializer {
}
VillagerInteractionRegistries.registerGiftLootTable(VillagerProfession.NITWIT, new Identifier("fake_loot_table"));
Registry.register(Registry.GAME_EVENT, TEST_EVENT_ID, TEST_EVENT);
Registry.register(Registry.BLOCK, TEST_EVENT_ID, new TestEventBlock(AbstractBlock.Settings.copy(Blocks.STONE)));
SculkSensorFrequencyRegistry.register(TEST_EVENT, 2);
// assert that SculkSensorFrequencyRegistry throws when registering a frequency outside the allowed range
try {
SculkSensorFrequencyRegistry.register(GameEvent.SHRIEK, 18);
throw new AssertionError("SculkSensorFrequencyRegistry didn't throw when frequency was outside allowed range!");
} catch (IllegalArgumentException e) {
// expected behavior
LOGGER.info("SculkSensorFrequencyRegistry test passed!");
}
}
public static class TestEventBlock extends Block {
public TestEventBlock(Settings settings) {
super(settings);
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
// Emit the test event
world.emitGameEvent(player, TEST_EVENT, pos);
return ActionResult.SUCCESS;
}
}
}

View file

@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"fabric-content-registries-v0-testmod:test_event"
]
}