Skip to content

Commit 57e2b35

Browse files
committed
Re-add infinite mode to Bridge/Door/Gate mechanics. Resolves #1370
1 parent 4e23206 commit 57e2b35

6 files changed

Lines changed: 129 additions & 10 deletions

File tree

craftbook-bukkit/src/main/java/org/enginehub/craftbook/mechanics/area/Bridge.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ public void onSignChange(SignChangeEvent event) {
9191
return;
9292
}
9393

94+
String signLine0 = PlainTextComponentSerializer.plainText().serialize(event.line(0));
95+
if (signLine0.equalsIgnoreCase("infinite") && !player.hasPermission("craftbook.bridge.create.infinite")) {
96+
if (CraftBook.getInstance().getPlatform().getConfiguration().showPermissionMessages) {
97+
player.printError(TranslatableComponent.of(
98+
"craftbook.bridge.infinite-permissions"
99+
));
100+
}
101+
SignUtil.cancelSignChange(event);
102+
return;
103+
}
104+
94105
if (signLine1.equalsIgnoreCase("[bridge]")) {
95106
event.line(1, Component.text("[Bridge]"));
96107
player.printInfo(TranslatableComponent.of("craftbook.bridge.create"));

craftbook-bukkit/src/main/java/org/enginehub/craftbook/mechanics/area/CuboidToggleMechanic.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public boolean close(Sign sign, Sign farSide, BlockData blockData, CuboidRegion
6767
Block b = sign.getWorld().getBlockAt(bv.x(), bv.y(), bv.z());
6868
if (BlockUtil.isBlockReplacable(b.getType())) {
6969
if (CraftBook.getInstance().getPlatform().getConfiguration().safeDestruction) {
70-
if (getStoredBlockCounts(sign, farSide) > 0) {
70+
if (hasRequiredBlockCounts(1, sign, farSide)) {
7171
b.setBlockData(blockData);
7272
takeFromStoredBlockCounts(getCostOfBlock(blockData), sign, farSide);
7373
} else {

craftbook-bukkit/src/main/java/org/enginehub/craftbook/mechanics/area/Door.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ public void onSignChange(SignChangeEvent event) {
9292
return;
9393
}
9494

95+
String signLine0 = PlainTextComponentSerializer.plainText().serialize(event.line(0));
96+
if (signLine0.equalsIgnoreCase("infinite") && !player.hasPermission("craftbook.door.create.infinite")) {
97+
if (CraftBook.getInstance().getPlatform().getConfiguration().showPermissionMessages) {
98+
player.printError(TranslatableComponent.of(
99+
"craftbook.door.infinite-permissions"
100+
));
101+
}
102+
SignUtil.cancelSignChange(event);
103+
return;
104+
}
105+
95106
if (signLine1.equalsIgnoreCase("[door]")) {
96107
event.line(1, Component.text("[Door]"));
97108
player.printInfo(TranslatableComponent.of("craftbook.door.end-create"));

craftbook-bukkit/src/main/java/org/enginehub/craftbook/mechanics/area/Gate.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,7 @@ private boolean toggleColumn(@Nullable BukkitChangedSign sign, GateColumn column
205205
}
206206

207207
if (CraftBook.getInstance().getPlatform().getConfiguration().safeDestruction) {
208-
int blockCount = getStoredBlockCounts(sign.getSign(), otherSign);
209-
if (!close || blockCount > 0) {
208+
if (!close || hasRequiredBlockCounts(1, sign.getSign(), otherSign)) {
210209
boolean transactionSuccess = false;
211210
if (!close && bloType == expectedType) {
212211
transactionSuccess = addToStoredBlockCount(sign.getSign(), 1);
@@ -368,6 +367,17 @@ public void onSignChange(SignChangeEvent event) {
368367
return;
369368
}
370369

370+
String signLine0 = PlainTextComponentSerializer.plainText().serialize(event.line(0));
371+
if (signLine0.equalsIgnoreCase("infinite") && !player.hasPermission("craftbook.gate.create.infinite")) {
372+
if (CraftBook.getInstance().getPlatform().getConfiguration().showPermissionMessages) {
373+
player.printError(TranslatableComponent.of(
374+
"craftbook.gate.infinite-permissions"
375+
));
376+
}
377+
SignUtil.cancelSignChange(event);
378+
return;
379+
}
380+
371381
event.line(1, Component.text("[Gate]"));
372382
player.printInfo(TranslatableComponent.of("craftbook.gate.create"));
373383
}

craftbook-bukkit/src/main/java/org/enginehub/craftbook/mechanics/area/StoredBlockMechanic.java

Lines changed: 91 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.sk89q.worldedit.bukkit.BukkitAdapter;
1919
import com.sk89q.worldedit.util.formatting.text.TextComponent;
2020
import com.sk89q.worldedit.world.block.BlockType;
21+
import net.kyori.adventure.text.Component;
2122
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
2223
import org.bukkit.Material;
2324
import org.bukkit.NamespacedKey;
@@ -55,6 +56,7 @@ public abstract class StoredBlockMechanic extends AbstractCraftBookMechanic impl
5556

5657
private final NamespacedKey storedBlockTypeKey = new NamespacedKey("craftbook", "toggle_block_type");
5758
private final NamespacedKey storedBlockQuantityKey = new NamespacedKey("craftbook", "toggle_block_quantity");
59+
protected final static int INFINITE_SENTINEL = Integer.MIN_VALUE;
5860

5961
public StoredBlockMechanic(MechanicType<? extends CraftBookMechanic> mechanicType) {
6062
super(mechanicType);
@@ -165,10 +167,10 @@ public void onPipeSuck(PipeSuckEvent event) {
165167
List<ItemStack> items = event.getItems();
166168
try {
167169
Material base = getOrSetStoredType(event.getSuckedBlock());
168-
int blocks = getStoredBlockCount(sign);
170+
int blocks = getStoredBlockCounts(sign);
169171
if (blocks > 0) {
170172
items.add(new ItemStack(base, blocks));
171-
setStoredBlockCount(sign, 0);
173+
takeFromStoredBlockCounts(blocks, sign);
172174
}
173175
event.setItems(items);
174176
} catch (InvalidMechanismException e) {
@@ -194,9 +196,10 @@ public void onBlockBreak(BlockBreakEvent event) {
194196
}
195197

196198
CraftBookPlayer player = CraftBookPlugin.inst().wrapPlayer(event.getPlayer());
197-
int amount = getStoredBlockCounts(sign);
199+
int amount = getStoredBlockCount(sign);
198200

199-
if (amount > 0) {
201+
//noinspection ConstantValue
202+
if (amount > 0 && amount != INFINITE_SENTINEL) {
200203
try {
201204
Material base = getOrSetStoredType(event.getBlock());
202205
while (amount > 0) {
@@ -248,6 +251,9 @@ public boolean takeFromStoredBlockCounts(int amount, @Nullable Sign... signs) {
248251
continue;
249252
}
250253
int stored = getStoredBlockCount(sign);
254+
if (stored == INFINITE_SENTINEL) {
255+
return true;
256+
}
251257
if (stored >= amount) {
252258
return setStoredBlockCount(sign, stored - amount);
253259
} else {
@@ -278,6 +284,11 @@ public boolean addToStoredBlockCount(Sign sign, int amount) {
278284
* If `enforce-type` is set, it will only return the amount of blocks of the type stored in the first sign.
279285
* </p>
280286
*
287+
* <p>
288+
* Only use this when getting actual physical blocks, it will not count infinite signs.
289+
* Use {@link #hasRequiredBlockCounts(int, Sign...)} for quantity checks.
290+
* </p>
291+
*
281292
* @param signs The list of signs
282293
* @return The stored block count
283294
*/
@@ -292,38 +303,111 @@ public int getStoredBlockCounts(@Nullable Sign... signs) {
292303
int sum = 0;
293304
for (Sign sign : signs) {
294305
if (sign != null && getStoredType(sign) == type) {
295-
sum += getStoredBlockCount(sign);
306+
int stored = getStoredBlockCount(sign);
307+
if (stored == INFINITE_SENTINEL) {
308+
// Skip infinite signs in this data.
309+
continue;
310+
}
311+
sum += stored;
296312
}
297313
}
298314

299315
return sum;
300316
}
301317

318+
/**
319+
* Checks whether the given signs contain enough blocks to meet the given count.
320+
*
321+
* @param count The count to check for
322+
* @param signs The list of signs
323+
* @return Whether the signs contain more or equal to count
324+
*/
325+
public boolean hasRequiredBlockCounts(int count, @Nullable Sign... signs) {
326+
if (count <= 0) {
327+
// Short-circuit if something asks for no blocks for whatever reason.
328+
return true;
329+
}
330+
if (signs.length == 0 || signs[0] == null) {
331+
return false;
332+
}
333+
334+
Material type = getStoredType(signs[0]);
335+
336+
int sum = 0;
337+
for (Sign sign : signs) {
338+
if (sign != null && getStoredType(sign) == type) {
339+
int stored = getStoredBlockCount(sign);
340+
if (stored == INFINITE_SENTINEL) {
341+
// Infinite means this is always true.
342+
return true;
343+
}
344+
sum += stored;
345+
}
346+
}
347+
348+
return count >= sum;
349+
}
350+
302351
/**
303352
* Gets the number of stored blocks within this sign.
304353
*
354+
* <p>
355+
* This gets the raw data, use {@link #getStoredBlockCounts(Sign...)} instead.
356+
* </p>
357+
*
305358
* @param sign The sign
306359
* @return The stored block count
307360
*/
308-
public int getStoredBlockCount(Sign sign) {
361+
private int getStoredBlockCount(Sign sign) {
309362
if (sign.getPersistentDataContainer().has(storedBlockQuantityKey, PersistentDataType.INTEGER)) {
310363
//noinspection DataFlowIssue
311364
return sign.getPersistentDataContainer().get(storedBlockQuantityKey, PersistentDataType.INTEGER);
312365
}
366+
for (Side side : Side.values()) {
367+
String signLine0 = PlainTextComponentSerializer.plainText().serialize(sign.getSide(side).line(0));
368+
if (signLine0.equals("infinite")) {
369+
// Persist infinite data to internal data.
370+
sign.getSide(side).line(0, Component.text(""));
371+
sign.getPersistentDataContainer().set(storedBlockQuantityKey, PersistentDataType.INTEGER, INFINITE_SENTINEL);
372+
sign.update(false, false);
373+
return INFINITE_SENTINEL;
374+
}
375+
}
313376
return 0;
314377
}
315378

379+
/**
380+
* Gets whether this sign contains infinite blocks.
381+
*
382+
* @param sign The sign to check
383+
* @return Whether it contains infinite blocks
384+
*/
385+
private boolean hasInfiniteBlockCount(Sign sign) {
386+
int count = getStoredBlockCount(sign);
387+
return count == INFINITE_SENTINEL;
388+
}
389+
316390
/**
317391
* Sets the stored block count within this sign.
318392
*
393+
* <p>
394+
* This sets the raw data, use {@link #takeFromStoredBlockCounts(int, Sign...)} instead.
395+
* </p>
396+
*
319397
* @param sign The sign
320398
* @param count The count
321399
* @return If the count was set
322400
*/
323-
public boolean setStoredBlockCount(Sign sign, int count) {
401+
private boolean setStoredBlockCount(Sign sign, int count) {
324402
if (count < 0) {
325403
return false;
326404
}
405+
406+
if (hasInfiniteBlockCount(sign)) {
407+
// Don't modify the count if it's infinite, to avoid accidentally making it finite.
408+
return true;
409+
}
410+
327411
sign.getPersistentDataContainer().set(storedBlockQuantityKey, PersistentDataType.INTEGER, count);
328412
return true;
329413
}

craftbook-core/src/main/resources/lang/strings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"craftbook.bridge.too-short": "This bridge is too short to activate",
3838
"craftbook.bridge.restock": "You restock the bridge",
3939
"craftbook.bridge.restock-permissions": "You don't have permission to restock bridges",
40+
"craftbook.bridge.infinite-permissions": "You don't have permission to create infinite bridges",
4041
"craftbook.bridge.unusable-material": "This material cannot be used to make a bridge",
4142

4243
"craftbook.chairs.description": "Allows sitting on stair blocks.",
@@ -63,6 +64,7 @@
6364
"craftbook.door.missing-other-sign": "Door sign required on other side (or it was too far away).",
6465
"craftbook.door.not-enough-blocks": "Not enough blocks to construct this door (try restocking?)",
6566
"craftbook.door.restock-permissions": "You don't have permission to restock doors",
67+
"craftbook.door.infinite-permissions": "You don't have permission to create infinite doors",
6668
"craftbook.door.restock": "You restock the door",
6769
"craftbook.door.toggle": "You activate the door",
6870
"craftbook.door.too-short": "This door is too short to activate",
@@ -85,6 +87,7 @@
8587
"craftbook.gate.description": "Create gates that can be opened and closed by players or redstone.",
8688
"craftbook.gate.not-enough-blocks": "Not enough blocks to construct this gate (try restocking?)",
8789
"craftbook.gate.restock-permissions": "You don't have permission to restock gates",
90+
"craftbook.gate.infinite-permissions": "You don't have permission to create infinite gates",
8891
"craftbook.gate.restock": "You restock the gate",
8992
"craftbook.gate.not-found": "No gate was found (is it too far away?)",
9093
"craftbook.gate.toggle": "You activate the gate",

0 commit comments

Comments
 (0)