Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -415,6 +418,15 @@ public static RegistryLoader<ResolveOperation> resolveOperation() {
});
}

public static RegistryLoader<SignalType> signalType() {
return RegistryLoader.of(l -> {
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);
});
}

public static RegistryLoader<SkinPart> skinPart() {
return RegistryLoader.of(l -> {
l.add(SkinParts.CAPE, k -> new SpongeSkinPart("cape"));
Expand Down
13 changes: 11 additions & 2 deletions src/main/java/org/spongepowered/common/util/DirectionUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<net.minecraft.core.Direction> property) {
final net.minecraft.core.Direction direction = DirectionUtil.getFor(value);
if (direction == null || !property.getPossibleValues().contains(direction)) {
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/org/spongepowered/common/world/SpongeSignalType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* 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 DIRECT = new SpongeSignalType();

public static final SignalType INDIRECT = new SpongeSignalType();

public static final SignalType COMPOSITE = new SpongeSignalType();

public static final SignalType ANALOG = new SpongeSignalType();

private SpongeSignalType() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* 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.DIRECT || type == SpongeSignalType.INDIRECT || 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.DIRECT) {
return this.impl$regularSignalFrom(pos, DirectionUtil.getForOrThrow(direction).getOpposite());
} 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());
}

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.DIRECT) {
return this.impl$highestSignalAt(pos, this::impl$regularSignalFrom);
} else if (type == SpongeSignalType.INDIRECT) {
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.DIRECT) {
return this.impl$hasSignalAt(pos, this::impl$regularSignalFrom);
} else if (type == SpongeSignalType.INDIRECT) {
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<BlockPos, net.minecraft.core.Direction> 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<BlockPos, net.minecraft.core.Direction> 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());
}
}
1 change: 1 addition & 0 deletions src/mixins/resources/mixins.sponge.api.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down