From 12fba075f403d20d4d6782ee46ffdaf7208a63b4 Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Mon, 21 Apr 2025 03:56:16 +0300 Subject: [PATCH 1/5] implement SignalAwareVolume --- SpongeAPI | 2 +- .../common/registry/SpongeRegistries.java | 1 + .../registry/loader/SpongeRegistryLoader.java | 12 ++ .../common/util/DirectionUtil.java | 11 +- .../common/world/SpongeSignalType.java | 41 +++++ .../world/level/SignalGetterMixin_API.java | 166 ++++++++++++++++++ src/mixins/resources/mixins.sponge.api.json | 3 +- 7 files changed, 233 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/spongepowered/common/world/SpongeSignalType.java create mode 100644 src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/SignalGetterMixin_API.java diff --git a/SpongeAPI b/SpongeAPI index 267c5df1e0f..cbcf39fa524 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit 267c5df1e0fe396a0ffc7f7768bb845dff092bfe +Subproject commit cbcf39fa52435f8fa60c7af2a30321780cc9c15b diff --git a/src/main/java/org/spongepowered/common/registry/SpongeRegistries.java b/src/main/java/org/spongepowered/common/registry/SpongeRegistries.java index 29ba343d72a..dc16e9b7b38 100644 --- a/src/main/java/org/spongepowered/common/registry/SpongeRegistries.java +++ b/src/main/java/org/spongepowered/common/registry/SpongeRegistries.java @@ -75,6 +75,7 @@ public static void registerEarlyGlobalRegistries(final SpongeRegistryHolder hold holder.createFrozenRegistry(RegistryTypes.PARTICLE_OPTION, SpongeRegistryLoader.particleOption()); holder.createFrozenRegistry(RegistryTypes.QUERY_TYPE, SpongeRegistryLoader.queryType()); holder.createFrozenRegistry(RegistryTypes.RESOLVE_OPERATION, SpongeRegistryLoader.resolveOperation()); + holder.createFrozenRegistry(RegistryTypes.SIGNAL_TYPE, SpongeRegistryLoader.signalType()); holder.createFrozenRegistry(RegistryTypes.SKIN_PART, SpongeRegistryLoader.skinPart()); holder.createFrozenRegistry(RegistryTypes.SPAWN_TYPE, SpongeRegistryLoader.spawnType()); holder.createFrozenRegistry(RegistryTypes.TRANSACTION_TYPE, SpongeRegistryLoader.transactionType()); diff --git a/src/main/java/org/spongepowered/common/registry/loader/SpongeRegistryLoader.java b/src/main/java/org/spongepowered/common/registry/loader/SpongeRegistryLoader.java index b8f9f664823..6a9f452f6fd 100644 --- a/src/main/java/org/spongepowered/common/registry/loader/SpongeRegistryLoader.java +++ b/src/main/java/org/spongepowered/common/registry/loader/SpongeRegistryLoader.java @@ -97,6 +97,8 @@ import org.spongepowered.api.world.ChunkRegenerateFlag; import org.spongepowered.api.world.ChunkRegenerateFlags; import org.spongepowered.api.world.PositionSource; +import org.spongepowered.api.world.SignalType; +import org.spongepowered.api.world.SignalTypes; import org.spongepowered.api.world.generation.config.flat.FlatGeneratorConfig; import org.spongepowered.api.world.generation.config.noise.NoiseConfig; import org.spongepowered.api.world.generation.config.noise.NoiseConfigs; @@ -150,6 +152,7 @@ import org.spongepowered.common.registry.RegistryLoader; import org.spongepowered.common.util.SpongeOrientation; import org.spongepowered.common.world.SpongeChunkRegenerateFlag; +import org.spongepowered.common.world.SpongeSignalType; import org.spongepowered.common.world.schematic.SpongePaletteType; import org.spongepowered.common.world.weather.SpongeWeatherType; import org.spongepowered.math.vector.Vector3d; @@ -415,6 +418,15 @@ public static RegistryLoader resolveOperation() { }); } + public static RegistryLoader signalType() { + return RegistryLoader.of(l -> { + l.add(SignalTypes.WEAK, k -> SpongeSignalType.WEAK); + l.add(SignalTypes.STRONG, k -> SpongeSignalType.STRONG); + l.add(SignalTypes.COMPOSITE, k -> SpongeSignalType.COMPOSITE); + l.add(SignalTypes.ANALOG, k -> SpongeSignalType.ANALOG); + }); + } + public static RegistryLoader skinPart() { return RegistryLoader.of(l -> { l.add(SkinParts.CAPE, k -> new SpongeSkinPart("cape")); diff --git a/src/main/java/org/spongepowered/common/util/DirectionUtil.java b/src/main/java/org/spongepowered/common/util/DirectionUtil.java index d7d8dd9365f..55ec6e5d83d 100644 --- a/src/main/java/org/spongepowered/common/util/DirectionUtil.java +++ b/src/main/java/org/spongepowered/common/util/DirectionUtil.java @@ -26,13 +26,14 @@ import net.minecraft.world.level.block.state.properties.EnumProperty; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.util.Direction; import java.util.Objects; public final class DirectionUtil { - public static net.minecraft.core.Direction getFor(final Direction direction) { + public static net.minecraft.core.@Nullable Direction getFor(final Direction direction) { Objects.requireNonNull(direction); return switch (direction) { case UP -> net.minecraft.core.Direction.UP; @@ -58,6 +59,14 @@ public static Direction getFor(final net.minecraft.core.Direction facing) { }; } + public static net.minecraft.core.Direction getForOrThrow(final Direction direction) { + final net.minecraft.core.@Nullable Direction result = DirectionUtil.getFor(direction); + if (result == null) { + throw new IllegalArgumentException("Direction must be cardinal: " + direction); + } + return result; + } + public static net.minecraft.world.level.block.state.BlockState set(final net.minecraft.world.level.block.state.BlockState holder, final Direction value, final EnumProperty property) { final net.minecraft.core.Direction direction = DirectionUtil.getFor(value); if (direction == null || !property.getPossibleValues().contains(direction)) { diff --git a/src/main/java/org/spongepowered/common/world/SpongeSignalType.java b/src/main/java/org/spongepowered/common/world/SpongeSignalType.java new file mode 100644 index 00000000000..a64a2022934 --- /dev/null +++ b/src/main/java/org/spongepowered/common/world/SpongeSignalType.java @@ -0,0 +1,41 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.world; + +import org.spongepowered.api.world.SignalType; + +public class SpongeSignalType implements SignalType { + + public static final SignalType WEAK = new SpongeSignalType(); + + public static final SignalType STRONG = new SpongeSignalType(); + + public static final SignalType COMPOSITE = new SpongeSignalType(); + + public static final SignalType ANALOG = new SpongeSignalType(); + + private SpongeSignalType() { + } +} diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/SignalGetterMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/SignalGetterMixin_API.java new file mode 100644 index 00000000000..1ffb2dfb5cc --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/SignalGetterMixin_API.java @@ -0,0 +1,166 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.mixin.api.minecraft.world.level; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.SignalGetter; +import org.spongepowered.api.registry.RegistryTypes; +import org.spongepowered.api.util.Direction; +import org.spongepowered.api.world.SignalType; +import org.spongepowered.api.world.volume.game.SignalAwareVolume; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.common.util.DirectionUtil; +import org.spongepowered.common.world.SpongeSignalType; + +import java.util.Objects; +import java.util.function.ToIntBiFunction; + +@Mixin(SignalGetter.class) +public interface SignalGetterMixin_API extends BlockGetter, SignalAwareVolume { + + @Shadow int shadow$getSignal(BlockPos $$0, net.minecraft.core.Direction $$1); + @Shadow int shadow$getBestNeighborSignal(BlockPos $$0); + @Shadow int shadow$getDirectSignal(BlockPos $$0, net.minecraft.core.Direction $$1); + @Shadow int shadow$getDirectSignalTo(BlockPos $$0); + @Shadow boolean shadow$hasNeighborSignal(BlockPos $$0); + + @Override + default boolean canConductSignal(final int x, final int y, final int z) { + final BlockPos pos = new BlockPos(x, y, z); + return this.getBlockState(pos).isRedstoneConductor(this, pos); + } + + @Override + default boolean canEmitSignal(final SignalType type, final int x, final int y, final int z) { + Objects.requireNonNull(type, "type"); + final BlockPos pos = new BlockPos(x, y, z); + if (type == SpongeSignalType.ANALOG) { + return this.getBlockState(pos).hasAnalogOutputSignal(); + } else if (type == SpongeSignalType.WEAK || type == SpongeSignalType.STRONG || type == SpongeSignalType.COMPOSITE) { + return this.getBlockState(pos).isSignalSource(); + } + + throw this.impl$unsupportedType(type); + } + + @Override + default int signalFrom(final SignalType type, final int x, final int y, final int z, final Direction direction) { + Objects.requireNonNull(type, "type"); + final BlockPos pos = new BlockPos(x, y, z); + if (type == SpongeSignalType.ANALOG) { + return this.impl$analogSignalFrom(pos); + } else if (type == SpongeSignalType.WEAK) { + return this.impl$regularSignalFrom(pos, DirectionUtil.getForOrThrow(direction).getOpposite()); + } else if (type == SpongeSignalType.STRONG) { + return this.shadow$getDirectSignal(pos, DirectionUtil.getForOrThrow(direction).getOpposite()); + } else if (type == SpongeSignalType.COMPOSITE) { + return this.shadow$getSignal(pos, DirectionUtil.getForOrThrow(direction).getOpposite()); + } + + throw this.impl$unsupportedType(type); + } + + @Override + default int highestSignalAt(final SignalType type, final int x, final int y, final int z) { + Objects.requireNonNull(type, "type"); + final BlockPos pos = new BlockPos(x, y, z); + if (type == SpongeSignalType.ANALOG) { + return this.impl$highestSignalAt(pos, (relativePos, $) -> this.impl$analogSignalFrom(relativePos)); + } else if (type == SpongeSignalType.WEAK) { + return this.impl$highestSignalAt(pos, this::impl$regularSignalFrom); + } else if (type == SpongeSignalType.STRONG) { + return this.shadow$getDirectSignalTo(pos); + } else if (type == SpongeSignalType.COMPOSITE) { + return this.shadow$getBestNeighborSignal(pos); + } + + throw this.impl$unsupportedType(type); + } + + @Override + default boolean hasSignalAt(final SignalType type, final int x, final int y, final int z) { + Objects.requireNonNull(type, "type"); + final BlockPos pos = new BlockPos(x, y, z); + if (type == SpongeSignalType.ANALOG) { + return this.impl$hasSignalAt(pos, (relativePos, $) -> this.impl$analogSignalFrom(relativePos)); + } else if (type == SpongeSignalType.WEAK) { + return this.impl$hasSignalAt(pos, this::impl$regularSignalFrom); + } else if (type == SpongeSignalType.STRONG) { + return this.impl$hasSignalAt(pos, this::shadow$getDirectSignal); + } else if (type == SpongeSignalType.COMPOSITE) { + return this.shadow$hasNeighborSignal(pos); + } + + throw this.impl$unsupportedType(type); + } + + private int impl$highestSignalAt( + final BlockPos pos, final ToIntBiFunction signalProvider + ) { + int maxSignal = 0; + for (final net.minecraft.core.Direction direction : SignalGetter.DIRECTIONS) { + final int signal = signalProvider.applyAsInt(pos.relative(direction), direction); + if (signal >= 15) { + return 15; + } + + if (signal > maxSignal) { + maxSignal = signal; + } + } + return maxSignal; + } + + private boolean impl$hasSignalAt( + final BlockPos pos, final ToIntBiFunction signalProvider + ) { + for (final net.minecraft.core.Direction direction : SignalGetter.DIRECTIONS) { + final int signal = signalProvider.applyAsInt(pos.relative(direction), direction); + if (signal > 0) { + return true; + } + } + return false; + } + + private int impl$analogSignalFrom(final BlockPos pos) { + if (this instanceof final Level level) { + return this.getBlockState(pos).getAnalogOutputSignal(level, pos); + } else { + throw new UnsupportedOperationException("This volume doesn't support getting analog signal"); + } + } + + private int impl$regularSignalFrom(final BlockPos pos, final net.minecraft.core.Direction direction) { + return this.getBlockState(pos).getSignal(this, pos, direction); + } + + private RuntimeException impl$unsupportedType(final SignalType type) { + return new IllegalArgumentException("Unsupported signal type: " + type.key(RegistryTypes.SIGNAL_TYPE).asString()); + } +} diff --git a/src/mixins/resources/mixins.sponge.api.json b/src/mixins/resources/mixins.sponge.api.json index 6af919666ac..6856d934343 100644 --- a/src/mixins/resources/mixins.sponge.api.json +++ b/src/mixins/resources/mixins.sponge.api.json @@ -180,7 +180,7 @@ "minecraft.world.entity.animal.TurtleMixin_API", "minecraft.world.entity.animal.WaterAnimalMixin_API", "minecraft.world.entity.animal.WolfMixin_API", - "minecraft.world.entity.animal.WolfVariantMixin_API", + "minecraft.world.entity.animal.WolfVariantMixin_API", "minecraft.world.entity.animal.allay.AllayMixin_API", "minecraft.world.entity.animal.armadillo.ArmadilloMixin_API", "minecraft.world.entity.animal.axolotl.AxolotlMixin_API", @@ -359,6 +359,7 @@ "minecraft.world.level.LevelWriterMixin_API", "minecraft.world.level.LightLayerMixin_API", "minecraft.world.level.ServerExplosionMixin_API", + "minecraft.world.level.SignalGetterMixin_API", "minecraft.world.level.biome.AmbientAdditionsSettingsMixin_API", "minecraft.world.level.biome.AmbientMoodSettingsMixin_API", "minecraft.world.level.biome.AmbientParticleSettingsMixin_API", From 7f84edab715ebdbcabb687ea238385249c74c8d3 Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Tue, 22 Apr 2025 17:38:25 +0300 Subject: [PATCH 2/5] Update DirectionUtil.java --- src/main/java/org/spongepowered/common/util/DirectionUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/spongepowered/common/util/DirectionUtil.java b/src/main/java/org/spongepowered/common/util/DirectionUtil.java index 55ec6e5d83d..9051444b26c 100644 --- a/src/main/java/org/spongepowered/common/util/DirectionUtil.java +++ b/src/main/java/org/spongepowered/common/util/DirectionUtil.java @@ -34,7 +34,7 @@ public final class DirectionUtil { public static net.minecraft.core.@Nullable Direction getFor(final Direction direction) { - Objects.requireNonNull(direction); + Objects.requireNonNull(direction, "direction"); return switch (direction) { case UP -> net.minecraft.core.Direction.UP; case DOWN -> net.minecraft.core.Direction.DOWN; From ce88207b94375e77a238f3d664344fce2d4209fc Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Mon, 21 Apr 2025 03:56:16 +0300 Subject: [PATCH 3/5] implement SignalAwareVolume --- SpongeAPI | 2 +- .../common/registry/SpongeRegistries.java | 1 + .../registry/loader/SpongeRegistryLoader.java | 12 ++ .../common/util/DirectionUtil.java | 13 +- .../common/world/SpongeSignalType.java | 41 +++++ .../world/level/SignalGetterMixin_API.java | 166 ++++++++++++++++++ src/mixins/resources/mixins.sponge.api.json | 3 +- 7 files changed, 234 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/spongepowered/common/world/SpongeSignalType.java create mode 100644 src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/SignalGetterMixin_API.java diff --git a/SpongeAPI b/SpongeAPI index 267c5df1e0f..cbcf39fa524 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit 267c5df1e0fe396a0ffc7f7768bb845dff092bfe +Subproject commit cbcf39fa52435f8fa60c7af2a30321780cc9c15b diff --git a/src/main/java/org/spongepowered/common/registry/SpongeRegistries.java b/src/main/java/org/spongepowered/common/registry/SpongeRegistries.java index 29ba343d72a..dc16e9b7b38 100644 --- a/src/main/java/org/spongepowered/common/registry/SpongeRegistries.java +++ b/src/main/java/org/spongepowered/common/registry/SpongeRegistries.java @@ -75,6 +75,7 @@ public static void registerEarlyGlobalRegistries(final SpongeRegistryHolder hold holder.createFrozenRegistry(RegistryTypes.PARTICLE_OPTION, SpongeRegistryLoader.particleOption()); holder.createFrozenRegistry(RegistryTypes.QUERY_TYPE, SpongeRegistryLoader.queryType()); holder.createFrozenRegistry(RegistryTypes.RESOLVE_OPERATION, SpongeRegistryLoader.resolveOperation()); + holder.createFrozenRegistry(RegistryTypes.SIGNAL_TYPE, SpongeRegistryLoader.signalType()); holder.createFrozenRegistry(RegistryTypes.SKIN_PART, SpongeRegistryLoader.skinPart()); holder.createFrozenRegistry(RegistryTypes.SPAWN_TYPE, SpongeRegistryLoader.spawnType()); holder.createFrozenRegistry(RegistryTypes.TRANSACTION_TYPE, SpongeRegistryLoader.transactionType()); diff --git a/src/main/java/org/spongepowered/common/registry/loader/SpongeRegistryLoader.java b/src/main/java/org/spongepowered/common/registry/loader/SpongeRegistryLoader.java index b8f9f664823..6a9f452f6fd 100644 --- a/src/main/java/org/spongepowered/common/registry/loader/SpongeRegistryLoader.java +++ b/src/main/java/org/spongepowered/common/registry/loader/SpongeRegistryLoader.java @@ -97,6 +97,8 @@ import org.spongepowered.api.world.ChunkRegenerateFlag; import org.spongepowered.api.world.ChunkRegenerateFlags; import org.spongepowered.api.world.PositionSource; +import org.spongepowered.api.world.SignalType; +import org.spongepowered.api.world.SignalTypes; import org.spongepowered.api.world.generation.config.flat.FlatGeneratorConfig; import org.spongepowered.api.world.generation.config.noise.NoiseConfig; import org.spongepowered.api.world.generation.config.noise.NoiseConfigs; @@ -150,6 +152,7 @@ import org.spongepowered.common.registry.RegistryLoader; import org.spongepowered.common.util.SpongeOrientation; import org.spongepowered.common.world.SpongeChunkRegenerateFlag; +import org.spongepowered.common.world.SpongeSignalType; import org.spongepowered.common.world.schematic.SpongePaletteType; import org.spongepowered.common.world.weather.SpongeWeatherType; import org.spongepowered.math.vector.Vector3d; @@ -415,6 +418,15 @@ public static RegistryLoader resolveOperation() { }); } + public static RegistryLoader signalType() { + return RegistryLoader.of(l -> { + l.add(SignalTypes.WEAK, k -> SpongeSignalType.WEAK); + l.add(SignalTypes.STRONG, k -> SpongeSignalType.STRONG); + l.add(SignalTypes.COMPOSITE, k -> SpongeSignalType.COMPOSITE); + l.add(SignalTypes.ANALOG, k -> SpongeSignalType.ANALOG); + }); + } + public static RegistryLoader skinPart() { return RegistryLoader.of(l -> { l.add(SkinParts.CAPE, k -> new SpongeSkinPart("cape")); diff --git a/src/main/java/org/spongepowered/common/util/DirectionUtil.java b/src/main/java/org/spongepowered/common/util/DirectionUtil.java index d7d8dd9365f..9051444b26c 100644 --- a/src/main/java/org/spongepowered/common/util/DirectionUtil.java +++ b/src/main/java/org/spongepowered/common/util/DirectionUtil.java @@ -26,14 +26,15 @@ import net.minecraft.world.level.block.state.properties.EnumProperty; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.util.Direction; import java.util.Objects; public final class DirectionUtil { - public static net.minecraft.core.Direction getFor(final Direction direction) { - Objects.requireNonNull(direction); + public static net.minecraft.core.@Nullable Direction getFor(final Direction direction) { + Objects.requireNonNull(direction, "direction"); return switch (direction) { case UP -> net.minecraft.core.Direction.UP; case DOWN -> net.minecraft.core.Direction.DOWN; @@ -58,6 +59,14 @@ public static Direction getFor(final net.minecraft.core.Direction facing) { }; } + public static net.minecraft.core.Direction getForOrThrow(final Direction direction) { + final net.minecraft.core.@Nullable Direction result = DirectionUtil.getFor(direction); + if (result == null) { + throw new IllegalArgumentException("Direction must be cardinal: " + direction); + } + return result; + } + public static net.minecraft.world.level.block.state.BlockState set(final net.minecraft.world.level.block.state.BlockState holder, final Direction value, final EnumProperty property) { final net.minecraft.core.Direction direction = DirectionUtil.getFor(value); if (direction == null || !property.getPossibleValues().contains(direction)) { diff --git a/src/main/java/org/spongepowered/common/world/SpongeSignalType.java b/src/main/java/org/spongepowered/common/world/SpongeSignalType.java new file mode 100644 index 00000000000..a64a2022934 --- /dev/null +++ b/src/main/java/org/spongepowered/common/world/SpongeSignalType.java @@ -0,0 +1,41 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.world; + +import org.spongepowered.api.world.SignalType; + +public class SpongeSignalType implements SignalType { + + public static final SignalType WEAK = new SpongeSignalType(); + + public static final SignalType STRONG = new SpongeSignalType(); + + public static final SignalType COMPOSITE = new SpongeSignalType(); + + public static final SignalType ANALOG = new SpongeSignalType(); + + private SpongeSignalType() { + } +} diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/SignalGetterMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/SignalGetterMixin_API.java new file mode 100644 index 00000000000..1ffb2dfb5cc --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/SignalGetterMixin_API.java @@ -0,0 +1,166 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.mixin.api.minecraft.world.level; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.SignalGetter; +import org.spongepowered.api.registry.RegistryTypes; +import org.spongepowered.api.util.Direction; +import org.spongepowered.api.world.SignalType; +import org.spongepowered.api.world.volume.game.SignalAwareVolume; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.common.util.DirectionUtil; +import org.spongepowered.common.world.SpongeSignalType; + +import java.util.Objects; +import java.util.function.ToIntBiFunction; + +@Mixin(SignalGetter.class) +public interface SignalGetterMixin_API extends BlockGetter, SignalAwareVolume { + + @Shadow int shadow$getSignal(BlockPos $$0, net.minecraft.core.Direction $$1); + @Shadow int shadow$getBestNeighborSignal(BlockPos $$0); + @Shadow int shadow$getDirectSignal(BlockPos $$0, net.minecraft.core.Direction $$1); + @Shadow int shadow$getDirectSignalTo(BlockPos $$0); + @Shadow boolean shadow$hasNeighborSignal(BlockPos $$0); + + @Override + default boolean canConductSignal(final int x, final int y, final int z) { + final BlockPos pos = new BlockPos(x, y, z); + return this.getBlockState(pos).isRedstoneConductor(this, pos); + } + + @Override + default boolean canEmitSignal(final SignalType type, final int x, final int y, final int z) { + Objects.requireNonNull(type, "type"); + final BlockPos pos = new BlockPos(x, y, z); + if (type == SpongeSignalType.ANALOG) { + return this.getBlockState(pos).hasAnalogOutputSignal(); + } else if (type == SpongeSignalType.WEAK || type == SpongeSignalType.STRONG || type == SpongeSignalType.COMPOSITE) { + return this.getBlockState(pos).isSignalSource(); + } + + throw this.impl$unsupportedType(type); + } + + @Override + default int signalFrom(final SignalType type, final int x, final int y, final int z, final Direction direction) { + Objects.requireNonNull(type, "type"); + final BlockPos pos = new BlockPos(x, y, z); + if (type == SpongeSignalType.ANALOG) { + return this.impl$analogSignalFrom(pos); + } else if (type == SpongeSignalType.WEAK) { + return this.impl$regularSignalFrom(pos, DirectionUtil.getForOrThrow(direction).getOpposite()); + } else if (type == SpongeSignalType.STRONG) { + return this.shadow$getDirectSignal(pos, DirectionUtil.getForOrThrow(direction).getOpposite()); + } else if (type == SpongeSignalType.COMPOSITE) { + return this.shadow$getSignal(pos, DirectionUtil.getForOrThrow(direction).getOpposite()); + } + + throw this.impl$unsupportedType(type); + } + + @Override + default int highestSignalAt(final SignalType type, final int x, final int y, final int z) { + Objects.requireNonNull(type, "type"); + final BlockPos pos = new BlockPos(x, y, z); + if (type == SpongeSignalType.ANALOG) { + return this.impl$highestSignalAt(pos, (relativePos, $) -> this.impl$analogSignalFrom(relativePos)); + } else if (type == SpongeSignalType.WEAK) { + return this.impl$highestSignalAt(pos, this::impl$regularSignalFrom); + } else if (type == SpongeSignalType.STRONG) { + return this.shadow$getDirectSignalTo(pos); + } else if (type == SpongeSignalType.COMPOSITE) { + return this.shadow$getBestNeighborSignal(pos); + } + + throw this.impl$unsupportedType(type); + } + + @Override + default boolean hasSignalAt(final SignalType type, final int x, final int y, final int z) { + Objects.requireNonNull(type, "type"); + final BlockPos pos = new BlockPos(x, y, z); + if (type == SpongeSignalType.ANALOG) { + return this.impl$hasSignalAt(pos, (relativePos, $) -> this.impl$analogSignalFrom(relativePos)); + } else if (type == SpongeSignalType.WEAK) { + return this.impl$hasSignalAt(pos, this::impl$regularSignalFrom); + } else if (type == SpongeSignalType.STRONG) { + return this.impl$hasSignalAt(pos, this::shadow$getDirectSignal); + } else if (type == SpongeSignalType.COMPOSITE) { + return this.shadow$hasNeighborSignal(pos); + } + + throw this.impl$unsupportedType(type); + } + + private int impl$highestSignalAt( + final BlockPos pos, final ToIntBiFunction signalProvider + ) { + int maxSignal = 0; + for (final net.minecraft.core.Direction direction : SignalGetter.DIRECTIONS) { + final int signal = signalProvider.applyAsInt(pos.relative(direction), direction); + if (signal >= 15) { + return 15; + } + + if (signal > maxSignal) { + maxSignal = signal; + } + } + return maxSignal; + } + + private boolean impl$hasSignalAt( + final BlockPos pos, final ToIntBiFunction signalProvider + ) { + for (final net.minecraft.core.Direction direction : SignalGetter.DIRECTIONS) { + final int signal = signalProvider.applyAsInt(pos.relative(direction), direction); + if (signal > 0) { + return true; + } + } + return false; + } + + private int impl$analogSignalFrom(final BlockPos pos) { + if (this instanceof final Level level) { + return this.getBlockState(pos).getAnalogOutputSignal(level, pos); + } else { + throw new UnsupportedOperationException("This volume doesn't support getting analog signal"); + } + } + + private int impl$regularSignalFrom(final BlockPos pos, final net.minecraft.core.Direction direction) { + return this.getBlockState(pos).getSignal(this, pos, direction); + } + + private RuntimeException impl$unsupportedType(final SignalType type) { + return new IllegalArgumentException("Unsupported signal type: " + type.key(RegistryTypes.SIGNAL_TYPE).asString()); + } +} diff --git a/src/mixins/resources/mixins.sponge.api.json b/src/mixins/resources/mixins.sponge.api.json index 6af919666ac..6856d934343 100644 --- a/src/mixins/resources/mixins.sponge.api.json +++ b/src/mixins/resources/mixins.sponge.api.json @@ -180,7 +180,7 @@ "minecraft.world.entity.animal.TurtleMixin_API", "minecraft.world.entity.animal.WaterAnimalMixin_API", "minecraft.world.entity.animal.WolfMixin_API", - "minecraft.world.entity.animal.WolfVariantMixin_API", + "minecraft.world.entity.animal.WolfVariantMixin_API", "minecraft.world.entity.animal.allay.AllayMixin_API", "minecraft.world.entity.animal.armadillo.ArmadilloMixin_API", "minecraft.world.entity.animal.axolotl.AxolotlMixin_API", @@ -359,6 +359,7 @@ "minecraft.world.level.LevelWriterMixin_API", "minecraft.world.level.LightLayerMixin_API", "minecraft.world.level.ServerExplosionMixin_API", + "minecraft.world.level.SignalGetterMixin_API", "minecraft.world.level.biome.AmbientAdditionsSettingsMixin_API", "minecraft.world.level.biome.AmbientMoodSettingsMixin_API", "minecraft.world.level.biome.AmbientParticleSettingsMixin_API", From eeeefae2090d54bf321e2fdaa5ff8819ecdf9f89 Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 23 Apr 2025 02:45:15 +0300 Subject: [PATCH 4/5] Update SpongeAPI --- SpongeAPI | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SpongeAPI b/SpongeAPI index cbcf39fa524..26abaff679d 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit cbcf39fa52435f8fa60c7af2a30321780cc9c15b +Subproject commit 26abaff679d7a90f94c24511dd52cf1e687ee032 From 7e2eaec0bff5400f5f48de0739993534953a48ac Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Mon, 9 Jun 2025 18:51:59 +0300 Subject: [PATCH 5/5] rename SignalTypes WEAK & STRONG -> DIRECT & INDIRECT --- SpongeAPI | 2 +- .../registry/loader/SpongeRegistryLoader.java | 4 ++-- .../common/world/SpongeSignalType.java | 4 ++-- .../world/level/SignalGetterMixin_API.java | 14 +++++++------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/SpongeAPI b/SpongeAPI index 26abaff679d..81f4a330a02 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit 26abaff679d7a90f94c24511dd52cf1e687ee032 +Subproject commit 81f4a330a02ee3a0f708cda80fc87bf3913f9ab5 diff --git a/src/main/java/org/spongepowered/common/registry/loader/SpongeRegistryLoader.java b/src/main/java/org/spongepowered/common/registry/loader/SpongeRegistryLoader.java index 6a9f452f6fd..56943ce58a7 100644 --- a/src/main/java/org/spongepowered/common/registry/loader/SpongeRegistryLoader.java +++ b/src/main/java/org/spongepowered/common/registry/loader/SpongeRegistryLoader.java @@ -420,8 +420,8 @@ public static RegistryLoader resolveOperation() { public static RegistryLoader signalType() { return RegistryLoader.of(l -> { - l.add(SignalTypes.WEAK, k -> SpongeSignalType.WEAK); - l.add(SignalTypes.STRONG, k -> SpongeSignalType.STRONG); + l.add(SignalTypes.DIRECT, k -> SpongeSignalType.DIRECT); + l.add(SignalTypes.INDIRECT, k -> SpongeSignalType.INDIRECT); l.add(SignalTypes.COMPOSITE, k -> SpongeSignalType.COMPOSITE); l.add(SignalTypes.ANALOG, k -> SpongeSignalType.ANALOG); }); diff --git a/src/main/java/org/spongepowered/common/world/SpongeSignalType.java b/src/main/java/org/spongepowered/common/world/SpongeSignalType.java index a64a2022934..4f46924e2bd 100644 --- a/src/main/java/org/spongepowered/common/world/SpongeSignalType.java +++ b/src/main/java/org/spongepowered/common/world/SpongeSignalType.java @@ -28,9 +28,9 @@ public class SpongeSignalType implements SignalType { - public static final SignalType WEAK = new SpongeSignalType(); + public static final SignalType DIRECT = new SpongeSignalType(); - public static final SignalType STRONG = new SpongeSignalType(); + public static final SignalType INDIRECT = new SpongeSignalType(); public static final SignalType COMPOSITE = new SpongeSignalType(); diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/SignalGetterMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/SignalGetterMixin_API.java index 1ffb2dfb5cc..231e32b2511 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/SignalGetterMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/SignalGetterMixin_API.java @@ -61,7 +61,7 @@ default boolean canEmitSignal(final SignalType type, final int x, final int y, f final BlockPos pos = new BlockPos(x, y, z); if (type == SpongeSignalType.ANALOG) { return this.getBlockState(pos).hasAnalogOutputSignal(); - } else if (type == SpongeSignalType.WEAK || type == SpongeSignalType.STRONG || type == SpongeSignalType.COMPOSITE) { + } else if (type == SpongeSignalType.DIRECT || type == SpongeSignalType.INDIRECT || type == SpongeSignalType.COMPOSITE) { return this.getBlockState(pos).isSignalSource(); } @@ -74,9 +74,9 @@ default int signalFrom(final SignalType type, final int x, final int y, final in final BlockPos pos = new BlockPos(x, y, z); if (type == SpongeSignalType.ANALOG) { return this.impl$analogSignalFrom(pos); - } else if (type == SpongeSignalType.WEAK) { + } else if (type == SpongeSignalType.DIRECT) { return this.impl$regularSignalFrom(pos, DirectionUtil.getForOrThrow(direction).getOpposite()); - } else if (type == SpongeSignalType.STRONG) { + } else if (type == SpongeSignalType.INDIRECT) { return this.shadow$getDirectSignal(pos, DirectionUtil.getForOrThrow(direction).getOpposite()); } else if (type == SpongeSignalType.COMPOSITE) { return this.shadow$getSignal(pos, DirectionUtil.getForOrThrow(direction).getOpposite()); @@ -91,9 +91,9 @@ default int highestSignalAt(final SignalType type, final int x, final int y, fin final BlockPos pos = new BlockPos(x, y, z); if (type == SpongeSignalType.ANALOG) { return this.impl$highestSignalAt(pos, (relativePos, $) -> this.impl$analogSignalFrom(relativePos)); - } else if (type == SpongeSignalType.WEAK) { + } else if (type == SpongeSignalType.DIRECT) { return this.impl$highestSignalAt(pos, this::impl$regularSignalFrom); - } else if (type == SpongeSignalType.STRONG) { + } else if (type == SpongeSignalType.INDIRECT) { return this.shadow$getDirectSignalTo(pos); } else if (type == SpongeSignalType.COMPOSITE) { return this.shadow$getBestNeighborSignal(pos); @@ -108,9 +108,9 @@ default boolean hasSignalAt(final SignalType type, final int x, final int y, fin final BlockPos pos = new BlockPos(x, y, z); if (type == SpongeSignalType.ANALOG) { return this.impl$hasSignalAt(pos, (relativePos, $) -> this.impl$analogSignalFrom(relativePos)); - } else if (type == SpongeSignalType.WEAK) { + } else if (type == SpongeSignalType.DIRECT) { return this.impl$hasSignalAt(pos, this::impl$regularSignalFrom); - } else if (type == SpongeSignalType.STRONG) { + } else if (type == SpongeSignalType.INDIRECT) { return this.impl$hasSignalAt(pos, this::shadow$getDirectSignal); } else if (type == SpongeSignalType.COMPOSITE) { return this.shadow$hasNeighborSignal(pos);