Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Peripheral tools #1692

Open
wants to merge 2 commits into
base: mc-1.20.x
Choose a base branch
from
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 @@ -63,6 +63,7 @@ public static class ToolBuilder {
private @Nullable Item craftingItem;
private @Nullable Float damageMultiplier = null;
private @Nullable TagKey<Block> breakable;
private String peripheralType = "";
private boolean allowEnchantments = false;
private TurtleToolDurability consumeDurability = TurtleToolDurability.NEVER;

Expand Down Expand Up @@ -96,6 +97,11 @@ public ToolBuilder craftingItem(Item craftingItem) {
return this;
}

public ToolBuilder peripheralType(String peripheralType) {
this.peripheralType = peripheralType;
return this;
}

/**
* The amount of damage a swing of this tool will do. This is multiplied by {@link Attributes#ATTACK_DAMAGE} to
* get the final damage.
Expand Down Expand Up @@ -162,6 +168,7 @@ public void add(Consumer<Upgrade<TurtleUpgradeSerialiser<?>>> add) {
if (consumeDurability != TurtleToolDurability.NEVER) {
s.addProperty("consumeDurability", consumeDurability.getSerializedName());
}
s.addProperty("peripheralType", peripheralType);
}));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ protected void addUpgrades(Consumer<Upgrade<TurtleUpgradeSerialiser<?>>> addUpgr
simpleWithCustomItem(id("wireless_modem_normal"), TurtleSerialisers.WIRELESS_MODEM_NORMAL.get(), Items.WIRELESS_MODEM_NORMAL.get()).add(addUpgrade);
simpleWithCustomItem(id("wireless_modem_advanced"), TurtleSerialisers.WIRELESS_MODEM_ADVANCED.get(), Items.WIRELESS_MODEM_ADVANCED.get()).add(addUpgrade);

tool(vanilla("diamond_axe"), net.minecraft.world.item.Items.DIAMOND_AXE).damageMultiplier(6.0f).add(addUpgrade);
tool(vanilla("diamond_pickaxe"), net.minecraft.world.item.Items.DIAMOND_PICKAXE).add(addUpgrade);
tool(vanilla("diamond_hoe"), net.minecraft.world.item.Items.DIAMOND_HOE).breakable(Blocks.TURTLE_HOE_BREAKABLE).add(addUpgrade);
tool(vanilla("diamond_shovel"), net.minecraft.world.item.Items.DIAMOND_SHOVEL).breakable(Blocks.TURTLE_SHOVEL_BREAKABLE).add(addUpgrade);
tool(vanilla("diamond_sword"), net.minecraft.world.item.Items.DIAMOND_SWORD).breakable(Blocks.TURTLE_SWORD_BREAKABLE).damageMultiplier(9.0f).add(addUpgrade);
tool(vanilla("diamond_axe"), net.minecraft.world.item.Items.DIAMOND_AXE).peripheralType("axe").damageMultiplier(6.0f).add(addUpgrade);
tool(vanilla("diamond_pickaxe"), net.minecraft.world.item.Items.DIAMOND_PICKAXE).peripheralType("pickaxe").add(addUpgrade);
tool(vanilla("diamond_hoe"), net.minecraft.world.item.Items.DIAMOND_HOE).breakable(Blocks.TURTLE_HOE_BREAKABLE).peripheralType("hoe").add(addUpgrade);
tool(vanilla("diamond_shovel"), net.minecraft.world.item.Items.DIAMOND_SHOVEL).breakable(Blocks.TURTLE_SHOVEL_BREAKABLE).peripheralType("shovel").add(addUpgrade);
tool(vanilla("diamond_sword"), net.minecraft.world.item.Items.DIAMOND_SWORD).breakable(Blocks.TURTLE_SWORD_BREAKABLE).peripheralType("sword").damageMultiplier(9.0f).add(addUpgrade);
}

private static ResourceLocation id(String id) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package dan200.computercraft.shared.turtle.upgrades;

import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.lua.MethodResult;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.shared.turtle.core.InteractDirection;
import dan200.computercraft.shared.turtle.core.TurtleToolCommand;

import javax.annotation.Nullable;

public class ToolPeripheral implements IPeripheral {
private final ITurtleAccess turtle;
private final TurtleSide side;
private final String type;

public ToolPeripheral(ITurtleAccess turtle, TurtleSide side, String type) {
this.turtle = turtle;
this.side = side;
this.type = type;
}

@Override
public String getType() {
return type;
}

@LuaFunction
public final MethodResult digDown() throws LuaException {
return turtle.executeCommand(TurtleToolCommand.dig(InteractDirection.DOWN, side));
}

@LuaFunction
public final MethodResult digUp() throws LuaException {
return turtle.executeCommand(TurtleToolCommand.dig(InteractDirection.UP, side));
}

@LuaFunction
public final MethodResult dig() throws LuaException {
return turtle.executeCommand(TurtleToolCommand.dig(InteractDirection.FORWARD, side));
}

@LuaFunction
public final MethodResult attackDown() throws LuaException {
return turtle.executeCommand(TurtleToolCommand.attack(InteractDirection.DOWN, side));
}

@LuaFunction
public final MethodResult attackUp() throws LuaException {
return turtle.executeCommand(TurtleToolCommand.attack(InteractDirection.UP, side));
}

@LuaFunction
public final MethodResult attack() throws LuaException {
return turtle.executeCommand(TurtleToolCommand.attack(InteractDirection.FORWARD, side));
}

@Override
public boolean equals(@Nullable IPeripheral other) {
return other instanceof ToolPeripheral && type.equals(other.getType());
}

@Override
public Object getTarget() {
return turtle;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package dan200.computercraft.shared.turtle.upgrades;

import dan200.computercraft.api.ComputerCraftTags;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.turtle.*;
import dan200.computercraft.shared.platform.PlatformHelper;
import dan200.computercraft.shared.turtle.TurtleUtil;
Expand Down Expand Up @@ -55,17 +56,19 @@ public class TurtleTool extends AbstractTurtleUpgrade {
final boolean allowEnchantments;
final TurtleToolDurability consumeDurability;
final @Nullable TagKey<Block> breakable;
final String peripheralType;

public TurtleTool(
ResourceLocation id, String adjective, Item craftItem, ItemStack toolItem, float damageMulitiplier,
boolean allowEnchantments, TurtleToolDurability consumeDurability, @Nullable TagKey<Block> breakable
boolean allowEnchantments, TurtleToolDurability consumeDurability, @Nullable TagKey<Block> breakable, String peripheralType
) {
super(id, TurtleUpgradeType.TOOL, adjective, new ItemStack(craftItem));
super(id, TurtleUpgradeType.BOTH, adjective, new ItemStack(craftItem));
item = toolItem;
this.damageMulitiplier = damageMulitiplier;
this.allowEnchantments = allowEnchantments;
this.consumeDurability = consumeDurability;
this.breakable = breakable;
this.peripheralType = peripheralType;
}

@Override
Expand Down Expand Up @@ -104,6 +107,11 @@ public ItemStack getUpgradeItem(CompoundTag upgradeData) {
return item;
}

@Override
public IPeripheral createPeripheral(ITurtleAccess turtle, TurtleSide side) {
return new ToolPeripheral(turtle, side, peripheralType);
}

private ItemStack getToolStack(ITurtleAccess turtle, TurtleSide side) {
return getUpgradeItem(turtle.getUpgradeNBTData(side)).copy();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public TurtleTool fromJson(ResourceLocation id, JsonObject object) {
var craftingItem = GsonHelper.getAsItem(object, "craftingItem", toolItem);
var damageMultiplier = GsonHelper.getAsFloat(object, "damageMultiplier", 3.0f);
var allowEnchantments = GsonHelper.getAsBoolean(object, "allowEnchantments", false);
var peripheralType = GsonHelper.getAsString(object, "peripheralType", "");
var consumeDurability = TurtleToolDurability.CODEC.byName(GsonHelper.getAsString(object, "consumeDurability", null), TurtleToolDurability.NEVER);

TagKey<Block> breakable = null;
Expand All @@ -40,7 +41,7 @@ public TurtleTool fromJson(ResourceLocation id, JsonObject object) {
breakable = TagKey.create(Registries.BLOCK, tag);
}

return new TurtleTool(id, adjective, craftingItem, new ItemStack(toolItem), damageMultiplier, allowEnchantments, consumeDurability, breakable);
return new TurtleTool(id, adjective, craftingItem, new ItemStack(toolItem), damageMultiplier, allowEnchantments, consumeDurability, breakable, peripheralType);
}

@Override
Expand All @@ -54,9 +55,10 @@ public TurtleTool fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
var damageMultiplier = buffer.readFloat();
var allowsEnchantments = buffer.readBoolean();
var consumesDurability = buffer.readEnum(TurtleToolDurability.class);
var peripheralType = buffer.readUtf();

var breakable = buffer.readNullable(b -> TagKey.create(Registries.BLOCK, b.readResourceLocation()));
return new TurtleTool(id, adjective, craftingItem, toolItem, damageMultiplier, allowsEnchantments, consumesDurability, breakable);
return new TurtleTool(id, adjective, craftingItem, toolItem, damageMultiplier, allowsEnchantments, consumesDurability, breakable, peripheralType);
}

@Override
Expand All @@ -67,6 +69,7 @@ public void toNetwork(FriendlyByteBuf buffer, TurtleTool upgrade) {
buffer.writeFloat(upgrade.damageMulitiplier);
buffer.writeBoolean(upgrade.allowEnchantments);
buffer.writeEnum(upgrade.consumeDurability);
buffer.writeUtf(upgrade.peripheralType);
buffer.writeNullable(upgrade.breakable, (b, x) -> b.writeResourceLocation(x.location()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,27 @@

package dan200.computercraft.shared.turtle.upgrades;

import net.jqwik.api.Arbitraries;
import net.jqwik.api.Arbitrary;
import net.jqwik.api.Builders;
import net.jqwik.api.ForAll;
import net.jqwik.api.Property;
import net.jqwik.api.Provide;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleToolDurability;
import dan200.computercraft.test.core.StructuralEquality;
import dan200.computercraft.test.shared.MinecraftArbitraries;
import dan200.computercraft.test.shared.MinecraftEqualities;
import dan200.computercraft.test.shared.NetworkSupport;
import dan200.computercraft.test.shared.WithMinecraft;
import net.jqwik.api.*;
import net.minecraft.core.registries.Registries;

import javax.annotation.Nullable;

import static org.hamcrest.MatcherAssert.assertThat;

Expand All @@ -22,6 +34,67 @@ class TurtleToolSerialiserTest {
WithMinecraft.Setup.bootstrap(); // @Property doesn't run test lifecycle methods.
}

static class TurtleToolBuilder {
ResourceLocation id;
String adjective;
Item craftItem;
ItemStack toolItem;
float damageMulitiplier;
boolean allowEnchantments;
TurtleToolDurability consumeDurability;
@Nullable TagKey<Block> breakable;
String peripheralType;

public TurtleToolBuilder withId(ResourceLocation id) {
this.id = id;
return this;
}

public TurtleToolBuilder withAdjective(String adjective) {
this.adjective = adjective;
return this;
}

public TurtleToolBuilder withCraftItem(Item craftItem) {
this.craftItem = craftItem;
return this;
}

public TurtleToolBuilder withToolItem(ItemStack toolItem) {
this.toolItem = toolItem;
return this;
}

public TurtleToolBuilder withDamageMultiplier(float damageMulitiplier) {
this.damageMulitiplier = damageMulitiplier;
return this;
}

public TurtleToolBuilder withAllowEnchantments(boolean allowEnchantments) {
this.allowEnchantments = allowEnchantments;
return this;
}

public TurtleToolBuilder withConsumeDurability(TurtleToolDurability consumeDurability) {
this.consumeDurability = consumeDurability;
return this;
}

public TurtleToolBuilder withBreakable(@Nullable TagKey<Block> breakable) {
this.breakable = breakable;
return this;
}

public TurtleToolBuilder withPeripheralType(String peripheralType) {
this.peripheralType = peripheralType;
return this;
}

public TurtleTool build() {
return new TurtleTool(id, adjective, craftItem, toolItem, damageMulitiplier, allowEnchantments, consumeDurability, breakable, peripheralType);
}
}

/**
* Sends turtle tools on a roundtrip, ensuring that their contents are reassembled on the other end.
*
Expand All @@ -41,16 +114,18 @@ public void testRoundTrip(@ForAll("tool") TurtleTool tool) {

@Provide
Arbitrary<TurtleTool> tool() {
return Combinators.combine(
MinecraftArbitraries.resourceLocation(),
Arbitraries.strings().ofMaxLength(100),
MinecraftArbitraries.item(),
MinecraftArbitraries.itemStack(),
Arbitraries.floats(),
Arbitraries.of(true, false),
Arbitraries.of(TurtleToolDurability.values()),
MinecraftArbitraries.tagKey(Registries.BLOCK)
).as(TurtleTool::new);

return Builders.withBuilder(() -> new TurtleToolBuilder())
.use(MinecraftArbitraries.resourceLocation()).in((builder, resourceLocation) -> builder.withId(resourceLocation))
.use(Arbitraries.strings().ofMaxLength(100)).in((builder, adjective) -> builder.withAdjective(adjective))
.use(MinecraftArbitraries.item()).in((builder, craftItem) -> builder.withCraftItem(craftItem))
.use(MinecraftArbitraries.itemStack()).in((builder, toolItem) -> builder.withToolItem(toolItem))
.use(Arbitraries.floats()).in((builder, damageMulitiplier) -> builder.withDamageMultiplier(damageMulitiplier))
.use(Arbitraries.of(true, false)).in((builder, allowEnchantments) -> builder.withAllowEnchantments(allowEnchantments))
.use(Arbitraries.of(TurtleToolDurability.values())).in((builder, consumeDurability) -> builder.withConsumeDurability(consumeDurability))
.use(MinecraftArbitraries.tagKey(Registries.BLOCK)).in((builder, breakable) -> builder.withBreakable(breakable))
.use(Arbitraries.strings().ofMaxLength(100)).in((builder, peripheralType) -> builder.withPeripheralType(peripheralType))
.build(builder -> builder.build());
}

private static final StructuralEquality<TurtleTool> equality = StructuralEquality.all(
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading