603 lines
21 KiB
Java
603 lines
21 KiB
Java
package me.wiefferink.areashop.features.signs;
|
|
|
|
import com.sk89q.worldguard.protection.managers.RegionManager;
|
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
|
import me.wiefferink.areashop.AreaShop;
|
|
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
|
|
import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
|
|
import me.wiefferink.areashop.features.RegionFeature;
|
|
import me.wiefferink.areashop.managers.FileManager;
|
|
import me.wiefferink.areashop.regions.BuyRegion;
|
|
import me.wiefferink.areashop.regions.GeneralRegion;
|
|
import me.wiefferink.areashop.regions.RentRegion;
|
|
import me.wiefferink.areashop.tools.Materials;
|
|
import me.wiefferink.areashop.tools.Utils;
|
|
import me.wiefferink.bukkitdo.Do;
|
|
import org.bukkit.Chunk;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.block.BlockFace;
|
|
import org.bukkit.configuration.ConfigurationSection;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.EventPriority;
|
|
import org.bukkit.event.block.Action;
|
|
import org.bukkit.event.block.BlockBreakEvent;
|
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
|
import org.bukkit.event.block.SignChangeEvent;
|
|
import org.bukkit.event.player.PlayerInteractEvent;
|
|
import org.bukkit.event.world.ChunkLoadEvent;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
public class SignsFeature extends RegionFeature {
|
|
|
|
private static final Map<String, RegionSign> allSigns = Collections.synchronizedMap(new HashMap<>());
|
|
private static final Map<String, List<RegionSign>> signsByChunk = Collections.synchronizedMap(new HashMap<>());
|
|
|
|
private Map<String, RegionSign> signs;
|
|
|
|
public SignsFeature() {
|
|
|
|
}
|
|
|
|
/**
|
|
* Constructor.
|
|
* @param region The region to bind to
|
|
*/
|
|
public SignsFeature(GeneralRegion region) {
|
|
setRegion(region);
|
|
signs = new HashMap<>();
|
|
// Setup current signs
|
|
ConfigurationSection signSection = region.getConfig().getConfigurationSection("general.signs");
|
|
if(signSection != null) {
|
|
for(String signKey : signSection.getKeys(false)) {
|
|
RegionSign sign = new RegionSign(this, signKey);
|
|
Location location = sign.getLocation();
|
|
if(location == null) {
|
|
AreaShop.warn("Sign with key " + signKey + " of region " + region.getName() + " does not have a proper location");
|
|
continue;
|
|
}
|
|
signs.put(sign.getStringLocation(), sign);
|
|
signsByChunk.computeIfAbsent(sign.getStringChunk(), key -> new ArrayList<>())
|
|
.add(sign);
|
|
}
|
|
allSigns.putAll(signs);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void shutdown() {
|
|
// Deregister signs from the registry
|
|
if(signs != null) {
|
|
for(Map.Entry<String, RegionSign> entry : signs.entrySet()) {
|
|
allSigns.remove(entry.getKey());
|
|
signsByChunk.get(entry.getValue().getStringChunk()).remove(entry.getValue());
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGH)
|
|
public void onSignBreak(BlockBreakEvent event) {
|
|
if(event.isCancelled()) {
|
|
return;
|
|
}
|
|
Block block = event.getBlock();
|
|
// Check if it is a sign
|
|
if(Materials.isSign(block.getType())) {
|
|
// Check if the rent sign is really the same as a saved rent
|
|
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
|
if(regionSign == null) {
|
|
return;
|
|
}
|
|
// Remove the sign of the rental region if the player has permission
|
|
if(event.getPlayer().hasPermission("areashop.delsign")) {
|
|
regionSign.remove();
|
|
plugin.message(event.getPlayer(), "delsign-success", regionSign.getRegion());
|
|
} else { // Cancel the breaking of the sign
|
|
event.setCancelled(true);
|
|
plugin.message(event.getPlayer(), "delsign-noPermission", regionSign.getRegion());
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
public void onIndirectSignBreak(BlockPhysicsEvent event) {
|
|
// Check if the block is a sign
|
|
if(!Materials.isSign(event.getBlock().getType())) {
|
|
return;
|
|
}
|
|
|
|
// Check if still attached to a block
|
|
Block attachedBlock = plugin.getBukkitHandler().getSignAttachedTo(event.getBlock());
|
|
// TODO: signs cannot be placed on all blocks, improve this check to isSolid()?
|
|
if (attachedBlock.getType() != Material.AIR) {
|
|
return;
|
|
}
|
|
|
|
// Check if the sign is really the same as a saved rent
|
|
RegionSign regionSign = SignsFeature.getSignByLocation(event.getBlock().getLocation());
|
|
if(regionSign == null) {
|
|
return;
|
|
}
|
|
|
|
// Remove the sign so that it does not fall on the floor as an item (next region update will place it back when possible)
|
|
AreaShop.debug("onIndirectSignBreak: Removed block of sign for", regionSign.getRegion().getName(), "at", regionSign.getStringLocation());
|
|
event.getBlock().setType(Material.AIR);
|
|
event.setCancelled(true);
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
|
public void onSignClick(PlayerInteractEvent event) {
|
|
Block block = event.getClickedBlock();
|
|
if (block == null) {
|
|
return;
|
|
}
|
|
|
|
// Only listen to left and right clicks on blocks
|
|
if (!(event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK)) {
|
|
return;
|
|
}
|
|
|
|
// Only care about clicking blocks
|
|
if(!Materials.isSign(block.getType())) {
|
|
return;
|
|
}
|
|
|
|
// Check if this sign belongs to a region
|
|
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
|
if(regionSign == null) {
|
|
return;
|
|
}
|
|
|
|
// Ignore players that are in sign link mode (which will handle the event itself)
|
|
Player player = event.getPlayer();
|
|
if(plugin.getSignlinkerManager().isInSignLinkMode(player)) {
|
|
return;
|
|
}
|
|
|
|
// Get the clicktype
|
|
GeneralRegion.ClickType clickType = null;
|
|
if(player.isSneaking() && event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
|
clickType = GeneralRegion.ClickType.SHIFTLEFTCLICK;
|
|
} else if(!player.isSneaking() && event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
|
clickType = GeneralRegion.ClickType.LEFTCLICK;
|
|
} else if(player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
|
clickType = GeneralRegion.ClickType.SHIFTRIGHTCLICK;
|
|
} else if(!player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
|
clickType = GeneralRegion.ClickType.RIGHTCLICK;
|
|
}
|
|
|
|
boolean ran = regionSign.runSignCommands(player, clickType);
|
|
|
|
// Only cancel event if at least one command has been executed
|
|
event.setCancelled(ran);
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.MONITOR)
|
|
public void onSignChange(SignChangeEvent event) {
|
|
if(event.isCancelled()) {
|
|
return;
|
|
}
|
|
Player player = event.getPlayer();
|
|
if(!plugin.isReady()) {
|
|
plugin.message(player, "general-notReady");
|
|
return;
|
|
}
|
|
|
|
// Check if the sign is meant for this plugin
|
|
if(event.getLine(0).contains(plugin.getConfig().getString("signTags.rent"))) {
|
|
if(!player.hasPermission("areashop.createrent") && !player.hasPermission("areashop.createrent.member") && !player.hasPermission("areashop.createrent.owner")) {
|
|
plugin.message(player, "setup-noPermissionRent");
|
|
return;
|
|
}
|
|
|
|
// Get the other lines
|
|
String secondLine = event.getLine(1);
|
|
String thirdLine = event.getLine(2);
|
|
String fourthLine = event.getLine(3);
|
|
|
|
// Get the regionManager for accessing regions
|
|
RegionManager regionManager = plugin.getRegionManager(event.getPlayer().getWorld());
|
|
|
|
// If the secondLine does not contain a name try to find the region by location
|
|
if(secondLine == null || secondLine.isEmpty()) {
|
|
Set<ProtectedRegion> regions = plugin.getWorldGuardHandler().getApplicableRegionsSet(event.getBlock().getLocation());
|
|
if(regions != null) {
|
|
boolean first = true;
|
|
ProtectedRegion candidate = null;
|
|
for(ProtectedRegion pr : regions) {
|
|
if(first) {
|
|
candidate = pr;
|
|
first = false;
|
|
} else {
|
|
if(pr.getPriority() > candidate.getPriority()) {
|
|
candidate = pr;
|
|
} else if(pr.getPriority() < candidate.getPriority()) {
|
|
// Already got the correct one
|
|
} else if(pr.getParent() != null && pr.getParent().equals(candidate)) {
|
|
candidate = pr;
|
|
} else if(candidate.getParent() != null && candidate.getParent().equals(pr)) {
|
|
// Already got the correct one
|
|
} else {
|
|
plugin.message(player, "setup-couldNotDetect", candidate.getId(), pr.getId());
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if(candidate != null) {
|
|
secondLine = candidate.getId();
|
|
}
|
|
}
|
|
}
|
|
|
|
boolean priceSet = fourthLine != null && !fourthLine.isEmpty();
|
|
boolean durationSet = thirdLine != null && !thirdLine.isEmpty();
|
|
// check if all the lines are correct
|
|
if(secondLine == null || secondLine.isEmpty()) {
|
|
plugin.message(player, "setup-noRegion");
|
|
return;
|
|
}
|
|
ProtectedRegion region = regionManager.getRegion(secondLine);
|
|
if(region == null) {
|
|
plugin.message(player, "cmd-noRegion", secondLine);
|
|
return;
|
|
}
|
|
|
|
FileManager.AddResult addResult = plugin.getFileManager().checkRegionAdd(player, regionManager.getRegion(secondLine), event.getPlayer().getWorld(), GeneralRegion.RegionType.RENT);
|
|
if(addResult == FileManager.AddResult.BLACKLISTED) {
|
|
plugin.message(player, "setup-blacklisted", secondLine);
|
|
} else if(addResult == FileManager.AddResult.ALREADYADDED) {
|
|
plugin.message(player, "setup-alreadyRentSign");
|
|
} else if(addResult == FileManager.AddResult.ALREADYADDEDOTHERWORLD) {
|
|
plugin.message(player, "setup-alreadyOtherWorld");
|
|
} else if(addResult == FileManager.AddResult.NOPERMISSION) {
|
|
plugin.message(player, "setup-noPermission", secondLine);
|
|
} else if(thirdLine != null && !thirdLine.isEmpty() && !Utils.checkTimeFormat(thirdLine)) {
|
|
plugin.message(player, "setup-wrongDuration");
|
|
} else {
|
|
double price = 0.0;
|
|
if(priceSet) {
|
|
// Check the fourth line
|
|
try {
|
|
price = Double.parseDouble(fourthLine);
|
|
} catch(NumberFormatException e) {
|
|
plugin.message(player, "setup-wrongPrice");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Add rent to the FileManager
|
|
final RentRegion rent = new RentRegion(secondLine, event.getPlayer().getWorld());
|
|
boolean isMember = plugin.getWorldGuardHandler().containsMember(rent.getRegion(), player.getUniqueId());
|
|
boolean isOwner = plugin.getWorldGuardHandler().containsOwner(rent.getRegion(), player.getUniqueId());
|
|
boolean landlord = (!player.hasPermission("areashop.createrent")
|
|
&& ((player.hasPermission("areashop.createrent.owner") && isOwner)
|
|
|| (player.hasPermission("areashop.createrent.member") && isMember)));
|
|
|
|
if(landlord) {
|
|
rent.setLandlord(player.getUniqueId(), player.getName());
|
|
}
|
|
if(priceSet) {
|
|
rent.setPrice(price);
|
|
}
|
|
if(durationSet) {
|
|
rent.setDuration(thirdLine);
|
|
}
|
|
rent.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), plugin.getBukkitHandler().getSignFacing(event.getBlock()), null);
|
|
|
|
AddingRegionEvent addingRegionEvent = plugin.getFileManager().addRegion(rent);
|
|
if (addingRegionEvent.isCancelled()) {
|
|
plugin.message(player, "general-cancelled", addingRegionEvent.getReason());
|
|
return;
|
|
}
|
|
|
|
rent.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
|
plugin.message(player, "setup-rentSuccess", rent);
|
|
// Update the region after the event has written its lines
|
|
Do.sync(rent::update);
|
|
}
|
|
} else if(event.getLine(0).contains(plugin.getConfig().getString("signTags.buy"))) {
|
|
// Check for permission
|
|
if(!player.hasPermission("areashop.createbuy") && !player.hasPermission("areashop.createbuy.member") && !player.hasPermission("areashop.createbuy.owner")) {
|
|
plugin.message(player, "setup-noPermissionBuy");
|
|
return;
|
|
}
|
|
|
|
// Get the other lines
|
|
String secondLine = event.getLine(1);
|
|
String thirdLine = event.getLine(2);
|
|
|
|
// Get the regionManager for accessing regions
|
|
RegionManager regionManager = plugin.getRegionManager(event.getPlayer().getWorld());
|
|
|
|
// If the secondLine does not contain a name try to find the region by location
|
|
if(secondLine == null || secondLine.isEmpty()) {
|
|
Set<ProtectedRegion> regions = plugin.getWorldGuardHandler().getApplicableRegionsSet(event.getBlock().getLocation());
|
|
if(regions != null) {
|
|
boolean first = true;
|
|
ProtectedRegion candidate = null;
|
|
for(ProtectedRegion pr : regions) {
|
|
if(first) {
|
|
candidate = pr;
|
|
first = false;
|
|
} else {
|
|
if(pr.getPriority() > candidate.getPriority()) {
|
|
candidate = pr;
|
|
} else if(pr.getPriority() < candidate.getPriority()) {
|
|
// Already got the correct one
|
|
} else if(pr.getParent() != null && pr.getParent().equals(candidate)) {
|
|
candidate = pr;
|
|
} else if(candidate.getParent() != null && candidate.getParent().equals(pr)) {
|
|
// Already got the correct one
|
|
} else {
|
|
plugin.message(player, "setup-couldNotDetect", candidate.getId(), pr.getId());
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if(candidate != null) {
|
|
secondLine = candidate.getId();
|
|
}
|
|
}
|
|
}
|
|
|
|
boolean priceSet = thirdLine != null && !thirdLine.isEmpty();
|
|
// Check if all the lines are correct
|
|
if(secondLine == null || secondLine.isEmpty()) {
|
|
plugin.message(player, "setup-noRegion");
|
|
return;
|
|
}
|
|
ProtectedRegion region = regionManager.getRegion(secondLine);
|
|
if(region == null) {
|
|
plugin.message(player, "cmd-noRegion", secondLine);
|
|
return;
|
|
}
|
|
FileManager.AddResult addResult = plugin.getFileManager().checkRegionAdd(player, region, event.getPlayer().getWorld(), GeneralRegion.RegionType.BUY);
|
|
if(addResult == FileManager.AddResult.BLACKLISTED) {
|
|
plugin.message(player, "setup-blacklisted", secondLine);
|
|
} else if(addResult == FileManager.AddResult.ALREADYADDED) {
|
|
plugin.message(player, "setup-alreadyRentSign");
|
|
} else if(addResult == FileManager.AddResult.ALREADYADDEDOTHERWORLD) {
|
|
plugin.message(player, "setup-alreadyOtherWorld");
|
|
} else if(addResult == FileManager.AddResult.NOPERMISSION) {
|
|
plugin.message(player, "setup-noPermission", secondLine);
|
|
} else {
|
|
double price = 0.0;
|
|
if(priceSet) {
|
|
// Check the fourth line
|
|
try {
|
|
price = Double.parseDouble(thirdLine);
|
|
} catch(NumberFormatException e) {
|
|
plugin.message(player, "setup-wrongPrice");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Add buy to the FileManager
|
|
final BuyRegion buy = new BuyRegion(secondLine, event.getPlayer().getWorld());
|
|
boolean isMember = plugin.getWorldGuardHandler().containsMember(buy.getRegion(), player.getUniqueId());
|
|
boolean isOwner = plugin.getWorldGuardHandler().containsOwner(buy.getRegion(), player.getUniqueId());
|
|
boolean landlord = (!player.hasPermission("areashop.createbuy")
|
|
&& ((player.hasPermission("areashop.createbuy.owner") && isOwner)
|
|
|| (player.hasPermission("areashop.createbuy.member") && isMember)));
|
|
|
|
if(landlord) {
|
|
buy.setLandlord(player.getUniqueId(), player.getName());
|
|
}
|
|
if(priceSet) {
|
|
buy.setPrice(price);
|
|
}
|
|
buy.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), plugin.getBukkitHandler().getSignFacing(event.getBlock()), null);
|
|
|
|
AddingRegionEvent addingRegionEvent = plugin.getFileManager().addRegion(buy);
|
|
if (addingRegionEvent.isCancelled()) {
|
|
plugin.message(player, "general-cancelled", addingRegionEvent.getReason());
|
|
return;
|
|
}
|
|
|
|
buy.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
|
plugin.message(player, "setup-buySuccess", buy);
|
|
// Update the region after the event has written its lines
|
|
Do.sync(buy::update);
|
|
}
|
|
} else if(event.getLine(0).contains(plugin.getConfig().getString("signTags.add"))) {
|
|
// Check for permission
|
|
if(!player.hasPermission("areashop.addsign")) {
|
|
plugin.message(player, "addsign-noPermission");
|
|
return;
|
|
}
|
|
|
|
// Get the other lines
|
|
String secondLine = event.getLine(1);
|
|
String thirdLine = event.getLine(2);
|
|
|
|
GeneralRegion region;
|
|
if(secondLine != null && !secondLine.isEmpty()) {
|
|
// Get region by secondLine of the sign
|
|
region = plugin.getFileManager().getRegion(secondLine);
|
|
if(region == null) {
|
|
plugin.message(player, "addSign-notRegistered", secondLine);
|
|
return;
|
|
}
|
|
} else {
|
|
// Get region by sign position
|
|
List<GeneralRegion> regions = Utils.getImportantRegions(event.getBlock().getLocation());
|
|
if(regions.isEmpty()) {
|
|
plugin.message(player, "addsign-noRegions");
|
|
return;
|
|
} else if(regions.size() > 1) {
|
|
plugin.message(player, "addsign-couldNotDetectSign", regions.get(0).getName(), regions.get(1).getName());
|
|
return;
|
|
}
|
|
region = regions.get(0);
|
|
}
|
|
|
|
if(thirdLine == null || thirdLine.isEmpty()) {
|
|
region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), plugin.getBukkitHandler().getSignFacing(event.getBlock()), null);
|
|
plugin.message(player, "addsign-success", region);
|
|
} else {
|
|
region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), plugin.getBukkitHandler().getSignFacing(event.getBlock()), thirdLine);
|
|
plugin.message(player, "addsign-successProfile", thirdLine, region);
|
|
}
|
|
|
|
// Update the region later because this event will do it first
|
|
Do.sync(region::update);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convert a location to a string to use as map key.
|
|
* @param location The location to get the key for
|
|
* @return A string to use in a map for a location
|
|
*/
|
|
public static String locationToString(Location location) {
|
|
return location.getWorld().getName() + ";" + location.getBlockX() + ";" + location.getBlockY() + ";" + location.getBlockZ();
|
|
}
|
|
|
|
/**
|
|
* Convert a chunk to a string to use as map key.
|
|
* @param location The location to get the key for
|
|
* @return A string to use in a map for a chunk
|
|
*/
|
|
public static String chunkToString(Location location) {
|
|
return location.getWorld().getName() + ";" + (location.getBlockX() >> 4) + ";" + (location.getBlockZ() >> 4);
|
|
}
|
|
|
|
/**
|
|
* Convert a chunk to a string to use as map key.
|
|
* Use a Location argument to prevent chunk loading!
|
|
* @param chunk The location to get the key for
|
|
* @return A string to use in a map for a chunk
|
|
*/
|
|
public static String chunkToString(Chunk chunk) {
|
|
return chunk.getWorld().getName() + ";" + chunk.getX() + ";" + chunk.getZ();
|
|
}
|
|
|
|
/**
|
|
* Get a sign by a location.
|
|
* @param location The location to get the sign for
|
|
* @return The RegionSign that is at the location, or null if none
|
|
*/
|
|
public static RegionSign getSignByLocation(Location location) {
|
|
return allSigns.get(locationToString(location));
|
|
}
|
|
|
|
/**
|
|
* Get the map with all signs.
|
|
* @return Map with all signs: locationString -> RegionSign
|
|
*/
|
|
public static Map<String, RegionSign> getAllSigns() {
|
|
return allSigns;
|
|
}
|
|
|
|
/**
|
|
* Get the map with signs by chunk.
|
|
* @return Map with signs by chunk: chunkString -> List<RegionSign>
|
|
*/
|
|
public static Map<String, List<RegionSign>> getSignsByChunk() {
|
|
return signsByChunk;
|
|
}
|
|
|
|
@EventHandler
|
|
public void regionUpdate(UpdateRegionEvent event) {
|
|
event.getRegion().getSignsFeature().update();
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.MONITOR)
|
|
public void onChunkLoad(ChunkLoadEvent event) {
|
|
List<RegionSign> chunkSigns = signsByChunk.get(chunkToString(event.getChunk()));
|
|
if(chunkSigns == null) {
|
|
return;
|
|
}
|
|
|
|
Do.forAll(chunkSigns, RegionSign::update);
|
|
}
|
|
|
|
/**
|
|
* Update all signs connected to this region.
|
|
* @return true if all signs are updated correctly, false if one or more updates failed
|
|
*/
|
|
public boolean update() {
|
|
boolean result = true;
|
|
for(RegionSign sign : signs.values()) {
|
|
result &= sign.update();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check if any of the signs need periodic updating.
|
|
* @return true if one or more of the signs need periodic updating, otherwise false
|
|
*/
|
|
public boolean needsPeriodicUpdate() {
|
|
boolean result = false;
|
|
for(RegionSign sign : signs.values()) {
|
|
result |= sign.needsPeriodicUpdate();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get the signs of this region.
|
|
* @return List of signs
|
|
*/
|
|
public List<RegionSign> getSigns() {
|
|
return Collections.unmodifiableList(new ArrayList<>(signs.values()));
|
|
}
|
|
|
|
/**
|
|
* Get the signs of this region.
|
|
* @return Map with signs: locationString -> RegionSign
|
|
*/
|
|
Map<String, RegionSign> getSignsRef() {
|
|
return signs;
|
|
}
|
|
|
|
/**
|
|
* Get a list with all sign locations.
|
|
* @return A List with all sign locations
|
|
*/
|
|
public List<Location> getSignLocations() {
|
|
List<Location> result = new ArrayList<>();
|
|
for(RegionSign sign : signs.values()) {
|
|
result.add(sign.getLocation());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Add a sign to this region.
|
|
* @param location The location of the sign
|
|
* @param signType The type of the sign (WALL_SIGN or SIGN_POST)
|
|
* @param facing The orientation of the sign
|
|
* @param profile The profile to use with this sign (null for default)
|
|
*/
|
|
public void addSign(Location location, Material signType, BlockFace facing, String profile) {
|
|
int i = 0;
|
|
while(getRegion().getConfig().isSet("general.signs." + i)) {
|
|
i++;
|
|
}
|
|
String signPath = "general.signs." + i + ".";
|
|
getRegion().setSetting(signPath + "location", Utils.locationToConfig(location));
|
|
getRegion().setSetting(signPath + "facing", facing != null ? facing.name() : null);
|
|
getRegion().setSetting(signPath + "signType", signType != null ? signType.name() : null);
|
|
if(profile != null && !profile.isEmpty()) {
|
|
getRegion().setSetting(signPath + "profile", profile);
|
|
}
|
|
// Add to the map
|
|
RegionSign sign = new RegionSign(this, i + "");
|
|
signs.put(sign.getStringLocation(), sign);
|
|
allSigns.put(sign.getStringLocation(), sign);
|
|
signsByChunk.computeIfAbsent(sign.getStringChunk(), key -> new ArrayList<>())
|
|
.add(sign);
|
|
}
|
|
|
|
}
|