Adds renaming and icon setting to the Blueprint Management panel

https://github.com/BentoBoxWorld/BentoBox/issues/701
This commit is contained in:
tastybento 2019-05-26 22:03:09 -07:00
parent 5acae3ff30
commit 94e90257fa
9 changed files with 234 additions and 58 deletions

View File

@ -54,7 +54,7 @@ public class PanelItemBuilder {
* @return PanelItemBuilder
*/
public PanelItemBuilder description(List<String> description) {
this.description.addAll(description);
description.forEach(this::description);
return this;
}

View File

@ -79,7 +79,7 @@ public class Blueprint {
}
/**
* @param icon the icon to set
* @return
* @return blueprint
*/
public Blueprint setIcon(Material icon) {
this.icon = icon;

View File

@ -8,18 +8,26 @@ import org.bukkit.entity.Player;
import net.md_5.bungee.api.ChatColor;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.blueprints.Blueprint;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
public class NamePrompt extends StringPrompt {
private GameModeAddon addon;
private BlueprintBundle bb;
private Blueprint bp;
public NamePrompt(GameModeAddon addon, BlueprintBundle bb) {
this.addon = addon;
this.bb = bb;
}
public NamePrompt(GameModeAddon addon, Blueprint bp, BlueprintBundle bb) {
this.addon = addon;
this.bp = bp;
this.bb = bb;
}
@Override
public String getPromptText(ConversationContext context) {
User user = User.getInstance((Player)context.getForWhom());
@ -48,7 +56,7 @@ public class NamePrompt extends StringPrompt {
}
context.setSessionData("uniqueId", uniqueId.toString());
context.setSessionData("name", input);
return new NameSuccessPrompt(addon, bb);
return new NameSuccessPrompt(addon, bb, bp);
}
}

View File

@ -9,6 +9,7 @@ import org.bukkit.entity.Player;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.blueprints.Blueprint;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
import world.bentobox.bentobox.panels.BlueprintManagementPanel;
@ -16,34 +17,50 @@ public class NameSuccessPrompt extends MessagePrompt {
private GameModeAddon addon;
private BlueprintBundle bb;
private Blueprint bp;
public NameSuccessPrompt(GameModeAddon addon, BlueprintBundle bb) {
/**
* Handles the name processing
* @param addon - Game Mode addon
* @param bb - Blueprint Bundle
* @param bp - blueprint
*/
public NameSuccessPrompt(GameModeAddon addon, BlueprintBundle bb, Blueprint bp) {
this.addon = addon;
this.bb = bb;
this.bp = bp;
}
@Override
public String getPromptText(ConversationContext context) {
String name = (String) context.getSessionData("name");
String uniqueId = (String) context.getSessionData("uniqueId");
if (bb == null) {
// New Blueprint bundle
bb = new BlueprintBundle();
bb.setIcon(Material.RED_WOOL);
} else {
// Rename - remove old named file
BentoBox.getInstance().getBlueprintsManager().deleteBlueprintBundle(addon, bb);
}
bb.setDisplayName(name);
bb.setUniqueId(uniqueId);
BentoBox.getInstance().getBlueprintsManager().addBlueprintBundle(addon, bb);
BentoBox.getInstance().getBlueprintsManager().saveBlueprintBundle(addon, bb);
User user = User.getInstance((Player)context.getForWhom());
new BlueprintManagementPanel(BentoBox.getInstance(), user, addon).openPanel();
// Set the name
// if successfully
return user.getTranslation("commands.admin.blueprint.management.description.success");
// Else return failure
// Rename blueprint
if (bp != null) {
BentoBox.getInstance().getBlueprintsManager().renameBlueprint(addon, bp, name);
new BlueprintManagementPanel(BentoBox.getInstance(), user, addon).openBB(bb);
return user.getTranslation("commands.admin.blueprint.management.description.success");
} else {
// Blueprint Bundle
if (bb == null) {
// New Blueprint bundle
bb = new BlueprintBundle();
bb.setIcon(Material.RED_WOOL);
} else {
// Rename - remove old named file
BentoBox.getInstance().getBlueprintsManager().deleteBlueprintBundle(addon, bb);
}
bb.setDisplayName(name);
bb.setUniqueId(uniqueId);
BentoBox.getInstance().getBlueprintsManager().addBlueprintBundle(addon, bb);
BentoBox.getInstance().getBlueprintsManager().saveBlueprintBundle(addon, bb);
new BlueprintManagementPanel(BentoBox.getInstance(), user, addon).openPanel();
// Set the name
// if successfully
return user.getTranslation("commands.admin.blueprint.management.description.success");
}
}
@Override

View File

@ -116,8 +116,8 @@ public class BlueprintBundle implements DataObject {
}
/**
* Adds a blueprint to the blueprint bundle. It will replace any blueprint that already exists of the same {@link World.Environment} type.
* @param env - the {@link World.Environment}
* Adds a blueprint to the blueprint bundle. It will replace any blueprint that already exists of the same Environment type.
* @param env - the Environment
* @param bp - blueprint
*/
public void setBlueprint(World.Environment env, Blueprint bp) {
@ -134,7 +134,7 @@ public class BlueprintBundle implements DataObject {
/**
* Get the blueprint for the environment type
* @param env - {@link World.Environment} type
* @param env - Environment type
* @return Blueprint or null if one does not exist
*/
public String getBlueprint(World.Environment env) {

View File

@ -416,4 +416,36 @@ public class BlueprintsManager {
}
}
/**
* Rename a blueprint
* @param addon - Game Mode Addon
* @param bp - blueprint
* @param name - new name
*/
public void renameBlueprint(GameModeAddon addon, Blueprint bp, String name) {
if (bp.getName().equalsIgnoreCase(name)) {
// If the name is the same, do not do anything
return;
}
File bpf = getBlueprintsFolder(addon);
// Get the filename
File fileName = new File(bpf, bp.getName().toLowerCase(Locale.ENGLISH) + BLUEPRINT_SUFFIX);
plugin.logDebug("Old blueprint filename = " + fileName);
// Delete the old file
try {
if (Files.deleteIfExists(fileName.toPath())) {
plugin.logDebug("Deleted");
} else {
plugin.logDebug("Could not delete - does not exist");
}
} catch (IOException e) {
plugin.logError("Could not delete old Blueprint " + e.getLocalizedMessage());
}
// Set new name
bp.setName(name);
// Save it
saveBlueprint(addon, bp);
}
}

View File

@ -13,7 +13,6 @@ import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.conversations.Conversable;
import org.bukkit.conversations.ConversationFactory;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.event.inventory.ClickType;
import org.eclipse.jdt.annotation.NonNull;
@ -72,6 +71,9 @@ public class BlueprintManagementPanel {
return user.getTranslation("commands.admin.blueprint.management." + t, vars);
}
/**
* Opens the management panel
*/
public void openPanel() {
// Show panel of blueprint bundles
// Clicking on a bundle opens up the bundle edit panel
@ -102,25 +104,19 @@ public class BlueprintManagementPanel {
pb.build();
}
/**
* Open the Blueprint Bundle panel
* @param bb - blueprint bundle
*/
public void openBB(BlueprintBundle bb) {
int index = 18;
for (Blueprint bp : plugin.getBlueprintsManager().getBlueprints(addon).values()) {
blueprints.put(index++, bp);
}
// Create the panel
PanelBuilder pb = new PanelBuilder().name(bb.getDisplayName()).user(user).size(45);
PanelBuilder pb = new PanelBuilder().name(bb.getDisplayName()).user(user).size(45).listener(new IconChanger(plugin, addon, this, bb));
// Display bundle icon
pb.item(0, new PanelItemBuilder()
.name(t("edit-description"))
.description(bb.getDescription())
.icon(bb.getIcon())
.clickHandler((panel, u, clickType, slot) -> {
u.closeInventory();
// Description conversation
askForDescription(u.getPlayer(), addon, bb);
return true;
})
.build());
pb.item(0, getBundleIcon(bb));
SLOT_TO_ENV.forEach((k,v) -> {
String bpName = bb.getBlueprint(v);
pb.item(k-1, getWorldInstrTile(v));
@ -148,6 +144,25 @@ public class BlueprintManagementPanel {
}
/**
* Gets the panel item for Blueprint Bundle
* @param bb - blueprint bundle
* @return - panel item
*/
protected PanelItem getBundleIcon(BlueprintBundle bb) {
return new PanelItemBuilder()
.name(t("edit-description"))
.description(bb.getDescription())
.icon(bb.getIcon())
.clickHandler((panel, u, clickType, slot) -> {
u.closeInventory();
// Description conversation
askForDescription(u.getPlayer(), addon, bb);
return true;
})
.build();
}
private PanelItem getWorldInstrTile(Environment env) {
return new PanelItemBuilder()
.name(t("world-name-syntax", TextVariables.NAME, Util.prettifyText(env.name())))
@ -187,7 +202,15 @@ public class BlueprintManagementPanel {
}).build();
}
private PanelItem getBlueprintItem(GameModeAddon addon, int pos, BlueprintBundle bb, Blueprint blueprint) {
/**
* Gets a panel item that fully represents a blueprint in a bundle for an addon
* @param addon - the GameMode Addon
* @param pos - the position where this icon will be placed - the description changes
* @param bb - the blueprint bundle this blueprint is in, if any
* @param blueprint - blueprint itself
* @return a panel item
*/
protected PanelItem getBlueprintItem(GameModeAddon addon, int pos, BlueprintBundle bb, Blueprint blueprint) {
// Create description
List<String> desc = blueprint.getDescription() == null ? new ArrayList<>() : blueprint.getDescription();
if ((!blueprint.equals(END_BP) && !blueprint.equals(NORMAL_BP) && !blueprint.equals(NETHER_BP))) {
@ -201,18 +224,23 @@ public class BlueprintManagementPanel {
.name(blueprint.getDisplayName() == null ? blueprint.getName() : blueprint.getDisplayName())
.description(desc)
.icon(blueprint.getIcon() == null ? Material.PAPER : blueprint.getIcon())
.glow(selected != null && pos == selected.getKey())
.clickHandler((panel, u, clickType, slot) -> {
// Renaming blueprint
if (clickType.equals(ClickType.RIGHT)) {
u.closeInventory();
this.askForBlueprintName(u.getPlayer(), addon, blueprint, bb);
return true;
}
// Handle the world squares
if (slot > MIN_WORLD_SLOT && slot < MAX_WORLD_SLOT) {
if (clickType.equals(ClickType.RIGHT)) {
u.getPlayer().playSound(u.getLocation(), Sound.BLOCK_GLASS_BREAK, 1F, 1F);
PanelItem item = getBlueprintItem(addon, slot, bb, ENV_TO_BP.get(SLOT_TO_ENV.get(slot)));
// Remove the item and replace with the blank
bb.clearBlueprint(SLOT_TO_ENV.get(slot));
panel.getItems().put(slot, item);
panel.getInventory().setItem(slot, item.getItem());
// Save
plugin.getBlueprintsManager().saveBlueprintBundle(addon, bb);
openBB(bb);
} else if (selected == null) {
u.sendMessage("commands.admin.blueprint.management.select-first");
u.getPlayer().playSound(u.getLocation(), Sound.BLOCK_ANVIL_HIT, 1F, 1F);
@ -220,35 +248,26 @@ public class BlueprintManagementPanel {
// Add
u.getPlayer().playSound(u.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F);
Blueprint bp = selected.getValue();
PanelItem item = getBlueprintItem(addon, slot, bb, bp);
// make slot the chosen one
bb.setBlueprint(SLOT_TO_ENV.get(slot), bp);
panel.getItems().put(slot, item);
panel.getInventory().setItem(slot, item.getItem());
// Save
plugin.getBlueprintsManager().saveBlueprintBundle(addon, bb);
openBB(bb);
}
} else {
// Select blueprint
if (blueprints.containsKey(slot)) {
if (selected == null) {
// Nothing selected
u.getPlayer().playSound(u.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 2F);
selected = new AbstractMap.SimpleEntry<>(slot, blueprints.get(slot));
panel.getInventory().getItem(slot).addUnsafeEnchantment(Enchantment.ARROW_DAMAGE, 1);
} else if (slot == selected.getKey()){
// Clicked on same item
if (selected != null && slot == selected.getKey()){
// Clicked on same item - deselect
selected = null;
} else {
// Another item already selected
panel.getInventory().getItem(selected.getKey()).removeEnchantment(Enchantment.ARROW_DAMAGE);
u.getPlayer().playSound(u.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 2F);
// Set selected
selected = new AbstractMap.SimpleEntry<>(slot, blueprints.get(slot));
panel.getInventory().getItem(slot).addUnsafeEnchantment(Enchantment.ARROW_DAMAGE, 1);
}
u.getPlayer().playSound(u.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 2F);
openBB(bb);
}
}
return true;
})
.build();
@ -278,6 +297,17 @@ public class BlueprintManagementPanel {
.buildConversation(whom).begin();
}
public void askForBlueprintName(Conversable whom, GameModeAddon addon, Blueprint bp, BlueprintBundle bb) {
new ConversationFactory(BentoBox.getInstance())
.withModality(true)
.withLocalEcho(false)
.withPrefix(new NameConversationPrefix())
.withTimeout(90)
.withFirstPrompt(new NamePrompt(addon, bp, bb))
.withEscapeSequence(t("name.quit"))
.buildConversation(whom).begin();
}
public void askForDescription(Conversable whom, GameModeAddon addon, BlueprintBundle bb) {
new ConversationFactory(BentoBox.getInstance())
.withModality(true)
@ -288,5 +318,12 @@ public class BlueprintManagementPanel {
.buildConversation(whom).begin();
}
/**
* @return the selected
*/
public Entry<Integer, Blueprint> getSelected() {
return selected;
}
}

View File

@ -0,0 +1,79 @@
package world.bentobox.bentobox.panels;
import java.util.Map.Entry;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.panels.PanelListener;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.blueprints.Blueprint;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
/**
* This class listens to clicks in the inventory and changes the icons of Blueprints and Blueprint Bundles
* @author tastybento
*
*/
public class IconChanger implements PanelListener {
private GameModeAddon addon;
private BlueprintBundle bb;
private BlueprintManagementPanel blueprintManagementPanel;
private BentoBox plugin;
/**
* Change the icon of a blueprint bundle or blueprint
* @param plugin - Bentobox
* @param addon - the Game Mode Addon
* @param blueprintManagementPanel - the open Blueprint Management Panel
* @param bb - the blueprint bundle
*/
public IconChanger(BentoBox plugin, GameModeAddon addon, BlueprintManagementPanel blueprintManagementPanel, BlueprintBundle bb) {
this.plugin = plugin;
this.addon = addon;
this.blueprintManagementPanel = blueprintManagementPanel;
this.bb = bb;
}
@Override
public void onInventoryClick(User user, InventoryClickEvent event) {
// Handle icon changing
if (event.getCurrentItem().getType() != null && !event.getCurrentItem().getType().equals(Material.AIR) && event.getRawSlot() > 44) {
Material icon = event.getCurrentItem().getType();
Entry<Integer, Blueprint> selected = blueprintManagementPanel.getSelected();
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F);
if (selected == null) {
// Change the Bundle Icon
bb.setIcon(icon);
// Save it
plugin.getBlueprintsManager().saveBlueprintBundle(addon, bb);
} else {
// Change the Blueprint icon
Blueprint bp = selected.getValue();
bp.setIcon(icon);
// Save it
plugin.getBlueprintsManager().saveBlueprint(addon, bp);
}
// Update the view
blueprintManagementPanel.openBB(bb);
}
}
@Override
public void onInventoryClose(InventoryCloseEvent event) {
// Do nothing
}
@Override
public void setup() {
// Do nothing
}
}

View File

@ -250,7 +250,10 @@ commands:
perm-not-required: "Not Required"
perm-format: "&e"
remove: "Right click to remove"
blueprint-instruction: "Click to select, then add to bundle"
blueprint-instruction: |
Click to select,
then add to bundle.
Right-click to rename.
select-first: "Select Blueprint first"
new-bundle: "New Bundle"
new-bundle-instructions: "Click to make a new bundle"