mirror of
https://github.com/zDevelopers/ImageOnMap.git
synced 2024-11-28 21:15:46 +01:00
commit
1b2599836e
@ -107,12 +107,18 @@ public final class ImageOnMap extends ZPlugin
|
|||||||
Commands.registerShortcut("maptool", NewCommand.class, "tomap");
|
Commands.registerShortcut("maptool", NewCommand.class, "tomap");
|
||||||
Commands.registerShortcut("maptool", ExploreCommand.class, "maps");
|
Commands.registerShortcut("maptool", ExploreCommand.class, "maps");
|
||||||
|
|
||||||
UpdateChecker.boot("imageonmap.26585");
|
if (PluginConfiguration.CHECK_FOR_UPDATES.get())
|
||||||
|
{
|
||||||
|
UpdateChecker.boot("imageonmap.26585");
|
||||||
|
}
|
||||||
|
|
||||||
final Metrics metrics = new Metrics(this);
|
if (PluginConfiguration.COLLECT_DATA.get())
|
||||||
|
{
|
||||||
|
final Metrics metrics = new Metrics(this);
|
||||||
|
|
||||||
metrics.addCustomChart(new Metrics.SingleLineChart("rendered-images", MapManager::getImagesCount));
|
metrics.addCustomChart(new Metrics.SingleLineChart("rendered-images", MapManager::getImagesCount));
|
||||||
metrics.addCustomChart(new Metrics.SingleLineChart("used-minecraft-maps", MapManager::getMapCount));
|
metrics.addCustomChart(new Metrics.SingleLineChart("used-minecraft-maps", MapManager::getMapCount));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -31,10 +31,18 @@ public final class PluginConfiguration extends Configuration
|
|||||||
static public ConfigurationItem<Locale> LANG = item("lang", Locale.class);
|
static public ConfigurationItem<Locale> LANG = item("lang", Locale.class);
|
||||||
|
|
||||||
static public ConfigurationItem<Boolean> COLLECT_DATA = item("collect-data", true);
|
static public ConfigurationItem<Boolean> COLLECT_DATA = item("collect-data", true);
|
||||||
static public ConfigurationItem<Boolean> SAVE_FULL_IMAGE = item("save-full-image", true);
|
|
||||||
|
static public ConfigurationItem<Boolean> CHECK_FOR_UPDATES = item("check-for-updates", true);
|
||||||
|
|
||||||
static public ConfigurationItem<Integer> MAP_GLOBAL_LIMIT = item("map-global-limit", 0, "Limit-map-by-server");
|
static public ConfigurationItem<Integer> MAP_GLOBAL_LIMIT = item("map-global-limit", 0, "Limit-map-by-server");
|
||||||
static public ConfigurationItem<Integer> MAP_PLAYER_LIMIT = item("map-player-limit", 0, "Limit-map-by-player");
|
static public ConfigurationItem<Integer> MAP_PLAYER_LIMIT = item("map-player-limit", 0, "Limit-map-by-player");
|
||||||
|
|
||||||
|
static public ConfigurationItem<Integer> MAP_SIZE_NOTOP_LIMIT = item("map-size-notop-limit", 0, "Size-limit-map-notop");
|
||||||
|
|
||||||
|
static public ConfigurationItem<Boolean> SAVE_FULL_IMAGE = item("save-full-image", true);
|
||||||
|
|
||||||
|
|
||||||
static public ConfigurationItem<Integer> LIMIT_SIZE_X = item("limit-map-size-x", 0);
|
static public ConfigurationItem<Integer> LIMIT_SIZE_X = item("limit-map-size-x", 0);
|
||||||
static public ConfigurationItem<Integer> LIMIT_SIZE_Y = item("limit-map-size-y", 0);
|
static public ConfigurationItem<Integer> LIMIT_SIZE_Y = item("limit-map-size-y", 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -75,34 +75,37 @@ public class NewCommand extends IoMCommand
|
|||||||
default: throwInvalidArgument(I.t("Invalid Stretching mode.")); break;
|
default: throwInvalidArgument(I.t("Invalid Stretching mode.")); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
ActionBar.sendPermanentMessage(player, ChatColor.DARK_GREEN + I.t("Rendering..."));
|
|
||||||
ImageRendererExecutor.render(url, scaling, player.getUniqueId(), width, height, new WorkerCallback<ImageMap>()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void finished(ImageMap result)
|
|
||||||
{
|
|
||||||
ActionBar.removeMessage(player);
|
|
||||||
MessageSender.sendActionBarMessage(player, ChatColor.DARK_GREEN + I.t("Rendering finished!"));
|
|
||||||
|
|
||||||
if (result.give(player) && (result instanceof PosterMap && !((PosterMap) result).hasColumnData()))
|
|
||||||
{
|
ActionBar.sendPermanentMessage(player, ChatColor.DARK_GREEN + I.t("Rendering..."));
|
||||||
info(I.t("The rendered map was too big to fit in your inventory."));
|
ImageRendererExecutor.render(url, scaling, player.getUniqueId(), width, height, new WorkerCallback<ImageMap>() {
|
||||||
info(I.t("Use '/maptool getremaining' to get the remaining maps."));
|
@Override
|
||||||
|
public void finished(ImageMap result) {
|
||||||
|
ActionBar.removeMessage(player);
|
||||||
|
MessageSender.sendActionBarMessage(player, ChatColor.DARK_GREEN + I.t("Rendering finished!"));
|
||||||
|
|
||||||
|
if (result.give(player) && (result instanceof PosterMap && !((PosterMap) result).hasColumnData())) {
|
||||||
|
info(I.t("The rendered map was too big to fit in your inventory."));
|
||||||
|
info(I.t("Use '/maptool getremaining' to get the remaining maps."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void errored(Throwable exception)
|
public void errored(Throwable exception) {
|
||||||
{
|
player.sendMessage(I.t("{ce}Map rendering failed: {0}", exception.getMessage()));
|
||||||
player.sendMessage(I.t("{ce}Map rendering failed: {0}", exception.getMessage()));
|
|
||||||
|
|
||||||
PluginLogger.warning("Rendering from {0} failed: {1}: {2}",
|
PluginLogger.warning("Rendering from {0} failed: {1}: {2}",
|
||||||
player.getName(),
|
player.getName(),
|
||||||
exception.getClass().getCanonicalName(),
|
exception.getClass().getCanonicalName(),
|
||||||
exception.getMessage());
|
exception.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
//Added to fix bug with rendering displaying after error
|
||||||
|
finally {
|
||||||
|
ActionBar.removeMessage(player);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -35,6 +35,7 @@ public class ImageIOExecutor extends Worker
|
|||||||
{
|
{
|
||||||
static public void loadImage(final File file, final Renderer mapRenderer)
|
static public void loadImage(final File file, final Renderer mapRenderer)
|
||||||
{
|
{
|
||||||
|
|
||||||
submitQuery(new WorkerRunnable<Void>()
|
submitQuery(new WorkerRunnable<Void>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
@ -40,7 +40,6 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
|
||||||
@WorkerAttributes (name = "Image Renderer", queriesMainThread = true)
|
@WorkerAttributes (name = "Image Renderer", queriesMainThread = true)
|
||||||
public class ImageRendererExecutor extends Worker
|
public class ImageRendererExecutor extends Worker
|
||||||
{
|
{
|
||||||
|
@ -94,4 +94,4 @@ public class ImageUtils {
|
|||||||
graphics.dispose();
|
graphics.dispose();
|
||||||
return newImage;
|
return newImage;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -38,7 +38,6 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import org.bukkit.map.MapView;
|
import org.bukkit.map.MapView;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
public class MapInitEvent implements Listener
|
public class MapInitEvent implements Listener
|
||||||
{
|
{
|
||||||
static public void init()
|
static public void init()
|
||||||
@ -113,8 +112,10 @@ public class MapInitEvent implements Listener
|
|||||||
|
|
||||||
static public void initMap(MapView map)
|
static public void initMap(MapView map)
|
||||||
{
|
{
|
||||||
if(map == null) return;
|
if(map == null) {
|
||||||
if(Renderer.isHandled(map)) return;
|
return;}
|
||||||
|
if(Renderer.isHandled(map)) {
|
||||||
|
return;}
|
||||||
|
|
||||||
File imageFile = ImageOnMap.getPlugin().getImageFile(map.getId());
|
File imageFile = ImageOnMap.getPlugin().getImageFile(map.getId());
|
||||||
if(imageFile.isFile())
|
if(imageFile.isFile())
|
||||||
|
@ -93,7 +93,6 @@ public class Renderer extends MapRenderer
|
|||||||
{
|
{
|
||||||
//Render only once to avoid overloading the server
|
//Render only once to avoid overloading the server
|
||||||
if (image == null) return;
|
if (image == null) return;
|
||||||
|
|
||||||
canvas.drawImage(0, 0, image);
|
canvas.drawImage(0, 0, image);
|
||||||
image = null;
|
image = null;
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@ abstract public class MapManager
|
|||||||
static public ImageMap createMap(PosterImage image, UUID playerUUID, int[] mapsIDs) throws MapManagerException
|
static public ImageMap createMap(PosterImage image, UUID playerUUID, int[] mapsIDs) throws MapManagerException
|
||||||
{
|
{
|
||||||
ImageMap newMap;
|
ImageMap newMap;
|
||||||
|
|
||||||
if(image.getImagesCount() == 1)
|
if(image.getImagesCount() == 1)
|
||||||
{
|
{
|
||||||
newMap = new SingleMap(playerUUID, mapsIDs[0]);
|
newMap = new SingleMap(playerUUID, mapsIDs[0]);
|
||||||
|
@ -263,6 +263,7 @@ public class PlayerMapStore implements ConfigurationSerializable
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
getToolConfig().save(mapsFile);
|
getToolConfig().save(mapsFile);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
|
@ -18,155 +18,163 @@
|
|||||||
|
|
||||||
package fr.moribus.imageonmap.map;
|
package fr.moribus.imageonmap.map;
|
||||||
|
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PosterMap extends ImageMap
|
public class PosterMap extends ImageMap {
|
||||||
{
|
protected final int[] mapsIDs;
|
||||||
protected final int[] mapsIDs;
|
protected final int columnCount;
|
||||||
protected final int columnCount;
|
protected final int rowCount;
|
||||||
protected final int rowCount;
|
|
||||||
|
|
||||||
public PosterMap(UUID userUUID, int[] mapsIDs, String id, String name, int columnCount, int rowCount)
|
|
||||||
{
|
|
||||||
super(userUUID, Type.POSTER, id, name);
|
|
||||||
this.mapsIDs = mapsIDs;
|
|
||||||
this.columnCount = Math.max(columnCount, 0);
|
|
||||||
this.rowCount = Math.max(rowCount, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PosterMap(UUID userUUID, int[] mapsIDs, int columnCount, int rowCount)
|
|
||||||
{
|
|
||||||
this(userUUID, mapsIDs, null, null, columnCount, rowCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int[] getMapsIDs()
|
|
||||||
{
|
|
||||||
return mapsIDs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public PosterMap(UUID userUUID, int[] mapsIDs, String id, String name, int columnCount, int rowCount) {
|
||||||
public boolean managesMap(int mapID)
|
super(userUUID, Type.POSTER, id, name);
|
||||||
{
|
this.mapsIDs = mapsIDs;
|
||||||
for(int i = 0; i < mapsIDs.length; i++)
|
this.columnCount = Math.max(columnCount, 0);
|
||||||
{
|
this.rowCount = Math.max(rowCount, 0);
|
||||||
if(mapsIDs[i] == mapID) return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ====== Serialization methods ====== */
|
public PosterMap(UUID userUUID, int[] mapsIDs, int columnCount, int rowCount) {
|
||||||
|
this(userUUID, mapsIDs, null, null, columnCount, rowCount);
|
||||||
public PosterMap(Map<String, Object> map, UUID userUUID) throws InvalidConfigurationException
|
}
|
||||||
{
|
|
||||||
super(map, userUUID, Type.POSTER);
|
|
||||||
|
|
||||||
columnCount = getFieldValue(map, "columns");
|
|
||||||
rowCount = getFieldValue(map, "rows");
|
|
||||||
|
|
||||||
List<Integer> idList = getFieldValue(map, "mapsIDs");
|
|
||||||
mapsIDs = new int[idList.size()];
|
|
||||||
for(int i = 0, c = idList.size(); i < c; i++)
|
|
||||||
{
|
|
||||||
mapsIDs[i] = (int) idList.get(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void postSerialize(Map<String, Object> map)
|
|
||||||
{
|
|
||||||
map.put("columns", columnCount);
|
|
||||||
map.put("rows", rowCount);
|
|
||||||
map.put("mapsIDs", mapsIDs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ====== Getters & Setters ====== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the amount of columns in the poster map
|
|
||||||
* @return The number of columns, or 0 if this data is missing
|
|
||||||
*/
|
|
||||||
public int getColumnCount()
|
|
||||||
{
|
|
||||||
return columnCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the amount of rows in the poster map
|
|
||||||
* @return The number of rows, or 0 if this data is missing
|
|
||||||
*/
|
|
||||||
public int getRowCount()
|
|
||||||
{
|
|
||||||
return rowCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColumnAt(int i)
|
|
||||||
{
|
|
||||||
if(columnCount == 0) return 0;
|
|
||||||
return (i % columnCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRowAt(int i)
|
|
||||||
{
|
|
||||||
if(columnCount == 0) return 0;
|
|
||||||
return (i / columnCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIndexAt(int col, int row)
|
|
||||||
{
|
|
||||||
return columnCount * row + col;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Returns the map id at the given column and line.
|
public int[] getMapsIDs() {
|
||||||
*
|
return mapsIDs;
|
||||||
* @param x The x coordinate. Starts at 0.
|
}
|
||||||
* @param y The y coordinate. Starts at 0.
|
|
||||||
* @return The Minecraft map ID.
|
|
||||||
*
|
|
||||||
* @throws ArrayIndexOutOfBoundsException if the given coordinates are too big (out of the poster).
|
|
||||||
*/
|
|
||||||
public int getMapIdAt(int x, int y)
|
|
||||||
{
|
|
||||||
return mapsIDs[y * columnCount + x];
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMapIdAtReverseY(int index)
|
|
||||||
{
|
|
||||||
int x = index % (columnCount);
|
|
||||||
int y = index / (columnCount);
|
|
||||||
return getMapIdAt(x, rowCount - y - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMapIdAt(int index)
|
|
||||||
{
|
|
||||||
return mapsIDs[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasColumnData()
|
|
||||||
{
|
|
||||||
return rowCount != 0 && columnCount != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMapCount()
|
public boolean managesMap(int mapID) {
|
||||||
{
|
for (int i = 0; i < mapsIDs.length; i++) {
|
||||||
return mapsIDs.length;
|
if (mapsIDs[i] == mapID)
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
public int getIndex(int mapID)
|
|
||||||
{
|
return false;
|
||||||
for(int i = 0; i < mapsIDs.length; i++)
|
}
|
||||||
{
|
|
||||||
if(mapsIDs[i] == mapID) return i;
|
/* ====== Serialization methods ====== */
|
||||||
}
|
|
||||||
|
public PosterMap(Map<String, Object> map, UUID userUUID) throws InvalidConfigurationException {
|
||||||
throw new IllegalArgumentException("Invalid map ID");
|
super(map, userUUID, Type.POSTER);
|
||||||
}
|
|
||||||
|
columnCount = getFieldValue(map, "columns");
|
||||||
|
rowCount = getFieldValue(map, "rows");
|
||||||
|
|
||||||
|
List<Integer> idList = getFieldValue(map, "mapsIDs");
|
||||||
|
mapsIDs = new int[idList.size()];
|
||||||
|
for (int i = 0, c = idList.size(); i < c; i++) {
|
||||||
|
mapsIDs[i] = idList.get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void postSerialize(Map<String, Object> map) {
|
||||||
|
map.put("columns", columnCount);
|
||||||
|
map.put("rows", rowCount);
|
||||||
|
map.put("mapsIDs", mapsIDs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ====== Getters & Setters ====== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the amount of columns in the poster map
|
||||||
|
*
|
||||||
|
* @return The number of columns, or 0 if this data is missing
|
||||||
|
*/
|
||||||
|
public int getColumnCount() {
|
||||||
|
return columnCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the amount of rows in the poster map
|
||||||
|
*
|
||||||
|
* @return The number of rows, or 0 if this data is missing
|
||||||
|
*/
|
||||||
|
public int getRowCount() {
|
||||||
|
return rowCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColumnAt(int i) {
|
||||||
|
if (columnCount == 0)
|
||||||
|
return 0;
|
||||||
|
return (i % columnCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRowAt(int i) {
|
||||||
|
if (columnCount == 0)
|
||||||
|
return 0;
|
||||||
|
return (i / columnCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndexAt(int col, int row) {
|
||||||
|
return columnCount * row + col;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the map id at the given column and line.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* The x coordinate. Starts at 0.
|
||||||
|
* @param y
|
||||||
|
* The y coordinate. Starts at 0.
|
||||||
|
* @return The Minecraft map ID.
|
||||||
|
*
|
||||||
|
* @throws ArrayIndexOutOfBoundsException
|
||||||
|
* if the given coordinates are too big (out of the poster).
|
||||||
|
*/
|
||||||
|
public int getMapIdAt(int x, int y) {
|
||||||
|
return mapsIDs[y * columnCount + x];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getMapIdAtReverseY(int index) {
|
||||||
|
int x = index % (columnCount);
|
||||||
|
int y = index / (columnCount);
|
||||||
|
return getMapIdAt(x, rowCount - y - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getMapIdAtReverseZ(int index, BlockFace orientation, BlockFace bf) {
|
||||||
|
int x = 0, y = 0;
|
||||||
|
switch (bf) {
|
||||||
|
case UP:
|
||||||
|
x = index % (columnCount);
|
||||||
|
y = index / (columnCount);
|
||||||
|
break;
|
||||||
|
case DOWN:
|
||||||
|
x = (columnCount - 1) - index % (columnCount);
|
||||||
|
y = index / (columnCount);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getMapIdAt(x, rowCount - y - 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMapIdAt(int index) {
|
||||||
|
return mapsIDs[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasColumnData() {
|
||||||
|
return rowCount != 0 && columnCount != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMapCount() {
|
||||||
|
return mapsIDs.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex(int mapID) {
|
||||||
|
for (int i = 0; i < mapsIDs.length; i++) {
|
||||||
|
if (mapsIDs[i] == mapID)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Invalid map ID");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -229,19 +229,20 @@ public class MapItemManager implements Listener
|
|||||||
if (frame.getItem().getType() != Material.AIR) return;
|
if (frame.getItem().getType() != Material.AIR) return;
|
||||||
if (!MapManager.managesMap(mapItem)) return;
|
if (!MapManager.managesMap(mapItem)) return;
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
|
|
||||||
if (SplatterMapManager.hasSplatterAttributes(mapItem))
|
if (SplatterMapManager.hasSplatterAttributes(mapItem))
|
||||||
{
|
{
|
||||||
if (!SplatterMapManager.placeSplatterMap(frame, player))
|
if (!SplatterMapManager.placeSplatterMap(frame, player,event)){
|
||||||
return;
|
event.setCancelled(true); //In case of an error allow to cancel map placement
|
||||||
|
return;}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If the item has a display name, bot not one from an anvil by the player, we remove it
|
// If the item has a display name, bot not one from an anvil by the player, we remove it
|
||||||
// si it is not displayed on hover on the wall.
|
// If it is not displayed on hover on the wall.
|
||||||
if (mapItem.hasItemMeta() && mapItem.getItemMeta().hasDisplayName() && mapItem.getItemMeta().getDisplayName().startsWith("§r"))
|
if (mapItem.hasItemMeta() && mapItem.getItemMeta().hasDisplayName() && mapItem.getItemMeta().getDisplayName().startsWith("§r"))
|
||||||
{
|
{
|
||||||
|
|
||||||
final ItemStack frameItem = mapItem.clone();
|
final ItemStack frameItem = mapItem.clone();
|
||||||
final ItemMeta meta = frameItem.getItemMeta();
|
final ItemMeta meta = frameItem.getItemMeta();
|
||||||
|
|
||||||
@ -251,9 +252,13 @@ public class MapItemManager implements Listener
|
|||||||
frame.setItem(frameItem);
|
frame.setItem(frameItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
else frame.setItem(mapItem);
|
else{
|
||||||
|
frame.setItem(mapItem);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ItemUtils.consumeItem(player);
|
ItemUtils.consumeItem(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +269,7 @@ public class MapItemManager implements Listener
|
|||||||
|
|
||||||
if (player.isSneaking())
|
if (player.isSneaking())
|
||||||
{
|
{
|
||||||
PosterMap poster = SplatterMapManager.removeSplatterMap(frame);
|
PosterMap poster = SplatterMapManager.removeSplatterMap(frame,player);
|
||||||
if (poster != null)
|
if (poster != null)
|
||||||
{
|
{
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
218
src/main/java/fr/moribus/imageonmap/ui/PosterOnASurface.java
Normal file
218
src/main/java/fr/moribus/imageonmap/ui/PosterOnASurface.java
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 Moribus
|
||||||
|
* Copyright (C) 2015 ProkopyL <prokopylmc@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package fr.moribus.imageonmap.ui;
|
||||||
|
|
||||||
|
import fr.moribus.imageonmap.map.PosterMap;
|
||||||
|
import fr.zcraft.zlib.tools.world.FlatLocation;
|
||||||
|
import fr.zcraft.zlib.tools.world.WorldUtils;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.ItemFrame;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class PosterOnASurface {
|
||||||
|
|
||||||
|
public FlatLocation loc1;
|
||||||
|
public FlatLocation loc2;
|
||||||
|
|
||||||
|
public ItemFrame[] frames;
|
||||||
|
|
||||||
|
public boolean isValid(Player p) {
|
||||||
|
ItemFrame curFrame;
|
||||||
|
|
||||||
|
|
||||||
|
FlatLocation l = loc1.clone();
|
||||||
|
|
||||||
|
BlockFace bf = WorldUtils.get4thOrientation(p.getLocation());
|
||||||
|
|
||||||
|
l.subtract(loc2);
|
||||||
|
|
||||||
|
|
||||||
|
int distX = Math.abs(l.getBlockX());
|
||||||
|
int distZ = Math.abs(l.getBlockZ());
|
||||||
|
|
||||||
|
frames = new ItemFrame[distX * distZ];
|
||||||
|
l = loc1.clone();
|
||||||
|
for (int x = 0; x < distX; x++) {
|
||||||
|
for (int z = 0; z < distZ; z++) {
|
||||||
|
|
||||||
|
curFrame = getEmptyFrameAt(l, l.getFacing());
|
||||||
|
|
||||||
|
if (curFrame == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
frames[z * distX + x] = curFrame;
|
||||||
|
|
||||||
|
switch (bf) {
|
||||||
|
case NORTH:
|
||||||
|
case SOUTH:
|
||||||
|
l.addH(0, 1, bf);
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
case WEST:
|
||||||
|
l.addH(1, 0, bf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (bf) {
|
||||||
|
case NORTH:
|
||||||
|
case SOUTH:
|
||||||
|
l.addH(1, -distZ, bf);
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
case WEST:
|
||||||
|
l.addH(-distZ, 1, bf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void expand() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the list of map Frames associated with a specific map
|
||||||
|
* */
|
||||||
|
static public ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, int mapId, BlockFace bf) {
|
||||||
|
int mapIndex = map.getIndex(mapId);
|
||||||
|
//int x = map.getColumnAt(mapIndex), y = map.getRowAt(mapIndex);
|
||||||
|
int x=0,y=0;
|
||||||
|
switch(bf){
|
||||||
|
case EAST:
|
||||||
|
case WEST:
|
||||||
|
y=map.getColumnCount()-1;
|
||||||
|
break;
|
||||||
|
case NORTH:
|
||||||
|
case SOUTH:
|
||||||
|
y=map.getRowCount()-1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return getMatchingMapFrames(map, location.clone().addH(x, y,bf),bf).clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
static public ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, BlockFace bf) {
|
||||||
|
ItemFrame[] frames = new ItemFrame[map.getMapCount()];
|
||||||
|
FlatLocation loc = location.clone();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int X=0;
|
||||||
|
int Y=0;
|
||||||
|
switch (bf){
|
||||||
|
case EAST:
|
||||||
|
case WEST:
|
||||||
|
/*X=map.getRowCount();
|
||||||
|
Y=map.getColumnCount();
|
||||||
|
break;*/
|
||||||
|
case NORTH:
|
||||||
|
case SOUTH:
|
||||||
|
|
||||||
|
Y=map.getRowCount();
|
||||||
|
X=map.getColumnCount();
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < Y; ++y) {
|
||||||
|
for (int x = 0; x < X; ++x) {
|
||||||
|
int mapIndex = map.getIndexAt(x, y);
|
||||||
|
|
||||||
|
ItemFrame frame = getMapFrameAt(loc, map);
|
||||||
|
if (frame != null)
|
||||||
|
frames[mapIndex] = frame;
|
||||||
|
switch (bf){
|
||||||
|
case EAST:
|
||||||
|
case WEST:
|
||||||
|
loc.addH( 0,-1,bf);
|
||||||
|
break;
|
||||||
|
case NORTH:
|
||||||
|
case SOUTH:
|
||||||
|
loc.addH( 1,0,bf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (bf){
|
||||||
|
case EAST:
|
||||||
|
case WEST:
|
||||||
|
loc.addH( 1,map.getColumnCount(),bf);//test
|
||||||
|
|
||||||
|
break;
|
||||||
|
case NORTH:
|
||||||
|
case SOUTH:
|
||||||
|
loc.addH(-map.getColumnCount(), -1,bf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public ItemFrame getMapFrameAt(FlatLocation location, PosterMap map) {
|
||||||
|
Entity entities[] = location.getChunk().getEntities();
|
||||||
|
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
if (!(entity instanceof ItemFrame))
|
||||||
|
continue;
|
||||||
|
if (!WorldUtils.blockEquals(location, entity.getLocation()))
|
||||||
|
continue;
|
||||||
|
ItemFrame frame = (ItemFrame) entity;
|
||||||
|
if (frame.getFacing() != location.getFacing())
|
||||||
|
continue;
|
||||||
|
ItemStack item = frame.getItem();
|
||||||
|
if (item.getType() != Material.FILLED_MAP)
|
||||||
|
continue;
|
||||||
|
if (!map.managesMap(item))
|
||||||
|
continue;
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public ItemFrame getEmptyFrameAt(Location location, BlockFace facing) {
|
||||||
|
Entity entities[] = location.getChunk().getEntities();
|
||||||
|
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
if (!(entity instanceof ItemFrame))
|
||||||
|
continue;
|
||||||
|
if (!WorldUtils.blockEquals(location, entity.getLocation()))
|
||||||
|
continue;
|
||||||
|
ItemFrame frame = (ItemFrame) entity;
|
||||||
|
if (frame.getFacing() != facing)
|
||||||
|
continue;
|
||||||
|
ItemStack item = frame.getItem();
|
||||||
|
if (item.getType() != Material.AIR)
|
||||||
|
continue;
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -44,7 +44,7 @@ public class PosterWall
|
|||||||
|
|
||||||
int distX = FlatLocation.flatBlockDistanceX(loc1, loc2);
|
int distX = FlatLocation.flatBlockDistanceX(loc1, loc2);
|
||||||
int distY = FlatLocation.flatBlockDistanceY(loc1, loc2);
|
int distY = FlatLocation.flatBlockDistanceY(loc1, loc2);
|
||||||
|
|
||||||
frames = new ItemFrame[distX * distY];
|
frames = new ItemFrame[distX * distY];
|
||||||
|
|
||||||
for(int x = 0; x < distX; x++)
|
for(int x = 0; x < distX; x++)
|
||||||
@ -65,9 +65,7 @@ public class PosterWall
|
|||||||
|
|
||||||
public void expand()
|
public void expand()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static public ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, int mapId)
|
static public ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, int mapId)
|
||||||
|
@ -33,182 +33,306 @@ import fr.zcraft.zlib.tools.items.ItemStackBuilder;
|
|||||||
import fr.zcraft.zlib.tools.reflection.NMSException;
|
import fr.zcraft.zlib.tools.reflection.NMSException;
|
||||||
import fr.zcraft.zlib.tools.text.MessageSender;
|
import fr.zcraft.zlib.tools.text.MessageSender;
|
||||||
import fr.zcraft.zlib.tools.world.FlatLocation;
|
import fr.zcraft.zlib.tools.world.FlatLocation;
|
||||||
|
import fr.zcraft.zlib.tools.world.WorldUtils;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Rotation;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.ItemFrame;
|
import org.bukkit.entity.ItemFrame;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.MapMeta;
|
import org.bukkit.inventory.meta.MapMeta;
|
||||||
|
|
||||||
abstract public class SplatterMapManager
|
abstract public class SplatterMapManager {
|
||||||
{
|
private SplatterMapManager() {
|
||||||
private SplatterMapManager() {}
|
}
|
||||||
|
|
||||||
static public ItemStack makeSplatterMap(PosterMap map)
|
|
||||||
{
|
|
||||||
final ItemStack splatter = new ItemStackBuilder(Material.FILLED_MAP)
|
|
||||||
.title(ChatColor.GOLD, map.getName())
|
|
||||||
.title(ChatColor.DARK_GRAY, " - ")
|
|
||||||
.title(ChatColor.GRAY, I.t("Splatter Map"))
|
|
||||||
.title(ChatColor.DARK_GRAY, " - ")
|
|
||||||
.title(ChatColor.GRAY, I.t("{0} × {1}", map.getColumnCount(), map.getRowCount()))
|
|
||||||
.loreLine(ChatColor.GRAY, map.getId())
|
|
||||||
.loreLine()
|
|
||||||
/// Title in a splatter map tooltip
|
|
||||||
.loreLine(ChatColor.BLUE, I.t("Item frames needed"))
|
|
||||||
/// Size of a map stored in a splatter map
|
|
||||||
.loreLine(ChatColor.GRAY, I.t("{0} × {1} (total {2} frames)", map.getColumnCount(), map.getRowCount(), map.getColumnCount() * map.getRowCount()))
|
|
||||||
.loreLine()
|
|
||||||
/// Title in a splatter map tooltip
|
|
||||||
.loreLine(ChatColor.BLUE, I.t("How to use this?"))
|
|
||||||
.longLore(ChatColor.GRAY + I.t("Place empty item frames on a wall, enough to host the whole map. Then, right-click on the bottom-left frame with this map."), 40)
|
|
||||||
.loreLine()
|
|
||||||
.longLore(ChatColor.GRAY + I.t("Shift-click one of the placed maps to remove the whole poster in one shot."), 40)
|
|
||||||
.hideAttributes()
|
|
||||||
.craftItem();
|
|
||||||
|
|
||||||
final MapMeta meta = (MapMeta) splatter.getItemMeta();
|
static public ItemStack makeSplatterMap(PosterMap map) {
|
||||||
meta.setMapId(map.getMapIdAt(0));
|
|
||||||
meta.setColor(Color.GREEN);
|
|
||||||
splatter.setItemMeta(meta);
|
|
||||||
|
|
||||||
return addSplatterAttribute(splatter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To identify image on maps for the auto-splattering to work, we mark the items
|
|
||||||
* using an enchantment maps are not supposed to have (Mending).
|
|
||||||
*
|
|
||||||
* Then we check if the map is enchanted at all to know if it's a splatter map.
|
|
||||||
* This ensure compatibility with old splatter maps from 3.x, where zLib's glow
|
|
||||||
* effect was used.
|
|
||||||
*
|
|
||||||
* An AttributeModifier (using zLib's attributes system) is not used, because
|
|
||||||
* Minecraft (or Spigot) removes them from maps in 1.14+, so that wasn't stable
|
|
||||||
* enough (and the glowing effect of enchantments is prettier).
|
|
||||||
*
|
|
||||||
* @param itemStack The item stack to mark as a splatter map.
|
|
||||||
* @return The modified item stack. The instance may be different if the
|
|
||||||
* passed item stack is not a craft item stack; that's why the instance is
|
|
||||||
* returned.
|
|
||||||
*/
|
|
||||||
static public ItemStack addSplatterAttribute(final ItemStack itemStack)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
final NBTCompound nbt = NBT.fromItemStack(itemStack);
|
|
||||||
final NBTList enchantments = new NBTList();
|
|
||||||
final NBTCompound protection = new NBTCompound();
|
|
||||||
|
|
||||||
protection.put("id", "minecraft:mending");
|
final ItemStack splatter = new ItemStackBuilder(Material.FILLED_MAP).title(ChatColor.GOLD, map.getName())
|
||||||
protection.put("lvl", 1);
|
.title(ChatColor.DARK_GRAY, " - ").title(ChatColor.GRAY, I.t("Splatter Map"))
|
||||||
enchantments.add(protection);
|
.title(ChatColor.DARK_GRAY, " - ")
|
||||||
|
.title(ChatColor.GRAY, I.t("{0} × {1}", map.getColumnCount(), map.getRowCount()))
|
||||||
|
.loreLine(ChatColor.GRAY, map.getId()).loreLine()
|
||||||
|
/// Title in a splatter map tooltip
|
||||||
|
.loreLine(ChatColor.BLUE, I.t("Item frames needed"))
|
||||||
|
/// Size of a map stored in a splatter map
|
||||||
|
.loreLine(ChatColor.GRAY,
|
||||||
|
I.t("{0} × {1} (total {2} frames)", map.getColumnCount(), map.getRowCount(),
|
||||||
|
map.getColumnCount() * map.getRowCount()))
|
||||||
|
.loreLine()
|
||||||
|
/// Title in a splatter map tooltip
|
||||||
|
.loreLine(ChatColor.BLUE, I.t("How to use this?"))
|
||||||
|
.longLore(
|
||||||
|
ChatColor.GRAY
|
||||||
|
+ I.t("Place empty item frames on a wall, enough to host the whole map. Then, right-click on the bottom-left frame with this map."),
|
||||||
|
40)
|
||||||
|
.loreLine()
|
||||||
|
.longLore(ChatColor.GRAY
|
||||||
|
+ I.t("Shift-click one of the placed maps to remove the whole poster in one shot."), 40)
|
||||||
|
.hideAttributes().craftItem();
|
||||||
|
|
||||||
nbt.put("Enchantments", enchantments);
|
final MapMeta meta = (MapMeta) splatter.getItemMeta();
|
||||||
|
meta.setMapId(map.getMapIdAt(0));
|
||||||
|
meta.setColor(Color.GREEN);
|
||||||
|
splatter.setItemMeta(meta);
|
||||||
|
|
||||||
return NBT.addToItemStack(itemStack, nbt, false);
|
return addSplatterAttribute(splatter);
|
||||||
}
|
}
|
||||||
catch (NBTException | NMSException e)
|
|
||||||
{
|
|
||||||
PluginLogger.error("Unable to set Splatter Map attribute on item", e);
|
|
||||||
return itemStack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if an item have the splatter attribute set (i.e. if the item is
|
* To identify image on maps for the auto-splattering to work, we mark the
|
||||||
* enchanted in any way).
|
* items using an enchantment maps are not supposed to have (Mending).
|
||||||
*
|
*
|
||||||
* @param itemStack The item to check.
|
* Then we check if the map is enchanted at all to know if it's a splatter
|
||||||
* @return True if the attribute was detected.
|
* map. This ensure compatibility with old splatter maps from 3.x, where
|
||||||
*/
|
* zLib's glow effect was used.
|
||||||
static public boolean hasSplatterAttributes(ItemStack itemStack)
|
*
|
||||||
{
|
* An AttributeModifier (using zLib's attributes system) is not used,
|
||||||
try
|
* because Minecraft (or Spigot) removes them from maps in 1.14+, so that
|
||||||
{
|
* wasn't stable enough (and the glowing effect of enchantments is
|
||||||
final NBTCompound nbt = NBT.fromItemStack(itemStack);
|
* prettier).
|
||||||
if (!nbt.containsKey("Enchantments")) return false;
|
*
|
||||||
|
* @param itemStack
|
||||||
|
* The item stack to mark as a splatter map.
|
||||||
|
* @return The modified item stack. The instance may be different if the
|
||||||
|
* passed item stack is not a craft item stack; that's why the
|
||||||
|
* instance is returned.
|
||||||
|
*/
|
||||||
|
static public ItemStack addSplatterAttribute(final ItemStack itemStack) {
|
||||||
|
try {
|
||||||
|
final NBTCompound nbt = NBT.fromItemStack(itemStack);
|
||||||
|
final NBTList enchantments = new NBTList();
|
||||||
|
final NBTCompound protection = new NBTCompound();
|
||||||
|
|
||||||
final Object enchantments = nbt.get("Enchantments");
|
protection.put("id", "minecraft:mending");
|
||||||
if (!(enchantments instanceof NBTList)) return false;
|
protection.put("lvl", 1);
|
||||||
|
enchantments.add(protection);
|
||||||
|
|
||||||
return !((NBTList) enchantments).isEmpty();
|
nbt.put("Enchantments", enchantments);
|
||||||
}
|
|
||||||
catch (NMSException e)
|
|
||||||
{
|
|
||||||
PluginLogger.error("Unable to get Splatter Map attribute on item", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static public boolean isSplatterMap(ItemStack itemStack)
|
|
||||||
{
|
|
||||||
return hasSplatterAttributes(itemStack) && MapManager.managesMap(itemStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
static public boolean hasSplatterMap(Player player, PosterMap map)
|
|
||||||
{
|
|
||||||
Inventory playerInventory = player.getInventory();
|
|
||||||
|
|
||||||
for(int i = 0; i < playerInventory.getSize(); ++i)
|
|
||||||
{
|
|
||||||
ItemStack item = playerInventory.getItem(i);
|
|
||||||
if(isSplatterMap(item) && map.managesMap(item))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static public boolean placeSplatterMap(ItemFrame startFrame, Player player)
|
|
||||||
{
|
|
||||||
ImageMap map = MapManager.getMap(player.getInventory().getItemInMainHand());
|
|
||||||
|
|
||||||
if(!(map instanceof PosterMap)) return false;
|
return NBT.addToItemStack(itemStack, nbt, false);
|
||||||
PosterMap poster = (PosterMap) map;
|
} catch (NBTException | NMSException e) {
|
||||||
|
PluginLogger.error("Unable to set Splatter Map attribute on item", e);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FlatLocation startLocation = new FlatLocation(startFrame.getLocation(), startFrame.getFacing());
|
/**
|
||||||
FlatLocation endLocation = startLocation.clone().add(poster.getColumnCount(), poster.getRowCount());
|
* Checks if an item have the splatter attribute set (i.e. if the item is
|
||||||
PosterWall wall = new PosterWall();
|
* enchanted in any way).
|
||||||
|
*
|
||||||
wall.loc1 = startLocation;
|
* @param itemStack
|
||||||
wall.loc2 = endLocation;
|
* The item to check.
|
||||||
|
* @return True if the attribute was detected.
|
||||||
if (!wall.isValid())
|
*/
|
||||||
{
|
static public boolean hasSplatterAttributes(ItemStack itemStack) {
|
||||||
MessageSender.sendActionBarMessage(player, I.t("{ce}There is not enough space to place this map ({0} × {1}).", poster.getColumnCount(), poster.getRowCount()));
|
try {
|
||||||
return false;
|
final NBTCompound nbt = NBT.fromItemStack(itemStack);
|
||||||
}
|
if (!nbt.containsKey("Enchantments"))
|
||||||
|
return false;
|
||||||
int i = 0;
|
final Object enchantments = nbt.get("Enchantments");
|
||||||
for (ItemFrame frame : wall.frames)
|
if (!(enchantments instanceof NBTList))
|
||||||
{
|
return false;
|
||||||
int id = poster.getMapIdAtReverseY(i);
|
return !((NBTList) enchantments).isEmpty();
|
||||||
frame.setItem(new ItemStackBuilder(Material.FILLED_MAP).nbt(ImmutableMap.of("map", id)).craftItem());
|
} catch (NMSException e) {
|
||||||
MapInitEvent.initMap(id);
|
PluginLogger.error("Unable to get Splatter Map attribute on item", e);
|
||||||
++i;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
|
||||||
}
|
/**
|
||||||
|
* Return true if it is a platter map
|
||||||
static public PosterMap removeSplatterMap(ItemFrame startFrame)
|
*
|
||||||
{
|
* @param itemStack
|
||||||
final ImageMap map = MapManager.getMap(startFrame.getItem());
|
* The item to check.
|
||||||
if(!(map instanceof PosterMap)) return null;
|
* @return True if is a splatter map
|
||||||
PosterMap poster = (PosterMap) map;
|
*/
|
||||||
if(!poster.hasColumnData()) return null;
|
static public boolean isSplatterMap(ItemStack itemStack) {
|
||||||
FlatLocation loc = new FlatLocation(startFrame.getLocation(), startFrame.getFacing());
|
if(itemStack==null) return false;
|
||||||
ItemFrame[] matchingFrames = PosterWall.getMatchingMapFrames(poster, loc, MapManager.getMapIdFromItemStack(startFrame.getItem()));
|
return hasSplatterAttributes(itemStack) && MapManager.managesMap(itemStack);
|
||||||
if(matchingFrames == null) return null;
|
}
|
||||||
|
|
||||||
for(ItemFrame frame : matchingFrames)
|
|
||||||
{
|
//TODO doc a faire
|
||||||
if(frame != null) frame.setItem(null);
|
static public boolean hasSplatterMap(Player player, PosterMap map) {
|
||||||
}
|
Inventory playerInventory = player.getInventory();
|
||||||
|
|
||||||
return poster;
|
for (int i = 0; i < playerInventory.getSize(); ++i) {
|
||||||
}
|
ItemStack item = playerInventory.getItem(i);
|
||||||
|
if (isSplatterMap(item) && map.managesMap(item))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Place a splatter map
|
||||||
|
*
|
||||||
|
* @param startFrame
|
||||||
|
* Frame clicked by the player
|
||||||
|
* @param player
|
||||||
|
* Player placing map
|
||||||
|
* @return true if the map was correctly placed
|
||||||
|
*/
|
||||||
|
static public boolean placeSplatterMap(ItemFrame startFrame, Player player, PlayerInteractEntityEvent event) {
|
||||||
|
ImageMap map = MapManager.getMap(player.getInventory().getItemInMainHand());
|
||||||
|
|
||||||
|
if (!(map instanceof PosterMap))
|
||||||
|
return false;
|
||||||
|
PosterMap poster = (PosterMap) map;
|
||||||
|
PosterWall wall = new PosterWall();
|
||||||
|
|
||||||
|
if (startFrame.getFacing().equals(BlockFace.DOWN) || startFrame.getFacing().equals(BlockFace.UP)) {
|
||||||
|
// If it is on floor or ceiling
|
||||||
|
PosterOnASurface surface = new PosterOnASurface();
|
||||||
|
FlatLocation startLocation = new FlatLocation(startFrame.getLocation(), startFrame.getFacing());
|
||||||
|
FlatLocation endLocation = startLocation.clone().addH(poster.getColumnCount(), poster.getRowCount(),
|
||||||
|
WorldUtils.get4thOrientation(player.getLocation()));
|
||||||
|
|
||||||
|
surface.loc1 = startLocation;
|
||||||
|
surface.loc2 = endLocation;
|
||||||
|
|
||||||
|
if (!surface.isValid(player)) {
|
||||||
|
MessageSender.sendActionBarMessage(player,
|
||||||
|
I.t("{ce}There is not enough space to place this map ({0} × {1}).", poster.getColumnCount(),
|
||||||
|
poster.getRowCount()));
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (ItemFrame frame : surface.frames) {
|
||||||
|
BlockFace bf = WorldUtils.get4thOrientation(player.getLocation());
|
||||||
|
int id = poster.getMapIdAtReverseZ(i, bf, startFrame.getFacing());
|
||||||
|
Rotation rot = Rotation.NONE;
|
||||||
|
switch(frame.getFacing()){
|
||||||
|
case UP:
|
||||||
|
break;
|
||||||
|
case DOWN:
|
||||||
|
rot = Rotation.FLIPPED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//Rotation management relative to player rotation the default position is North, when on ceiling we flipped the rotation
|
||||||
|
frame.setItem(new ItemStackBuilder(Material.FILLED_MAP).nbt(ImmutableMap.of("map", id)).craftItem());
|
||||||
|
if(i==0){//First map need to be rotate one time CounterClockwise
|
||||||
|
rot=rot.rotateCounterClockwise();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (bf) {
|
||||||
|
case NORTH:
|
||||||
|
if (frame.getFacing() == BlockFace.DOWN) {
|
||||||
|
rot = rot.rotateClockwise();
|
||||||
|
rot = rot.rotateClockwise();
|
||||||
|
}
|
||||||
|
frame.setRotation(rot);
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
rot = rot.rotateClockwise();
|
||||||
|
frame.setRotation(rot);
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
if (frame.getFacing() == BlockFace.UP) {
|
||||||
|
rot = rot.rotateClockwise();
|
||||||
|
rot = rot.rotateClockwise();
|
||||||
|
}
|
||||||
|
frame.setRotation(rot);
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
rot = rot.rotateCounterClockwise();
|
||||||
|
frame.setRotation(rot);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MapInitEvent.initMap(id);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If it is on a wall NSEW
|
||||||
|
FlatLocation startLocation = new FlatLocation(startFrame.getLocation(), startFrame.getFacing());
|
||||||
|
FlatLocation endLocation = startLocation.clone().add(poster.getColumnCount(), poster.getRowCount());
|
||||||
|
|
||||||
|
wall.loc1 = startLocation;
|
||||||
|
wall.loc2 = endLocation;
|
||||||
|
|
||||||
|
if (!wall.isValid()) {
|
||||||
|
MessageSender.sendActionBarMessage(player,
|
||||||
|
I.t("{ce}There is not enough space to place this map ({0} × {1}).", poster.getColumnCount(),
|
||||||
|
poster.getRowCount()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (ItemFrame frame : wall.frames) {
|
||||||
|
|
||||||
|
int id = poster.getMapIdAtReverseY(i);
|
||||||
|
frame.setItem(new ItemStackBuilder(Material.FILLED_MAP).nbt(ImmutableMap.of("map", id)).craftItem());
|
||||||
|
|
||||||
|
//Force reset of rotation
|
||||||
|
if(i==0){//First map need to be rotate one time Clockwise
|
||||||
|
frame.setRotation(Rotation.NONE.rotateCounterClockwise());
|
||||||
|
}
|
||||||
|
else{frame.setRotation(Rotation.NONE);}
|
||||||
|
MapInitEvent.initMap(id);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove splattermap
|
||||||
|
*
|
||||||
|
* @param startFrame
|
||||||
|
* Frame clicked by the player
|
||||||
|
* @param player
|
||||||
|
* The player removing the map
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static public PosterMap removeSplatterMap(ItemFrame startFrame, Player player) {
|
||||||
|
final ImageMap map = MapManager.getMap(startFrame.getItem());
|
||||||
|
if (!(map instanceof PosterMap))
|
||||||
|
return null;
|
||||||
|
PosterMap poster = (PosterMap) map;
|
||||||
|
if (!poster.hasColumnData())
|
||||||
|
return null;
|
||||||
|
FlatLocation loc = new FlatLocation(startFrame.getLocation(), startFrame.getFacing());
|
||||||
|
ItemFrame[] matchingFrames=null;
|
||||||
|
|
||||||
|
switch(startFrame.getFacing()){
|
||||||
|
case UP:
|
||||||
|
case DOWN:
|
||||||
|
matchingFrames = PosterOnASurface.getMatchingMapFrames(poster, loc,
|
||||||
|
MapManager.getMapIdFromItemStack(startFrame.getItem()),WorldUtils.get4thOrientation(player.getLocation()));//startFrame.getFacing());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NORTH:
|
||||||
|
case SOUTH:
|
||||||
|
case EAST:
|
||||||
|
case WEST:
|
||||||
|
matchingFrames = PosterWall.getMatchingMapFrames(poster, loc,
|
||||||
|
MapManager.getMapIdFromItemStack(startFrame.getItem()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchingFrames == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
for (ItemFrame frame : matchingFrames) {
|
||||||
|
if (frame != null)
|
||||||
|
frame.setItem(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return poster;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,11 @@ map-global-limit: 0
|
|||||||
map-player-limit: 0
|
map-player-limit: 0
|
||||||
|
|
||||||
|
|
||||||
|
#Limit to the size of map non operator can render
|
||||||
|
#The value is the number of map used for the image for instance if you make a map 10 X 12 you will get 120 maps
|
||||||
|
map-size-notop-limit: 256
|
||||||
|
|
||||||
|
|
||||||
#Maximum size in pixels for an image to be. 0 is unlimited.
|
#Maximum size in pixels for an image to be. 0 is unlimited.
|
||||||
limit-map-size-x: 0
|
limit-map-size-x: 0
|
||||||
limit-map-size-y: 0
|
limit-map-size-y: 0
|
||||||
|
595
src/main/resources/i18n/ru_RU.po
Normal file
595
src/main/resources/i18n/ru_RU.po
Normal file
@ -0,0 +1,595 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: \n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2016-07-10 03:07+0200\n"
|
||||||
|
"PO-Revision-Date: 2016-07-10 03:08+0200\n"
|
||||||
|
"Last-Translator: danechek\n"
|
||||||
|
"Language-Team: \n"
|
||||||
|
"Language: ru_RU\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n < 1 || n > 1);\n"
|
||||||
|
"X-Generator: Poedit 1.8.7.1\n"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/IoMCommand.java:40
|
||||||
|
msgid "You need to give a map name."
|
||||||
|
msgstr "Вам нужно дать имя карте."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/IoMCommand.java:57
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteNoConfirmCommand.java:51
|
||||||
|
msgid "This map does not exist."
|
||||||
|
msgstr "Такая карта не существует."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:39
|
||||||
|
msgid "You are going to delete"
|
||||||
|
msgstr "Вы собираетесь удалить"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:42
|
||||||
|
msgid "Are you sure ? "
|
||||||
|
msgstr "Вы уверены? "
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:44
|
||||||
|
msgid "[Confirm]"
|
||||||
|
msgstr "[Подтвердить]"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:46
|
||||||
|
msgid "{red}This map will be deleted {bold}forever{red}!"
|
||||||
|
msgstr "{red}Эта карта будет удалена {bold}навсегда{red}!"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteNoConfirmCommand.java:46
|
||||||
|
msgid "Map successfully deleted."
|
||||||
|
msgstr "Карта успешно удалена."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetCommand.java:38
|
||||||
|
msgid "The requested map was too big to fit in your inventory."
|
||||||
|
msgstr "Запрашиваемая карта слишком большая для вашего инвентаря."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetCommand.java:39
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:71
|
||||||
|
msgid "Use '/maptool getremaining' to get the remaining maps."
|
||||||
|
msgstr "Используйте '/maptool getremaining', чтобы получить остальные карты."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetRemainingCommand.java:38
|
||||||
|
msgid "You have no remaining map."
|
||||||
|
msgstr "У вас нет остальных карт."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetRemainingCommand.java:46
|
||||||
|
msgid ""
|
||||||
|
"Your inventory is full! Make some space before requesting the remaining maps."
|
||||||
|
msgstr ""
|
||||||
|
"Ваш инвентарь заполнен! Освободите место перед тем, как запросить остальные карты."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetRemainingCommand.java:50
|
||||||
|
#, java-format
|
||||||
|
msgid "There is {0} map remaining."
|
||||||
|
msgid_plural "There are {0} maps remaining."
|
||||||
|
msgstr[0] "Осталась {0} карта."
|
||||||
|
msgstr[1] "Осталось {0} карт."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java:49
|
||||||
|
msgid "No map found."
|
||||||
|
msgstr "Карта не найдена."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java:53
|
||||||
|
msgid "{white}{bold}{0} map found."
|
||||||
|
msgid_plural "{white}{bold}{0} maps found."
|
||||||
|
msgstr[0] "{white}{bold}{0} карта найдена."
|
||||||
|
msgstr[1] "{white}{bold}{0} карты найдены."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java:79
|
||||||
|
msgid "{white}Click{gray} to get this map"
|
||||||
|
msgstr "{white}Кликните{gray}, чтобы получить эту карту"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/MigrateCommand.java:36
|
||||||
|
msgid "A migration process is already running. Check console for details."
|
||||||
|
msgstr "Процесс миграции уже запущен. Проверьте консоль, чтобы уточнить детали."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/MigrateCommand.java:40
|
||||||
|
msgid "Migration started. See console for details."
|
||||||
|
msgstr "Миграция начата. Смотрите консоль, чтобы уточнить детали."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:44
|
||||||
|
msgid "You must give an URL to take the image from."
|
||||||
|
msgstr "Вы должны дать URL, откуда будет взято изображение."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:52
|
||||||
|
msgid "Invalid URL."
|
||||||
|
msgstr "Неверный URL"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:61
|
||||||
|
msgid "Rendering..."
|
||||||
|
msgstr "Прорисовка..."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:67
|
||||||
|
msgid "Rendering finished!"
|
||||||
|
msgstr "Прорисовка завершена!"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:70
|
||||||
|
msgid "The rendered map was too big to fit in your inventory."
|
||||||
|
msgstr "Прорисованная карта слишком большая для вашего инвентаря."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:78
|
||||||
|
msgid "{ce}Map rendering failed: {0}"
|
||||||
|
msgstr "{ce}Ошибока прорисовки карты: {0}"
|
||||||
|
|
||||||
|
#. The title of the map deletion GUI. {0}: map name.
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:102
|
||||||
|
msgid "{0} » {black}Confirm deletion"
|
||||||
|
msgstr "{0} » {black}Подтвердить удаление"
|
||||||
|
|
||||||
|
#. The title of the map deletion item
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:110
|
||||||
|
msgid "{red}You're about to destroy this map..."
|
||||||
|
msgstr "{red}Вы собираетесь уничтожить эту карту..."
|
||||||
|
|
||||||
|
#. The end, in the lore, of a title starting with “You're about to destroy this map...”.
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:112
|
||||||
|
msgid "{red}...{italic}forever{red}."
|
||||||
|
msgstr "{red}...{italic}навсегда{red}."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:114
|
||||||
|
msgid "{gray}Name: {white}{0}"
|
||||||
|
msgstr "{gray}Имя: {white}{0}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:115
|
||||||
|
msgid "{gray}Map ID: {white}{0}"
|
||||||
|
msgstr "{gray}ID карты: {white}{0}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:116
|
||||||
|
msgid "{gray}Maps inside: {white}{0}"
|
||||||
|
msgstr "{gray}Карты внутри: {white}{0}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:178
|
||||||
|
msgid "{gray}Map successfully deleted."
|
||||||
|
msgstr "{gray}Карта успешно удалена."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:54
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:71
|
||||||
|
msgid "{green}Map part"
|
||||||
|
msgstr "{green}Часть карты"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:55
|
||||||
|
msgid "{gray}Column: {white}{0}"
|
||||||
|
msgstr "{gray}Столбец: {white}{0}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:56
|
||||||
|
msgid "{gray}Row: {white}{0}"
|
||||||
|
msgstr "{gray}Строка: {white}{0}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:58
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:74
|
||||||
|
msgid "{gray}» {white}Click{gray} to get only this part"
|
||||||
|
msgstr "{gray}» {white}Кликните{gray}, чтобы получить эту часть"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:72
|
||||||
|
msgid "{gray}Part: {white}{0}"
|
||||||
|
msgstr "{gray}Часть: {white}{0}"
|
||||||
|
|
||||||
|
#. Title of the map details GUI
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:114
|
||||||
|
msgid "Your maps » {black}{0}"
|
||||||
|
msgstr "Ваши карты » {black}{0}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:136
|
||||||
|
msgid "{blue}Rename this image"
|
||||||
|
msgstr "{blue}Переименуйте это изображение"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:137
|
||||||
|
msgid ""
|
||||||
|
"{gray}Click here to rename this image; this is used for your own "
|
||||||
|
"organization."
|
||||||
|
msgstr ""
|
||||||
|
"{gray}Кликните сюда, чтобы переименовать это изображение; это используется для вашей собственной "
|
||||||
|
"организации."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:141
|
||||||
|
msgid "{red}Delete this image"
|
||||||
|
msgstr "{red}Удалить это изображение"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:142
|
||||||
|
msgid ""
|
||||||
|
"{gray}Deletes this map {white}forever{gray}. This action cannot be undone!"
|
||||||
|
msgstr ""
|
||||||
|
"{gray}Удаляет эту карту {white}навсегда{gray}. Это действие не может быть завершено!"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:144
|
||||||
|
msgid "{gray}You will be asked to confirm your choice if you click here."
|
||||||
|
msgstr "{gray}Вам будет предложено подтвердить свой выбор, если вы кликните здесь."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:156
|
||||||
|
msgid "{green}« Back"
|
||||||
|
msgstr "{green}« Назад"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:157
|
||||||
|
msgid "{gray}Go back to the list."
|
||||||
|
msgstr "{gray}Вернуться к списку."
|
||||||
|
|
||||||
|
#. Displayed subtitle description of a single map on the list GUI
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:44
|
||||||
|
msgid "{white}Single map"
|
||||||
|
msgstr "{white}Одиночная карта"
|
||||||
|
|
||||||
|
#. Displayed subtitle description of a poster map on the list GUI (columns × rows in english)
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:52
|
||||||
|
msgid "{white}Poster map ({0} × {1})"
|
||||||
|
msgstr "{white}Постер ({0} × {1})"
|
||||||
|
|
||||||
|
#. Displayed subtitle description of a poster map without column data on the list GUI
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:57
|
||||||
|
msgid "{white}Poster map ({0} parts)"
|
||||||
|
msgstr "{white}Постер ({0} parts)"
|
||||||
|
|
||||||
|
#. Displayed title of a map on the list GUI
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:62
|
||||||
|
msgid "{green}{bold}{0}"
|
||||||
|
msgstr "{green}{bold}{0}"
|
||||||
|
|
||||||
|
#. Map ID displayed in the tooltip of a map on the list GUI
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:67
|
||||||
|
msgid "{gray}Map ID: {0}"
|
||||||
|
msgstr "{gray}ID карты: {0}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:69
|
||||||
|
msgid "{gray}» {white}Left-click{gray} to get this map"
|
||||||
|
msgstr "{gray}» {white}ЛКМ{gray} для получения этой карты"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:70
|
||||||
|
msgid "{gray}» {white}Right-click{gray} for details and options"
|
||||||
|
msgstr "{gray}» {white}ПКМ{gray} для деталей и опций"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:79
|
||||||
|
msgid "{red}You don't have any map."
|
||||||
|
msgstr "{red}У вас нет карт."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:80
|
||||||
|
msgid ""
|
||||||
|
"{gray}Get started by creating a new one using {white}/tomap <URL> [resize]"
|
||||||
|
"{gray}!"
|
||||||
|
msgstr ""
|
||||||
|
"{gray}Начните создание новой с помощью {white}/tomap <URL> [resize]"
|
||||||
|
"{gray}!"
|
||||||
|
|
||||||
|
#. The maps list GUI title
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:119
|
||||||
|
msgid "{black}Your maps {reset}({0})"
|
||||||
|
msgstr "{black}Ваши карты {reset}({0})"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:148
|
||||||
|
msgid "{blue}Usage statistics"
|
||||||
|
msgstr "{blue}Статистика использования"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:150
|
||||||
|
msgid "{white}{0}{gray} image rendered"
|
||||||
|
msgid_plural "{white}{0}{gray} images rendered"
|
||||||
|
msgstr[0] "{white}{0}{gray} изображение прорисовано"
|
||||||
|
msgstr[1] "{white}{0}{gray} изображения прорисованы"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:151
|
||||||
|
msgid "{white}{0}{gray} Minecraft map used"
|
||||||
|
msgid_plural "{white}{0}{gray} Minecraft maps used"
|
||||||
|
msgstr[0] "{white}{0}{gray} Minecraft карта использована"
|
||||||
|
msgstr[1] "{white}{0}{gray} Minecraft карты использованы"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:156
|
||||||
|
msgid "{blue}Minecraft maps limits"
|
||||||
|
msgstr "{blue}Minecraft лимит карт"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:158
|
||||||
|
msgid "{gray}Server-wide limit: {white}unlimited"
|
||||||
|
msgstr "{gray}Лимит на сервере: {white}неограничено"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:159
|
||||||
|
msgid "{gray}Server-wide limit: {white}{0}"
|
||||||
|
msgstr "{gray}Лимит на сервере: {white}{0}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:161
|
||||||
|
msgid "{gray}Per-player limit: {white}unlimited"
|
||||||
|
msgstr "{gray}Лимит для игрокаt: {white}неограничено"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:162
|
||||||
|
msgid "{gray}Per-player limit: {white}{0}"
|
||||||
|
msgstr "{gray}Лимит для игрока: {white}{0}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:164
|
||||||
|
msgid "{white}{0} %{gray} of your quota used"
|
||||||
|
msgstr "{white}{0} %{gray} часть, используемая вами"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:165
|
||||||
|
msgid "{white}{0}{gray} map left"
|
||||||
|
msgid_plural "{white}{0}{gray} maps left"
|
||||||
|
msgstr[0] "{white}{0}{gray} карта осталась"
|
||||||
|
msgstr[1] "{white}{0}{gray} карт осталось"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java:73
|
||||||
|
#, java-format
|
||||||
|
msgid "HTTP error : {0} {1}"
|
||||||
|
msgstr "HTTP ошибка : {0} {1}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java:79
|
||||||
|
msgid "The given URL is not a valid image"
|
||||||
|
msgstr "Указанный URL имеет неверный формат изображения"
|
||||||
|
|
||||||
|
#. The default display name of a map
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/map/ImageMap.java:44
|
||||||
|
msgid "Map"
|
||||||
|
msgstr "Карта"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/map/MapManagerException.java:29
|
||||||
|
#, java-format
|
||||||
|
msgid "You have too many maps (maximum : {0})."
|
||||||
|
msgstr "Вы имеете слишком много карт (максимум : {0})."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/map/MapManagerException.java:30
|
||||||
|
msgid "The server ImageOnMap limit has been reached."
|
||||||
|
msgstr "Лимит карт на сервере достигнут."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/map/MapManagerException.java:31
|
||||||
|
msgid "The given map does not exist."
|
||||||
|
msgstr "Данная карта не существует."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java:34
|
||||||
|
msgid "Migration is already running."
|
||||||
|
msgstr "Миграция уже запущена."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java:50
|
||||||
|
msgid "Waiting for migration to finish..."
|
||||||
|
msgstr "Подождите окончания миграции..."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java:58
|
||||||
|
msgid ""
|
||||||
|
"Migration thread has been interrupted while waiting to finish. It may not "
|
||||||
|
"have ended correctly."
|
||||||
|
msgstr ""
|
||||||
|
"Поток миграции был прерван во время ожидания завершения. Может быть "
|
||||||
|
"не завершено корректно."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:176
|
||||||
|
msgid "Error while preparing migration"
|
||||||
|
msgstr "Ошибка во время подготовки миграции"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:177
|
||||||
|
msgid "Aborting migration. No change has been made."
|
||||||
|
msgstr "Прерываю миграции. Изменения не будут применены."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:189
|
||||||
|
msgid "Error while migrating"
|
||||||
|
msgstr "Ошибка во время миграции"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:190
|
||||||
|
msgid "Aborting migration. Some changes may already have been made."
|
||||||
|
msgstr "Прерываю миграции. Некоторые изменения могут быть применены."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:191
|
||||||
|
msgid ""
|
||||||
|
"Before trying to migrate again, you must recover player files from the "
|
||||||
|
"backups, and then move the backups away from the plugin directory to avoid "
|
||||||
|
"overwriting them."
|
||||||
|
msgstr ""
|
||||||
|
"Перед попыткой повторной миграции, вы должны восстановить файлы игроков из "
|
||||||
|
"бэкапов, затем переместить резервные копии из каталога плагинов, чтобы избежать "
|
||||||
|
"их перезаписи."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:203
|
||||||
|
msgid "Looking for configuration files to migrate..."
|
||||||
|
msgstr "Ищем файлы для конфигурации миграции..."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:206
|
||||||
|
#, java-format
|
||||||
|
msgid "Detected former posters file {0}"
|
||||||
|
msgstr "Обнаружен файл прошлых постеров{0}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:209
|
||||||
|
#, java-format
|
||||||
|
msgid "Detected former maps file {0}"
|
||||||
|
msgstr "Обнаружен файл прошлых постеров {0}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:213
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:416
|
||||||
|
msgid "There is nothing to migrate. Stopping."
|
||||||
|
msgstr "Нечему мигрировать. Останавливаю."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:218
|
||||||
|
msgid "Done."
|
||||||
|
msgstr "Завершено."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:232
|
||||||
|
msgid "Backup directories already exists."
|
||||||
|
msgstr "Бэкап каталоги уже существуют."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:233
|
||||||
|
msgid ""
|
||||||
|
"This means that a migration has already been done, or may not have ended "
|
||||||
|
"well."
|
||||||
|
msgstr ""
|
||||||
|
"Это означает, что миграция уже выполнена, или, возможно, не закончилась"
|
||||||
|
"хорошо."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:234
|
||||||
|
msgid ""
|
||||||
|
"To start a new migration, you must move away the backup directories so they "
|
||||||
|
"are not overwritten."
|
||||||
|
msgstr ""
|
||||||
|
"Чтобы начать новую миграцию, вы должны переместить каталоги бэкапов, чтобы "
|
||||||
|
"они не перезаписались."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:247
|
||||||
|
msgid "Backing up map data before migrating..."
|
||||||
|
msgstr "Резервное копирование карт перед миграцией..."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:271
|
||||||
|
msgid "Backup complete."
|
||||||
|
msgstr "Бэкап завершён."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:352
|
||||||
|
msgid "Fetching UUIDs from Mojang..."
|
||||||
|
msgstr "Получаем UUIDs от Mojang..."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:359
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:387
|
||||||
|
msgid "An error occurred while fetching the UUIDs from Mojang"
|
||||||
|
msgstr "Произошла ошибка при получении UUIDs от Mojang"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:364
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:392
|
||||||
|
msgid "The migration worker has been interrupted"
|
||||||
|
msgstr "Миграционный работник был прерван"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:367
|
||||||
|
#, java-format
|
||||||
|
msgid "Fetching done. {0} UUID have been retrieved."
|
||||||
|
msgid_plural "Fetching done. {0} UUIDs have been retrieved."
|
||||||
|
msgstr[0] "Получение завершено. {0} UUID был получен."
|
||||||
|
msgstr[1] "Получение завершено. {0} UUIDs были получены."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:378
|
||||||
|
#, java-format
|
||||||
|
msgid "Mojang did not find UUIDs for {0} player at the current time."
|
||||||
|
msgid_plural "Mojang did not find UUIDs for {0} players at the current time."
|
||||||
|
msgstr[0] "Mojang не нашёл UUIDs для {0} игрока на текущее время."
|
||||||
|
msgstr[1] "Mojang не нашёл UUIDs для {0} игроков на текущее время."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:379
|
||||||
|
msgid ""
|
||||||
|
"The Mojang servers limit requests rate at one per second, this may take some "
|
||||||
|
"time..."
|
||||||
|
msgstr ""
|
||||||
|
"Серверы Mojang имеют ограничение запросов, это может занять некоторое "
|
||||||
|
"время..."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:398
|
||||||
|
#, java-format
|
||||||
|
msgid "Mojang did not find player data for {0} player"
|
||||||
|
msgid_plural "Mojang did not find player data for {0} players"
|
||||||
|
msgstr[0] "Mojang не нашёл данных для игрока {0}"
|
||||||
|
msgstr[1] "Mojang не нашёл данных для игроков {0}"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:400
|
||||||
|
msgid "The following players do not exist or do not have paid accounts :"
|
||||||
|
msgstr "Следующие игроки не существуют или не имеют платных аккаунтов:"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:415
|
||||||
|
msgid "Mojang could not find any of the registered players."
|
||||||
|
msgstr "Mojang не удалось найти существующих игроков."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:425
|
||||||
|
msgid "Merging map data..."
|
||||||
|
msgstr "Объединяю данные карт..."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:475
|
||||||
|
#, java-format
|
||||||
|
msgid "{0} registered minecraft map is missing from the save."
|
||||||
|
msgid_plural "{0} registered minecraft maps are missing from the save."
|
||||||
|
msgstr[0] "{0} зарегистрированная minecraft карта отсутствует в сохранении."
|
||||||
|
msgstr[1] "{0} зарегистрированные minecraft карты отсутствуют в сохранении."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:476
|
||||||
|
msgid ""
|
||||||
|
"These maps will not be migrated, but this could mean the save has been "
|
||||||
|
"altered or corrupted."
|
||||||
|
msgstr ""
|
||||||
|
"Эти карты не будут перенесены, но это может означать, что сохранение было "
|
||||||
|
"изменено или повреждено."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:477
|
||||||
|
#, java-format
|
||||||
|
msgid "The following maps are missing : {0} "
|
||||||
|
msgstr "Следующие карты отсутствуют : {0} "
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:483
|
||||||
|
msgid "Saving changes..."
|
||||||
|
msgstr "Сохраняю изменения..."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:489
|
||||||
|
msgid "Cleaning up old data files..."
|
||||||
|
msgstr "Очищаю устаревшие данные файлов..."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:496
|
||||||
|
msgid "Deleting old map data file..."
|
||||||
|
msgstr "Удаляю устаревший файл карты..."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:501
|
||||||
|
#, java-format
|
||||||
|
msgid "{0} map could not be migrated."
|
||||||
|
msgid_plural "{0} maps could not be migrated."
|
||||||
|
msgstr[0] "{0} карта не может быть перенесена."
|
||||||
|
msgstr[1] "{0} карты не могут быть перенесены."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:519
|
||||||
|
msgid "Deleting old poster data file..."
|
||||||
|
msgstr "Удаление устаревшего файла данных постера..."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:524
|
||||||
|
#, java-format
|
||||||
|
msgid "{0} poster could not be migrated."
|
||||||
|
msgid_plural "{0} posters could not be migrated."
|
||||||
|
msgstr[0] "{0} постер не может быть перенесён."
|
||||||
|
msgstr[1] "{0} постеры не могут быть перенесены."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:537
|
||||||
|
msgid "Data that has not been migrated will be kept in the old data files."
|
||||||
|
msgstr "Данные, которые не были перенесены, будут сохранены в старых файлах данных."
|
||||||
|
|
||||||
|
#. The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = index.
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:139
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:215
|
||||||
|
#, java-format
|
||||||
|
msgid "{0} (part {1})"
|
||||||
|
msgstr "{0} (часть {1})"
|
||||||
|
|
||||||
|
#. The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = row; 2 = column.
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:145
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:213
|
||||||
|
#, java-format
|
||||||
|
msgid "{0} (row {1}, column {2})"
|
||||||
|
msgstr "{0} (строка {1}, столбец {2})"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:44
|
||||||
|
msgid "Splatter Map"
|
||||||
|
msgstr "Размещаю карту"
|
||||||
|
|
||||||
|
#. Title in a splatter map tooltip
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:48
|
||||||
|
msgid "Item frames needed"
|
||||||
|
msgstr "Нужны рамки для предметов"
|
||||||
|
|
||||||
|
#. Size of a map stored in a splatter map
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:56
|
||||||
|
#, java-format
|
||||||
|
msgid "{0} × {1}"
|
||||||
|
msgstr "{0} × {1}"
|
||||||
|
|
||||||
|
#. Size of a map stored in a splatter map, including the total frames count
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:62
|
||||||
|
#, java-format
|
||||||
|
msgid "{0} × {1} (total {2} frames)"
|
||||||
|
msgstr "{0} × {1} (всего {2} рамок)"
|
||||||
|
|
||||||
|
#. Title in a splatter map tooltip
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:53
|
||||||
|
msgid "How to use this?"
|
||||||
|
msgstr "Как использовать это?"
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:54
|
||||||
|
msgid ""
|
||||||
|
"Place empty item frames on a wall, enough to host the whole map. Then, right-"
|
||||||
|
"click on the bottom-left frame with this map."
|
||||||
|
msgstr ""
|
||||||
|
"Поместите пустые рамки на стену, столько, чтобы разместить всю карту. Теперь, ПКМ по"
|
||||||
|
"нижней левой рамке этой картой."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:56
|
||||||
|
msgid ""
|
||||||
|
"Shift-click one of the placed maps to remove the whole poster in one shot."
|
||||||
|
msgstr ""
|
||||||
|
"Shift-клик по одной из размещенных карт для удаления всего постера за один раз."
|
||||||
|
|
||||||
|
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:101
|
||||||
|
msgid "{ce}There is not enough space to place this map ({0} × {1})."
|
||||||
|
msgstr "{ce}Здесь недостаточно места для размещения этой картй ({0} × {1})."
|
Loading…
Reference in New Issue
Block a user