Skip to content

Commit 5263ede

Browse files
committed
Merge branch 'refs/heads/dev/1.19.2' into feat/tests
2 parents 2c4c172 + 1309b60 commit 5263ede

File tree

12 files changed

+276
-38
lines changed

12 files changed

+276
-38
lines changed

src/main/java/de/srendi/advancedperipherals/common/addons/botania/ManaFlowerIntegration.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import net.minecraft.world.level.block.entity.BlockEntity;
66
import org.jetbrains.annotations.NotNull;
77
import vazkii.botania.api.block_entity.GeneratingFlowerBlockEntity;
8+
import vazkii.botania.common.block.BotaniaBlocks;
89

910
public class ManaFlowerIntegration extends BlockEntityIntegrationPeripheral<GeneratingFlowerBlockEntity> {
1011

@@ -35,6 +36,14 @@ public final int getMana() {
3536

3637
@LuaFunction(mainThread = true)
3738
public final boolean isOnEnchantedSoil() {
38-
return blockEntity.overgrowth;
39+
return isOnSpecialSoil();
40+
}
41+
42+
private boolean isOnSpecialSoil() {
43+
if (blockEntity.isFloating()) {
44+
return false;
45+
} else {
46+
return blockEntity.getLevel().getBlockState(blockEntity.getBlockPos().below()).is(BotaniaBlocks.enchantedSoil);
47+
}
3948
}
4049
}

src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/operations/SingleOperation.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ public enum SingleOperation implements IPeripheralOperation<SingleOperationConte
1313
SUCK(1000, 1),
1414
USE_ON_ANIMAL(2500, 10),
1515
CAPTURE_ANIMAL(50_000, 100),
16-
WARP(1000, DistancePolicy.IGNORED, CountPolicy.MULTIPLY, 1, DistancePolicy.SQRT, CountPolicy.MULTIPLY);
16+
WARP(1000, DistancePolicy.IGNORED, CountPolicy.MULTIPLY, 1, DistancePolicy.SQRT, CountPolicy.MULTIPLY),
17+
ACCURE_PLACE(1000, DistancePolicy.IGNORED, CountPolicy.MULTIPLY, 1, DistancePolicy.LINEAR, CountPolicy.MULTIPLY);
1718

1819
private final int defaultCooldown;
1920
private final DistancePolicy distanceCooldownPolicy;
@@ -74,6 +75,7 @@ public void addToConfig(ForgeConfigSpec.Builder builder) {
7475

7576
public enum DistancePolicy {
7677
IGNORED(d -> 1),
78+
LINEAR(d -> d),
7779
SQRT(d -> (int) Math.sqrt(d));
7880

7981
private final Function<Integer, Integer> factorFunction;

src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/TurtlePeripheralOwner.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,10 @@ public Direction getFacing() {
5555
return turtle.getDirection();
5656
}
5757

58-
/**
59-
* Not used for turtles
60-
*/
6158
@NotNull
6259
@Override
6360
public FrontAndTop getOrientation() {
64-
return FrontAndTop.NORTH_UP;
61+
return FrontAndTop.fromFrontAndTop(getFacing(), Direction.UP);
6562
}
6663

6764
@Nullable

src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ChatBoxPeripheral.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import de.srendi.advancedperipherals.common.configuration.APConfig;
1919
import de.srendi.advancedperipherals.common.events.Events;
2020
import de.srendi.advancedperipherals.common.util.CoordUtil;
21+
import de.srendi.advancedperipherals.common.util.StringUtil;
2122
import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral;
2223
import de.srendi.advancedperipherals.lib.peripherals.IPeripheralFunction;
2324
import de.srendi.advancedperipherals.network.APNetworking;
@@ -121,9 +122,9 @@ public final MethodResult sendFormattedMessage(@NotNull IArguments arguments) th
121122
return MethodResult.of(null, "incorrect bracket string (e.g. [], {}, <>, ...)");
122123

123124
MutableComponent preparedMessage = appendPrefix(
124-
arguments.optString(1, APConfig.PERIPHERALS_CONFIG.defaultChatBoxPrefix.get()).replaceAll("&", "\u00a7"),
125+
StringUtil.convertAndToSectionMark(arguments.optString(1, APConfig.PERIPHERALS_CONFIG.defaultChatBoxPrefix.get())),
125126
arguments.optString(2, "[]"),
126-
arguments.optString(3, "").replaceAll("&", "\u00a7")
127+
StringUtil.convertAndToSectionMark(arguments.optString(3, ""))
127128
).append(component);
128129
for (ServerPlayer player : ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayers()) {
129130
if (!APConfig.PERIPHERALS_CONFIG.chatBoxMultiDimensional.get() && player.getLevel().dimension() != dimension)
@@ -147,9 +148,9 @@ public final MethodResult sendMessage(@NotNull IArguments arguments) throws LuaE
147148
return MethodResult.of(null, "incorrect bracket string (e.g. [], {}, <>, ...)");
148149

149150
MutableComponent preparedMessage = appendPrefix(
150-
arguments.optString(1, APConfig.PERIPHERALS_CONFIG.defaultChatBoxPrefix.get()).replaceAll("&", "\u00a7"),
151+
StringUtil.convertAndToSectionMark(arguments.optString(1, APConfig.PERIPHERALS_CONFIG.defaultChatBoxPrefix.get())),
151152
arguments.optString(2, "[]"),
152-
arguments.optString(3, "").replaceAll("&", "\u00a7")
153+
StringUtil.convertAndToSectionMark(arguments.optString(3, ""))
153154
).append(message);
154155
for (ServerPlayer player : ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayers()) {
155156
if (!APConfig.PERIPHERALS_CONFIG.chatBoxMultiDimensional.get() && player.getLevel().dimension() != dimension)
@@ -182,9 +183,9 @@ public final MethodResult sendFormattedMessageToPlayer(@NotNull IArguments argum
182183
return MethodResult.of(null, "incorrect bracket string (e.g. [], {}, <>, ...)");
183184

184185
MutableComponent preparedMessage = appendPrefix(
185-
arguments.optString(2, APConfig.PERIPHERALS_CONFIG.defaultChatBoxPrefix.get()).replaceAll("&", "\u00a7"),
186+
StringUtil.convertAndToSectionMark(arguments.optString(2, APConfig.PERIPHERALS_CONFIG.defaultChatBoxPrefix.get())),
186187
arguments.optString(3, "[]"),
187-
arguments.optString(4, "").replaceAll("&", "\u00a7")
188+
StringUtil.convertAndToSectionMark(arguments.optString(4, ""))
188189
).append(component);
189190
if (!APConfig.PERIPHERALS_CONFIG.chatBoxMultiDimensional.get() && player.getLevel().dimension() != dimension)
190191
return MethodResult.of(false, "NOT_SAME_DIMENSION");
@@ -222,9 +223,9 @@ public final MethodResult sendFormattedToastToPlayer(@NotNull IArguments argumen
222223
return MethodResult.of(null, "incorrect bracket string (e.g. [], {}, <>, ,,,)");
223224

224225
MutableComponent preparedMessage = appendPrefix(
225-
arguments.optString(3, APConfig.PERIPHERALS_CONFIG.defaultChatBoxPrefix.get()).replaceAll("&", "\u00a7"),
226+
StringUtil.convertAndToSectionMark(arguments.optString(3, APConfig.PERIPHERALS_CONFIG.defaultChatBoxPrefix.get())),
226227
arguments.optString(4, "[]"),
227-
arguments.optString(5, "").replaceAll("&", "\u00a7")
228+
StringUtil.convertAndToSectionMark(arguments.optString(5, ""))
228229
).append(messageComponent);
229230

230231
if (!APConfig.PERIPHERALS_CONFIG.chatBoxMultiDimensional.get() && player.getLevel().dimension() != dimension)
@@ -256,9 +257,9 @@ public final MethodResult sendMessageToPlayer(@NotNull IArguments arguments) thr
256257
return MethodResult.of(null, "incorrect bracket string (e.g. [], {}, <>, ...)");
257258

258259
MutableComponent preparedMessage = appendPrefix(
259-
arguments.optString(2, APConfig.PERIPHERALS_CONFIG.defaultChatBoxPrefix.get()).replaceAll("&", "\u00a7"),
260+
StringUtil.convertAndToSectionMark(arguments.optString(2, APConfig.PERIPHERALS_CONFIG.defaultChatBoxPrefix.get())),
260261
arguments.optString(3, "[]"),
261-
arguments.optString(4, "").replaceAll("&", "\u00a7")
262+
StringUtil.convertAndToSectionMark(arguments.optString(4, ""))
262263
).append(message);
263264
if (!APConfig.PERIPHERALS_CONFIG.chatBoxMultiDimensional.get() && player.getLevel().dimension() != dimension)
264265
return MethodResult.of(false, "NOT_SAME_DIMENSION");
@@ -287,9 +288,9 @@ public final MethodResult sendToastToPlayer(@NotNull IArguments arguments) throw
287288
return MethodResult.of(null, "incorrect bracket string (e.g. [], {}, <>, ...)");
288289

289290
MutableComponent preparedMessage = appendPrefix(
290-
arguments.optString(3, APConfig.PERIPHERALS_CONFIG.defaultChatBoxPrefix.get()).replaceAll("&", "\u00a7"),
291+
StringUtil.convertAndToSectionMark(arguments.optString(3, APConfig.PERIPHERALS_CONFIG.defaultChatBoxPrefix.get())),
291292
arguments.optString(4, "[]"),
292-
arguments.optString(5, "").replaceAll("&", "\u00a7")
293+
StringUtil.convertAndToSectionMark(arguments.optString(5, ""))
293294
).append(message);
294295

295296
if (!APConfig.PERIPHERALS_CONFIG.chatBoxMultiDimensional.get() && player.getLevel().dimension() != dimension)

src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/CompassPeripheral.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ public class CompassPeripheral extends BasePeripheral<TurtlePeripheralOwner> {
1111

1212
public static final String PERIPHERAL_TYPE = "compass";
1313

14+
protected CompassPeripheral(TurtlePeripheralOwner owner) {
15+
super(PERIPHERAL_TYPE, owner);
16+
}
17+
1418
public CompassPeripheral(ITurtleAccess turtle, TurtleSide side) {
15-
super(PERIPHERAL_TYPE, new TurtlePeripheralOwner(turtle, side));
19+
this(new TurtlePeripheralOwner(turtle, side));
1620
}
1721

1822
@Override

src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataBlockHandPlugin.java

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,47 @@
44
import dan200.computercraft.api.lua.LuaException;
55
import dan200.computercraft.api.lua.LuaFunction;
66
import dan200.computercraft.api.lua.MethodResult;
7+
import dan200.computercraft.api.turtle.ITurtleAccess;
8+
import dan200.computercraft.api.turtle.TurtleSide;
79
import dan200.computercraft.core.apis.TableHelper;
10+
import dan200.computercraft.shared.turtle.core.TurtlePlayer;
11+
import de.srendi.advancedperipherals.common.addons.computercraft.operations.SingleOperationContext;
812
import de.srendi.advancedperipherals.common.addons.computercraft.owner.TurtlePeripheralOwner;
13+
import de.srendi.advancedperipherals.common.addons.computercraft.peripheral.CompassPeripheral;
14+
import de.srendi.advancedperipherals.common.configuration.APConfig;
915
import de.srendi.advancedperipherals.common.util.Pair;
16+
import de.srendi.advancedperipherals.common.util.StringUtil;
1017
import de.srendi.advancedperipherals.common.util.fakeplayer.APFakePlayer;
1118
import de.srendi.advancedperipherals.lib.peripherals.AutomataCorePeripheral;
1219
import de.srendi.advancedperipherals.lib.peripherals.IPeripheralOperation;
20+
import net.minecraft.core.BlockPos;
21+
import net.minecraft.core.Direction;
22+
import net.minecraft.network.chat.Component;
23+
import net.minecraft.world.InteractionHand;
1324
import net.minecraft.world.InteractionResult;
25+
import net.minecraft.world.item.BlockItem;
26+
import net.minecraft.world.item.Item;
1427
import net.minecraft.world.item.ItemStack;
28+
import net.minecraft.world.item.SignItem;
29+
import net.minecraft.world.item.context.DirectionalPlaceContext;
30+
import net.minecraft.world.level.block.Block;
31+
import net.minecraft.world.level.block.entity.BlockEntity;
32+
import net.minecraft.world.level.block.entity.SignBlockEntity;
33+
import net.minecraft.world.level.Level;
34+
import net.minecraft.world.phys.BlockHitResult;
35+
import net.minecraft.world.phys.Vec3;
36+
import net.minecraftforge.common.ForgeHooks;
37+
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
1538

1639
import org.jetbrains.annotations.NotNull;
1740
import org.jetbrains.annotations.Nullable;
1841
import java.util.Collections;
1942
import java.util.Map;
43+
import java.util.stream.Stream;
2044

2145
import static de.srendi.advancedperipherals.common.addons.computercraft.operations.SingleOperation.DIG;
2246
import static de.srendi.advancedperipherals.common.addons.computercraft.operations.SingleOperation.USE_ON_BLOCK;
47+
import static de.srendi.advancedperipherals.common.addons.computercraft.operations.SingleOperation.ACCURE_PLACE;
2348

2449
public class AutomataBlockHandPlugin extends AutomataCorePlugin {
2550

@@ -71,4 +96,139 @@ public final MethodResult useOnBlock(@NotNull IArguments arguments) throws LuaEx
7196
});
7297
}
7398

99+
/**
100+
* placeBlock method will let turtle place a block with more details when compass has equipped.
101+
* It should not able to place fluids / use any item, because compass do not recognize them.
102+
*
103+
* @param options A table contains how to place the block:
104+
* x: the x offset relative to the turtle. Default 0
105+
* y: the y offset relative to the turtle. Default 0
106+
* z: the z offset relative to the turtle. Default 0
107+
* anchor: the direction the block is going to hanging on. Default is the direction of the turtle
108+
* front: the direction the block is going to facing. Default is same as anchor
109+
* top: the direction the block's top is going to facing. Default is TOP
110+
* text: the text going to write on the sign. Default is null
111+
*/
112+
@LuaFunction(mainThread = true)
113+
public MethodResult placeBlock(@NotNull Map<?, ?> options) throws LuaException {
114+
ITurtleAccess turtle = automataCore.getPeripheralOwner().getTurtle();
115+
CompassPeripheral compassPeripheral = Stream.of(TurtleSide.values()).map(side -> turtle.getPeripheral(side) instanceof CompassPeripheral compass ? compass : null).filter(peripheral -> peripheral != null).findFirst().orElse(null);
116+
if (compassPeripheral == null || !compassPeripheral.isEnabled()) {
117+
return MethodResult.of(false, "COMPASS_NOT_EQUIPPED");
118+
}
119+
int x = TableHelper.optIntField(options, "x", 0);
120+
int y = TableHelper.optIntField(options, "y", 0);
121+
int z = TableHelper.optIntField(options, "z", 0);
122+
final int maxDist = APConfig.PERIPHERALS_CONFIG.compassAccurePlaceRadius.get();
123+
final int freeDist = APConfig.PERIPHERALS_CONFIG.compassAccurePlaceFreeRadius.get();
124+
if (Math.abs(x) > maxDist || Math.abs(y) > maxDist || Math.abs(z) > maxDist) {
125+
return MethodResult.of(null, "OUT_OF_RANGE");
126+
}
127+
String anchor = TableHelper.optStringField(options, "anchor", null);
128+
String front = TableHelper.optStringField(options, "front", null);
129+
String top = TableHelper.optStringField(options, "top", null);
130+
Direction anchorDir = anchor != null ? automataCore.validateSide(anchor) : null;
131+
Direction frontDir = front != null ? automataCore.validateSide(front) : null;
132+
Direction topDir = top != null ? automataCore.validateSide(top) : null;
133+
134+
int distance =
135+
Math.max(0, Math.abs(x) - freeDist) +
136+
Math.max(0, Math.abs(y) - freeDist) +
137+
Math.max(0, Math.abs(z) - freeDist);
138+
return automataCore.withOperation(ACCURE_PLACE, new SingleOperationContext(1, distance), context -> {
139+
ItemStack stack = turtle.getInventory().getItem(turtle.getSelectedSlot());
140+
if (stack.isEmpty()) {
141+
return MethodResult.of(null, "EMPTY_SLOT");
142+
}
143+
BlockPos position = turtle.getPosition().offset(x, y, z);
144+
String err = deployOn(stack, position, anchorDir, frontDir, topDir, options);
145+
if (err != null) {
146+
return MethodResult.of(null, err);
147+
}
148+
return MethodResult.of(true);
149+
}, null);
150+
}
151+
152+
/**
153+
* @return A nullable string of the error. <code>null</code> means the operation is successful
154+
*/
155+
@Nullable
156+
private String deployOn(ItemStack stack, BlockPos position, Direction anchor, Direction front, Direction top, Map<?, ?> options) throws LuaException {
157+
ITurtleAccess turtle = automataCore.getPeripheralOwner().getTurtle();
158+
Level world = turtle.getLevel();
159+
if (anchor == null) {
160+
anchor = turtle.getDirection();
161+
}
162+
if (front == null) {
163+
front = anchor;
164+
}
165+
if (top == null) {
166+
top = Direction.UP;
167+
}
168+
TurtlePlayer turtlePlayer = TurtlePlayer.getWithPosition(turtle, position, front.getOpposite());
169+
BlockHitResult hit = BlockHitResult.miss(Vec3.atCenterOf(position), top, position);
170+
AdvanceDirectionalPlaceContext context = new AdvanceDirectionalPlaceContext(world, position, anchor, front, stack, top);
171+
PlayerInteractEvent.RightClickBlock event = ForgeHooks.onRightClickBlock(turtlePlayer, InteractionHand.MAIN_HAND, position, hit);
172+
if (event.isCanceled()) {
173+
return "EVENT_CANCELED";
174+
}
175+
Item item = stack.getItem();
176+
if (!(item instanceof BlockItem)) {
177+
return "NOT_BLOCK";
178+
}
179+
BlockItem block = (BlockItem) item;
180+
InteractionResult res = block.place(context);
181+
if (!res.consumesAction()) {
182+
return "CANNOT_PLACE";
183+
}
184+
if (block instanceof SignItem) {
185+
BlockEntity blockEntity = world.getBlockEntity(position);
186+
if (blockEntity instanceof SignBlockEntity sign) {
187+
String text = StringUtil.convertAndToSectionMark(TableHelper.optStringField(options, "text", null));
188+
setSignText(world, sign, text);
189+
}
190+
}
191+
return null;
192+
}
193+
194+
private static void setSignText(Level world, SignBlockEntity sign, String text) {
195+
if (text == null) {
196+
for (int i = 0; i < SignBlockEntity.LINES; i++) {
197+
sign.setMessage(i, Component.literal(""));
198+
}
199+
} else {
200+
String[] lines = text.split("\n");
201+
for (int i = 0; i < SignBlockEntity.LINES; i++) {
202+
sign.setMessage(i, Component.literal(i < lines.length ? lines[i] : ""));
203+
}
204+
}
205+
sign.setChanged();
206+
world.sendBlockUpdated(sign.getBlockPos(), sign.getBlockState(), sign.getBlockState(), Block.UPDATE_ALL);
207+
}
208+
209+
private static class AdvanceDirectionalPlaceContext extends DirectionalPlaceContext {
210+
private final Direction anchor;
211+
212+
AdvanceDirectionalPlaceContext(Level world, BlockPos pos, Direction anchor, Direction front, ItemStack stack, Direction top) {
213+
super(world, pos, front, stack, top);
214+
this.anchor = anchor;
215+
}
216+
217+
@Override
218+
public Direction getNearestLookingDirection() {
219+
return this.anchor;
220+
}
221+
222+
@Override
223+
public Direction[] getNearestLookingDirections() {
224+
return switch (this.anchor) {
225+
case DOWN -> new Direction[]{Direction.DOWN, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP};
226+
case UP -> new Direction[]{Direction.UP, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.DOWN};
227+
case NORTH -> new Direction[]{Direction.NORTH, Direction.EAST, Direction.WEST, Direction.UP, Direction.DOWN, Direction.SOUTH};
228+
case SOUTH -> new Direction[]{Direction.SOUTH, Direction.EAST, Direction.WEST, Direction.UP, Direction.DOWN, Direction.NORTH};
229+
case WEST -> new Direction[]{Direction.WEST, Direction.SOUTH, Direction.UP, Direction.NORTH, Direction.DOWN, Direction.EAST};
230+
case EAST -> new Direction[]{Direction.EAST, Direction.SOUTH, Direction.UP, Direction.NORTH, Direction.DOWN, Direction.WEST};
231+
};
232+
}
233+
}
74234
}

src/main/java/de/srendi/advancedperipherals/common/configuration/GeneralConfig.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ public class GeneralConfig implements IAPConfig {
2323

2424
LibConfig.build(builder);
2525

26+
builder.pop();
27+
builder.push("Unsafe");
28+
29+
UnsafeConfig.build(builder);
30+
2631
builder.pop();
2732

2833
configSpec = builder.build();

0 commit comments

Comments
 (0)