mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-26 17:46:25 -05:00
Add ability for minecarts to specify their detector rail comparator value (#1321)
* Add ability for minecarts to specify their detector rail comparator value Address comments * Apply suggestions from code review Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com> * Warn instead of debug Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com>
This commit is contained in:
parent
3fec4ad922
commit
3b82842e3d
4 changed files with 160 additions and 0 deletions
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* 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.object.builder.v1.entity;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides custom comparator output for minecarts resting on detector rails.
|
||||||
|
* @param <T> the handled minecart type
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface MinecartComparatorLogic<T extends AbstractMinecartEntity> {
|
||||||
|
/**
|
||||||
|
* Compute the comparator output of a detector rail when a minecart is resting
|
||||||
|
* on top of it. Called from {@link net.minecraft.block.DetectorRailBlock#getComparatorOutput}.
|
||||||
|
* @param minecart The minecart on the rail
|
||||||
|
* @param state Block state of the rail
|
||||||
|
* @param pos Position of the rail
|
||||||
|
* @return A redstone power value {@literal >=} 0 to use, else a value {@literal <} 0 to try the next minecart with
|
||||||
|
* a registered logic. If no logic chooses to provide a value, vanilla's logic is invoked.
|
||||||
|
*/
|
||||||
|
int getComparatorValue(T minecart, BlockState state, BlockPos pos);
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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.object.builder.v1.entity;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A registry for {@linkplain MinecartComparatorLogic custom minecart compator logic}.
|
||||||
|
*/
|
||||||
|
public final class MinecartComparatorLogicRegistry {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
private static final Map<EntityType<?>, MinecartComparatorLogic<?>> logics = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the registered custom comparator logic for the specified minecart entity type.
|
||||||
|
*
|
||||||
|
* @param type the entity type
|
||||||
|
* @return the comparator logic, or {@code null} if not registered
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static MinecartComparatorLogic<AbstractMinecartEntity> getCustomComparatorLogic(EntityType<?> type) {
|
||||||
|
return (MinecartComparatorLogic<AbstractMinecartEntity>) logics.get(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a comparator logic for a minecart entity type.
|
||||||
|
*
|
||||||
|
* <p>Registering a second value for an entity type will replace the old logic.
|
||||||
|
*
|
||||||
|
* @param <T> the handled minecart type
|
||||||
|
* @param type the minecart entity type
|
||||||
|
* @param logic the logic to register
|
||||||
|
*/
|
||||||
|
public static <T extends AbstractMinecartEntity> void register(EntityType<T> type, MinecartComparatorLogic<? super T> logic) {
|
||||||
|
if (logics.put(type, logic) != null) {
|
||||||
|
LOGGER.warn("Overriding existing minecart comparator logic for entity type {}", Registry.ENTITY_TYPE.getId(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* 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.object.builder;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.DetectorRailBlock;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.entity.MinecartComparatorLogicRegistry;
|
||||||
|
|
||||||
|
@Mixin(DetectorRailBlock.class)
|
||||||
|
public abstract class DetectorRailBlockMixin {
|
||||||
|
@Shadow protected abstract <T extends AbstractMinecartEntity> List<T> getCarts(World world, BlockPos pos, Class<T> entityClass, @Nullable Predicate<Entity> entityPredicate);
|
||||||
|
|
||||||
|
@Inject(at = @At("HEAD"), method = "getComparatorOutput", cancellable = true)
|
||||||
|
private void getCustomComparatorOutput(BlockState state, World world, BlockPos pos, CallbackInfoReturnable<Integer> cir) {
|
||||||
|
if (state.get(DetectorRailBlock.POWERED)) {
|
||||||
|
List<AbstractMinecartEntity> carts = getCarts(world, pos, AbstractMinecartEntity.class,
|
||||||
|
cart -> MinecartComparatorLogicRegistry.getCustomComparatorLogic(cart.getType()) != null);
|
||||||
|
for (AbstractMinecartEntity cart : carts) {
|
||||||
|
int comparatorValue = MinecartComparatorLogicRegistry.getCustomComparatorLogic(cart.getType())
|
||||||
|
.getComparatorValue(cart, state, pos);
|
||||||
|
if (comparatorValue >= 0) {
|
||||||
|
cir.setReturnValue(comparatorValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@
|
||||||
"CriteriaAccessor",
|
"CriteriaAccessor",
|
||||||
"DefaultAttributeRegistryAccessor",
|
"DefaultAttributeRegistryAccessor",
|
||||||
"DefaultAttributeRegistryMixin",
|
"DefaultAttributeRegistryMixin",
|
||||||
|
"DetectorRailBlockMixin",
|
||||||
"MaterialBuilderAccessor",
|
"MaterialBuilderAccessor",
|
||||||
"MixinBlock",
|
"MixinBlock",
|
||||||
"PointOfInterestTypeAccessor",
|
"PointOfInterestTypeAccessor",
|
||||||
|
|
Loading…
Reference in a new issue