Added a map details GUI.

* NEW: Right-clicking on a GUI opens another one with details about the map.
* NEW: The details GUI displays the map on a screen with scrollbars to consult the map per-minecraft-map.
* NEW: Each part of the map can be taken independently.
This commit is contained in:
Amaury Carrade 2015-07-12 16:04:19 +02:00
parent cd9b310aa2
commit 7809c95d80
4 changed files with 375 additions and 8 deletions

View File

@ -0,0 +1,318 @@
/*
* 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.gui.list;
import fr.moribus.imageonmap.gui.core.AbstractGui;
import fr.moribus.imageonmap.gui.core.GuiManager;
import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.PosterMap;
import fr.moribus.imageonmap.ui.MapItemManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Arrays;
import java.util.Collections;
public class MapDetailGui extends AbstractGui
{
/**
* The max width of the window open on the image.
*/
private final int MAX_WINDOW_WIDTH = 7;
/**
* The max height of the window open on the image.
*/
private final int MAX_WINDOW_HEIGHT = 3;
/**
* The map displayed in this GUI.
*/
ImageMap map;
/**
* The previously-viewed page of the list GUI.
* Used to be able to bring the user back to the same page.
*/
int currentPage;
/**
* The row currently at the top of the window open on the displayed map.
*/
int topRow = 0;
/**
* The column currently at the top of the window open on the displayed map.
*/
int topColumn = 0;
/**
*
* @param map The map displayed in this GUI.
*/
public MapDetailGui(ImageMap map)
{
this(map, 0);
}
/**
*
* @param map The map displayed in this GUI.
* @param currentPage The previously-viewed page of the list GUI.
*/
public MapDetailGui(ImageMap map, int currentPage)
{
this.map = map;
this.currentPage = currentPage;
}
@Override
public void display(Player player)
{
inventory = Bukkit.createInventory(player, 6 * 9, ChatColor.BLACK + "Your maps");
ItemStack back = new ItemStack(Material.EMERALD);
ItemMeta meta = back.getItemMeta();
meta.setDisplayName(ChatColor.GREEN + "« Back");
meta.setLore(Collections.singletonList(
ChatColor.GRAY + "Go back to the list."
));
back.setItemMeta(meta);
setSlotData(back, inventory.getSize() - 5, "back");
update(player);
player.openInventory(inventory);
}
@Override
public void update(Player player)
{
/* ** The map itself ** */
if(map instanceof PosterMap && ((PosterMap) map).hasColumnData()) {
int slot = 10;
for (int row = topRow; row < topRow + MAX_WINDOW_HEIGHT; row++)
{
for (int col = topColumn; col < topColumn + MAX_WINDOW_WIDTH; col++)
{
if(col < ((PosterMap) map).getColumnCount() && row < ((PosterMap) map).getRowCount())
{
setSlotData(getMapPartRepresentation(col, row), slot, col + ";" + row);
}
else
{
setSlotData(new ItemStack(Material.AIR), slot, "");
}
slot++;
}
slot += 2;
}
placeArrowSlider('\u2B07', canGoDown(), 35, "down");
placeArrowSlider('\u2B06', canGoUp() , 17, "up" );
placeArrowSlider('«' , canGoLeft() , 37, "left" );
placeArrowSlider('»' , canGoRight(), 43, "right");
}
else
{
setSlotData(getMapPartRepresentation(0, 0), 13, "0;0");
}
}
private ItemStack getMapPartRepresentation(int col, int row)
{
ItemStack part = new ItemStack(Material.MAP);
ItemMeta meta = part.getItemMeta();
meta.setDisplayName(ChatColor.GREEN + "Map part");
meta.setLore(Arrays.asList(
ChatColor.GRAY + "Column: " + ChatColor.WHITE + (col + 1),
ChatColor.GRAY + "Row: " + ChatColor.WHITE + (row + 1),
"",
ChatColor.GRAY + "» Click to get only this part"
));
part.setItemMeta(meta);
return part;
}
private void placeArrowSlider(Character nameCharacter, boolean active, int slot, String action)
{
/* ** Item ** */
ItemStack slider = new ItemStack(Material.ARROW);
ItemMeta meta = slider.getItemMeta();
String title = "";
for(int i = 0; i < 5; i++)
title += nameCharacter;
meta.setDisplayName((active ? ChatColor.GREEN : ChatColor.GRAY) + title);
slider.setItemMeta(meta);
/* ** Placement ** */
setSlotData(slider, slot, active ? action : "");
}
@Override
public void onClick(Player player, ItemStack stack, String action, ClickType click, InventoryAction invAction, InventoryClickEvent ev)
{
switch (action)
{
case "down":
goDown(player);
return;
case "up":
goUp(player);
return;
case "left":
goLeft(player);
return;
case "right":
goRight(player);
return;
case "back":
goBack(player);
return;
default:
Integer col;
Integer row;
if(map instanceof PosterMap && ((PosterMap) map).hasColumnData()) {
String[] coords = action.split(";");
if (coords.length != 2) return; // Other unhandled action.
try {
col = Integer.valueOf(coords[0]);
row = Integer.valueOf(coords[1]);
} catch (NumberFormatException e) {
return; // Other unhandled action.
}
}
else
{
col = row = 0;
}
ev.setCursor(MapItemManager.createSubMapItem(map, col, row));
}
}
private void goDown(Player player)
{
if (!(map instanceof PosterMap)) return;
if(canGoDown())
{
topRow++;
update(player);
}
}
private void goUp(Player player)
{
if (!(map instanceof PosterMap)) return;
if(canGoUp())
{
topRow--;
update(player);
}
}
private void goRight(Player player)
{
if (!(map instanceof PosterMap)) return;
if(canGoRight())
{
topColumn++;
update(player);
}
}
private void goLeft(Player player)
{
if (!(map instanceof PosterMap)) return;
if(canGoLeft())
{
topColumn--;
update(player);
}
}
private void goBack(Player player)
{
GuiManager.openGui(player, new MapListGui(currentPage));
}
private boolean canGoDown()
{
return topRow + MAX_WINDOW_HEIGHT < ((PosterMap) map).getRowCount();
}
private boolean canGoUp()
{
return topRow > 0;
}
private boolean canGoRight()
{
return topColumn + MAX_WINDOW_WIDTH < ((PosterMap) map).getColumnCount();
}
private boolean canGoLeft()
{
return topColumn > 0;
}
}

View File

@ -173,7 +173,7 @@ public class MapListGui extends AbstractGui
case RIGHT:
case SHIFT_RIGHT:
// TODO
GuiManager.openGui(player, new MapDetailGui(map, currentPage));
break;
}
}

View File

@ -18,10 +18,11 @@
package fr.moribus.imageonmap.map;
import org.bukkit.configuration.InvalidConfigurationException;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.configuration.InvalidConfigurationException;
public class PosterMap extends ImageMap
{
@ -115,6 +116,20 @@ public class PosterMap extends ImageMap
if(columnCount == 0) return 0;
return (i / columnCount) + 1;
}
/**
* Returns the map id at the given column and line.
*
* @param col The column. Starts at 0.
* @param row The row. Starts at 0.
* @return The Minecraft map ID.
*
* @throws ArrayIndexOutOfBoundsException if the given coordinates are too big (out of the poster).
*/
public short getMapIdAt(int col, int row)
{
return mapsIDs[getColumnCount() * col + row];
}
public boolean hasColumnData()
{

View File

@ -21,10 +21,7 @@ package fr.moribus.imageonmap.ui;
import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.PosterMap;
import fr.moribus.imageonmap.map.SingleMap;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Queue;
import java.util.UUID;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
@ -32,6 +29,11 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Queue;
import java.util.UUID;
public class MapItemManager implements Listener
{
static private HashMap<UUID, Queue<ItemStack>> mapItemCache;
@ -69,7 +71,7 @@ public class MapItemManager implements Listener
{
if(map.hasColumnData())
{
mapName = map.getName() +
mapName = map.getName() +
" (row " + map.getRowAt(i) +
", column " + map.getColumnAt(i) + ")";
}
@ -117,11 +119,43 @@ public class MapItemManager implements Listener
ItemStack itemMap = new ItemStack(Material.MAP, 1, mapID);
ItemMeta meta = itemMap.getItemMeta();
meta.setDisplayName(text);
meta.setDisplayName(ChatColor.RESET + text);
itemMap.setItemMeta(meta);
return itemMap;
}
/**
* Returns the item to place to display the (col;row) part of the given poster.
*
* @param col The column to display. Starts at 0.
* @param row The row to display. Starts at 0.
*
* @return The map.
*
* @throws ArrayIndexOutOfBoundsException If col;row is not inside the map.
*/
static public ItemStack createSubMapItem(ImageMap map, int col, int row)
{
if(map instanceof PosterMap && ((PosterMap) map).hasColumnData())
{
return MapItemManager.createMapItem(
((PosterMap) map).getMapIdAt(row, col),
map.getName() +
" (row " + (row + 1) +
", column " + (col + 1) + ")"
);
}
else
{
if(row != 0 || col != 0)
{
throw new ArrayIndexOutOfBoundsException(); // Coherence
}
return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName());
}
}
static public int getCacheSize(Player player)
{