SteamWar/BauSystem2.0
Archiviert
12
0

Add ObserverTracer

Add ObserverTracerListener

Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
yoyosource 2021-06-20 08:12:12 +02:00
Ursprung dc8bc30b88
Commit adaff21d0f
2 geänderte Dateien mit 128 neuen und 41 gelöschten Zeilen

Datei anzeigen

@ -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);
}
}
}
}
}

Datei anzeigen

@ -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());
}
}
}