Compare commits
71 Commits
b048af8001
...
1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1dbe281a6 | ||
|
|
8485e34756 | ||
|
|
7e6601d56d | ||
|
|
982190b730 | ||
|
|
4626646292 | ||
|
|
e82de277ef | ||
|
|
28658329a8 | ||
|
|
ac810349ac | ||
|
|
2a713d269e | ||
|
|
b20e0a03fd | ||
|
|
5a1c809d89 | ||
|
|
ef9643c2ae | ||
|
|
c732aa31b1 | ||
|
|
51c9ee0716 | ||
|
|
e10eaf9b66 | ||
|
|
686ad312c5 | ||
|
|
973897cc3e | ||
|
|
1eb472b576 | ||
|
|
c41ab95baf | ||
|
|
5e22456f61 | ||
|
|
2bda948c8f | ||
|
|
6c2e06afaf | ||
|
|
b54af93d4b | ||
|
|
1168b8859a | ||
|
|
b8ed619b1c | ||
|
|
1ab17c1ab6 | ||
|
|
fdc17aad0f | ||
|
|
bf18c82d6d | ||
|
|
2f64eb5ed0 | ||
|
|
cf061f9d75 | ||
|
|
b593a22568 | ||
|
|
884184006c | ||
|
|
41a15103b3 | ||
|
|
b010280111 | ||
|
|
63bab8ae2e | ||
|
|
3d602c526d | ||
|
|
f03a80cf99 | ||
|
|
51e22f2f9e | ||
|
|
3695315d42 | ||
|
|
b819fcb9f5 | ||
|
|
ddb6525c40 | ||
|
|
c0917a1ab6 | ||
|
|
3d757a6ccf | ||
|
|
a296a190c6 | ||
|
|
800032f530 | ||
|
|
3df5c9d4ac | ||
|
|
d9c95a5e53 | ||
|
|
3f73d15a5a | ||
|
|
de1c2816a2 | ||
|
|
4efa26fe0e | ||
|
|
8889a16bdc | ||
|
|
f8c7672cfa | ||
|
|
cb4adc3bc1 | ||
|
|
6a4369c527 | ||
|
|
a7a8a4b037 | ||
|
|
b1169f48db | ||
|
|
efb18aa711 | ||
|
|
0b538db2a4 | ||
|
|
90443d51f7 | ||
|
|
69fcab7bbc | ||
|
|
376695b466 | ||
|
|
da05087876 | ||
|
|
2f621d7a9b | ||
|
|
59e8768ddb | ||
|
|
48f961fc9c | ||
|
|
16a46a6a35 | ||
|
|
abde30e2e1 | ||
|
|
87d6d4bd70 | ||
|
|
bcd147052c | ||
|
|
92718de5a9 | ||
|
|
a850972224 |
45
pom.xml
Normal file
45
pom.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>eu.ruekov.ruakij</groupId>
|
||||
<artifactId>LinkedBeaconTeleporters</artifactId>
|
||||
<version>1.0</version>
|
||||
|
||||
|
||||
|
||||
<properties>
|
||||
<author>Ruakij</author>
|
||||
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>papermc</id>
|
||||
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.destroystokyo.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.16.5-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,155 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Function {
|
||||
public static String serialiseBlockLocation(Location loc){
|
||||
return loc.getWorld().getName()+";"+loc.getBlockX()+";"+loc.getBlockY()+";"+loc.getBlockZ();
|
||||
}
|
||||
public static Location deserializeBlockLocation(String serialisedLoc) throws InvalidPropertiesFormatException {
|
||||
try{
|
||||
String[] locData = serialisedLoc.split(";");
|
||||
|
||||
World world = Bukkit.getWorld(locData[0]);
|
||||
int x = Integer.parseInt(locData[1]);
|
||||
int y = Integer.parseInt(locData[2]);
|
||||
int z = Integer.parseInt(locData[3]);
|
||||
|
||||
return new Location(world, x, y, z);
|
||||
}catch(Exception ex){
|
||||
throw new InvalidPropertiesFormatException("Could not deserialize BlockLocation '"+ serialisedLoc +"'");
|
||||
}
|
||||
}
|
||||
|
||||
public static String randomString(String alphabet, int length){
|
||||
char[] alphabetChars = alphabet.toCharArray();
|
||||
|
||||
String str = "";
|
||||
Random random = new Random();
|
||||
for(int i=0; i<length; i++){
|
||||
str += alphabetChars[random.nextInt(alphabet.length())];
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public static List<Material> transparentMaterials = Arrays.asList(
|
||||
Material.AIR,
|
||||
Material.GLASS,
|
||||
Material.GLASS_PANE,
|
||||
Material.BLACK_STAINED_GLASS,
|
||||
Material.BLACK_STAINED_GLASS_PANE,
|
||||
Material.BLUE_STAINED_GLASS,
|
||||
Material.BLUE_STAINED_GLASS_PANE,
|
||||
Material.BROWN_STAINED_GLASS,
|
||||
Material.BROWN_STAINED_GLASS_PANE,
|
||||
Material.CYAN_STAINED_GLASS,
|
||||
Material.CYAN_STAINED_GLASS_PANE,
|
||||
Material.GRAY_STAINED_GLASS,
|
||||
Material.GRAY_STAINED_GLASS_PANE,
|
||||
Material.GREEN_STAINED_GLASS,
|
||||
Material.GREEN_STAINED_GLASS_PANE,
|
||||
Material.LIGHT_BLUE_STAINED_GLASS,
|
||||
Material.LIGHT_BLUE_STAINED_GLASS_PANE,
|
||||
Material.LIGHT_GRAY_STAINED_GLASS,
|
||||
Material.LIGHT_GRAY_STAINED_GLASS_PANE,
|
||||
Material.LIME_STAINED_GLASS,
|
||||
Material.LIME_STAINED_GLASS_PANE,
|
||||
Material.MAGENTA_STAINED_GLASS,
|
||||
Material.MAGENTA_STAINED_GLASS_PANE,
|
||||
Material.ORANGE_STAINED_GLASS,
|
||||
Material.ORANGE_STAINED_GLASS_PANE,
|
||||
Material.PINK_STAINED_GLASS,
|
||||
Material.PINK_STAINED_GLASS_PANE,
|
||||
Material.PURPLE_STAINED_GLASS,
|
||||
Material.PURPLE_STAINED_GLASS_PANE,
|
||||
Material.RED_STAINED_GLASS,
|
||||
Material.RED_STAINED_GLASS_PANE,
|
||||
Material.WHITE_STAINED_GLASS,
|
||||
Material.WHITE_STAINED_GLASS_PANE,
|
||||
Material.YELLOW_STAINED_GLASS,
|
||||
Material.YELLOW_STAINED_GLASS_PANE,
|
||||
Material.PISTON,
|
||||
Material.PISTON_HEAD,
|
||||
Material.MOVING_PISTON,
|
||||
Material.STICKY_PISTON,
|
||||
Material.ACACIA_LEAVES,
|
||||
Material.BIRCH_LEAVES,
|
||||
Material.DARK_OAK_LEAVES,
|
||||
Material.JUNGLE_LEAVES,
|
||||
Material.OAK_LEAVES,
|
||||
Material.SPRUCE_LEAVES,
|
||||
Material.ACACIA_SLAB,
|
||||
Material.ANDESITE_SLAB,
|
||||
Material.BIRCH_SLAB,
|
||||
Material.BLACKSTONE_SLAB,
|
||||
Material.BRICK_SLAB,
|
||||
Material.COBBLESTONE_SLAB,
|
||||
Material.CRIMSON_SLAB,
|
||||
Material.CUT_RED_SANDSTONE_SLAB,
|
||||
Material.CUT_SANDSTONE_SLAB,
|
||||
Material.DARK_OAK_SLAB,
|
||||
Material.DARK_PRISMARINE_SLAB,
|
||||
Material.DIORITE_SLAB,
|
||||
Material.END_STONE_BRICK_SLAB,
|
||||
Material.GRANITE_SLAB,
|
||||
Material.JUNGLE_SLAB,
|
||||
Material.MOSSY_COBBLESTONE_SLAB,
|
||||
Material.MOSSY_STONE_BRICK_SLAB,
|
||||
Material.NETHER_BRICK_SLAB,
|
||||
Material.OAK_SLAB,
|
||||
Material.PETRIFIED_OAK_SLAB,
|
||||
Material.POLISHED_ANDESITE_SLAB,
|
||||
Material.POLISHED_BLACKSTONE_BRICK_SLAB,
|
||||
Material.POLISHED_BLACKSTONE_SLAB,
|
||||
Material.POLISHED_DIORITE_SLAB,
|
||||
Material.POLISHED_GRANITE_SLAB,
|
||||
Material.PRISMARINE_BRICK_SLAB,
|
||||
Material.PRISMARINE_SLAB,
|
||||
Material.PURPUR_SLAB,
|
||||
Material.QUARTZ_SLAB,
|
||||
Material.RED_NETHER_BRICK_SLAB,
|
||||
Material.RED_SANDSTONE_SLAB,
|
||||
Material.SANDSTONE_SLAB,
|
||||
Material.SMOOTH_QUARTZ_SLAB,
|
||||
Material.SMOOTH_RED_SANDSTONE_SLAB,
|
||||
Material.SMOOTH_SANDSTONE_SLAB,
|
||||
Material.SMOOTH_STONE_SLAB,
|
||||
Material.SPRUCE_SLAB,
|
||||
Material.STONE_BRICK_SLAB,
|
||||
Material.STONE_SLAB,
|
||||
Material.WARPED_SLAB
|
||||
);
|
||||
public static Block searchForMaterial(Location startLoc, Vector searchDirection, Material searchMaterial){
|
||||
return searchForMaterial(startLoc, searchDirection, searchMaterial, new ArrayList<>());
|
||||
}
|
||||
public static Block searchForMaterial(Location startLoc, Vector searchDirection, Material searchMaterial, List<Material> ignoreMaterials){
|
||||
Location loc = new Location(startLoc.getWorld(), startLoc.getBlockX(), startLoc.getBlockY(), startLoc.getBlockZ());
|
||||
for(int i=0; loc.getBlockY()>=0 && loc.getBlockY()<=255; loc.add(searchDirection)){
|
||||
Block block = loc.getBlock();
|
||||
|
||||
// Check for correct material
|
||||
if(block.getType() == searchMaterial) return block;
|
||||
|
||||
// Check for non-ignore-block
|
||||
boolean found = false;
|
||||
for(Material ignoreMaterial : ignoreMaterials){
|
||||
if(block.getType() == ignoreMaterial){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If not found, searchMaterial not found
|
||||
if(!found) return null;
|
||||
}
|
||||
|
||||
// Reached 0 or 255, searchMaterial not found
|
||||
return null;
|
||||
}
|
||||
}
|
||||
101
src/main/java/eu/ruekov/ruakij/LinkedBeaconTeleporters/Main.java
Normal file
101
src/main/java/eu/ruekov/ruakij/LinkedBeaconTeleporters/Main.java
Normal file
@@ -0,0 +1,101 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters;
|
||||
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.customPlayerMoveEvent.CustomPlayerMoveEventHandler;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter.LinkedBeaconTeleporterManager;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.listener.OnBlockBreak;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.listener.OnBlockPlace;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.listener.OnCraftItemEvent;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.listener.OnCustomPlayerMove;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class Main extends JavaPlugin {
|
||||
|
||||
public static Plugin plugin;
|
||||
|
||||
public static FileConfiguration config;
|
||||
public static FileConfiguration data;
|
||||
|
||||
public static Logger log;
|
||||
|
||||
public void onEnable() {
|
||||
log = getLogger();
|
||||
|
||||
plugin = this;
|
||||
|
||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
pluginManager.registerEvents(new OnBlockBreak(), this);
|
||||
pluginManager.registerEvents(new OnBlockPlace(), this);
|
||||
pluginManager.registerEvents(new OnCraftItemEvent(), this);
|
||||
|
||||
loadConfigs();
|
||||
|
||||
CustomPlayerMoveEventHandler cpmHandler = new CustomPlayerMoveEventHandler(this, config.getInt("locationCheck.interval"), true);
|
||||
cpmHandler.registerListener(new OnCustomPlayerMove());
|
||||
|
||||
LinkedBeaconTeleporterManager.init();
|
||||
|
||||
initAutoSave();
|
||||
|
||||
log.info("Plugin activated");
|
||||
}
|
||||
|
||||
public void onDisable() {
|
||||
saveData();
|
||||
|
||||
log.info("Plugin deactivated");
|
||||
}
|
||||
|
||||
public void loadConfigs() {
|
||||
// config.yml
|
||||
this.saveDefaultConfig();
|
||||
config = this.getConfig();
|
||||
|
||||
// data.yml
|
||||
try{
|
||||
File dataFile = new File("plugins/"+ plugin.getName() +"/data.yml");
|
||||
dataFile.createNewFile();
|
||||
data = YamlConfiguration.loadConfiguration(
|
||||
dataFile
|
||||
);
|
||||
}catch (Exception ex){
|
||||
log.severe("Could not load/create data.yml!");
|
||||
ex.printStackTrace();
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveData(){
|
||||
boolean lbtDataChanged = LinkedBeaconTeleporterManager.writeData();
|
||||
|
||||
// Only run save, when data changed
|
||||
if(lbtDataChanged)
|
||||
saveFiles();
|
||||
}
|
||||
|
||||
public static void saveFiles() {
|
||||
// data.yml
|
||||
try{
|
||||
File dataFile = new File("plugins/"+ plugin.getName() +"/data.yml");
|
||||
data.save(dataFile);
|
||||
}catch (Exception ex){
|
||||
log.severe("Could not save data.yml!");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
static void initAutoSave(){
|
||||
int autosaveInterval = config.getInt("config.interval")*20;
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () -> {
|
||||
saveData();
|
||||
|
||||
}, autosaveInterval, autosaveInterval);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters.customPlayerMoveEvent;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class CustomPlayerMoveEvent {
|
||||
|
||||
Player p;
|
||||
Location loc;
|
||||
Location oldLoc;
|
||||
protected double distance;
|
||||
public CustomPlayerMoveEvent(Player p, Location loc, Location oldLoc){
|
||||
this.p = p;
|
||||
this.loc = loc;
|
||||
this.oldLoc = oldLoc;
|
||||
}
|
||||
|
||||
public Player player(){
|
||||
return p;
|
||||
}
|
||||
|
||||
public Location location(){
|
||||
return loc;
|
||||
}
|
||||
|
||||
public Location oldLocation(){
|
||||
return oldLoc;
|
||||
}
|
||||
|
||||
public double distance(){
|
||||
return distance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters.customPlayerMoveEvent;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CustomPlayerMoveEventHandler {
|
||||
|
||||
List<CustomPlayerMoveEventListener> listeners = new ArrayList<>();
|
||||
|
||||
HashMap<UUID, Location> oldPlayerLoc = new HashMap<>();
|
||||
|
||||
boolean locationChangeOnBlockChange;
|
||||
public CustomPlayerMoveEventHandler(Plugin plugin, int interval, boolean locationChangeOnBlockChange){
|
||||
this.locationChangeOnBlockChange = locationChangeOnBlockChange;
|
||||
|
||||
startRunnable(plugin, interval);
|
||||
}
|
||||
public CustomPlayerMoveEventHandler(Plugin plugin){
|
||||
this(plugin, 5, false);
|
||||
}
|
||||
|
||||
void startRunnable(Plugin plugin, int interval){
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () -> {
|
||||
// Dont do anything without listeners
|
||||
if(listeners.size() == 0) return;
|
||||
|
||||
// Check all players
|
||||
for(Player p : Bukkit.getOnlinePlayers()){
|
||||
UUID uuid = p.getUniqueId();
|
||||
Location loc = p.getLocation();
|
||||
|
||||
// Get old-location
|
||||
Location oldLoc = oldPlayerLoc.get(uuid);
|
||||
|
||||
// Create data-obj
|
||||
CustomPlayerMoveEvent e = new CustomPlayerMoveEvent(p, loc, oldLoc);
|
||||
|
||||
// When player has an old-location
|
||||
if(oldLoc != null){
|
||||
if(!locationChangeOnBlockChange){
|
||||
double distance = loc.distance(oldLoc);
|
||||
e.distance = distance;
|
||||
|
||||
if(distance > 0)
|
||||
locationChangeListeners(e);
|
||||
}
|
||||
else if(loc.getBlockX() != oldLoc.getBlockX() ||
|
||||
loc.getBlockY() != oldLoc.getBlockY() ||
|
||||
loc.getBlockZ() != oldLoc.getBlockZ())
|
||||
locationChangeListeners(e);
|
||||
}
|
||||
|
||||
tickListeners(e);
|
||||
|
||||
// Save old location
|
||||
oldPlayerLoc.put(uuid, loc);
|
||||
}
|
||||
|
||||
}, interval, interval);
|
||||
}
|
||||
|
||||
boolean blockLocationChanged(Location loc, Location oldLoc){
|
||||
return loc.getBlockX() != oldLoc.getBlockX() ||
|
||||
loc.getBlockY() != oldLoc.getBlockY() ||
|
||||
loc.getBlockZ() != oldLoc.getBlockZ();
|
||||
}
|
||||
|
||||
void tickListeners(CustomPlayerMoveEvent e){
|
||||
for(CustomPlayerMoveEventListener listener : listeners){
|
||||
listener.tick(e);
|
||||
}
|
||||
}
|
||||
void locationChangeListeners(CustomPlayerMoveEvent e){
|
||||
for(CustomPlayerMoveEventListener listener : listeners){
|
||||
listener.locationChange(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void registerListener(CustomPlayerMoveEventListener listener){
|
||||
listeners.add(listener);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters.customPlayerMoveEvent;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface CustomPlayerMoveEventListener {
|
||||
|
||||
void tick(CustomPlayerMoveEvent e);
|
||||
|
||||
void locationChange(CustomPlayerMoveEvent e);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter;
|
||||
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Function;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Main;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Describes a placed-beacon-teleporter in the world
|
||||
*/
|
||||
public abstract class LinkedBeaconTeleporter {
|
||||
static String id_alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
static int id_length = 10;
|
||||
|
||||
// Persistent id for linked-beacons
|
||||
public String teleporterId;
|
||||
|
||||
// List of all linkedBeaconTeleporters with same teleporterId (real Type is usually ..Block, because linked Items are temporary constructs are useless)
|
||||
protected List<LinkedBeaconTeleporter> linkedBeaconTeleporters = new ArrayList<>();
|
||||
|
||||
LinkedBeaconTeleporter(){
|
||||
this.teleporterId = Function.randomString(id_alphabet, id_length);
|
||||
|
||||
linkedBeaconTeleporters = new ArrayList<>();
|
||||
}
|
||||
public LinkedBeaconTeleporter(String teleporterId){
|
||||
this.teleporterId = teleporterId;
|
||||
|
||||
// Check if id exists
|
||||
linkedBeaconTeleporters = LinkedBeaconTeleporterManager.placedLBTsById.get(this.teleporterId());
|
||||
if(linkedBeaconTeleporters == null){
|
||||
// Create empty if not found
|
||||
linkedBeaconTeleporters = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public String teleporterId(){
|
||||
return teleporterId;
|
||||
}
|
||||
|
||||
public List<LinkedBeaconTeleporter> linkedBeaconTeleporters(){
|
||||
return linkedBeaconTeleporters;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter;
|
||||
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Function;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Main;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LinkedBeaconTeleporterBlock extends LinkedBeaconTeleporter {
|
||||
// FIXME: Storing the block like this will block the world from unloading and might be dangerous
|
||||
Block block;
|
||||
|
||||
public LinkedBeaconTeleporterBlock(String teleporterId, Block block) {
|
||||
super(teleporterId);
|
||||
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
public Block block(){
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
public LinkedBeaconTeleporterItem break_(BlockBreakEvent e){
|
||||
Location loc = this.block().getLocation();
|
||||
|
||||
// Dont drop anything
|
||||
e.setDropItems(false);
|
||||
e.setExpToDrop(0);
|
||||
|
||||
// Notify Player when link was destroyed
|
||||
if(this.linkedBeaconTeleporters.size() == 2){
|
||||
e.getPlayer().sendMessage("§cConnection to Teleporter with id §7"+ this.teleporterId +" §e("+
|
||||
(int)((LinkedBeaconTeleporterBlock)this.linkedBeaconTeleporters.get(0)).block.getLocation().distance(
|
||||
((LinkedBeaconTeleporterBlock)this.linkedBeaconTeleporters.get(1)).block().getLocation()
|
||||
)
|
||||
+" Blocks away) §cdestroyed");
|
||||
}
|
||||
|
||||
// Remove from list
|
||||
this.linkedBeaconTeleporters.remove(this);
|
||||
|
||||
if(this.linkedBeaconTeleporters.size() == 0){
|
||||
// List empty, delete from placedLBTsById
|
||||
LinkedBeaconTeleporterManager.placedLBTsById.remove(
|
||||
this.teleporterId
|
||||
);
|
||||
}
|
||||
|
||||
// Remove from loc
|
||||
LinkedBeaconTeleporterManager.placedLBTByLoc.remove(
|
||||
Function.serialiseBlockLocation(loc)
|
||||
);
|
||||
|
||||
// Item from block
|
||||
LinkedBeaconTeleporterItem lbtItem = new LinkedBeaconTeleporterItem(this.teleporterId());
|
||||
|
||||
// Drop custom-item
|
||||
if(e.getPlayer().getGameMode() != GameMode.CREATIVE)
|
||||
loc.getWorld().dropItemNaturally(
|
||||
loc.add(0.5, 0, 0.5),
|
||||
lbtItem.item()
|
||||
);
|
||||
|
||||
return lbtItem;
|
||||
}
|
||||
|
||||
|
||||
// Conversion methods
|
||||
public static LinkedBeaconTeleporterBlock getFromLocation(Location loc){
|
||||
return LinkedBeaconTeleporterManager.getLbtBlockFromLocation(loc);
|
||||
}
|
||||
public static List<LinkedBeaconTeleporter> getListFromTeleportId(String teleportId){
|
||||
return LinkedBeaconTeleporterManager.getLbtBlocksFromTeleportId(teleportId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter;
|
||||
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Function;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Main;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class LinkedBeaconTeleporterItem extends LinkedBeaconTeleporter {
|
||||
// INFO: Safe to store as its always cloned by bukkit
|
||||
ItemStack item;
|
||||
|
||||
public LinkedBeaconTeleporterItem(){
|
||||
// Create a new LinkedBeaconTeleporter
|
||||
super();
|
||||
|
||||
this.item = LinkedBeaconTeleporterManager.getItemStackFromData(this.teleporterId);
|
||||
}
|
||||
public LinkedBeaconTeleporterItem(String teleporterId, ItemStack item) {
|
||||
super(teleporterId);
|
||||
|
||||
this.item = item;
|
||||
}
|
||||
public LinkedBeaconTeleporterItem(String teleporterId){
|
||||
super(teleporterId);
|
||||
|
||||
this.item = LinkedBeaconTeleporterManager.getItemStackFromData(teleporterId);
|
||||
}
|
||||
|
||||
public ItemStack item(){
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
public LinkedBeaconTeleporterBlock place(BlockPlaceEvent e){
|
||||
// Deny placing when 2 LinkedBeaconTeleporter's are already placed
|
||||
if(this.linkedBeaconTeleporters.size() == 2){
|
||||
e.getPlayer().sendMessage("§cMaximum-Amount §7(2) §cof §6LinkedBeaconTeleporters §cwith id §7"+ this.teleporterId +" §care already placed");
|
||||
|
||||
e.setCancelled(true);
|
||||
return null;
|
||||
}
|
||||
|
||||
Block block = e.getBlock();
|
||||
Location loc = block.getLocation();
|
||||
|
||||
// Block from item
|
||||
LinkedBeaconTeleporterBlock lbtBlock = new LinkedBeaconTeleporterBlock(this.teleporterId(), block);
|
||||
// Both objects have different lists (as both are new), overwrite block-list with item-list
|
||||
// FIXME: This seems like a bad design.. maybe only create the list when necessary? (e.g. keep null if no linked objects found)
|
||||
lbtBlock.linkedBeaconTeleporters = this.linkedBeaconTeleporters;
|
||||
|
||||
// Add to list
|
||||
this.linkedBeaconTeleporters.add(lbtBlock);
|
||||
|
||||
// Add to id if not exists
|
||||
if(!LinkedBeaconTeleporterManager.placedLBTsById.containsKey(this.teleporterId))
|
||||
LinkedBeaconTeleporterManager.placedLBTsById.put(this.teleporterId, this.linkedBeaconTeleporters);
|
||||
|
||||
// Add to location
|
||||
LinkedBeaconTeleporterManager.placedLBTByLoc.put(
|
||||
Function.serialiseBlockLocation(loc),
|
||||
lbtBlock
|
||||
);
|
||||
|
||||
// Notify Player when no other teleporter was found (yet?)
|
||||
if(this.linkedBeaconTeleporters.size() == 1){
|
||||
e.getPlayer().sendMessage("§6No other Teleporter found with with id §7"+ this.teleporterId);
|
||||
}
|
||||
// Notify Player when we have a full link
|
||||
else if(this.linkedBeaconTeleporters.size() == 2){
|
||||
e.getPlayer().sendMessage("§aConnected to Teleporter with id §7"+ this.teleporterId +" §e("+
|
||||
(int)((LinkedBeaconTeleporterBlock)this.linkedBeaconTeleporters.get(0)).block.getLocation().distance(
|
||||
((LinkedBeaconTeleporterBlock)this.linkedBeaconTeleporters.get(1)).block().getLocation()
|
||||
)
|
||||
+" Blocks away)");
|
||||
}
|
||||
|
||||
return lbtBlock;
|
||||
}
|
||||
|
||||
|
||||
// Conversion methods
|
||||
public static LinkedBeaconTeleporterItem getFromItemStack(ItemStack itemStack){
|
||||
return LinkedBeaconTeleporterManager.getLbtItemFromItemStack(itemStack);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter;
|
||||
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Function;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Main;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.ShapelessRecipe;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class LinkedBeaconTeleporterManager {
|
||||
// Stores all placed Beacon-Teleporters for fast access
|
||||
// TODO: Evaluate necessity of 2 HashMaps with main reason of performance
|
||||
public static HashMap<String, List<LinkedBeaconTeleporter>> placedLBTsById = new HashMap();
|
||||
public static HashMap<String, LinkedBeaconTeleporterBlock> placedLBTByLoc = new HashMap();
|
||||
|
||||
// Regex to match item-name&lore and extract id (group 1)
|
||||
static String regex;
|
||||
|
||||
public static void init(){
|
||||
Main.log.info("Loading LinkedBeaconTeleporter from config..");
|
||||
|
||||
// Construct search item-regex
|
||||
regex = constructRegex(
|
||||
Main.config.getString("item.name"),
|
||||
Main.config.getStringList("item.lore")
|
||||
);
|
||||
|
||||
// Load settings
|
||||
LinkedBeaconTeleporter.id_alphabet = Main.config.getString("id.alphabet");
|
||||
LinkedBeaconTeleporter.id_length = Main.config.getInt("id.length");
|
||||
|
||||
// Construct & add crafting-receipes
|
||||
constructAndAddRecipes();
|
||||
|
||||
// Load teleporters
|
||||
for(String teleporterId : Main.data.getKeys(false)){
|
||||
List<String> serialisedLocs = Main.data.getStringList(teleporterId);
|
||||
|
||||
// New list for this id
|
||||
List<LinkedBeaconTeleporter> linkedBeaconTeleporters = new ArrayList();
|
||||
|
||||
for(String serializedLoc : serialisedLocs) {
|
||||
|
||||
// Load location
|
||||
Location loc;
|
||||
try {
|
||||
loc = Function.deserializeBlockLocation(serializedLoc);
|
||||
} catch (InvalidPropertiesFormatException e) {
|
||||
Main.log.severe("Could not load location='"+ serializedLoc +"' from "+ teleporterId);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if block is of type Beacon (in case the world was changed without the plugin running)
|
||||
Block block = loc.getBlock();
|
||||
if(block.getType() != Material.BEACON){
|
||||
// Data out of sync! Skipping
|
||||
Main.log.warning(teleporterId +" at location "+ serializedLoc +" changed and is no longer LinkedBlockTeleporter! (Changed without the plugin running?)");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Construct block
|
||||
LinkedBeaconTeleporterBlock lbtBlock = new LinkedBeaconTeleporterBlock(teleporterId, block);
|
||||
// Write reference of list
|
||||
lbtBlock.linkedBeaconTeleporters = linkedBeaconTeleporters;
|
||||
|
||||
// Write block to list
|
||||
linkedBeaconTeleporters.add(lbtBlock);
|
||||
// Save to loc-list
|
||||
placedLBTByLoc.put(serializedLoc, lbtBlock);
|
||||
}
|
||||
|
||||
// Save list to id-list
|
||||
placedLBTsById.put(teleporterId, linkedBeaconTeleporters);
|
||||
}
|
||||
|
||||
Main.saveData();
|
||||
|
||||
Main.log.info("All done!");
|
||||
}
|
||||
|
||||
static int oldDataHashCode;
|
||||
public static boolean writeData(){
|
||||
// Check if data changed
|
||||
int dataHashCode = placedLBTsById.hashCode();
|
||||
if(oldDataHashCode != dataHashCode){
|
||||
// Changed
|
||||
oldDataHashCode = dataHashCode;
|
||||
}
|
||||
else // Did not change
|
||||
return false;
|
||||
|
||||
Main.data = new YamlConfiguration();
|
||||
for(String teleporterId : placedLBTsById.keySet()){
|
||||
List<LinkedBeaconTeleporter> LBTs = placedLBTsById.get(teleporterId);
|
||||
|
||||
// Generate clean array with data we want
|
||||
List<String> dataList = new ArrayList<>();
|
||||
for(LinkedBeaconTeleporter lbt : LBTs){
|
||||
dataList.add(
|
||||
Function.serialiseBlockLocation(
|
||||
((LinkedBeaconTeleporterBlock)lbt).block().getLocation()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Main.data.set(teleporterId, dataList);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void constructAndAddRecipes(){
|
||||
// Create result-item
|
||||
ItemStack item = getItemStackFromData("-");
|
||||
item.setAmount(2);
|
||||
|
||||
// Create recipe
|
||||
ShapelessRecipe recipe = new ShapelessRecipe(
|
||||
new NamespacedKey(Main.plugin, "linked_beacon_teleporter")
|
||||
, item);
|
||||
recipe.addIngredient(2, Material.BEACON);
|
||||
Bukkit.addRecipe(recipe);
|
||||
|
||||
// Empty recipe to reset beacon
|
||||
ShapelessRecipe recipe2 = new ShapelessRecipe(
|
||||
new NamespacedKey(Main.plugin, "linked_beacon_teleporter_reset"),
|
||||
new ItemStack(Material.BEACON)
|
||||
);
|
||||
recipe2.addIngredient(1, Material.BEACON);
|
||||
Bukkit.addRecipe(recipe2);
|
||||
}
|
||||
|
||||
// Conversion-methods
|
||||
public static ItemStack getItemStackFromData(String teleporterId){
|
||||
ItemStack item = new ItemStack(Material.BEACON);
|
||||
ItemMeta itemMeta = item.getItemMeta();
|
||||
|
||||
// Get config-values
|
||||
String name = Main.config.getString("item.name");
|
||||
List<String> lore = Main.config.getStringList("item.lore");
|
||||
|
||||
// Replace parameters
|
||||
name = name.replace("%id%", teleporterId);
|
||||
for(int i=0; i<lore.size(); i++){
|
||||
lore.set(i,
|
||||
lore.get(i).replace("%id%", teleporterId)
|
||||
);
|
||||
}
|
||||
|
||||
// Set meta
|
||||
itemMeta.setDisplayName(name);
|
||||
itemMeta.setLore(lore);
|
||||
|
||||
item.setItemMeta(itemMeta);
|
||||
|
||||
return item;
|
||||
}
|
||||
public static LinkedBeaconTeleporterItem getLbtItemFromItemStack(ItemStack itemStack){
|
||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||
|
||||
// Serialize
|
||||
String nameAndLore = serialiseBeaconItem(
|
||||
itemMeta.getDisplayName(),
|
||||
itemMeta.getLore()
|
||||
);
|
||||
|
||||
// Regex match
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(nameAndLore);
|
||||
if(!matcher.find())
|
||||
// No data
|
||||
return null;
|
||||
|
||||
LinkedBeaconTeleporterItem lbtItem = new LinkedBeaconTeleporterItem(
|
||||
matcher.group(1),
|
||||
itemStack
|
||||
);
|
||||
|
||||
return lbtItem;
|
||||
}
|
||||
|
||||
public static LinkedBeaconTeleporterBlock getLbtBlockFromLocation(Location loc){
|
||||
// Serialize
|
||||
String serializedLoc = Function.serialiseBlockLocation(loc);
|
||||
|
||||
return placedLBTByLoc.get(serializedLoc);
|
||||
}
|
||||
public static List<LinkedBeaconTeleporter> getLbtBlocksFromTeleportId(String teleportId){
|
||||
return placedLBTsById.get(teleportId);
|
||||
}
|
||||
|
||||
static String constructRegex(String name, List<String> lore){
|
||||
// Serialize
|
||||
String regex = serialiseBeaconItem(name, lore);
|
||||
|
||||
// Wrap in regex-quotes
|
||||
regex = "^\\Q"+ regex +"\\E$";
|
||||
// Exclude id from regex-quotes and create group
|
||||
regex = regex.replace("%id%", "\\E(.*)\\Q");
|
||||
|
||||
// Remove empty regex-quotes
|
||||
regex = regex.replace("\\E\\Q", "");
|
||||
|
||||
return regex;
|
||||
}
|
||||
static String serialiseBeaconItem(String name, List<String> lore){
|
||||
// get name and remove control-chars
|
||||
String str = name.replace("\\", "\\\\");
|
||||
if(lore != null){
|
||||
for (String loreLine : lore) {
|
||||
// get lore-lines and remove control-chars
|
||||
str += "\n"+ loreLine.replace("\\", "\\\\");
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters.listener;
|
||||
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Main;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter.LinkedBeaconTeleporterBlock;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter.LinkedBeaconTeleporterItem;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
|
||||
public class OnBlockBreak implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onBlockBreakEvent(BlockBreakEvent e){
|
||||
Block block = e.getBlock();
|
||||
Location loc = block.getLocation();
|
||||
|
||||
if(block.getType() == Material.BEACON){
|
||||
// Check if this beacon is a LinkedBeaconTeleporter
|
||||
LinkedBeaconTeleporterBlock lbtBlock = LinkedBeaconTeleporterBlock.getFromLocation(loc);
|
||||
|
||||
// Ignore if not found
|
||||
if(lbtBlock == null) return;
|
||||
|
||||
LinkedBeaconTeleporterItem lbtItem = lbtBlock.break_(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters.listener;
|
||||
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Main;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter.LinkedBeaconTeleporterBlock;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter.LinkedBeaconTeleporterItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class OnBlockPlace implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onBlockPlaceEvent(BlockPlaceEvent e){
|
||||
ItemStack item = e.getItemInHand();
|
||||
|
||||
|
||||
if(item.getType() == Material.BEACON){
|
||||
// Check if this beacon is a LinkedBeaconTeleporter
|
||||
LinkedBeaconTeleporterItem lbtItem = LinkedBeaconTeleporterItem.getFromItemStack(item);
|
||||
|
||||
// Ignore if not found
|
||||
if(lbtItem == null) return;
|
||||
|
||||
LinkedBeaconTeleporterBlock lbtBlock = lbtItem.place(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters.listener;
|
||||
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Main;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter.LinkedBeaconTeleporterItem;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter.LinkedBeaconTeleporterManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.CraftItemEvent;
|
||||
import org.bukkit.event.inventory.PrepareItemCraftEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.Recipe;
|
||||
|
||||
public class OnCraftItemEvent implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onCraftItemEvent(CraftItemEvent e){
|
||||
|
||||
Recipe recipe = e.getRecipe();
|
||||
ItemStack itemResult = recipe.getResult();
|
||||
|
||||
// Check if it has LinkedBeaconTeleporter-Data
|
||||
LinkedBeaconTeleporterItem lbtItem = LinkedBeaconTeleporterManager.getLbtItemFromItemStack(itemResult);
|
||||
|
||||
// Ignore if not found
|
||||
if(lbtItem == null) return;
|
||||
|
||||
// Create new LinkedBeaconTeleporterItem
|
||||
lbtItem = new LinkedBeaconTeleporterItem();
|
||||
|
||||
ItemStack item = lbtItem.item();
|
||||
// Exactly 2
|
||||
item.setAmount(2);
|
||||
|
||||
// FIXME: Changing the just-crafted-item only works for a single item, bulk-crafting (e.g. Shift-Click) will result in default-items getting crafted!
|
||||
|
||||
e.setCurrentItem(item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package eu.ruekov.ruakij.LinkedBeaconTeleporters.listener;
|
||||
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Function;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.Main;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.customPlayerMoveEvent.CustomPlayerMoveEvent;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.customPlayerMoveEvent.CustomPlayerMoveEventListener;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter.LinkedBeaconTeleporter;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter.LinkedBeaconTeleporterBlock;
|
||||
import eu.ruekov.ruakij.LinkedBeaconTeleporters.linkedBeaconTeleporter.LinkedBeaconTeleporterManager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class OnCustomPlayerMove implements CustomPlayerMoveEventListener {
|
||||
|
||||
static HashMap<UUID, LinkedBeaconTeleporterBlock> playerBeaconLocation = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void tick(CustomPlayerMoveEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void locationChange(CustomPlayerMoveEvent e) {
|
||||
|
||||
Player p = e.player();
|
||||
UUID uuid = p.getUniqueId();
|
||||
|
||||
// If player found in ignoreList, check if he stepped out of the Beacon-light
|
||||
if(playerBeaconLocation.containsKey(uuid)) {
|
||||
LinkedBeaconTeleporterBlock lbtBlock = playerBeaconLocation.get(uuid);
|
||||
Location lbtBlockLoc = lbtBlock.block().getLocation();
|
||||
Location pLoc = p.getLocation();
|
||||
if(lbtBlockLoc.getBlockX() != pLoc.getBlockX() || lbtBlockLoc.getBlockZ() != pLoc.getBlockZ()){
|
||||
playerBeaconLocation.remove(uuid);
|
||||
}
|
||||
else
|
||||
// Player still on beacon, ignore
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if player is on-top of a beacon
|
||||
Block block = Function.searchForMaterial(
|
||||
p.getLocation().add(0, -1, 0),
|
||||
new Vector(0, -1, 0),
|
||||
Material.BEACON,
|
||||
Function.transparentMaterials
|
||||
);
|
||||
|
||||
// Skip if not found
|
||||
if(block == null) return;
|
||||
|
||||
// TODO: Check if beacon is active
|
||||
|
||||
// Check if beacon is a LinkedBeaconTeleporter
|
||||
LinkedBeaconTeleporterBlock lbtBlock = LinkedBeaconTeleporterManager.getLbtBlockFromLocation(block.getLocation());
|
||||
|
||||
// Ignore if not found
|
||||
if(lbtBlock == null) return;
|
||||
|
||||
// Check if player should be ignored on this LinkedBeaconTeleporter
|
||||
if(playerBeaconLocation.get(uuid) != null && playerBeaconLocation.get(uuid) == lbtBlock) return;
|
||||
|
||||
// Get first partner thats not our current-block
|
||||
LinkedBeaconTeleporterBlock lbtBlockPartner = null;
|
||||
for(LinkedBeaconTeleporter lbtBlockTmp: lbtBlock.linkedBeaconTeleporters()){
|
||||
if(lbtBlockTmp != lbtBlock){
|
||||
lbtBlockPartner = (LinkedBeaconTeleporterBlock)lbtBlockTmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(lbtBlockPartner == null){
|
||||
// No other partner
|
||||
p.sendMessage("§cNo linked beacon found with id §7"+ lbtBlock.teleporterId());
|
||||
|
||||
// Set player as ignored on this LinkedBeaconTeleporter (so he wont trigger the checks again)
|
||||
playerBeaconLocation.put(uuid, lbtBlock);
|
||||
}
|
||||
else{
|
||||
// TODO: Check if beacon is active
|
||||
|
||||
// Get safe-location on top of other beacon
|
||||
Block safeBlock = Function.searchForMaterial(
|
||||
lbtBlockPartner.block().getLocation().add(0, 1, 0),
|
||||
new Vector(0, 1, 0),
|
||||
Material.AIR,
|
||||
Function.transparentMaterials
|
||||
);
|
||||
|
||||
if(safeBlock == null){
|
||||
// No safe location found
|
||||
p.sendMessage("§cNo safe-location found at target teleporter");
|
||||
playerBeaconLocation.put(uuid, lbtBlock);
|
||||
return;
|
||||
}
|
||||
// TODO: Check if there is enough space for a player
|
||||
|
||||
// Set player as ignored on target-LinkedBeaconTeleporter (so he wont trigger the teleport again)
|
||||
playerBeaconLocation.put(uuid, lbtBlockPartner);
|
||||
|
||||
// Teleport
|
||||
Location loc = safeBlock.getLocation();
|
||||
// Middle of block
|
||||
loc.add(0.5, 0, 0.5);
|
||||
// Preserve pitch and yaw from player
|
||||
loc.setPitch(p.getLocation().getPitch());
|
||||
loc.setYaw(p.getLocation().getYaw());
|
||||
|
||||
e.player().teleport(
|
||||
loc
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
28
src/main/resources/config.yml
Normal file
28
src/main/resources/config.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
item:
|
||||
# Name & Lore for linked-beacon-blocks
|
||||
# - Has to include %id% somewhere for identification!
|
||||
name: '§9BeaconTeleporter'
|
||||
lore:
|
||||
- '§8§o%id%'
|
||||
|
||||
beacon:
|
||||
# Checks that have to succeed for a teleporter to be active (source and target)
|
||||
checks: # TODO
|
||||
active: true
|
||||
|
||||
id:
|
||||
# Alphabet to use for random-generation
|
||||
alphabet: 'abcdefghijklmnopqrstuvwxyz0123456789'
|
||||
# Length of id
|
||||
# If its too short, ids will "collide" more often (e.g. 2 players generating same linked-teleporters independently), but maybe thats a gameplay-feature for you :)
|
||||
length: 10
|
||||
|
||||
locationCheck:
|
||||
# Interval [in ticks] to check if a player is on a beacon
|
||||
# 5 (= 4 times/s) is usually responsive enough for most interactions
|
||||
interval: 5
|
||||
|
||||
autosave:
|
||||
# Interval [in seconds] for autosave
|
||||
interval: 600
|
||||
5
src/main/resources/plugin.yml
Normal file
5
src/main/resources/plugin.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
name: ${artifactId}
|
||||
version: ${version}
|
||||
author: ${author}
|
||||
main: ${groupId}.${artifactId}.Main
|
||||
api-version: 1.16
|
||||
Reference in New Issue
Block a user