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

Datei anzeigen

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