-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #271 from JohanVonElectrum/ss-command-feature
ss-command-feature
- Loading branch information
Showing
5 changed files
with
246 additions
and
69 deletions.
There are no files selected for viewing
15 changes: 15 additions & 0 deletions
15
...va/tools/redstone/redstonetools/features/arguments/serializers/SignalBlockSerializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package tools.redstone.redstonetools.features.arguments.serializers; | ||
|
||
import tools.redstone.redstonetools.utils.SignalBlock; | ||
|
||
public class SignalBlockSerializer extends EnumSerializer<SignalBlock> { | ||
private static final SignalBlockSerializer INSTANCE = new SignalBlockSerializer(); | ||
|
||
private SignalBlockSerializer() { | ||
super(SignalBlock.class); | ||
} | ||
|
||
public static SignalBlockSerializer signalBlock() { | ||
return INSTANCE; | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
src/main/java/tools/redstone/redstonetools/features/commands/SignalStrengthBlockFeature.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package tools.redstone.redstonetools.features.commands; | ||
|
||
import com.google.auto.service.AutoService; | ||
import com.mojang.brigadier.exceptions.CommandSyntaxException; | ||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; | ||
import net.minecraft.item.ItemStack; | ||
import net.minecraft.server.command.ServerCommandSource; | ||
import net.minecraft.text.Text; | ||
import tools.redstone.redstonetools.features.AbstractFeature; | ||
import tools.redstone.redstonetools.features.Feature; | ||
import tools.redstone.redstonetools.features.arguments.Argument; | ||
import tools.redstone.redstonetools.features.arguments.serializers.SignalBlockSerializer; | ||
import tools.redstone.redstonetools.features.feedback.Feedback; | ||
import tools.redstone.redstonetools.utils.SignalBlock; | ||
|
||
import java.util.Random; | ||
|
||
import static tools.redstone.redstonetools.features.arguments.serializers.IntegerSerializer.integer; | ||
|
||
@AutoService(AbstractFeature.class) | ||
@Feature(name = "Signal Strength Block", description = "Creates a block with the specified signal strength.", command = "ssb") | ||
public class SignalStrengthBlockFeature extends CommandFeature { | ||
|
||
public static final Argument<Integer> signalStrength = Argument | ||
.ofType(integer(0)); | ||
|
||
public static final Argument<SignalBlock> block = Argument | ||
.ofType(SignalBlockSerializer.signalBlock()) | ||
.withDefault(SignalBlock.AUTO); | ||
|
||
@Override | ||
protected Feedback execute(ServerCommandSource source) throws CommandSyntaxException { | ||
try { | ||
ItemStack itemStack = block.getValue().getItemStack(signalStrength.getValue()); | ||
source.getPlayer().giveItemStack(itemStack); | ||
} catch (IllegalArgumentException | IllegalStateException e) { | ||
return Feedback.error(e.getMessage()); | ||
} | ||
|
||
//funny | ||
if(signalStrength.getValue() == 0) { | ||
String[] funny = { | ||
"Why would you want this??", "Wtf are you going to use this for?", "What for?", | ||
"... Ok, if you're sure.", "I'm 99% sure you could just use any other block.", | ||
"This seems unnecessary.", "Is that a typo?", "Do you just like the glint?", | ||
"Wow, what a fancy but otherwise useless barrel.", "For decoration?"}; | ||
return Feedback.success(funny[new Random().nextInt(funny.length)]); | ||
} | ||
|
||
return Feedback.none(); | ||
} | ||
|
||
} |
69 changes: 0 additions & 69 deletions
69
src/main/java/tools/redstone/redstonetools/features/commands/SsBarrelFeature.java
This file was deleted.
Oops, something went wrong.
47 changes: 47 additions & 0 deletions
47
src/main/java/tools/redstone/redstonetools/utils/SignalBlock.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package tools.redstone.redstonetools.utils; | ||
|
||
import net.minecraft.block.Block; | ||
import net.minecraft.block.Blocks; | ||
import net.minecraft.item.ItemStack; | ||
|
||
public enum SignalBlock { | ||
COMPOSTER(Blocks.COMPOSTER, SignalBlockSupplier.composter()), | ||
BARREL(Blocks.BARREL, SignalBlockSupplier.container(27)), | ||
CHEST(Blocks.CHEST, SignalBlockSupplier.container(27)), | ||
SHULKER_BOX(Blocks.SHULKER_BOX, SignalBlockSupplier.container(27)), | ||
DISPENSER(Blocks.DISPENSER, SignalBlockSupplier.container(9)), | ||
DROPPER(Blocks.DROPPER, SignalBlockSupplier.container(9)), | ||
HOPPER(Blocks.HOPPER, SignalBlockSupplier.container(5)), | ||
BREWING_STAND(Blocks.BREWING_STAND, SignalBlockSupplier.container(5)), | ||
FURNACE(Blocks.FURNACE, SignalBlockSupplier.container(3)), | ||
SMOKER(Blocks.SMOKER, SignalBlockSupplier.container(3)), | ||
BLAST_FURNACE(Blocks.BLAST_FURNACE, SignalBlockSupplier.container(3)), | ||
COMMAND_BLOCK(Blocks.COMMAND_BLOCK, SignalBlockSupplier.commandBlock()), | ||
AUTO(null, null); | ||
|
||
private final Block block; | ||
private final SignalBlockSupplier supplier; | ||
|
||
SignalBlock(Block block, SignalBlockSupplier supplier) { | ||
this.block = block; | ||
this.supplier = supplier; | ||
} | ||
|
||
public static SignalBlock getBestBlock(int signal) { | ||
return signal < 1780 | ||
? BARREL | ||
: COMMAND_BLOCK; | ||
} | ||
|
||
public ItemStack getItemStack(int signal) { | ||
if (block == null || supplier == null) | ||
return getBestBlock(signal).getItemStack(signal); | ||
|
||
return supplier.getItemStack(block, signal); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return this.name().toLowerCase(); | ||
} | ||
} |
131 changes: 131 additions & 0 deletions
131
src/main/java/tools/redstone/redstonetools/utils/SignalBlockSupplier.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package tools.redstone.redstonetools.utils; | ||
|
||
import net.minecraft.block.Block; | ||
import net.minecraft.enchantment.Enchantment; | ||
import net.minecraft.item.Item; | ||
import net.minecraft.item.ItemStack; | ||
import net.minecraft.item.Items; | ||
import net.minecraft.nbt.NbtCompound; | ||
import net.minecraft.nbt.NbtList; | ||
import net.minecraft.text.LiteralText; | ||
import net.minecraft.text.MutableText; | ||
import net.minecraft.util.Formatting; | ||
import net.minecraft.util.math.MathHelper; | ||
import net.minecraft.util.registry.Registry; | ||
|
||
@FunctionalInterface | ||
public interface SignalBlockSupplier { | ||
|
||
NbtCompound createNbt(int signalStrength); | ||
|
||
default ItemStack getItemStack(Block block, int signalStrength) { | ||
ItemStack item = new ItemStack(block); | ||
setCompoundNbt(item, this.createNbt(signalStrength)); | ||
setItemName(item, signalStrength); | ||
return item; | ||
} | ||
|
||
static SignalBlockSupplier container(int slots) { | ||
return signalStrength -> { | ||
if (isInvalidSignalStrength(signalStrength, 1779)) | ||
throw new IllegalArgumentException("Container signal must be 0-1779"); | ||
|
||
NbtCompound tags = new NbtCompound(); | ||
NbtList itemsTag = new NbtList(); | ||
|
||
Item item = getBestItem(signalStrength, slots); | ||
int stackSize = getStackSize(signalStrength, item); | ||
int itemsNeeded = signalStrength == 1 | ||
? 1 | ||
: (int) Math.ceil(slots * (signalStrength - 1) / 14D * item.getMaxCount()); | ||
String itemId = Registry.ITEM.getId(item).toString(); | ||
|
||
// Check that the calculated number of items is correct. | ||
// This is to prevent problems with items that have a maximum stack size of 1 but stackSize > 1. | ||
// TODO: This can be improved by removing an item and adding stackable items up to the desired signal strength. | ||
// Even with the improvement, this will still fail for inventories with no available slots. | ||
if (calculateComparatorOutput(itemsNeeded, slots, item.getMaxCount()) != signalStrength) | ||
throw new IllegalStateException("This signal strength cannot be achieved with the selected container"); | ||
|
||
for (int slot = 0, count = itemsNeeded; count > 0; slot++, count -= stackSize) { | ||
NbtCompound slotTag = new NbtCompound(); | ||
slotTag.putByte("Slot", (byte) slot); | ||
slotTag.putString("id", itemId); | ||
slotTag.putByte("Count", (byte) Math.min(stackSize, count)); | ||
itemsTag.add(slotTag); | ||
} | ||
|
||
NbtCompound tag = new NbtCompound(); | ||
tag.put("Items", itemsTag); | ||
tags.put("BlockEntityTag", tag); | ||
|
||
return tags; | ||
}; | ||
} | ||
|
||
static SignalBlockSupplier composter() { | ||
return signalStrength -> { | ||
if (signalStrength == 7 || isInvalidSignalStrength(signalStrength, 8)) | ||
throw new IllegalArgumentException("Composter signal must be 0-6 or 8"); | ||
|
||
NbtCompound tags = new NbtCompound(); | ||
NbtCompound tag = new NbtCompound(); | ||
tag.putInt("level", signalStrength); | ||
tags.put("BlockStateTag", tag); | ||
return tags; | ||
}; | ||
} | ||
|
||
static SignalBlockSupplier commandBlock() { | ||
return signalStrength -> { | ||
if (isInvalidSignalStrength(signalStrength, Integer.MAX_VALUE)) | ||
throw new IllegalArgumentException("Command block signal must be positive"); | ||
|
||
NbtCompound tags = new NbtCompound(); | ||
NbtCompound tag = new NbtCompound(); | ||
tag.putInt("SuccessCount", signalStrength); | ||
tags.put("BlockEntityTag", tag); | ||
return tags; | ||
}; | ||
} | ||
|
||
private static boolean isInvalidSignalStrength(int signalStrength, int maxSignalStrength) { | ||
return signalStrength < 0 || signalStrength > maxSignalStrength; | ||
} | ||
|
||
private static int calculateComparatorOutput(int items, int slots, int item$getMaxCount) { | ||
float f = (float) items / (float) item$getMaxCount; | ||
return MathHelper.floor((f /= (float)slots) * 14.0f) + (items > 0 ? 1 : 0); | ||
} | ||
|
||
private static Item getBestItem(int signalStrength, int slots) { | ||
if (signalStrength > 15) | ||
return Items.WHITE_SHULKER_BOX; | ||
else if (slots >= 15) | ||
return Items.WOODEN_SHOVEL; | ||
else | ||
return Items.STICK; | ||
} | ||
|
||
private static int getStackSize(int signalStrength, Item item) { | ||
if (signalStrength > 897) | ||
return 127; | ||
else if (signalStrength > 15) | ||
return 64; | ||
else | ||
return item.getMaxCount(); | ||
} | ||
|
||
private static void setCompoundNbt(ItemStack item, NbtCompound nbt) { | ||
nbt.putBoolean("HideFlags", true); | ||
item.setNbt(nbt); | ||
item.addEnchantment(Enchantment.byRawId(0), 0); | ||
} | ||
|
||
private static void setItemName(ItemStack item, int signalStrength) { | ||
MutableText text = new LiteralText(String.valueOf(signalStrength)); | ||
text.setStyle(text.getStyle().withColor(Formatting.RED)); | ||
item.setCustomName(text); | ||
} | ||
|
||
} |