Add ObserverTracer
Add ObserverTracerListener Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
Ursprung
dc8bc30b88
Commit
adaff21d0f
@ -19,58 +19,74 @@
|
||||
|
||||
package de.steamwar.bausystem.features.observer;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.block.*;
|
||||
import org.bukkit.block.Dispenser;
|
||||
import org.bukkit.block.Hopper;
|
||||
import org.bukkit.block.data.Powerable;
|
||||
import org.bukkit.block.data.type.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Bisected;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Observer;
|
||||
import org.bukkit.block.data.type.*;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.block.impl.CraftPoweredRail;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
@UtilityClass
|
||||
public class ObserverTracer {
|
||||
|
||||
private final Set<BlockFace> ALLOWED = EnumSet.of(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST, BlockFace.UP, BlockFace.DOWN);
|
||||
private static final Set<BlockFace> ALLOWED = EnumSet.of(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST, BlockFace.UP, BlockFace.DOWN);
|
||||
|
||||
private Set<BiPredicate<Block, BlockFace>> predicates = new HashSet<>();
|
||||
private Player player;
|
||||
private Set<Location> seen = new HashSet<>();
|
||||
private List<Block> blockList = new ArrayList<>();
|
||||
|
||||
static {
|
||||
predicates.add((block, blockFace) -> {
|
||||
if (block.getType() != Material.OBSERVER) {
|
||||
return false;
|
||||
}
|
||||
Observer observer = (Observer) block.getBlockData();
|
||||
return observer.getFacing() == blockFace.getOppositeFace();
|
||||
});
|
||||
public ObserverTracer(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public void trace(Player player, Block block) {
|
||||
public void trace(Block block) {
|
||||
if (block.getType() != Material.OBSERVER) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Location> seen = new HashSet<>();
|
||||
List<Block> blockList = new ArrayList<>();
|
||||
blockList.add(block);
|
||||
while (!blockList.isEmpty()) {
|
||||
Block b = blockList.remove(0);
|
||||
for (BlockFace blockFace : ALLOWED) {
|
||||
Location location = b.getLocation().add(blockFace.getModX(), blockFace.getModY(), blockFace.getModZ());
|
||||
Block toCheck = location.getBlock();
|
||||
if (!seen.add(location)) {
|
||||
continue;
|
||||
blockList.removeIf(b -> seen.contains(b.getLocation()));
|
||||
if (blockList.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (BiPredicate<Block, BlockFace> predicate : predicates) {
|
||||
if (predicate.test(toCheck, blockFace)) {
|
||||
blockList.add(toCheck);
|
||||
Block b = blockList.remove(0);
|
||||
seen.add(b.getLocation());
|
||||
spawnParticle(player, b.getLocation());
|
||||
|
||||
switch (b.getType()) {
|
||||
case OBSERVER:
|
||||
calculateObserver(b);
|
||||
break;
|
||||
default:
|
||||
BlockData blockData = b.getBlockData();
|
||||
if (blockData instanceof Door) {
|
||||
if (((Door) blockData).getHalf() == Bisected.Half.BOTTOM) {
|
||||
blockList.add(b.getLocation().add(0, 1, 0).getBlock());
|
||||
} else {
|
||||
blockList.add(b.getLocation().add(0, -1, 0).getBlock());
|
||||
}
|
||||
}
|
||||
if (checkAllowed(b, blockData)) {
|
||||
calculateSpecial(b);
|
||||
break;
|
||||
}
|
||||
if (b.getType().isBlock() && b.getType().isSolid()) {
|
||||
calculateSolidBlock(b);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnParticle(Player player, Location location) {
|
||||
player.spawnParticle(Particle.FLAME, location.clone().add(0, 0, 0), 1, 0, 0, 0, 0);
|
||||
player.spawnParticle(Particle.FLAME, location.clone().add(1, 0, 0), 1, 0, 0, 0, 0);
|
||||
player.spawnParticle(Particle.FLAME, location.clone().add(1, 0, 1), 1, 0, 0, 0, 0);
|
||||
@ -79,11 +95,82 @@ public class ObserverTracer {
|
||||
player.spawnParticle(Particle.FLAME, location.clone().add(1, 1, 0), 1, 0, 0, 0, 0);
|
||||
player.spawnParticle(Particle.FLAME, location.clone().add(1, 1, 1), 1, 0, 0, 0, 0);
|
||||
player.spawnParticle(Particle.FLAME, location.clone().add(0, 1, 1), 1, 0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
private void calculateObserver(Block block) {
|
||||
Observer observer = (Observer) block.getBlockData();
|
||||
for (BlockFace blockFace : ALLOWED) {
|
||||
Location location = block.getLocation().add(blockFace.getModX(), blockFace.getModY(), blockFace.getModZ());
|
||||
Block b = location.getBlock();
|
||||
if (blockFace == observer.getFacing().getOppositeFace() && !b.getType().isAir()) {
|
||||
blockList.add(b);
|
||||
Material material = b.getType();
|
||||
if (material == Material.REDSTONE_LAMP || material == Material.DROPPER || material == Material.DISPENSER) {
|
||||
calculateRedstoneLamp(b);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (b.getType() != Material.OBSERVER) {
|
||||
continue;
|
||||
}
|
||||
if (((Observer) b.getBlockData()).getFacing() == blockFace.getOppositeFace()) {
|
||||
blockList.add(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateRedstoneLamp(Block block) {
|
||||
for (BlockFace blockFace : ALLOWED) {
|
||||
Location location = block.getLocation().add(blockFace.getModX(), blockFace.getModY(), blockFace.getModZ());
|
||||
Block b = location.getBlock();
|
||||
if (checkAllowed(b, b.getBlockData())) {
|
||||
blockList.add(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateSolidBlock(Block block) {
|
||||
for (BlockFace blockFace : ALLOWED) {
|
||||
Location location = block.getLocation().add(blockFace.getModX(), blockFace.getModY(), blockFace.getModZ());
|
||||
Block b = location.getBlock();
|
||||
BlockData blockData = b.getBlockData();
|
||||
if (checkAllowed(b, blockData)) {
|
||||
blockList.add(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkAllowed(Block block, BlockData blockData) {
|
||||
if (block.getType() == Material.DROPPER) {
|
||||
return true;
|
||||
}
|
||||
if (block.getType() == Material.HOPPER) {
|
||||
return true;
|
||||
}
|
||||
if (block.getType() == Material.DISPENSER) {
|
||||
return true;
|
||||
}
|
||||
if (block.getType() == Material.REDSTONE_LAMP) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return blockData instanceof Door
|
||||
|| blockData instanceof Gate
|
||||
|| blockData instanceof NoteBlock
|
||||
|| blockData instanceof CraftPoweredRail
|
||||
|| blockData instanceof TrapDoor;
|
||||
}
|
||||
|
||||
private void calculateSpecial(Block block) {
|
||||
for (BlockFace blockFace : ALLOWED) {
|
||||
Location location = block.getLocation().add(blockFace.getModX(), blockFace.getModY(), blockFace.getModZ());
|
||||
Block b = location.getBlock();
|
||||
if (b.getType() == Material.OBSERVER) {
|
||||
Observer blockData = (Observer) b.getBlockData();
|
||||
if (blockData.getFacing() == blockFace.getOppositeFace()) {
|
||||
blockList.add(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public class ObserverTracerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
if (event.getClickedBlock().getType() == Material.OBSERVER) {
|
||||
ObserverTracer.trace(event.getPlayer(), event.getClickedBlock());
|
||||
new ObserverTracer(event.getPlayer()).trace(event.getClickedBlock());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren