Add ObserverTracer
Add ObserverTracerListener Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
Ursprung
dc8bc30b88
Commit
adaff21d0f
@ -19,71 +19,158 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.observer;
|
package de.steamwar.bausystem.features.observer;
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
import org.bukkit.block.*;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.Dispenser;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.Hopper;
|
import org.bukkit.block.data.Bisected;
|
||||||
import org.bukkit.block.data.Powerable;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.type.*;
|
|
||||||
import org.bukkit.block.data.type.Observer;
|
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 org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.BiPredicate;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class ObserverTracer {
|
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 {
|
public ObserverTracer(Player player) {
|
||||||
predicates.add((block, blockFace) -> {
|
this.player = player;
|
||||||
if (block.getType() != Material.OBSERVER) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Observer observer = (Observer) block.getBlockData();
|
|
||||||
return observer.getFacing() == blockFace.getOppositeFace();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void trace(Player player, Block block) {
|
public void trace(Block block) {
|
||||||
if (block.getType() != Material.OBSERVER) {
|
if (block.getType() != Material.OBSERVER) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Location> seen = new HashSet<>();
|
|
||||||
List<Block> blockList = new ArrayList<>();
|
|
||||||
blockList.add(block);
|
blockList.add(block);
|
||||||
while (!blockList.isEmpty()) {
|
while (!blockList.isEmpty()) {
|
||||||
Block b = blockList.remove(0);
|
blockList.removeIf(b -> seen.contains(b.getLocation()));
|
||||||
for (BlockFace blockFace : ALLOWED) {
|
if (blockList.isEmpty()) {
|
||||||
Location location = b.getLocation().add(blockFace.getModX(), blockFace.getModY(), blockFace.getModZ());
|
break;
|
||||||
Block toCheck = location.getBlock();
|
}
|
||||||
if (!seen.add(location)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (BiPredicate<Block, BlockFace> predicate : predicates) {
|
Block b = blockList.remove(0);
|
||||||
if (predicate.test(toCheck, blockFace)) {
|
seen.add(b.getLocation());
|
||||||
blockList.add(toCheck);
|
spawnParticle(player, b.getLocation());
|
||||||
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);
|
switch (b.getType()) {
|
||||||
player.spawnParticle(Particle.FLAME, location.clone().add(1, 0, 1), 1, 0, 0, 0, 0);
|
case OBSERVER:
|
||||||
player.spawnParticle(Particle.FLAME, location.clone().add(0, 0, 1), 1, 0, 0, 0, 0);
|
calculateObserver(b);
|
||||||
player.spawnParticle(Particle.FLAME, location.clone().add(0, 1, 0), 1, 0, 0, 0, 0);
|
break;
|
||||||
player.spawnParticle(Particle.FLAME, location.clone().add(1, 1, 0), 1, 0, 0, 0, 0);
|
default:
|
||||||
player.spawnParticle(Particle.FLAME, location.clone().add(1, 1, 1), 1, 0, 0, 0, 0);
|
BlockData blockData = b.getBlockData();
|
||||||
player.spawnParticle(Particle.FLAME, location.clone().add(0, 1, 1), 1, 0, 0, 0, 0);
|
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;
|
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);
|
||||||
|
player.spawnParticle(Particle.FLAME, location.clone().add(0, 0, 1), 1, 0, 0, 0, 0);
|
||||||
|
player.spawnParticle(Particle.FLAME, location.clone().add(0, 1, 0), 1, 0, 0, 0, 0);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (event.getClickedBlock().getType() == Material.OBSERVER) {
|
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