Closes: #132 Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
Ursprung
f854f4896f
Commit
e247dbe8f3
@ -1244,6 +1244,8 @@ SELECT_ITEM_TESTBLOCK=§eDummy
|
|||||||
CHESTFILLER_FILLED = §eChest filled
|
CHESTFILLER_FILLED = §eChest filled
|
||||||
CHESTFILLER_COUNT = §7{0}§8: §e§l{1}
|
CHESTFILLER_COUNT = §7{0}§8: §e§l{1}
|
||||||
|
|
||||||
|
PISTON_INFO = §7Moved Blocks {0}{1}§8/§712
|
||||||
|
|
||||||
# Warp
|
# Warp
|
||||||
WARP_DISALLOWED = §cYou are not allowed to use the warp here
|
WARP_DISALLOWED = §cYou are not allowed to use the warp here
|
||||||
WARP_LOC_X = §7X§8: §e{0}
|
WARP_LOC_X = §7X§8: §e{0}
|
||||||
|
@ -1223,6 +1223,8 @@ SELECT_ITEM_TESTBLOCK=§eTestblock
|
|||||||
|
|
||||||
CHESTFILLER_FILLED = §eKiste gefüllt
|
CHESTFILLER_FILLED = §eKiste gefüllt
|
||||||
|
|
||||||
|
PISTON_INFO = §7Bewegte Blöcke {0}{1}§8/§712
|
||||||
|
|
||||||
# Warp
|
# Warp
|
||||||
WARP_DISALLOWED = §cDu darfst hier nicht das Warp System nutzen
|
WARP_DISALLOWED = §cDu darfst hier nicht das Warp System nutzen
|
||||||
WARP_LOC_X = §7X§8: §e{0}
|
WARP_LOC_X = §7X§8: §e{0}
|
||||||
|
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.features.util;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.BauSystem;
|
||||||
|
import de.steamwar.bausystem.linkage.LinkageType;
|
||||||
|
import de.steamwar.bausystem.linkage.Linked;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.block.PistonMoveReaction;
|
||||||
|
import org.bukkit.block.TileState;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.block.data.type.Piston;
|
||||||
|
import org.bukkit.block.data.type.PistonHead;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
@Linked(LinkageType.LISTENER)
|
||||||
|
public class PistonCalculator implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
|
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
|
||||||
|
if (event.getPlayer().getInventory().getItemInMainHand().getType() != Material.SLIME_BALL) return;
|
||||||
|
if (event.getClickedBlock() == null) return;
|
||||||
|
Block clickedBlock = event.getClickedBlock();
|
||||||
|
Material blockType = clickedBlock.getType();
|
||||||
|
if (!(blockType == Material.PISTON || blockType == Material.STICKY_PISTON)) return;
|
||||||
|
Piston piston = (Piston) clickedBlock.getBlockData();
|
||||||
|
|
||||||
|
boolean pulling = blockType == Material.STICKY_PISTON && (clickedBlock.getRelative(piston.getFacing()).getType() == Material.AIR || piston.isExtended());
|
||||||
|
|
||||||
|
CalculationResult result = calc(clickedBlock, piston.getFacing(), (pulling ? piston.getFacing().getOppositeFace() : piston.getFacing()));
|
||||||
|
BauSystem.MESSAGE.sendPrefixless("PISTON_INFO", event.getPlayer(), ChatMessageType.ACTION_BAR, result.unmovable ? "§c" : (result.tooMany ? "§e" : "§a"), result.amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BlockFace[] FACES = new BlockFace[]{BlockFace.UP, BlockFace.DOWN, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST};
|
||||||
|
|
||||||
|
private CalculationResult calc(Block origin, BlockFace facing, BlockFace direction) {
|
||||||
|
Set<Block> blockSet = new HashSet<>();
|
||||||
|
AtomicBoolean unmovable = new AtomicBoolean();
|
||||||
|
|
||||||
|
Block calcOrigin = origin;
|
||||||
|
if (facing != direction) calcOrigin = origin.getRelative(facing, 3);
|
||||||
|
|
||||||
|
List<Block> toCalc = new LinkedList<>();
|
||||||
|
calcDirection(origin, calcOrigin, facing != direction ? origin.getRelative(facing) : null, facing, direction, blockSet, toCalc, unmovable);
|
||||||
|
|
||||||
|
while (!toCalc.isEmpty()) {
|
||||||
|
Block current = toCalc.remove(0);
|
||||||
|
blockSet.add(current);
|
||||||
|
|
||||||
|
Material type = current.getType();
|
||||||
|
if (type != Material.SLIME_BLOCK && type != Material.HONEY_BLOCK) continue;
|
||||||
|
Material oppositeType = type == Material.SLIME_BLOCK ? Material.HONEY_BLOCK : Material.SLIME_BLOCK;
|
||||||
|
|
||||||
|
for (BlockFace face : FACES) {
|
||||||
|
Block block = current.getRelative(face);
|
||||||
|
if (block.getType().isAir()) continue;
|
||||||
|
if (!isPiston(block) && (block.getPistonMoveReaction() == PistonMoveReaction.BLOCK || block.getPistonMoveReaction() == PistonMoveReaction.IGNORE || block.getPistonMoveReaction() == PistonMoveReaction.PUSH_ONLY || block.getState() instanceof TileState)) continue;
|
||||||
|
if (block.getType() != oppositeType) {
|
||||||
|
if (!blockSet.contains(block)) toCalc.add(block);
|
||||||
|
calcDirection(null, block, null, facing, direction, blockSet, toCalc, unmovable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blockSet.remove(origin);
|
||||||
|
if (facing != direction) blockSet.remove(origin.getRelative(facing, 1));
|
||||||
|
return new CalculationResult(blockSet.size(), blockSet.size() > 12, unmovable.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calcDirection(Block origin, Block calcOrigin, Block ignore, BlockFace facing, BlockFace direction, Set<Block> blockSet, List<Block> toCalc, AtomicBoolean unmovable) {
|
||||||
|
for (int i = 1; i < 13; i++) {
|
||||||
|
Block block = calcOrigin.getRelative(direction, i);
|
||||||
|
if (block.equals(ignore)) return;
|
||||||
|
if (block.getPistonMoveReaction() == PistonMoveReaction.BREAK) return;
|
||||||
|
if (!isPiston(block) && (block.getPistonMoveReaction() == PistonMoveReaction.BLOCK || block.getPistonMoveReaction() == PistonMoveReaction.IGNORE || block.getState() instanceof TileState)) {
|
||||||
|
unmovable.set(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (block.getType().isAir()) return;
|
||||||
|
if (facing != direction && (block.equals(origin) || block.getRelative(facing.getOppositeFace()).equals(origin))) return;
|
||||||
|
if (!blockSet.contains(block)) toCalc.add(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPiston(Block block) {
|
||||||
|
BlockData blockData = block.getBlockData();
|
||||||
|
if (blockData instanceof Piston) {
|
||||||
|
return !((Piston) blockData).isExtended();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
private static class CalculationResult {
|
||||||
|
private int amount;
|
||||||
|
private boolean tooMany;
|
||||||
|
private boolean unmovable;
|
||||||
|
}
|
||||||
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren