Skip to content

Commit

Permalink
Cleaned up pairing tools
Browse files Browse the repository at this point in the history
  • Loading branch information
Sm0keySa1m0n committed Sep 10, 2023
1 parent 76cd834 commit 2eb222e
Show file tree
Hide file tree
Showing 7 changed files with 316 additions and 218 deletions.
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// 1.20.1 2023-09-04T20:53:55.046849 Languages: en_us
9f0012e8e466d4e0775e6550ef59e1001ffef02e assets/railcraft/lang/en_us.json
// 1.20.1 2023-09-10T16:28:13.344594 Languages: en_us
3d94fe9dac885db8064e1f5978c4aaafa0026200 assets/railcraft/lang/en_us.json
27 changes: 14 additions & 13 deletions src/generated/resources/assets/railcraft/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -741,19 +741,20 @@
"signal.railcraft.capacitor.falling_edge.desc": "Start timer when the last input signal turns off.",
"signal.railcraft.capacitor.rising_edge": "Rising Edge",
"signal.railcraft.capacitor.rising_edge.desc": "Start timer as soon as the input signal is received.",
"signal.railcraft.surveyor.abandoned": "Survey Abandoned",
"signal.railcraft.surveyor.begin": "Beginning Survey",
"signal.railcraft.surveyor.invalid_block": "Not a Valid Signal",
"signal.railcraft.surveyor.invalid_pair": "Pairing Invalid",
"signal.railcraft.surveyor.invalid_track": "No Track Found Near %s",
"signal.railcraft.surveyor.lost": "First Signal No Longer Exists",
"signal.railcraft.surveyor.success": "Successfully Paired Signals",
"signal.railcraft.surveyor.unloaded": "First Signal's Chunk Has Been Unloaded",
"signal.railcraft.tuner.abandoned": "Stopped Pairing",
"signal.railcraft.tuner.begin": "Started Pairing %s With a Receiver",
"signal.railcraft.tuner.lost": "Signal Controller No Longer Exists",
"signal.railcraft.tuner.success": "Successfully Paired Signal Receiver",
"signal.railcraft.tuner.unloaded": "Signal Controller's Chunk Has Been Unloaded",
"signal.railcraft.surveyor.abandoned": "Signal survey abandoned",
"signal.railcraft.surveyor.begin": "Beginning signal survey",
"signal.railcraft.surveyor.invalid_block": "Invalid signal",
"signal.railcraft.surveyor.invalid_pair": "Invalid pair",
"signal.railcraft.surveyor.invalid_track": "Track not found",
"signal.railcraft.surveyor.lost": "First signal has been destroyed",
"signal.railcraft.surveyor.success": "Successfully paired %s to %s",
"signal.railcraft.tuner.abandoned": "Pairing abandoned",
"signal.railcraft.tuner.already_paired": "%s is already paired to %s",
"signal.railcraft.tuner.begin": "Started pairing %s with a receiver",
"signal.railcraft.tuner.invalid_controller": "Invalid signal controller",
"signal.railcraft.tuner.invalid_receiver": "Invalid signal receiver",
"signal.railcraft.tuner.lost": "Signal controller has been destroyed",
"signal.railcraft.tuner.success": "Successfully paired %s to %s",
"subtitle.railcraft.locomotive.electric.whistle": "Electric Locomotive Whistle",
"subtitle.railcraft.locomotive.steam.whistle": "Steam Locomotive Whistle",
"subtitle.railcraft.machine.steam.burst": "Machine Steam Burst",
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/mods/railcraft/Translations.java
Original file line number Diff line number Diff line change
Expand Up @@ -413,16 +413,19 @@ public static class Signal {
public static final String SIGNAL_SURVEYOR_INVALID_PAIR =
makeKey("signal", "surveyor.invalid_pair");
public static final String SIGNAL_SURVEYOR_LOST = makeKey("signal", "surveyor.lost");
public static final String SIGNAL_SURVEYOR_UNLOADED =
makeKey("signal", "surveyor.unloaded");
public static final String SIGNAL_SURVEYOR_ABANDONED =
makeKey("signal", "surveyor.abandoned");
public static final String SIGNAL_SURVEYOR_INVALID_BLOCK =
makeKey("signal", "surveyor.invalid_block");

public static final String SIGNAL_TUNER_BEGIN = makeKey("signal", "tuner.begin");
public static final String SIGNAL_TUNER_ABANDONED = makeKey("signal", "tuner.abandoned");
public static final String SIGNAL_TUNER_UNLOADED = makeKey("signal", "tuner.unloaded");
public static final String SIGNAL_TUNER_INVALID_CONTROLLER =
makeKey("signal", "tuner.invalid_controller");
public static final String SIGNAL_TUNER_INVALID_RECEIVER =
makeKey("signal", "tuner.invalid_receiver");
public static final String SIGNAL_TUNER_ALREADY_PAIRED =
makeKey("signal", "tuner.already_paired");
public static final String SIGNAL_TUNER_LOST = makeKey("signal", "tuner.lost");
public static final String SIGNAL_TUNER_SUCCESS = makeKey("signal", "tuner.success");
}
Expand Down
45 changes: 22 additions & 23 deletions src/main/java/mods/railcraft/data/RailcraftLanguageProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -856,38 +856,37 @@ private void jeiTranslations() {
this.add(Translations.Jei.NICKEL_IRON_BATTERY,
"A battery designed to work with the charge network. Good for general purpose usage.");
this.add(Translations.Jei.NICKEL_ZINC_BATTERY, """
A battery designed to work with the charge network. \
Good for low draw, long term storage.""");
A battery designed to work with the charge network. \
Good for low draw, long term storage.""");
this.add(Translations.Jei.DISPOSABLE_BATTERY, """
A battery designed to work with the charge network. \
Good for cheap, single use storage. Comes fully charged.""");
A battery designed to work with the charge network. \
Good for cheap, single use storage. Comes fully charged.""");
this.add(Translations.Jei.DISPOSABLE_BATTERY_EMPTY, """
A battery designed to work with the charge network. \
Good for cheap, single use storage. \
This one is empty and can be recycled in the Crusher.""");
A battery designed to work with the charge network. \
Good for cheap, single use storage. \
This one is empty and can be recycled in the Crusher.""");
this.add(Translations.Jei.PAINT, "Paint");
this.add(Translations.Jei.COPY_TAG, "Copy Tag");
this.add(Translations.Jei.REPAIR, "Repair");
this.add(Translations.Jei.SPLIT, "Split");
}

private void signalTranslations() {
this.add(Translations.Signal.SIGNAL_SURVEYOR_INVALID_TRACK, "No Track Found Near %s");
this.add(Translations.Signal.SIGNAL_SURVEYOR_BEGIN, "Beginning Survey");
this.add(Translations.Signal.SIGNAL_SURVEYOR_SUCCESS, "Successfully Paired Signals");
this.add(Translations.Signal.SIGNAL_SURVEYOR_INVALID_PAIR, "Pairing Invalid");
this.add(Translations.Signal.SIGNAL_SURVEYOR_LOST, "First Signal No Longer Exists");
this.add(Translations.Signal.SIGNAL_SURVEYOR_UNLOADED,
"First Signal's Chunk Has Been Unloaded");
this.add(Translations.Signal.SIGNAL_SURVEYOR_ABANDONED, "Survey Abandoned");
this.add(Translations.Signal.SIGNAL_SURVEYOR_INVALID_BLOCK, "Not a Valid Signal");

this.add(Translations.Signal.SIGNAL_TUNER_BEGIN, "Started Pairing %s With a Receiver");
this.add(Translations.Signal.SIGNAL_TUNER_ABANDONED, "Stopped Pairing");
this.add(Translations.Signal.SIGNAL_TUNER_UNLOADED,
"Signal Controller's Chunk Has Been Unloaded");
this.add(Translations.Signal.SIGNAL_TUNER_LOST, "Signal Controller No Longer Exists");
this.add(Translations.Signal.SIGNAL_TUNER_SUCCESS, "Successfully Paired Signal Receiver");
this.add(Translations.Signal.SIGNAL_SURVEYOR_INVALID_TRACK, "Track not found");
this.add(Translations.Signal.SIGNAL_SURVEYOR_BEGIN, "Beginning signal survey");
this.add(Translations.Signal.SIGNAL_SURVEYOR_SUCCESS, "Successfully paired %s to %s");
this.add(Translations.Signal.SIGNAL_SURVEYOR_INVALID_PAIR, "Invalid pair");
this.add(Translations.Signal.SIGNAL_SURVEYOR_LOST, "First signal has been destroyed");
this.add(Translations.Signal.SIGNAL_SURVEYOR_ABANDONED, "Signal survey abandoned");
this.add(Translations.Signal.SIGNAL_SURVEYOR_INVALID_BLOCK, "Invalid signal");

this.add(Translations.Signal.SIGNAL_TUNER_BEGIN, "Started pairing %s with a receiver");
this.add(Translations.Signal.SIGNAL_TUNER_INVALID_CONTROLLER, "Invalid signal controller");
this.add(Translations.Signal.SIGNAL_TUNER_INVALID_RECEIVER, "Invalid signal receiver");
this.add(Translations.Signal.SIGNAL_TUNER_ABANDONED, "Pairing abandoned");
this.add(Translations.Signal.SIGNAL_TUNER_ALREADY_PAIRED, "%s is already paired to %s");
this.add(Translations.Signal.SIGNAL_TUNER_LOST, "Signal controller has been destroyed");
this.add(Translations.Signal.SIGNAL_TUNER_SUCCESS, "Successfully paired %s to %s");
}

private void enchantmentTranslations() {
Expand Down
152 changes: 148 additions & 4 deletions src/main/java/mods/railcraft/world/item/PairingToolItem.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,171 @@
package mods.railcraft.world.item;

import java.util.Optional;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import com.mojang.logging.LogUtils;
import mods.railcraft.api.item.ActivationBlockingItem;
import net.minecraft.core.BlockPos;
import net.minecraft.core.GlobalPos;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.entity.BlockEntity;

@ActivationBlockingItem
public class PairingToolItem extends Item {
public abstract class PairingToolItem<T, P> extends Item {

private static final Logger logger = LogUtils.getLogger();

public PairingToolItem(Properties properties) {
super(properties);
}

public static Optional<GlobalPos> getPeerPos(ItemStack itemStack) {
protected abstract Class<T> targetType();

protected abstract Class<P> peerType();

@Override
public final InteractionResult onItemUseFirst(ItemStack itemStack, UseOnContext context) {
var level = context.getLevel();
if (!(level instanceof ServerLevel serverLevel)) {
return InteractionResult.SUCCESS;
}

var player = context.getPlayer();
var pos = context.getClickedPos();
var targetPos = getTargetPos(itemStack).orElse(null);

if (targetPos != null) {
// Clicked on target twice
if (targetPos.pos().equals(pos)) {
this.displayMessageForState(player, State.ABANDONED);
return InteractionResult.CONSUME;
}
// Target dimension is different to current dimension so silently start new pairing
if (targetPos.dimension().compareTo(level.dimension()) != 0) {
var dimension = level.getServer().getLevel(targetPos.dimension());
if (dimension != null) {
this.abandon(getBlockEntity(dimension, targetPos.pos(), this.targetType()));
}
clearTargetPos(itemStack);
targetPos = null;
}
}

// No target has been set yet
if (targetPos == null) {
var target = getBlockEntity(level, pos, this.targetType());
if (target == null) {
this.displayMessageForState(player, State.INVALID_TARGET);
return InteractionResult.FAIL;
}
var result = this.begin(target);
player.displayClientMessage(result.message(), true);
if (result.success()) {
setTargetPos(itemStack, GlobalPos.of(level.dimension(), pos));
return InteractionResult.CONSUME;
} else {
return InteractionResult.FAIL;
}
}

var targetEntity = getBlockEntity(level, targetPos.pos(), this.targetType());

if (player.isShiftKeyDown()) {
this.abandon(targetEntity);
this.displayMessageForState(player, State.ABANDONED);
clearTargetPos(itemStack);
return InteractionResult.CONSUME;
}

// Target no longer exists
if (targetEntity == null) {
this.displayMessageForState(player, State.LOST_TARGET);
clearTargetPos(itemStack);
return InteractionResult.FAIL;
}

var peerEntity = getBlockEntity(level, pos, this.peerType());
if (peerEntity == null) {
this.displayMessageForState(player, State.INVALID_PEER);
return InteractionResult.FAIL;
}

if (targetEntity == peerEntity) {
throw new IllegalStateException("Target entity is the same as the peer entity.");
}

var result = this.complete(targetEntity, peerEntity);
player.displayClientMessage(result.message(), true);
clearTargetPos(itemStack);
return result.success() ? InteractionResult.CONSUME : InteractionResult.FAIL;
}

private void displayMessageForState(Player player, State state) {
player.displayClientMessage(this.getMessageForState(state), true);
}

/**
* {@return the message for the specified {@link State}}
*
* @param state - the state to retrieve the message for
*/
protected abstract Component getMessageForState(State state);

/**
* Abandons pairing with the specified {@link BlockEntity}.
*
* @param target - the {@link BlockEntity} to cancel pairing for
*/
protected abstract void abandon(@Nullable T target);

/**
* Begins pairing with the specified {@link BlockEntity}.
*
* @param target - the {@link BlockEntity} to begin pairing with
* @return the result of the operation
*/
protected abstract Result begin(T target);

/**
* Completes pairing.
*
* @param target - the target {@link BlockEntity}
* @param peer - the peer {@link BlockEntity}
* @return the result of the operation
*/
protected abstract Result complete(T target, P peer);

protected enum State {

ABANDONED, LOST_TARGET, INVALID_TARGET, INVALID_PEER;
}

protected record Result(boolean success, Component message) {

public static Result success(Component message) {
return new Result(true, message);
}

public static Result failure(Component message) {
return new Result(false, message);
}
}

private static <T> T getBlockEntity(BlockGetter getter, BlockPos pos, Class<T> type) {
var entity = getter.getBlockEntity(pos);
return type.isInstance(entity) ? type.cast(entity) : null;
}

public static Optional<GlobalPos> getTargetPos(ItemStack itemStack) {
var tag = itemStack.getTag();
return tag != null && tag.contains("peerPos", Tag.TAG_COMPOUND)
? GlobalPos.CODEC
Expand All @@ -30,14 +174,14 @@ public static Optional<GlobalPos> getPeerPos(ItemStack itemStack) {
: Optional.empty();
}

public static void setPeerPos(ItemStack itemStack, GlobalPos peerPos) {
public static void setTargetPos(ItemStack itemStack, GlobalPos peerPos) {
GlobalPos.CODEC
.encodeStart(NbtOps.INSTANCE, peerPos)
.resultOrPartial(logger::error)
.ifPresent(tag -> itemStack.getOrCreateTag().put("peerPos", tag));
}

public static void clearPeerPos(ItemStack itemStack) {
public static void clearTargetPos(ItemStack itemStack) {
var tag = itemStack.getTag();
if (tag != null) {
tag.remove("peerPos");
Expand Down

0 comments on commit 2eb222e

Please sign in to comment.